Copy-On-Write机制,全局hook(一)
2010-09-28 18:29
405 查看
我本来想在ring3下全局hook,大约有这么几种方法:
1: 用SetWindowsHookEx,安装的钩子类型,如WH_GETMESSAGE,WH_KEYBOARD等,但这种方法只能挂接系统中的所有GUI线程。
2: 还有一种通过插入注册表来实现 HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs,这种方法简单,但是还是只能挂钩GUI 程序,并且这个键值已经被广大HIPS所关注,吃力不讨好。
3: 用CreateRemoteThread注入到系统所有进程,但这种方法效率太低,特别是实时性太差,因为它要不停循环扫描所有进程,如果突然新建一个进程可能要过好久才能注进去,可能会漏掉很多API。
4: 通过挂钩NtResumeThread实现全局Hook,这种方法比较好,可以看http://www.xfocus.net/articles/200805/981.html
5: 禁用Copy-On-Write机制实现全局hook,但是难度很大,最终还是要去ring0禁用,http://www.xfocus.net/articles/200510/830.html
(它是非PAE的)
说起Copy-On-Write,先看一个结构
struct _hardware_pte_x86 (sizeof=4)
+0 bits0-0 valid
+0
bits1-1 write
+0 bits2-2 owner
+0 bits3-3
writethrough
+0 bits4-4 cachedisable
+0 bits5-5
accessed
+0 bits6-6 dirty
+0 bits7-7 largepage
+0
bits8-8 global
+0 bits9-9 copyonwrite
+0 bits10-10
prototype
+0 bits11-11 reserved
+0 bits12-31
pageframenumber
从上面可以看出,bits 9 被用于Copy-On-Write机制!
系统中很多dll的页面都是Copy-On-Write,但是我用调试器观察却发现Copy-On-Write(bit 9)都没有置1,调试了N久终于明白了:
只怪我被调试器忽悠了,那是因为默认所有DLL代码页、文件头等都是只读(PAGE_READONLY)的,根本不能修改。只要把
它们改成可写的,相应PTE的CopyOnWrite(bit 9)就会显现出来,但write(bit 1)仍然为0,因为copy-on-write
一定会引发异常 KiTrap0E->MmAccessFault->MiCopyOnWrite,所有这两位一定是配合使用的。我们以ntdll举例:
用OD任意加载/附加一个exe/进程,Alt+M 打开内存映射表
.txt代码节 (7c921000)
然后打开windbg->Kernel Debug
lkd> !process 0 0 Test.exe
PROCESS 87b99c88 SessionId: 0 Cid: 0f78 Peb: 7ffd5000 ParentCid: 058c
DirBase: 0a7c0600
ObjectTable: e3b9f270 HandleCount: 12.
Image: Test.exe
lkd> !vtop 0a7c0600
7c921000
X86VtoP: Virt 7c921000, pagedir a7c0600
X86VtoP: PAE PDPE a7c0608 - 000000000bdc5801
X86VtoP: PAE PDE bdc5f20 - 000000002d5e6867
X86VtoP: PAE PTE 2d5e6908 - 000000000e227025
X86VtoP: PAE Mapped phys e227000
Virtual address 7c921000 translates to physical address e227000.
!vtop可以把虚拟地址转换成物理地址,蓝色部分就是PTE!
再用OD把内存映射表中的7c921000一行改成read/write(右键单击,od的访问属性一栏不准的),再用windbg查看:
lkd> !vtop 0a7c0600
7c921000
X86VtoP: Virt 7c921000, pagedir a7c0600
X86VtoP: PAE PDPE a7c0608 - 000000000bdc5801
X86VtoP: PAE PDE bdc5f20 - 000000002d5e6867
X86VtoP: PAE PTE 2d5e6908 - 800000000e227225
X86VtoP: PAE Mapped phys e227000
Virtual address 7c921000 translates to physical address e227000.
哈哈,确实只有第九位发生变化吧(最高位置1,可能是不可执行的意思,XD Flag)。
这时,如果改动.text节的内容的话
lkd> !vtop 0a7c0600
7c921000
X86VtoP: Virt 7c921000, pagedir a7c0600
X86VtoP: PAE PDPE a7c0608 - 000000000bdc5801
X86VtoP: PAE PDE bdc5f20 - 000000002d5e6867
X86VtoP: PAE PTE 2d5e6908 - 0000000064e2e025
X86VtoP: PAE Mapped phys 64e2e000
Virtual address 7c921000 translates to physical address 64e2e000
.
可以看到PTE发生了巨大变化,从新映射了一个新的物理页64e2e000
!
也可以试一下其它节,但是千万不要去试.data数据节,因为软件在运行过程中早就修改了data数据,也就是说早就引发了CopyOnWrite,所
以.date已经不是原生dll映射的页了,这些页也没了写时复制特性,再改也没用。如果其它节也有这种情况,也肯定被改过了!
未完待续~~~~
1: 用SetWindowsHookEx,安装的钩子类型,如WH_GETMESSAGE,WH_KEYBOARD等,但这种方法只能挂接系统中的所有GUI线程。
2: 还有一种通过插入注册表来实现 HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs,这种方法简单,但是还是只能挂钩GUI 程序,并且这个键值已经被广大HIPS所关注,吃力不讨好。
3: 用CreateRemoteThread注入到系统所有进程,但这种方法效率太低,特别是实时性太差,因为它要不停循环扫描所有进程,如果突然新建一个进程可能要过好久才能注进去,可能会漏掉很多API。
4: 通过挂钩NtResumeThread实现全局Hook,这种方法比较好,可以看http://www.xfocus.net/articles/200805/981.html
5: 禁用Copy-On-Write机制实现全局hook,但是难度很大,最终还是要去ring0禁用,http://www.xfocus.net/articles/200510/830.html
(它是非PAE的)
说起Copy-On-Write,先看一个结构
struct _hardware_pte_x86 (sizeof=4)
+0 bits0-0 valid
+0
bits1-1 write
+0 bits2-2 owner
+0 bits3-3
writethrough
+0 bits4-4 cachedisable
+0 bits5-5
accessed
+0 bits6-6 dirty
+0 bits7-7 largepage
+0
bits8-8 global
+0 bits9-9 copyonwrite
+0 bits10-10
prototype
+0 bits11-11 reserved
+0 bits12-31
pageframenumber
从上面可以看出,bits 9 被用于Copy-On-Write机制!
系统中很多dll的页面都是Copy-On-Write,但是我用调试器观察却发现Copy-On-Write(bit 9)都没有置1,调试了N久终于明白了:
只怪我被调试器忽悠了,那是因为默认所有DLL代码页、文件头等都是只读(PAGE_READONLY)的,根本不能修改。只要把
它们改成可写的,相应PTE的CopyOnWrite(bit 9)就会显现出来,但write(bit 1)仍然为0,因为copy-on-write
一定会引发异常 KiTrap0E->MmAccessFault->MiCopyOnWrite,所有这两位一定是配合使用的。我们以ntdll举例:
用OD任意加载/附加一个exe/进程,Alt+M 打开内存映射表
.txt代码节 (7c921000)
然后打开windbg->Kernel Debug
lkd> !process 0 0 Test.exe
PROCESS 87b99c88 SessionId: 0 Cid: 0f78 Peb: 7ffd5000 ParentCid: 058c
DirBase: 0a7c0600
ObjectTable: e3b9f270 HandleCount: 12.
Image: Test.exe
lkd> !vtop 0a7c0600
7c921000
X86VtoP: Virt 7c921000, pagedir a7c0600
X86VtoP: PAE PDPE a7c0608 - 000000000bdc5801
X86VtoP: PAE PDE bdc5f20 - 000000002d5e6867
X86VtoP: PAE PTE 2d5e6908 - 000000000e227025
X86VtoP: PAE Mapped phys e227000
Virtual address 7c921000 translates to physical address e227000.
!vtop可以把虚拟地址转换成物理地址,蓝色部分就是PTE!
再用OD把内存映射表中的7c921000一行改成read/write(右键单击,od的访问属性一栏不准的),再用windbg查看:
lkd> !vtop 0a7c0600
7c921000
X86VtoP: Virt 7c921000, pagedir a7c0600
X86VtoP: PAE PDPE a7c0608 - 000000000bdc5801
X86VtoP: PAE PDE bdc5f20 - 000000002d5e6867
X86VtoP: PAE PTE 2d5e6908 - 800000000e227225
X86VtoP: PAE Mapped phys e227000
Virtual address 7c921000 translates to physical address e227000.
哈哈,确实只有第九位发生变化吧(最高位置1,可能是不可执行的意思,XD Flag)。
这时,如果改动.text节的内容的话
lkd> !vtop 0a7c0600
7c921000
X86VtoP: Virt 7c921000, pagedir a7c0600
X86VtoP: PAE PDPE a7c0608 - 000000000bdc5801
X86VtoP: PAE PDE bdc5f20 - 000000002d5e6867
X86VtoP: PAE PTE 2d5e6908 - 0000000064e2e025
X86VtoP: PAE Mapped phys 64e2e000
Virtual address 7c921000 translates to physical address 64e2e000
.
可以看到PTE发生了巨大变化,从新映射了一个新的物理页64e2e000
!
也可以试一下其它节,但是千万不要去试.data数据节,因为软件在运行过程中早就修改了data数据,也就是说早就引发了CopyOnWrite,所
以.date已经不是原生dll映射的页了,这些页也没了写时复制特性,再改也没用。如果其它节也有这种情况,也肯定被改过了!
未完待续~~~~
相关文章推荐
- Copy-On-Write机制,全局hook(二)
- (转载)绕过Copy-On-Write机制安装全局Hook
- 绕过Copy-On-Write机制安装全局Hook
- 绕过Copy-On-Write机制安装全局Hook
- 写时拷贝机制(copy on write)(转自搜狐达人空间的笔记)
- 从win32中的写时复制(Copy on write )机制谈起
- PHP中copy on write写时复制机制介绍
- 写时拷贝机制(copy on write)(转自搜狐达人空间的笔记)
- 探索NTFS探寻Windows NT/2000 Copy On Write机制
- 探寻Windows NT/2000 Copy On Write机制(http://wecrazy.yeah.net)
- COW奶牛!Copy On Write机制了解一下
- 底层存储变量的写时复制机制(copy on write)
- 《GOF设计模式》—代理(PROXY)—Delphi源码示例:更新前拷贝机制(copy-on-write)
- PHP中copy on write写时复制机制介绍
- Matlab的copy-on-write机制、mex参数传递机制及其他
- Copy-On-Write技术
- copy on write
- std::string的Copy-on-Write:不如想象中美好 转载
- Windows内存中page的copy on write Memo
- JUC(二)—— 聊聊 Copy-On-Write