刚学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的时候都隐藏了?
我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的时候都隐藏了?
你看看这个库是否调用了ws2_32.dll。
因为你没有递归, 所以没有发现改模块
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的高手们,再帮我想想吧,期待中
"sendto"),(PROC)&H_sendto,GetModuleHandle(NULL));
是可以找到的
71A20000 模块 D:\windows\system32\WS2_32.dll
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法还少。