我通过覆盖函数开始的5字节的方式来达到API HOOK 的目的,部分代码如下://获取系统API调用jmp xxxx // 指令,将其保存到g_OldCode中
_asm
{
push edi
push esi
lea edi , g_OldCodeSend
mov esi , g_pfnSendProc
cld
movsd
movsb
pop edi
pop esi
}//获取新的jmp xxxx跳转指令并保存到g_NewCode中
g_NewCodeSend[0] = 0xe9;
g_NewCodeSendto[0] = 0xe9;
g_NewCodeRecv[0] = 0xe9;
g_NewCodeRecvfrom[0] = 0xe9;
_asm
{
push eax
push ebx
lea eax , MySend
mov ebx , g_pfnSendProc
sub eax , ebx
sub eax , 5
mov dword ptr [g_NewCodeSend + 1] , eax
pop eax
pop ebx
}
void HookOn()
{
DWORD dwOldProtectSend;
DWORD dwOldProtectSendto;
DWORD dwOldProtectRecv;
DWORD dwOldProtectRecvfrom;
DWORD dwTemp;
BOOL bRet = FALSE;
DWORD dwPid = GetCurrentProcessId();
DWORD dwAccess = PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE;
HANDLE hProcess = OpenProcess(dwAccess , FALSE , dwPid);
if(NULL == hProcess)
return;
bRet = VirtualProtectEx(hProcess , g_pfnSendProc , 5 , PAGE_READWRITE , &dwOldProtectSend);
bRet = WriteProcessMemory(hProcess , g_pfnSendProc , g_NewCodeSend , 5 , NULL);
bRet = VirtualProtectEx(hProcess , g_pfnSendProc , 5 , dwOldProtectSend, &dwTemp);
......
/恢复旧指令
void HookOff()
{
DWORD dwOldProtectSend;
DWORD dwOldProtectSendto;
DWORD dwOldProtectRecv;
DWORD dwOldProtectRecvfrom;
DWORD dwTemp;
BOOL bRet = FALSE;
DWORD dwPid = GetCurrentProcessId();
DWORD dwAccess = PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE;
HANDLE hProcess = OpenProcess(dwAccess , FALSE , dwPid);
if(NULL == hProcess)
return;
bRet = VirtualProtectEx(hProcess , g_pfnSendProc , 5 , PAGE_READWRITE , &dwOldProtectSend);
bRet = WriteProcessMemory(hProcess , g_pfnSendProc , g_OldCodeSend , 5 , NULL);
bRet = VirtualProtectEx(hProcess , g_pfnSendProc , 5 , dwOldProtectSend, &dwTemp);
.........但是,调试中,我发现当执行了,hookon hookoff ,这类写内存操作之后,我的程序退出的时候就会弹出异常,而且被HOOK 的那些应用程序也会出现各种问题,会崩溃!
我程序退出的异常对话框显示如下:
Unhandled exception at 0x10012b04 (InjectSocket.dll) in HookSocket.exe: 0xC0000005: Access violation writing location 0x10018050.
搞不清楚到底是怎么回事!还有,我想问下,在调试这段代码的时候push eax
push ebx
lea eax , MySend
mov ebx , g_pfnSendProc
sub eax , ebx
sub eax , 5
mov dword ptr [g_NewCodeSend + 1] , eax
pop eax
pop ebxMySend 的地址比g_pfnSendProc 的地址要小,这样做减法,会不会出问题!相对地址,是怎么来计算的!
为什么要用MySend - g_pfnSendProc ,而不反过来这样减g_pfnSendProc - MySend ,望高手指点!谢谢!!
还问下,通过覆盖代码的方式来拦截API ,是不是已经不在被使用了??需要其他方式来拦截API ,有的话,不妨说说!谢谢各位!

解决方案 »

  1.   

    你搜一下钩子函数 及 dll导入表,这个比直接操作内存,然后jump好一些
    你是怎样查找api函数入口点的?对于一般dll来说,入口点是经常变化的,需要现查
      

  2.   

    http://blog.csdn.net/DavidHsing/archive/2009/05/27/4219226.aspx建议 lz 还是用 IAT 吧
      

  3.   

    我是先用全局钩子注入所有进程,然后,在各自的进程中,通过GetProcAddress对函数定位的!
      

  4.   

    想问下,IAT方式有没有局限性,我想所有调用目标API 的进程!的调用都被拦截!