进程外内存空间分配
当我们想得到另一个进程空间中的某编辑窗口的文字时,可以首先找到这个窗口的句柄(这个不难),然后向这个窗口发送EM_GETLINE消息,就可以在消息的返回参数中得到那个窗口的标题文字了。很早就有人写了偷取密码的工具,就是利用这个原理实现的。但是,如果想当然的认为可以通过这种方法读取另一个进程窗口的状态,那就错了。
当发送EM_GETLINE消息时,LPARAM参数是指向一个字符数组的指针,当SendMessage返回时,目标窗口的文字就在这个字符数组中了。这里有个问题,字符数组是在进程A中分配的,EM_GETLINE消息被发送到进程B中的窗口,然后进程B的窗口过程函数收到并处理消息,把文字填充到字符数组。也就是说,进程B访问了进程A的内存。
如果真的是那样,也挺好,可是,如果你用同样的方法向一个ListView窗口发送消息,就会发现不对劲了,会有一个致命错误跑出来。实际上,错误的原因是一个进程不能自由访问另一个进程的内存。那么,为什么Edit窗口就可以呢。据说这是历史原因,因为在Windows95之前,16位Windows的时代,进程间是可以自由访问内存的,然后,32位Windows改变了内存管理方式,不再允许这种容易导致系统崩溃的内存访问方式了。但是,为了兼容以前的代码和程序,Windows内部为我们做了一些工作,使得这些代码还能工作,所以向一个编辑框发送消息,仍然可以获得它的状态。但是后来新加入的控件就没那么幸运了,ListView, TreeView, Spin, ToolBar等新的Win32 通用控件没有享受到MS的额外服务,所以,要向这些控件发送消息获取状态,我们必须自己写内存管理的代码。
举个例子来说吧,如果我们想得到另一个进程中的某个ProgressBar的进度变化范围,需要怎么做呢?
- 首先必须找到这个窗口句柄,这个就不多说了;
- 第二步是调用API函数GetWindowThreadProcessId得到那个窗口的进程ID;
- 接着用OpenProcess得到这个进程的句柄;
- 然后就可以调用VirtualAllocEx函数了,这个函数为目标进程分配内存空间,并得到其在目标进程中的地址,这个地址可以直接通过SendMessage传给目标窗口,从而由目标窗口读取或写入地址所对应的内存;
- 要在控制进程中读写这些内存空间,可以调用WriteProcessMemory和ReadProcessMemory函数;
- 最后,调用VirtualFreeEx释放内存,并用CloseHandle关闭前面打开的进程句柄
要下班了,下次再写,再给出些代码
posted on 2004-04-20 17:19 vibration 阅读(1672) 评论(1) 编辑 收藏 举报