```cpp
#include
// Define the API hooking item structure
typedef struct _HOOK_ITEM {
DWORD dwAddr; // Address where the IAT entry is located
DWORD dwOldValue; // Original function address of the IAT entry
DWORD dwNewValue; // New function address of the IAT entry
} HOOK_ITEM, *PHOOK_ITEM;
HOOK_ITEM HookItem = {0}; // Define the IAT entry to save the IAT information of MessageBoxA
// Define the function prototype of MessageBoxA
typedef int (WINAPI* PFNMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
// Define the implementation function to redirect API
BOOL WINAPI RedirectApi(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem);
// Custom MessageBoxA function
// Realize monitoring of input and output parameters of the original MessageBoxA, and even cancel the call
int WINAPI NEW_MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
// Here you can observe/modify the call parameters, and even cancel the call and return directly.
// ……
// Get the original function address
PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.dwOldValue;
// Output test information,
// If you call MessageBoxA directly here, it will enter an infinite loop
pfnMessageBoxA(hWnd, "This is the message box in the API redirection process", "Test", 0);
// Call the original function
int ret = pfnMessageBoxA(hWnd, lpText, lpCaption, uType);
// Here you can view/modify the return value of the original function call
// ……
return ret;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Redirect API
if (!RedirectApi("USER32.dll", "MessageBoxA", (DWORD)NEW_MessageBoxA, &HookItem))
OutputDebugStringA("RedirectApi failed!");
else
OutputDebugStringA("RedirectApi success!");
MessageBoxA(0, "Normal message box", "Test", 0);
return 0;
}
// Implement API redirection
// Parameter pDllName: DLL name where the target API is located
// Parameter pFunName: Target API name
// Parameter dwNewProc: Address of the custom function
// Parameter pItem: Used to save IAT entry information
BOOL WINAPI RedirectApi(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem)
{
// Check if parameters are valid
if (pDllName == NULL || pFunName == NULL || !dwNewProc || !pItem)
return FALSE;
// Check if the target module exists
char szTempDllName[256] = {0};
DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL);
if (dwBaseImage == 0)
return FALSE;
// Get the pointer to the PE file header information
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew));
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader);
// Traverse the import table
PIMAGE_THUNK_DATA pThunk, pIAT;
PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage + pOptionalHeader->DataDirectory[1].VirtualAddress);
while (pIID->FirstThunk)
{
// Check if it is the target module
if (strcmp((PCHAR)(dwBaseImage + pIID->Name), pDllName))
{
pIID++;
continue;
}
pIAT = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->FirstThunk);
if (pIID->OriginalFirstThunk)
pThunk = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->OriginalFirstThunk);
else
pThunk = pIAT;
// Traverse the IAT
DWORD dwThunkValue = 0;
while ((dwThunkValue = *((DWORD*)pThunk)) != 0)
{
if ((dwThunkValue & IMAGE_ORDINAL_FLAG32) == 0)
{
// Check if it is the target function
if (strcmp((PCHAR)(dwBaseImage + dwThunkValue + 2), pFunName) == 0)
{
// Fill in the function redirection information
pItem->dwAddr = (DWORD)pIAT;
pItem->dwOldValue = *((DWORD*)pIAT);
pItem->dwNewValue = dwNewProc;
// Modify the IAT entry
DWORD dwOldProtect = 0;
VirtualProtect(pIAT, 4, PAGE_READWRITE, &dwOldProtect);
*((DWORD*)pIAT) = dwNewProc;
VirtualProtect(pIAT, 4, PAGE_READWRITE, &dwOldProtect);
return TRUE;
}
}
pThunk++;
pIAT++;
}
pIID++;
}
return FALSE;
}
```
#include
// Define the API hooking item structure
typedef struct _HOOK_ITEM {
DWORD dwAddr; // Address where the IAT entry is located
DWORD dwOldValue; // Original function address of the IAT entry
DWORD dwNewValue; // New function address of the IAT entry
} HOOK_ITEM, *PHOOK_ITEM;
HOOK_ITEM HookItem = {0}; // Define the IAT entry to save the IAT information of MessageBoxA
// Define the function prototype of MessageBoxA
typedef int (WINAPI* PFNMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
// Define the implementation function to redirect API
BOOL WINAPI RedirectApi(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem);
// Custom MessageBoxA function
// Realize monitoring of input and output parameters of the original MessageBoxA, and even cancel the call
int WINAPI NEW_MessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
// Here you can observe/modify the call parameters, and even cancel the call and return directly.
// ……
// Get the original function address
PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.dwOldValue;
// Output test information,
// If you call MessageBoxA directly here, it will enter an infinite loop
pfnMessageBoxA(hWnd, "This is the message box in the API redirection process", "Test", 0);
// Call the original function
int ret = pfnMessageBoxA(hWnd, lpText, lpCaption, uType);
// Here you can view/modify the return value of the original function call
// ……
return ret;
}
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Redirect API
if (!RedirectApi("USER32.dll", "MessageBoxA", (DWORD)NEW_MessageBoxA, &HookItem))
OutputDebugStringA("RedirectApi failed!");
else
OutputDebugStringA("RedirectApi success!");
MessageBoxA(0, "Normal message box", "Test", 0);
return 0;
}
// Implement API redirection
// Parameter pDllName: DLL name where the target API is located
// Parameter pFunName: Target API name
// Parameter dwNewProc: Address of the custom function
// Parameter pItem: Used to save IAT entry information
BOOL WINAPI RedirectApi(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem)
{
// Check if parameters are valid
if (pDllName == NULL || pFunName == NULL || !dwNewProc || !pItem)
return FALSE;
// Check if the target module exists
char szTempDllName[256] = {0};
DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL);
if (dwBaseImage == 0)
return FALSE;
// Get the pointer to the PE file header information
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew));
PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader);
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader);
// Traverse the import table
PIMAGE_THUNK_DATA pThunk, pIAT;
PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage + pOptionalHeader->DataDirectory[1].VirtualAddress);
while (pIID->FirstThunk)
{
// Check if it is the target module
if (strcmp((PCHAR)(dwBaseImage + pIID->Name), pDllName))
{
pIID++;
continue;
}
pIAT = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->FirstThunk);
if (pIID->OriginalFirstThunk)
pThunk = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->OriginalFirstThunk);
else
pThunk = pIAT;
// Traverse the IAT
DWORD dwThunkValue = 0;
while ((dwThunkValue = *((DWORD*)pThunk)) != 0)
{
if ((dwThunkValue & IMAGE_ORDINAL_FLAG32) == 0)
{
// Check if it is the target function
if (strcmp((PCHAR)(dwBaseImage + dwThunkValue + 2), pFunName) == 0)
{
// Fill in the function redirection information
pItem->dwAddr = (DWORD)pIAT;
pItem->dwOldValue = *((DWORD*)pIAT);
pItem->dwNewValue = dwNewProc;
// Modify the IAT entry
DWORD dwOldProtect = 0;
VirtualProtect(pIAT, 4, PAGE_READWRITE, &dwOldProtect);
*((DWORD*)pIAT) = dwNewProc;
VirtualProtect(pIAT, 4, PAGE_READWRITE, &dwOldProtect);
return TRUE;
}
}
pThunk++;
pIAT++;
}
pIID++;
}
return FALSE;
}
```
FITTEC-TE
