关于覆盖API代码HOOK的疑问?高手请进!

iamsuqi 2009-03-12 04:40:18
如果要通过覆盖API代码前几个字节进行JUMP跳转,有本书上说是WriteProcessMemory写DLL中API代码的前几个字节!
问题来了,大家知道DLL是Windows系统内共享的只有一份拷贝,其它进程只是映射该内存拷贝到自己的虚拟地址空间,如果用WriteProcessMemory改写该地址,到底是改写了哪里?是系统共享的DLL内存空间还是进程自己的虚拟地址空间???
1、如果是改写系统共享DLL内存空间,那这种HOOK是存在问题的,因为其它进程也要读这个空间,而JUMP跳转地址代码却不存在!
2、如果说是改写了进程自己的虚拟地址空间,那DLL共享对这个进程就不成立了,这个进程必须有一个新的DLL或API代码拷贝!
3、能不能直接修改所有进程共享的那份DLL内存拷贝?
4、进程自己是否可以使用非共享的自己独占的User32等DLL?就是不和别人共享这些DLL?
到底再修改DLL中API代码前几个字节时发生了什么?请高手讲解一下!书本上只只知其然,不知其所以然!
...全文
194 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
pangqi022 2009-03-17
  • 打赏
  • 举报
回复
对于第三个问题
应该可以做 inline的hook 在DLL加栽前直接修改你想hook的DLL文件
野男孩 2009-03-15
  • 打赏
  • 举报
回复
共享的前提是大家用的都一样。当发生了变化时,会触发系统的CopyOnWrite机制(写拷贝)。这样的话,被更改的进程中的dll就会跟别的进程中的代码不一样。
iamsuqi 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 wangjia184 的回复:]
...而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且…
[/Quote]
现在HOOK时修改的是API的代码前几个字节,不是它的数据?这时候是不是代码也有一份拷贝???
yeliangang 2009-03-13
  • 打赏
  • 举报
回复
补充:或者说每个进程空间里都有一个SSDT?
yeliangang 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wangjia184 的回复:]
Unducomented Windows 2000 译文:

系统服务调度表(SSDT)中存放了所有系统服务函数的入口地址。系统服务调度程序通过查找SSDT来调用相应的系统服务。因此,Rootkit可以将SSDT中的系统服务地址替换为自己代码的地址。这样,当调用系统服务时,实际运行的是Rootkit代码,由Rootkit代码调用真正的系统服务并对结果作相应处理。系统中存在2个SSDT,位于文件ntoskrnl.exe中,分别由指针KeServiceDescriptorTable和KeServiceDescrip…
[/Quote]
那又有个问题了,SSDT里的函数入口地址应该是物理地址了吧,要是虚拟地址那对各个进程都不一样这个表也就不起作用了,那么:
1.如果是物理地址,那么操作系统讲面临虚拟模式向纯保护模式的切换,这中间不会出现问题么?
2.如果是用专门建立一个公用系统服务进程,另外其他的进程通过这个服务进程得到相对服务进程来说的入口地址,接下来其它进程又怎么跳至这个服务进程中的函数入口地址呢?
另外,如果属于第二钟情况,那么这种hook只针对一个进程,当它修改了地址后,其他的进程来访时岂不都要转到这个虚拟地址中去?而这个地址中是什么谁也无法预料啊?
iamsuqi 2009-03-13
  • 打赏
  • 举报
回复
楼上说的是呀!如果HOOK共享DLL,JUMP时就必须跳到一个共享的代码空间,而且这一空间地址在所有PROCESS中都必须是相同的!
如果DLL在PROCESS中被加载时进行了重定位基址那么是否一定COPY副本?
what2say3 2009-03-13
  • 打赏
  • 举报
回复
NT下的OS DLL已经不在是唯一的那个image被shared的了,各Process都有它们自己的image拷贝;第3点理论上可以实现,但是不靠谱从难度和系统稳定性的影响来说,假设你找到了那个'父本'image,你的HOOK要跳到一个什么地址呢?别忘记那个父本的hook也会被映射到所有的process
hxfjb 2009-03-13
  • 打赏
  • 举报
回复
所以在用户态修改进程的DLL达到hook的目的,因为Copy-On-Write机制,修改的内容仅仅影响本进程。你要试图hook所有的进程才能达到在系统范围内hook的目的。
csbinchina 2009-03-13
  • 打赏
  • 举报
回复
mark
CodeProject-Jerry 2009-03-12
  • 打赏
  • 举报
回复
Unducomented Windows 2000 译文:

系统服务调度表(SSDT)中存放了所有系统服务函数的入口地址。系统服务调度程序通过查找SSDT来调用相应的系统服务。因此,Rootkit可以将SSDT中的系统服务地址替换为自己代码的地址。这样,当调用系统服务时,实际运行的是Rootkit代码,由Rootkit代码调用真正的系统服务并对结果作相应处理。系统中存在2个SSDT,位于文件ntoskrnl.exe中,分别由指针KeServiceDescriptorTable和KeServiceDescriptor Table Shadow导出,对应了2类不同的系统服务。前者对应的系统服务,功能代码在ntoskrnl.exe中实现,用户模式下的访问接口由NTDLL.dll提供,通常kernel32.dll/advapi32.dll导出的API最终调用的都是这类系统服务;后者对应的是USER和GDI系统服务,访问接口由User32.dll/Gdi32.dll提供,功能代码在Win32k.sys中实现。Rootkit关注的主要是对进程、文件、注册表等的操作,对应的系统服务属于第1类,需修改KeService Descriptor Table导出的SSDT。KeServiceDescriptorTable指向一个KSERVICE_TABLE_ DESCRIPTOR结构,其中的Service TableBase指针指向真正的系统服务入口地址表。如要Hook某个系统服务,将该表中相应的代码入口地址修改为钩子函数的地址即可。例如,ZwQuerySystemInformation是系统列举进程时须调用的系统服务,通过挂钩它来实现进程的隐藏
CodeProject-Jerry 2009-03-12
  • 打赏
  • 举报
回复
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。

对于你说的第3点,要么注入所有的应用层进程修改, 要么在驱动层去挂钩。
从应用层发起的API调用, 在通过 Win32 Sub System(包括User32.dll, Gdi32.dll,. Advapi32.dll, Kernel32.dll 等), 就进入了驱动层,由Ntdll.dll转发调用。

在内核中,最常见的HOOK方式就是Hook SSDT. Hook掉你需要的内核层API,全局有效

wwwhhb4001 2009-03-12
  • 打赏
  • 举报
回复

学习
jingzhongrong 2009-03-12
  • 打赏
  • 举报
回复
进程自己的虚拟地址空间。在没改写前共享同一份dll内容。楼主可看看Windows的Copy-On-Write机制。
CLATZJ 2009-03-12
  • 打赏
  • 举报
回复
关注
码农wuhb 2009-03-12
  • 打赏
  • 举报
回复
Hook必须用DLL注入到其他进程,而且是共享应用程序的内存,3.4点楼主可能不太容易实现哟:)

15,471

社区成员

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

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