访问其他应用程序所占的内存空间
2008-11-02 01:24
239 查看
首先获取进程ID 然后根据ID创建句柄,读取或者写入内存。呵呵,写得太简单了是吧。
http://sanjianxia.myrice.com/vb/112.htm 这个教你怎样获得进程ID
下面是怎样处理内存
VirtualQueryEx和ReadProcessMemory/WriteProcessMemory的使用。
本来只是想看看ReadProcessMemory/WriteProcessMemory函数怎么使用,于是就想到编写一个类似游戏修改器的东西,但搜索4G的地址空间显然不现实,于是求助于VirtualQueryEx。
先说VirtualQueryEx,这个函数的作用是查询指定进程中某个地址的信息,如哪些内存是空闲的,哪些是被占用区等等,它在VB自带的API浏览器里的声明是
Public Declare Function VirtualQueryEx Lib "kernel32" Alias "VirtualQueryEx" (ByVal hProcess As Long, lpAddress As Any, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
其中lpAddress是要查询的地址值,它用了Any类型,而且是引用传参。这样当然有它的道理,但我需要查某个指定地址(例如0x123456)的信息就显得麻烦了,因为这个参数在C语言里是个void型的指针,这是个32位的值,因此我决定把它改为ByVal lpAddress as Long。
另外,像MEM_COMMIT = &H1000&这些常用的常数在VB自带的API浏览器里居然没有,真是可气!只好自己加了。
先举个例子吧,看。这个函数是求某个进程占用内存的大小。
Public Function GetTotalCommittedMemory(ByVal ProcessId As Long) As Long
Dim hProcess As Long
Dim mi As MEMORY_BASIC_INFORMATION
Dim pAddr As Long
Dim dwTotalCommit As Long
Dim ret As Long
Dim miLen As Long
miLen = Len(mi)
dwTotalCommit = 0'这是结果
pAddr = 0'这个时查询起始地址,设为0,即进程虚拟地址开始处。
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, ProcessId)'首先打开进程供查询信息
ret = VirtualQueryEx(hProcess, pAddr, mi, miLen)'从起始地址开始查询
Do While (ret = miLen)
If mi.State = MEM_COMMIT Then'如果State是MEM_COMMIT则表明这块内存被占用,RegionSize是这一块内存的大小,这一块内存的State都一样
dwTotalCommit = dwTotalCommit + mi.RegionSize
End If
pAddr = mi.BaseAddress + mi.RegionSize'跳过已经查询过的内存块,到未被查询的内存地址起始处
ret = VirtualQueryEx(hProcess, pAddr, mi, miLen)'再次查询,直到查询失败(所有可查询地址都已经查过了)
Loop
GetTotalCommittedMemory = dwTotalCommit
End Function
下面再说ReadProcessMemory,这个函数从指定进程中指定地址读出指定长度的内容。它在VB自带的API浏览器里的声明是
Public Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As
Long
同样,为了使用方便,lpBaseAddress As Any被我改成了ByVal lpBaseAddress As Long,然后讲一下在进程内存里查找数据的技术。
首先,要打开进程,由于要用ReadProcessMemory读出数据,所以权限要大一些。下面这个打开进程的方式具备了查询、读和写的权限
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, ProcessId)
然后就要结合上面的程序来搜索了。只有当内存是处于被占用状态时才去读取其中的内容,而忽略空闲状态的内存。程序我就不在这儿写了,和上面那段差不多。只是把dwTotalCommit = dwTotalCommit + mi.RegionSize换成了读取内存以及搜索这一块内存的函数而已。
还有WriteProcessMemory,这个函数向指定进程中指定地址写入指定长度的内容。同样,lpBaseAddress As Any被我改成了ByVal lpBaseAddress As Long,这个函数的使用很简单,我就不再赘述了。
http://sanjianxia.myrice.com/vb/112.htm 这个教你怎样获得进程ID
下面是怎样处理内存
VirtualQueryEx和ReadProcessMemory/WriteProcessMemory的使用。
本来只是想看看ReadProcessMemory/WriteProcessMemory函数怎么使用,于是就想到编写一个类似游戏修改器的东西,但搜索4G的地址空间显然不现实,于是求助于VirtualQueryEx。
先说VirtualQueryEx,这个函数的作用是查询指定进程中某个地址的信息,如哪些内存是空闲的,哪些是被占用区等等,它在VB自带的API浏览器里的声明是
Public Declare Function VirtualQueryEx Lib "kernel32" Alias "VirtualQueryEx" (ByVal hProcess As Long, lpAddress As Any, lpBuffer As MEMORY_BASIC_INFORMATION, ByVal dwLength As Long) As Long
其中lpAddress是要查询的地址值,它用了Any类型,而且是引用传参。这样当然有它的道理,但我需要查某个指定地址(例如0x123456)的信息就显得麻烦了,因为这个参数在C语言里是个void型的指针,这是个32位的值,因此我决定把它改为ByVal lpAddress as Long。
另外,像MEM_COMMIT = &H1000&这些常用的常数在VB自带的API浏览器里居然没有,真是可气!只好自己加了。
先举个例子吧,看。这个函数是求某个进程占用内存的大小。
Public Function GetTotalCommittedMemory(ByVal ProcessId As Long) As Long
Dim hProcess As Long
Dim mi As MEMORY_BASIC_INFORMATION
Dim pAddr As Long
Dim dwTotalCommit As Long
Dim ret As Long
Dim miLen As Long
miLen = Len(mi)
dwTotalCommit = 0'这是结果
pAddr = 0'这个时查询起始地址,设为0,即进程虚拟地址开始处。
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, ProcessId)'首先打开进程供查询信息
ret = VirtualQueryEx(hProcess, pAddr, mi, miLen)'从起始地址开始查询
Do While (ret = miLen)
If mi.State = MEM_COMMIT Then'如果State是MEM_COMMIT则表明这块内存被占用,RegionSize是这一块内存的大小,这一块内存的State都一样
dwTotalCommit = dwTotalCommit + mi.RegionSize
End If
pAddr = mi.BaseAddress + mi.RegionSize'跳过已经查询过的内存块,到未被查询的内存地址起始处
ret = VirtualQueryEx(hProcess, pAddr, mi, miLen)'再次查询,直到查询失败(所有可查询地址都已经查过了)
Loop
GetTotalCommittedMemory = dwTotalCommit
End Function
下面再说ReadProcessMemory,这个函数从指定进程中指定地址读出指定长度的内容。它在VB自带的API浏览器里的声明是
Public Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As
Long
同样,为了使用方便,lpBaseAddress As Any被我改成了ByVal lpBaseAddress As Long,然后讲一下在进程内存里查找数据的技术。
首先,要打开进程,由于要用ReadProcessMemory读出数据,所以权限要大一些。下面这个打开进程的方式具备了查询、读和写的权限
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, ProcessId)
然后就要结合上面的程序来搜索了。只有当内存是处于被占用状态时才去读取其中的内容,而忽略空闲状态的内存。程序我就不在这儿写了,和上面那段差不多。只是把dwTotalCommit = dwTotalCommit + mi.RegionSize换成了读取内存以及搜索这一块内存的函数而已。
还有WriteProcessMemory,这个函数向指定进程中指定地址写入指定长度的内容。同样,lpBaseAddress As Any被我改成了ByVal lpBaseAddress As Long,这个函数的使用很简单,我就不再赘述了。
相关文章推荐
- 虚拟字符驱动,申请n页内存,使用mmap映射到应用程序空间,用户就可以直接访问不需要任何同步机制
- Howto: 从应用程序访问任意的内存空间
- 进入用友通:提示"由于文件不可访问,内存磁盘空间不足无法打开ufsystem数据库"登录失败
- 当程序用ado的jet4.0方式连接的时候,对于设有access数据库密码的mdb的访问居然报错“无法启动应用程序,工作组信息文件丢失,或是已被其他用户已独占方式打开”,而用odbc方式不报错,小阴沟里翻船,郁闷中然后查文档解决之
- 在用户空间(和内核空间)访问内存的绝对地址
- 解决Mac内存不足,清理其他和应用程序过多问题
- 在用户空间(和内核空间)访问内存的绝对地址
- 使用 .NET 远程处理访问其他应用程序域中的对象
- 内存 其访问权已经不属于该应用程序
- 如何应用程序中载入其他域的swf文件,并且允许它访问程序中的 ActionScript
- access数据库密码的mdb的访问报错“无法启动应用程序,或是已被其他用户已独占方式打开”
- 【c#】让.Net 应用程序突破2G的内存访问限制
- 由于文件不可访问,或者内存或磁盘空间不足,所以无法打开数据库 'msdb'。有关详细信息,请参阅 SQL Server 错误日志。 (Microsoft SQL Server,错误: 945)
- 当程序用ado的jet4.0方式连接的时候,对于设有access数据库密码的mdb的访问居然报错“无法启动应用程序,工作组信息文件丢失,或是已被其他用户已独占方式打开”,而用odbc方式不报错,小阴沟里翻船,郁闷中然后查文档解决之
- WinCE6.0中应用程序如何直接访问物理空间
- 从 Linux 内核访问用户空间内存
- WinCE6.0中应用程序如何直接访问物理空间
- 访问一个进程的内存空间
- MFC中访问应用程序的其他类。
- 从 Linux 内核访问用户空间内存