前天看到kruglinski的一段程序,我看了一下今天花了一下午的时间来自己实现了一个。不过我的没有用动态地址的方法,而是自己去写了静态的地址到里面灵活性没有他的大不过功能上面还是差不多的。下面我简单讲一下我的原理。
跳转的具体原理 就是用两句汇编句:
mov eax , 12345678 (自定义函数的地址,每个机器各不相同是需要手动调整) jmp eax
汇编代码:
e8 78 56 34 12 //第2,3,4,5是需要手工调整的 ff e0
1。计算出地址“冒名顶替函数”的入口地址。 2。得要HOOK的API函数的地址。 3。保存API函数的入口内容。 4。修改API函数的入口内容。 5。再在“冒名顶替函数”里面实现完其他功能后,把原来的API函数的入口内容给回去。
代码如下:
// //write by Gxter // //通过覆盖系统函数的地址来实现HOOK API // #include "stdio.h" #include "windows.h" #include "tchar.h"
BYTE addr_old[8] = {0}; BYTE addr_new[8] = { 0xB8, 0x20, 0x10, 0x40, 0x00, 0xFF, 0xE0, 0x00 }; //第2,3,4,5是需要手工调整的(重要的步骤) DWORD pfnMsgBox=0; //API函数地址
int WINAPI MessageBoxProxy(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType) { int ret = 0;
DWORD dwOldProtect; MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery((void *)pfnMsgBox, &mbi, sizeof(mbi)); ::VirtualProtect((void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);
// 写入原来的执行代码 ::WriteProcessMemory(::GetCurrentProcess(), (void *)pfnMsgBox, addr_old, sizeof(DWORD)*2, NULL);
::VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);
ret=MessageBox(hWnd,"gxter","gxter",uType);
return ret; }
//----------------------------------------------程序入口 int main() { DWORD dwOldProtect; MEMORY_BASIC_INFORMATION mbi;
MessageBox(NULL,_T("Hook Demo!"),_T("API Hook"),MB_ICONINFORMATION); pfnMsgBox=(DWORD)GetProcAddress(GetModuleHandle(_T("user32.dll")),_T("MessageBoxA")); printf("api入口地址: %x/n",pfnMsgBox);
VirtualQuery( (void *)pfnMsgBox, &mbi, sizeof(mbi) ); //修改我们要改的地址的页属性,为可读可写 VirtualProtect( (void *)pfnMsgBox, 8, PAGE_READWRITE, &dwOldProtect);
// 保存原来的执行代码 memcpy(addr_old, (void *)pfnMsgBox, 8);
// 写入新的执行代码 WriteProcessMemory( GetCurrentProcess(), (void *)pfnMsgBox, addr_new, sizeof(DWORD)*2, NULL); //修改为原来的属性属性 VirtualProtect((void *)pfnMsgBox, 8, mbi.Protect, 0);
//当调用这个函数的时候就跳到我的函数上面了 MessageBox(NULL,_T("Hook Demo!"),_T("API Hook"),MB_ICONINFORMATION);
getchar(); return 0; }
//--------------------------------the end-----------------------------
|
用心飞翔! | |