对于DLL,书上是这么说的: “它们有助于节省内存。如果两个或多个应用程序使用同一个D L L,那么该D L L的页面只要放入R A M一次,所有的应用程序都可以共享它的各个页面。”
-摘自《windows核心编程》 但是实际操作中,却有些疑问:
我用APIHook时,必须针对每个我感兴趣的进程、对我感兴趣的API进行hook,而若果按照书中的说法,实际上我只需要对我感兴趣的API进行一次Hook就好了,跟进程无关。 这么看起来,实际与书中的说法似乎有些矛盾。琢磨了半天,只想出一个可能性:copy-on-write机制(具体的机制《windows核心编程》里也有详细的说明)。 So,自己动手写了个修改Ntdll.dll代码段的DLL,代码如下:
/*
WriteCopy_Test.cpp
*/
#include <windows.h> BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to the DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
if (DLL_PROCESS_ATTACH == fdwReason)
{
unsigned char ucBuf[1] = {0};
HMODULE hModule = GetModuleHandle("ntdll.dll"); typedef VOID (NTAPI *_DbgBreakPoint)(VOID);
_DbgBreakPoint DbgBreakPoint = (_DbgBreakPoint)GetProcAddress(hModule, "DbgBreakPoint");
memcpy(&ucBuf, DbgBreakPoint, 1);
DWORD dwOldProtect = 0;
VirtualProtect(DbgBreakPoint, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy(DbgBreakPoint, &ucBuf, 1);
}
//为了省内存,避免干扰,干脆连DLL_PROCESS_DETACH部分的代码也省略了
} 我机子上的NtDll.dll文件大小为578KB,启动了一个基本上什么事都不干的小程序,该程序初始占用内存442KB。
将上面的WriteCopy_Test.dll注入该程序,发现内存占用达到1524KB。 测试的结果让我很迷惑,测试前后内存占用相差约1MB,除去NtDLL.dll的代码体积和一些WriteCopy.dll、注入程序申请的少许内存(不到1KB),还有500K去哪了?
是不是我分析的有问题?疑惑中。
-摘自《windows核心编程》 但是实际操作中,却有些疑问:
我用APIHook时,必须针对每个我感兴趣的进程、对我感兴趣的API进行hook,而若果按照书中的说法,实际上我只需要对我感兴趣的API进行一次Hook就好了,跟进程无关。 这么看起来,实际与书中的说法似乎有些矛盾。琢磨了半天,只想出一个可能性:copy-on-write机制(具体的机制《windows核心编程》里也有详细的说明)。 So,自己动手写了个修改Ntdll.dll代码段的DLL,代码如下:
/*
WriteCopy_Test.cpp
*/
#include <windows.h> BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to the DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved // reserved
)
{
if (DLL_PROCESS_ATTACH == fdwReason)
{
unsigned char ucBuf[1] = {0};
HMODULE hModule = GetModuleHandle("ntdll.dll"); typedef VOID (NTAPI *_DbgBreakPoint)(VOID);
_DbgBreakPoint DbgBreakPoint = (_DbgBreakPoint)GetProcAddress(hModule, "DbgBreakPoint");
memcpy(&ucBuf, DbgBreakPoint, 1);
DWORD dwOldProtect = 0;
VirtualProtect(DbgBreakPoint, 1, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy(DbgBreakPoint, &ucBuf, 1);
}
//为了省内存,避免干扰,干脆连DLL_PROCESS_DETACH部分的代码也省略了
} 我机子上的NtDll.dll文件大小为578KB,启动了一个基本上什么事都不干的小程序,该程序初始占用内存442KB。
将上面的WriteCopy_Test.dll注入该程序,发现内存占用达到1524KB。 测试的结果让我很迷惑,测试前后内存占用相差约1MB,除去NtDLL.dll的代码体积和一些WriteCopy.dll、注入程序申请的少许内存(不到1KB),还有500K去哪了?
是不是我分析的有问题?疑惑中。
解决方案 »
- excel文件名中含有[或],如何处理?
- 白痴再次送分,简单地很(在线等)
- 一张图片如何把它做成对话框背景图,并且在窗体改变大小的时候,图片也随着自适应. 看看QQ窗体如何绘制的呢?
- SetWindowpos问题
- 怎么做??急!!!
- 讨厌的typedef,定义来定义去,怎么知道最终的类型是什么
- 高分求Http Tunnel穿透防火墙的代码
- 线程UINT的问题(在线等)
- 写日志文件时如何保证不会损坏硬盘?
- VC STL find()函数有没有人用过,如何判断没有找到那一项
- VC做的一个画图软件,安装到有些机器可以出来,有些机器出来不(会将内存不停的吃掉,直至弹出内存不足),请帮分析一下什么原因?谢谢
- 一个 C 的 . LIB 文件 在 c++ 中调用的问题
不知道你怎么注入DLL的,如果是远程线程,线程堆栈和线程信息需要内存.
copy-on-write机制应该不会影响虚拟内存大小
理论上,的确是只有代码段是共享的。我就是在测试代码段是否也有copy-on-write机制。
此外,“它们有助于节省内存。如果两个或多个应用程序使用同一个D L L,那么该D L L的页面只要放入R A M一次,所有的应用程序都可以共享它的各个页面。”的说法是不正确的,估计你买的书说的是 Windows 9x 版本,而你使用的 却是 Windows NT/2000/XP/Vista 版本,在后者中, DLL 在内存中并不仅仅只有一份,实际上,在每个相关进程中都有一个该 DLL 的拷贝,这种拷贝不仅仅是数据段,还包括了代码段,当然,明确指定了的共享段是例外。
我十分认同您的说法。
这两天我也完善了我的测试环境,现在测试的结果多是4K,但是个别情况会出现8K的增长。
这个我就不明白了。
copy-on-write机制的单位是页,在我现在的机器上是4KB。所以我一旦修改了某个共享区某处,则copy-on-write机制就会把修改处所在的整个4KB都“搬”到进程私有空间里。可是为什么会出现8KB的情况?
十分期待您的解答!
等该程序正常启动,并内存占用稳定后(因为这个程序什么具体的事都不做,所以内存很快就会稳定下来。),点击OK按钮。在任务管理器里看到的就是4KB。
更细的测试环境我正在写,最近两天会再进行更细的测试。
"我用APIHook时,必须针对每个我感兴趣的进程、对我感兴趣的API进行hook,而若果按照书中的说法,实际上我只需要对我感兴趣的API进行一次Hook就好了,跟进程无关。"如果是这样的话,你在一个程序里面设个CreateFile的断点,所有的程序就都停下来了。
我现在写的测试程序就是用GetProcessMemoryInfo
等我得出了测试结果,立刻就发上来,并且通知您,希望您能继续指导我 :)
{
MessageBoxA(0,"start",0,0);
//看TaskManager
改DLL
MessageBoxA(0,"take another look", 0,0)
//看TaskManager
}
到目前为止,我只是证明了这样改会有一个内存页的增量,看上去似乎是copy-on-write
可是怎么拿出强有力的数据证据来证明我的问题的源头就是copy-on-write机制呢?
我查了下资料,copy-on-write机制是操作系统和CPU合作完成的,所以我很郁闷。
暂时还没想好怎么继续分析~
如果你有好点子,分享(期待你的跟帖,所以就不用“指导”一词了 :) )下
看了你的分析,很好,很强大~
我最近也会做些分析,可能会碰到些问题,到时候找你讨论吧(在你BLOG上留言,然后给你发CSDN消息)