# Include <windows. h>
// Define the API hook item Structure
Typedef struct _ hook_item {
DWORD dwaddr; // address of the IAT entry
DWORD dwoldvalue; // Original Function address of the IAT item
DWORD dwnewvalue; // new function address of the IAT item
} Hook_item, * phook_item;
Hook_item hookitem = {0}; // defines the IAT item to save the IAT item information of messageboxa
// Define the messageboxa function prototype
Typedef int (winapi * pfnmessageboxa) (hwnd, lpcstr lptext, lpcstr lpcaption, uint utype );
// Define the implementation function of the redirection API
Bool winapi redirectapi (pchar pdllname, pchar pfunname, DWORD dwnewproc, phook_item pitem );
// Custom messageboxa Function
// Monitors the input and output parameters of the original messageboxa, or even cancels the call.
Int winapi new_messageboxa (hwnd, lpcstr lptext, lpcstr lpcaption, uint utype)
{
// Here you can observe/modify the call parameters, or even cancel the call and return directly.
//......
// Obtain the original function address
Pfnmessageboxa = (pfnmessageboxa) hookitem. dwoldvalue;
// Output the test information,
// If messageboxa is called 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 );
// You can view/modify the return values of calling the original function.
//......
Return ret;
}
Int winmain (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 the redirection API
// Parameter pdllname: DLL name of the target API
// Parameter pfunname: name of the target API
// Parameter dwnewproc: the address of the custom function
// Parameter pitem: used to save IAT item information
Bool winapi redirectapi (pchar pdllname, pchar pfunname, DWORD dwnewproc, phook_item pitem)
{
// Check whether the parameters are valid
If (pdllname = NULL | pfunname = NULL |! Dwnewproc |! Pitem)
Return false;
// Check whether the target module exists
Char sztempdllname [1, 256] = {0 };
DWORD dwbaseimage = (DWORD) getmodulehandle (null );
If (dwbaseimage = 0)
Return false;
// Obtain the PE file header information pointer
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 pseheader header = (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 whether the target module is used
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 IAT
DWORD dwthunkvalue = 0;
While (dwthunkvalue = * (DWORD *) pthunk ))! = 0)
{
If (dwthunkvalue & image_ordinal_flag32) = 0)
{
// Check whether the target function is used
If (strcmp (pchar) (dwbaseimage + dwthunkvalue + 2), pfunname) = 0)
{
// Fill in 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;
}