刚学API HOOK,搞了个例子试验了几天,就是HOOK 不到 sendto之类的函数,今天找出问题所在,被我HOOK的进程的PE表里面竟然没有ws2_32.dll的记录!! 但是不知道原因,哪位高手可以看下吗?
我HOOK qq程序试过了,都是没有找到ws2_32.dll这是主要的函数
int WINAPI HookOneAPI(LPCTSTR pszCalleeModuleName,PROC pfnOriginApiAddress, 
PROC pfnDummyFuncAddress,HMODULE hModCallerModule) 

ULONG size; 
FILE *fp=fopen("333.txt","w");  //该语句仅测试使用
//获取指向PE文件中的Import中IMAGE_DIRECTORY_DESCRIPTOR数组的指针 PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) 
ImageDirectoryEntryToData(hModCallerModule,TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT,&size); if (pImportDesc == NULL) 
return 1; //查找记录,看看有没有我们想要的DLL 
for (;pImportDesc->Name;pImportDesc++) 

PSTR pszDllName = (PSTR)((PBYTE)hModCallerModule+pImportDesc->Name); fprintf(fp,"%s\n",pszDllName);  //该语句仅测试使用if (lstrcmpiA(pszDllName,pszCalleeModuleName) == 0) 
break; 
} if (pImportDesc->Name == NULL) 

return 2; 

//寻找我们想要的函数 
PIMAGE_THUNK_DATA pThunk = 
(PIMAGE_THUNK_DATA)((PBYTE)hModCallerModule+pImportDesc->FirstThunk);//IAT 
for (;pThunk->u1.Function;pThunk++) 

//ppfn记录了与IAT表项相应的函数的地址 PROC * ppfn= (PROC *)&pThunk->u1.Function; 
if (*ppfn == pfnOriginApiAddress) 

//如果地址相同,也就是找到了我们想要的函数,进行改写,将其指向我们所定义的函数 
/*
HANDLE han=GetCurrentProcess();
char *str=(char*)han;
//str=(char*)han;
MessageBox(NULL,"F2",str,MB_OK);*/
WriteProcessMemory(GetCurrentProcess(),ppfn,&(pfnDummyFuncAddress), 
sizeof(pfnDummyFuncAddress),NULL); 
return 3; 


return 4;
} 调用语句:HookOneAPI("ws2_32.dll",GetProcAddress(GetModuleHandle("ws2_32.dll"), 
"sendto"),(PROC)&H_sendto,GetModuleHandle(NULL));返回指是2,证明是没有找到ws2_32.dll,但其他的DLL可以找到,我用文件记录了测试qq的时调用的DLL:
QQBaseClassInDll.dll
QQHelperDll.dll
BasicCtrlDll.dll
iphlpapi.dll
SHLWAPI.dll
MFC42.DLL
MSVCRT.dll
KERNEL32.dll
USER32.dll
ADVAPI32.dll
SHELL32.dll
ole32.dll
OLEAUT32.dll
WSOCK32.dll
MSVCP60.dll
VERSION.dll
WINMM.dll
WININET.dll
GDI32.dll
COMCTL32.dll为何就是没有ws2_32.dll???难道这个年代调用ws2_32.dll的时候都隐藏了?

解决方案 »

  1.   

    把GetModuleHandle 改为LoadLibrary
      

  2.   

    这是什么 WSOCK32.dll 
    你看看这个库是否调用了ws2_32.dll。
      

  3.   

    进程不一定要调用ws2_32.dll,即使调用也不一定是隐式链接,你可以用LoadLibrary替代GetModuleHandle。
      

  4.   

    为何就是没有ws2_32.dll???ws2_32.dll是间接被使用, 模块WSOCK32.dll会加载ws2_32.dll
    因为你没有递归, 所以没有发现改模块
      

  5.   

    我把调用语句改成了
    HookOneAPI("ws2_32.dll",GetProcAddress(GetModuleHandle("ws2_32.dll"), 
    "sendto"),(PROC)&H_sendto,LoadLibrary(“ws2_32.dll”));
    还是不行,返回值也是2.
    而且第四个参数需要的是当前进程的句柄吧,比如下面HOOK可以实现:
    HookOneAPI("GDI32.dll",GetProcAddress(GetModuleHandle("GDI32.dll"), 
    "TextOutW"),(PROC)&H_TextOutW,GetModuleHandle(NULL)); 至于“进程不一定要调用ws2_32.dll”,我测试的是QQ程序啊,肯定用到ws2_32.dll的高手们,再帮我想想吧,期待中
      

  6.   

    HookOneAPI("ws2_32.dll",GetProcAddress(LoadLibrary("ws2_32.dll"),  
    "sendto"),(PROC)&H_sendto,GetModuleHandle(NULL)); 
      

  7.   

    兄弟,用DETOURS吧! 我钩send是没得问题的,而且很好使用。
      

  8.   

    用ollydbg看看导入库中有ws2_32.dll的函数没有。
      

  9.   

    效果和(GetModuleHandle("GDI32.dll"),"TextOutW")一样哦,至于用ollydbg看看导入库中有ws2_32.dll的函数没有
    是可以找到的
    71A20000   模块 D:\windows\system32\WS2_32.dll
      

  10.   

    我知道,QQ可以有两种方式使用send
    1)#include "socket.h"  ::send(...)
    这样用的话,编译出来QQ的PE表里就会有导入表,即你要找的ws2_32.dll及send
    这种情况就用IAT替换PE导入表的方法来HOOKAPI,就是你用的方法。2)funsend=GetprocAddress(LoadLibarary("ws2_32.dll","send")
    这样使用,编译出来PE里就没有相应的导入项了,因为他是程序里动态获取的,所以你HOOK不到。
    这时IAT法就无效了,要用JMP方法,就是直接把send函数的前5字节改成JMP->你的函数。
    JMP法对两种方式均有效,DETOURS就是用的JMP法。代码量比IAT法还少。