欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

(40)写拷贝

发布时间:2025/3/21 编程问答 22 豆豆
生活随笔 收集整理的这篇文章主要介绍了 (40)写拷贝 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一、什么是写拷贝

写拷贝是VAD树里的属性。当访问一个线性地址,页表项 PTE = 0 时,就会触发缺页异常,跳转到异常处理函数,处理函数会检查VAD树,看看这个线性地址到底是没挂物理页,还是写拷贝,或者是别的什么情况。

举个例子,在Windows XP系统里,MessageBoxA 这个函数位于 ntdll.dll,假如我想HOOK它,比如把它头两个字节的 MOV EDI,EDI 改成JMP,此时由于 PTE = 0,就会触发缺页异常。然后异常处理函数遍历 VAD 树,就会发现 MessageBoxA 的属性是 WriteCopy.

此时,如果你对数据进行修改,系统会帮你拷贝一份 MessageBoxA 的代码,然后你的HOOK就只对本进程有效。

二、如何在windbg中打印 VAD 树

首先,!process 0 0 查看进程信息

PROCESS 81ecbd50 SessionId: 0 Cid: 0118 Peb: 7ffde000 ParentCid: 05c4DirBase: 11edc000 ObjectTable: e15ae880 HandleCount: 18.Image: MessageBoxA_PDE_PTE.exe

然后查看 EPROCESS 结构:

kd> dt _EPROCESS 81ecbd50 ntdll!_EPROCESS...+0x11c VadRoot : 0x81e8e8d8 Void+0x120 VadHint : 0x81e8e8d8 Void+0x124 CloneRoot : (null) +0x128 NumberOfPrivatePages : 0x4a+0x12c NumberOfLockedPages : 0+0x130 Win32Process : 0xe1ad8608 Void+0x134 Job : (null) ...

然后 !vad 打印:

kd> !vad 0x81e8e8d8 VAD level start end commit 81d440b0 ( 1) 10 10 1 Private READWRITE 81e2cb70 ( 2) 20 20 1 Private READWRITE 81e8e8d8 ( 0) 30 12f 6 Private READWRITE 81d12318 ( 3) 130 132 0 Mapped READONLY Pagefile-backed section 81e552c8 ( 2) 140 140 0 Mapped READONLY Pagefile-backed section 81e25c60 ( 4) 150 24f 9 Private READWRITE 81d71d60 ( 3) 250 25f 6 Private READWRITE 81dead50 ( 5) 260 26f 0 Mapped READWRITE Pagefile-backed section 81f12898 ( 4) 270 285 0 Mapped READONLY \WINDOWS\system32\unicode.nls 81e3f2d8 ( 6) 290 2d0 0 Mapped READONLY \WINDOWS\system32\locale.nls 81d5e648 ( 5) 2e0 320 0 Mapped READONLY \WINDOWS\system32\sortkey.nls 81ec9320 ( 7) 330 335 0 Mapped READONLY \WINDOWS\system32\sorttbls.nls 81d707f0 ( 6) 340 380 0 Mapped READONLY Pagefile-backed section 81e929c0 ( 7) 3d0 3df 8 Private READWRITE 81e90970 ( 8) 3e0 3e0 1 Private READWRITE 81b47688 ( 9) 3f0 3f0 1 Private READWRITE 81b29358 ( 1) 400 41a 18 Mapped Exe EXECUTE_WRITECOPY \;F:\VBoxSvr\Projects\MessageBoxA_PDE_PTE\Debug\MessageBoxA_PDE_PTE.exe 81d400a8 ( 6) 420 4e7 0 Mapped EXECUTE_READ Pagefile-backed section 81b0f3a0 ( 7) 4f0 5f2 0 Mapped READONLY Pagefile-backed section 81d5ed80 ( 8) 600 8ff 0 Mapped EXECUTE_READ Pagefile-backed section 81e918b0 ( 9) 900 90f 8 Private READWRITE 81d40110 (10) 910 912 0 Mapped READONLY \WINDOWS\system32\ctype.nls 81d18980 (11) 920 92d 0 Mapped READWRITE Pagefile-backed section 81fc0768 (12) 930 930 1 Private READWRITE 81d4b238 ( 5) 10200 10371 7 Mapped Exe EXECUTE_WRITECOPY \;F:\VBoxSvr\Projects\MessageBoxA_PDE_PTE\Debug\MSVCR100D.dll 81aee750 ( 7) 62c20 62c28 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\lpk.dll 81e55128 ( 8) 73fa0 7400a 16 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\usp10.dll 81d8fd30 ( 6) 76300 7631c 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\imm32.dll 81d55d00 ( 7) 76d70 76d91 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\apphelp.dll 81d57998 ( 8) 77bd0 77bd7 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\version.dll 81d19630 ( 4) 77d10 77d9f 2 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\user32.dll 81d90128 ( 6) 77da0 77e48 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\advapi32.dll 81ea8c48 ( 7) 77e50 77ee1 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\rpcrt4.dll 81d5e618 ( 5) 77ef0 77f38 2 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\gdi32.dll 81d40178 ( 6) 77fc0 77fd0 1 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\secur32.dll 81da9d10 ( 3) 7c800 7c91d 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\kernel32.dll 81d5bca0 ( 2) 7c920 7c9b2 5 Mapped Exe EXECUTE_WRITECOPY \WINDOWS\system32\ntdll.dll 81dc4f70 ( 4) 7f6f0 7f7ef 0 Mapped EXECUTE_READ Pagefile-backed section 81b2f1d8 ( 3) 7ffa0 7ffd2 0 Mapped READONLY Pagefile-backed section 81d13f88 ( 5) 7ffdd 7ffdd 1 Private READWRITE 81f5c498 ( 4) 7ffde 7ffde 1 Private READWRITE Total VADs: 41 average level: 6 maximum depth: 12

三、如何绕过写拷贝

提供两种思路:

1、另外申请一个线性地址,映射到MessageBoxA的物理页,设置PTE的R/W属性,使其可读写。
2、修改 VAD 树,将写拷贝改为可读可写。

总结

以上是生活随笔为你收集整理的(40)写拷贝的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。