This article describes how to modify the first five bytes of an API in Win2k. Win2k provides us with a powerful memory API operation function-virtualprotectex, writeprocessmemeory, and readprocessmemeory. With these functions, we can dynamically modify the code in the memory. Its prototype is:
Bool virtualprotectex (
Handle hprocess, // Process Handle for memory modification
Lpvoid lpaddress, // The starting address of the memory to be modified
DWORD dwsize, // modify the memory byte
DWORD flnewprotect, // modified Memory attribute
Pdword lpfloldprotect // address of the Memory attribute before modification
);
Bool writeprocessmemory (
Handle hprocess, // handle of the process to be written
Lpvoid lpbaseaddress, // start address of the write memory
Lpvoid lpbuffer, // The data write address
DWORD nsize, // number of bytes to write
Lpdword lpnumberofbyteswritten // Number of actually written sub-sections
);
Bool readprocessmemory (
Handle hprocess, // handle of the process to be read
Lpcvoid lpbaseaddress, // start address of the Read Memory
Lpvoid lpbuffer, // address for reading data
DWORD nsize, // number of bytes to read
Lpdword lpnumberofbytesread // number of sub-sections actually read
);
For specific parameters, see the msdn help. In Win2k, the DLL and the process are in the same address space, which is different from that in Win9x/me. Therefore, you must use the hook function and remote process injection method to hook up the APIs of all processes. Here is an example of blocking messageboxa with a simple hook function:
The DLL file is:
Hhook g_hhook;
Hinstance g_hinstdll;
Farproc pfmessageboxa;
Int winapi mymessageboxa (hwnd, maid );
Byte oldmessageboxacode [5], newmessageboxacode [5];
Hmodule;
DWORD dwidold, dwidnew;
Bool bhook = false;
Void hookon ();
Void hookoff ();
Bool Init ();
Lresult winapi moushook (INT ncode, wparam, lparam );
Bool apientry dllmain (handle hmodule,
DWORD ul_reason_for_call,
Lpvoid lpreserved
)
{
Switch (ul_reason_for_call)
{
Case dll_process_attach:
If (! Init ())
{
Messageboxa (null, "init", "error", mb_ OK );
Return (false );
}
Case dll_thread_attach:
Case dll_thread_detach:
Case dll_process_detach:
If (bhook) unintallhook ();
Break;
}
Return true;
}
Lresult winapi hook (INT ncode, wparam, lparam) // empty Hook Function
{
Return (callnexthookex (g_hhook, ncode, wparam, lparam ));
}
Hookapi2_api bool installhook () // outputs the function of installing an empty hook
{
G_hinstdll = loadlibrary ("hookapi2.dll ");
G_hhook = setwindowshookex (wh_getmessage, (hookproc) Hook, g_hinstdll, 0 );
If (! G_hhook)
{
Messageboxa (null, "set error", "error", mb_ OK );
Return (false );
}
Return (true );
}
Hookapi2_api bool uninstallhook () // output the Yu in the hook function
{
Return (unhookwindowshookex (g_hhook ));
}
Bool Init () // obtain the messageboxa address after initialization, and generate a jump command for jmp xxx (mymessageboxa)
{
Hmodule = loadlibrary ("user32.dll ");
Pfmessageboxa = getprocaddress (hmodule, "messageboxa ");
If (pfmessageboxa = NULL)
Return false;
_ ASM
{
Lea EDI, oldmessageboxacode
MoV ESI, pfmessageboxa
ClD
Movsd
Movsb
}
Newmessageboxacode [0] = 0xe9; // command for the relative address of JMP mymessageboxa
_ ASM
{
Lea eax, mymessageboxa
MoV EBX, pfmessageboxa
Sub eax, EBX
Sub eax, 5
MoV dword ptr [newmessageboxacode + 1], eax
}
Dwidnew = getcurrentprocessid (); // obtain the ID of the process
Dwidold = dwidnew;
Hookon (); // start Interception
Return (true );
}
Int winapi mymessageboxa (hwnd, lpctstr lptext, lpctstr lpcaption, uint utype) // disable interception before calling the intercepted API Function
{
Int nreturn = 0;
Hookoff ();
Nreturn = messageboxa (hwnd, "MessageBox has been intercepted, haha! ", Lpcaption, utype );
Hookon ();
Return (nreturn );
}
Void hookon ()
{
Handle hproc;
Dwidold = dwidnew;
Hproc = OpenProcess (process_all_access, 0, dwidold); // obtain the Process Handle
Virtualprotectex (hproc, pfmessageboxa, 5, page_readwrite, & dwidold); // modify the attribute of the first five bytes of messageboxa in the process to be writable.
Writeprocessmemory (hproc, pfmessageboxa, newmessageboxacode, 5, 0); // change the first five bytes of messageboxa in the process to JMP to mymessageboxa
Virtualprotectex (hproc, pfmessageboxa, 5, dwidold, & dwidold); // modify the attributes of the first five bytes of messageboxa in the process to the original attributes
Bhook = true;
}
Void hookoff () // change the JMP mymessageboxa code in the process to JMP messageboxa
{
Handle hproc;
Dwidold = dwidnew;
Hproc = OpenProcess (process_all_access, 0, dwidold );
Virtualprotectex (hproc, pfmessageboxa, 5, page_readwrite, & dwidold );
Writeprocessmemory (hproc, pfmessageboxa, oldmessageboxacode, 5, 0 );
Virtualprotectex (hproc, pfmessageboxa, 5, dwidold, & dwidold );
Bhook = false;
}
// Test file:
Int apientry winmain (hinstance,
Hinstance hprevinstance,
Lpstr lpcmdline,
Int ncmdshow)
{
If (! Installhook ())
{
Messageboxa (null, "hook error! "," Hook ", mb_ OK );
Return 1;
}
Messageboxa (null, "test", "test", mb_ OK); // You Can See That test is the string we have intercepted. All processes are intercepted.
If (! Uninstallhook ())
{
Messageboxa (null, "Uninstall error! "," Hook ", mb_ OK );
Return 1;
}
Return 0;
}
The above programs are debugged and passed in Win2k, vc7.0
Image:
Call the MessageBox function directly before mounting. The effect is as follows:
Apihook hook interface:
Effect of MessageBox interception: (implemented in different processes)
Here, I re-compiled a simple program for testing and directly called the MessageBox function. The screen shows that the MessageBox of all processes in the system is mounted successfully.
The promotion of this software model: here only shows the tip of the iceberg of API hook. You may have come up with smart functions such as efile, which can implement file protection and mount functions such as findfirstfile, you can hide files and mount Winsock functions to implement some firewall functions.
Continuing study ......