这个世界变了吗?怎么HOOK不到ws2_32.dll了

after80 2008-04-23 12:57:14
刚学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的时候都隐藏了?

...全文
476 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
after80 2008-04-26
  • 打赏
  • 举报
回复 1
谢谢,收获匪浅
wushigang 2008-04-25
  • 打赏
  • 举报
回复
我知道,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法还少。
hityct1 2008-04-24
  • 打赏
  • 举报
回复
ding
cnzdgs 2008-04-23
  • 打赏
  • 举报
回复
进程不一定要调用ws2_32.dll,即使调用也不一定是隐式链接,你可以用LoadLibrary替代GetModuleHandle。
zhoujianhei 2008-04-23
  • 打赏
  • 举报
回复
这是什么 WSOCK32.dll
你看看这个库是否调用了ws2_32.dll。
CathySun118 2008-04-23
  • 打赏
  • 举报
回复
把GetModuleHandle 改为LoadLibrary
after80 2008-04-23
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 cnzdgs 的回复:]
HookOneAPI("ws2_32.dll",GetProcAddress(LoadLibrary("ws2_32.dll"),
"sendto"),(PROC)&H_sendto,GetModuleHandle(NULL));
[/Quote]
效果和(GetModuleHandle("GDI32.dll"),"TextOutW")一样哦,

至于用ollydbg看看导入库中有ws2_32.dll的函数没有
是可以找到的
71A20000 模块 D:\windows\system32\WS2_32.dll
fanofvc 2008-04-23
  • 打赏
  • 举报
回复
用ollydbg看看导入库中有ws2_32.dll的函数没有。
vcPlayer 2008-04-23
  • 打赏
  • 举报
回复
兄弟,用DETOURS吧! 我钩send是没得问题的,而且很好使用。
cnzdgs 2008-04-23
  • 打赏
  • 举报
回复
HookOneAPI("ws2_32.dll",GetProcAddress(LoadLibrary("ws2_32.dll"),
"sendto"),(PROC)&H_sendto,GetModuleHandle(NULL));
after80 2008-04-23
  • 打赏
  • 举报
回复
递归??需要怎么做呢?可以给点详细的建议吗
after80 2008-04-23
  • 打赏
  • 举报
回复
我把调用语句改成了
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的

高手们,再帮我想想吧,期待中。。。
lwykj 2008-04-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 zzz3265 的回复:]
为何就是没有ws2_32.dll???

ws2_32.dll是间接被使用, 模块WSOCK32.dll会加载ws2_32.dll
因为你没有递归, 所以没有发现改模块
[/Quote]
Yofoo 2008-04-23
  • 打赏
  • 举报
回复
为何就是没有ws2_32.dll???

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

一、简介   AheadLib 是用来生成一个特洛伊DLL的工具,用于分析DLL中的函数参数调用(比如记录Socket send了什么等等)、更改函数功能(随心所欲了:)、更改界面功能(比如在Hook里面生成一个按钮,截获事件等等)。 二、使用   1.用 AheadLib 打开要模拟的 DLL,生成一个 CPP 文件。   2.用 Visual Studio 6.0/.NET 建立一个 DLL 工程,把这个 CPP 文件加入到项目中。   3.使用 Release 方式编译,生成的 DLL 将和原来的 DLL 具有一模一样的导出函数,并且能顺利把这些函数转发到原来的函数中。   4.AheadLib 还可以生成 Hook 代码,用于截取当前进程的所有消息,这样就可以随心所欲地处理各种消息了 (修改第三方程序界面功能的好助手)。 三、备注   1.如果导出函数过多,在 Visual Studio 6.0 中,如果出现编译错误,请在项目属性关闭与编译头功能。   2.如果是 C++ 、C __stdcall、C __fastcall 的方式导出的话,生成的函数声明将会还原成原代码级别(可能需要修改才能编译,比如导出C++类的情况)。此时使用 __declspec(dllexport) 导出 ——不能指定导出序号。   3.如果是 NONAME 或者 C _CDECL 方式导出(比如 DEF 导出,大多数Windows DLL都是这种情况,比如WS2_32等等),则使用#pragma comment(linker, "/EXPORT:...)导出,且指定导出序号。   4.如果系统中没有 DbgHelp.dll,将无法识别 C++ 模式的导出。
以一个D3D为例子,表现DLL劫持 由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境量中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的输出表,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了。 利用这种方法取得控制权后,可以对主程序进行补丁。此种方法只对除kernel32.dll、ntdll.dll等核心系统库以外的DLL有效,如网络应用程序的ws2_32.dll、游戏程序中的d3d8.dll,还有大部分应用程序都调用的lpk.dll、sxs.dll,这些DLL都可被劫持。 伪造的dll制作好后,放到程序当前目录下,这样当原程序调用原函数时就调用了伪造的dll的同名函数,进入劫持DLL的代码,处理完毕后,再调用原DLL此函数。 这种补丁技术,对加壳保护的软件很有效,选择挂接的函数最好是在壳中没有被调用的,当挂接函数被执行时,相关的代码已被解压,可以直接补丁了。在有些情况下,必须用计数器统计挂接的函数的调用次数来接近OEP。此方法巧妙地绕过了壳的复杂检测,很适合加壳程序的补丁制作。 一些木马或病毒也会利用DLL劫持技术搞破坏,因此当在应用程序目录下发现系统一些DLL文件存在时,如lpk.dll,应引起注意。 首先 运行exe他会把需要的DLL加载进来,加载的目录如无特别的制定的话,现在当前目录找,然后再去系统目录找 我的附件中自带了一个D3D9的绘图程序,是VC写的 调用的是系统的D3D9.DLL(因为目录下没有) 只解压那个exe文件,是不会有文字出现的 如果把其他的DLL一起解压,就会出现下图文字  hello D3D hook! 那么我们如何劫持了D3D9.dll呢 d3d9_Ex.dll 这个文件其实就是D3D9.dll了,但是我们改名字了,程序就不认识了 我们先用 把D3D9.DLL的输出表找到,弄到易语言里,并且生成D3D9.DLL到目录 这样他调用的就是我们的DLL,但是这样会报错,因为我们的DLL没有内容只是一个壳子 只要我们再把他要调用的函数调用一下不就行了吗 源码中的汇编指令是把函数传递到原来的D3D9。现在的D3D9_Ex里 这样调用就是调用我们的DLL->原来的DLL,中间就可以加些我们需要的代码了
以一个D3D为例子,表现DLL劫持 DLL劫持原理[url=]编辑[/url] 由于输入表中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索DLL文件。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在Windows系统目录中查找,最后是在环境量中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的输出表,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了。 利用这种方法取得控制权后,可以对主程序进行补丁。此种方法只对除kernel32.dll、ntdll.dll等核心系统库以外的DLL有效,如网络应用程序的ws2_32.dll、游戏程序中的d3d8.dll,还有大部分应用程序都调用的lpk.dll、sxs.dll,这些DLL都可被劫持。 伪造的dll制作好后,放到程序当前目录下,这样当原程序调用原函数时就调用了伪造的dll的同名函数,进入劫持DLL的代码,处理完毕后,再调用原DLL此函数。 这种补丁技术,对加壳保护的软件很有效,选择挂接的函数最好是在壳中没有被调用的,当挂接函数被执行时,相关的代码已被解压,可以直接补丁了。在有些情况下,必须用计数器统计挂接的函数的调用次数来接近OEP。此方法巧妙地绕过了壳的复杂检测,很适合加壳程序的补丁制作。 一些木马或病毒也会利用DLL劫持技术搞破坏,因此当在应用程序目录下发现系统一些DLL文件存在时,如lpk.dll,应引起注意。 首先 运行exe他会把需要的DLL加载进来,加载的目录如无特别的制定的话,现在当前目录找,然后再去系统目录找 我的附件中自带了一个D3D9的绘图程序,是VC写的 调用的是系统的D3D9.DLL(因为目录下没有) 只解压那个exe文件,是不会有文字出现的 如果把其他的DLL一起解压,就会出现下图文字hello D3D hook! 那么我们如何劫持了D3D9.dll呢 d3d9_Ex.dll 这个文件其实就是D3D9.dll了,但是我们改名字了,程序就不认识了 我们先用 把D3D9.DLL的输出表找到,弄到 易语言 里,并且生成D3D9.DLL到目录 这样他调用的就是我们的DLL,但是这样会报错,因为我们的DLL没有内容只是一个壳子 只要我们再把他要调用的函数调用一下不就行了吗 源码中的汇编指令是把函数传递到原来的D3D9。现在的D3D9_Ex里 这样调用就是调用 我们的DLL->原来的DLL,中间就可以加些我们需要的代码了
一、简介   AheadLib 是用来生成一个特洛伊DLL的工具,用于分析DLL中的函数参数调用(比如记录Socket send了什么等等)、更改函数功能(随心所欲了:)、更改界面功能(比如在Hook里面生成一个按钮,截获事件等等)。 二、使用   1.用 AheadLib 打开要模拟的 DLL,生成一个 CPP 文件。   2.用 Visual Studio 6.0/.NET 建立一个 DLL 工程,把这个 CPP 文件加入到项目中。   3.使用 Release 方式编译,生成的 DLL 将和原来的 DLL 具有一模一样的导出函数,并且能顺利把这些函数转发到原来的函数中。   4.AheadLib 还可以生成 Hook 代码,用于截取当前进程的所有消息,这样就可以随心所欲地处理各种消息了 (修改第三方程序界面功能的好助手)。 三、备注   1.如果导出函数过多,在 Visual Studio 6.0 中,如果出现编译错误,请在项目属性关闭与编译头功能。   2.如果是 C++ 、C __stdcall、C __fastcall 的方式导出的话,生成的函数声明将会还原成原代码级别(可能需要修改才能编译,比如导出C++类的情况)。此时使用 __declspec(dllexport) 导出 ——不能指定导出序号。   3.如果是 NONAME 或者 C _CDECL 方式导出(比如 DEF 导出,大多数Windows DLL都是这种情况,比如WS2_32等等),则使用#pragma comment(linker, "/EXPORT:...)导出,且指定导出序号。   4.如果系统中没有 DbgHelp.dll,将无法识别 C++ 模式的导出。 主页:http://Yonsm.reg365.com 邮件:Yonsm@163.com 源码:如果需要,请访问作者主页

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧