请问如何读取内存中的数据?
麻烦给出一个例子
谢谢 :)
麻烦给出一个例子
谢谢 :)
解决方案 »
- 图片压缩问题???
- 点击"屏幕保护程序"->"设置"如何打开自己设计的程序?谢谢各位弟兄帮忙!
- 再進來幫下忙,還是SQL語句!
- 纯外行求助~~牛顿法解一个非线性方程~
- 怎么设置文件与应用程序的关联?
- 用vb怎样连接远程的dbf数据库
- 在用Open打开一个大的文件进行二进制的读写时,现在要计算一个很大的循环,如果要在程序循环时能够接受暂停和继续的工作,要如何实现?
- 程序员是怎样炼成的?
- 有谁知道怎么开发象Google toolbar或Yahoo!companion之类的软件??
- 请高手们帮我看看,为什么我的时间要的这么长?
- 如何利用SQL Server 的存儲過程導入文本文件中的數據?
- Tab控件怎么用啊?最好能提供代码
2。用API:MEMCPY
=================================================================
如何操作内存
这次我来讲讲如何读写一个游戏进程的内存。看完这篇文章,相信你应该对内存的操作有点认识了,甚至, 如果你希望的话,你马上就可以动手写像FPE一样的内存编辑工具。
在这之前我们先来复习一下一些基本概念:
进程:用最简洁的话来说,进程就是一个正在执行的程序,一个或多个线程在进程中运行。
线程:线程是操作系统分配CPU运算时间的最小单位。
每一个进程都提供了运行一个程序所必需的资源,一个进程具有4GB的虚拟地址空间,可执行代码,数据,对象句柄,环境变量,优先权以及设置最大化最小化的功能。每一个进程都从一个主线程开始执行,但可以在它所拥有的线程中创建额外的线程。如果在某个线程中创建了一个子线程,那么当它开始执行后,就是一匹脱缰的野马,很难再控制它了。因此,多线程技术在Win32平台下是需要很高的技巧的。一个进程的所有线程共享进程的虚拟地址空间和系统资源,一个线程的资源包括线程的机器寄存器设置,内核堆栈,线程环境变量和进程虚拟地址中的用户堆栈。
对于不同的操作系统,每个进程的虚拟地址空间的分配是不同的。Windows NT Server Enterprise Edition及Windows 2000 Advanced Server中低3GB虚拟地址空间供进程使用,高1GB供操作系统的内核代码使用。Windows NT/2000中低2GB供进程使用,高2GB供操作系统内核代码使用。Windows9X:0——64K只读空间用来装入Microsoft DOS信息,64K——4M装入DOS的兼容代码,4M——2GB的私有空间供进程使用,2GB——3GB的共享空间装入各种DLL代码,3GB——4GB为共享的系统内核代码空间,其中共享的2GB——4GB的空间是99%的“内存无效页错误”、“General Protect Error(GPE)”及蓝屏的罪魁祸首。
当然,操作系统不会真的给每个进程分配4GB的内存空间,否则,别说内存,连虚拟内存都不够用。操作系统会将需要用到的某段虚拟地址的内容映射到物理内存,这种映射操作是操作系统内核完成的,无需程序员来控制。
基本概念就是这样,现在我们开始学习如何操作某个所需的进程的内存(严格来讲,是操作它的虚拟地址上的数据,下同)。
首先,用CreateToolhelp32Snapshot创建当前内存的一个快照,将返回的句柄传递给Process32First、Process32Next来遍历内存中的所有进程,一旦遇到所需修改的某个游戏的进程,就将其进程ID保存下来,再用OpenProcess打开这个进程,从而获得该进程的进程句柄。最后,利用这个句柄,使用ReadProcessMemory、WriteProcessMemory来读写虚拟地址。
以下是一段例子代码(结构及API函数的声明略去):保存API函数返回值的临时变量
Dim lngAPIReturn As Long
内存快照的句柄
Dim lngHSnapShot As Long
保存进程可执行文件名的临时变量
Dim strExe As String
某个你感兴趣的可执行文件执行后的进程的ID
Dim lngProcessID As Long
某个你感兴趣的可执行文件执行后的进程的句柄
Dim lngHProcess As Long
字节缓冲区,保存从内存中读取的数据
Dim bytBuffer as Byte
保存ReadProcessMemory函数返回信息的临时变量
Dim lngCharaWrite As Long
保存进程信息的结构
Dim tProcessEntry As PROCESSENTRY32tProcessEntry.dwSize = Len(tProcessEntry)获得当前内存快照的句柄
lngHSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)查找内存中第一个进程
lngAPIReturn = Process32First(lngHSnapShot, tProcessEntry)
Do
strExe = ""
If InStr(tProcessEntry.szExeFile, Chr(0)) > 1 Then
对win9X,strExe为带路径的文件名,对win2K为不带路径的文件名
strExe = Left(tProcessEntry.szExeFile, InStr(tProcessEntry.szExeFile, Chr(0)) - 1)
tProcessEntry.szExeFile = Space(MAX_PATH)
End If
查看可执行文件名是不是某个感兴趣的文件
If UCase(strExe) = UCase("某个可执行文件名") Then
保存下该进程的ID
lngProcessID = tProcessEntry.th32ProcessID
Exit Do
End If
查找内存中下一个进程
lngAPIReturn = Process32Next(lngHSnapShot, tProcessEntry)
Loop While (lngAPIReturn <> 0)打开进程
lngHProcess = OpenProcess(PROCESS_VM_READ + PROCESS_VM_WRITE + PROCESS_VM_OPERATION, 0, lngProcessID)
读取进程虚拟地址1048576中的数据
lngAPIReturn = ReadProcessMemory(lngHProcess, 1048576, bytBuffer, 1, lngCharaWrite)
写入进程虚拟地址1048576中的数据
lngAPIReturn = WriteProcessMemory(lngHProcess, 1048576, bytBuffer, 1, lngCharaWrite)
关闭句柄
lngAPIReturn = CloseHandle(lngHProcess)