用C#读写游戏进程内存

发布时间:2009年06月04日      浏览次数:586 次
《游戏修改器DIY之三》
——用C#读写游戏进程内存
天津 赵春生
相关下载
这是《游戏修改器DIY》系列的第三篇,通过前两篇拙作相信大家对游戏修改器的制作有了初步的了解,前两篇使用的编程工具是“Microsoft Visual C++ 6.0”,而这次将使用“Microsoft Visual C# 2005 Express Edition”。在C#中使用API可不像在C/C++那么简单,因为对我来说,C#还很陌生……
本篇不再赘述游戏修改器的原理了,如果对此不了解的朋友可先看看我写的前两篇拙作或其他相关资料。
一:在C#中使用API。
首先要导入一个namespace,以便简化后面的代码输入:
using System.Runtime.InteropServices;
其次要使用DllImport引入API函数,如:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);
现在就可以使用了,如:
MessageBox(new IntPtr(0), "Hello World!", "Hello Dialog", 0);
为了使用方便,我制作了一个简单的类:
class ProcessMemoryWorkApi
{
//HANDLE OpenProcess(
// DWORD dwDesiredAccess,// access flag
// BOOL bInheritHandle, // handle inheritance flag
// DWORD dwProcessId // process identifier
// );
[DllImport("kernel32.dll")]
public static extern
IntPtr OpenProcess(UInt32 dwDesiredAccess, Int32 bInheritHandle, UInt32 dwProcessId);
//BOOL CloseHandle(
// HANDLE hObject // handle to object to close
// );
[DllImport("kernel32.dll")]
public static extern
Int32 CloseHandle(IntPtr hObject);
//BOOL WriteProcessMemory(
// HANDLE hProcess, // handle to process whose memory is written to
// LPVOID lpBaseAddress, // address to start writing to
// LPVOID lpBuffer, // pointer to buffer to write data to
// DWORD nSize, // number of bytes to write
// LPDWORD lpNumberOfBytesWritten // actual number of bytes written
// );
[DllImport("kernel32.dll")]
public static extern
Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, uint[] lpBuffer, UInt32 nSize, IntPtr lpNumberOfBytesWritten);
//BOOL ReadProcessMemory(
// HANDLE hProcess, // handle of the process whose memory is read
// LPCVOID lpBaseAddress, // address to start reading
// LPVOID lpBuffer, // address of buffer to place read data
// DWORD nSize, // number of bytes to read
// LPDWORD lpNumberOfBytesRead // address of number of bytes read
// );
[DllImport("kernel32.dll")]
public static extern
Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, uint[] lpBuffer, UInt32 nSize, IntPtr lpNumberOfBytesRead);
}
二:用C#制作游戏修改器。
游戏是大家熟悉的“三维弹球”,这是WinXP自带的一款游戏,目的是修改她的分数,选这个游戏的原因是因为大家都能很容易地得到她,而且修改起来也很方便:取0x1025040中的值,然后与0x52相加,即可得到存放游戏分数的地址。
单击“Go”按钮,可显示当前分数,并将分数改为:“999600000”(图1),关键代码如下:
private void button_go_Click(object sender, EventArgs e)
{
IntPtr PinballHandle;
IntPtr PinballScoreAddressPointer = (IntPtr)0x1025040; //内存0x1025040中的值+0x52->PinballScoreAddress
uint[] PinballScoreAddress = new uint[1]; //游戏分数的内存地址
uint[] PinballScoreWrite = new uint[] { 0x3B94AF80 }; //将分数改为:999600000
uint[] PinballScoreRead = new uint[1]; //用来存放当前分数
//"3D Pinball"在“Windows 任务管理器”中显示为"PINBALL.EXE",但作为
//GetProcessesByName的参数使用时并不能包含扩展名".EXE"。
System.Diagnostics.Process[] PinballProcessID
= System.Diagnostics.Process.GetProcessesByName("PINBALL"); //根据进程名获取进程ID
if (PinballProcessID.Length != 0)
{
PinballHandle = ProcessMemoryWorkApi.OpenProcess(0x1F0FFF, 0, (UInt32)PinballProcessID[0].Id); //PROCESS_ALL_ACCESS=0x1F0FFF
ProcessMemoryWorkApi.ReadProcessMemory(PinballHandle, PinballScoreAddressPointer, PinballScoreAddress, 4, (IntPtr)0);//通过指针得到PinballScoreAddress
PinballScoreAddress[0] = PinballScoreAddress[0] + 0x52; //PinballScoreAddress+0x52才是游戏分数的内存地址
ProcessMemoryWorkApi.ReadProcessMemory(PinballHandle, (IntPtr)PinballScoreAddress[0], PinballScoreRead, 4, (IntPtr)0); //当前游戏分数
MessageBox.Show("当前分数为: " + PinballScoreRead[0].ToString() + "\n" + "分数即将被修改成: 999600000", "ProcessMemoryWork_Demo");
ProcessMemoryWorkApi.WriteProcessMemory(PinballHandle, (IntPtr)PinballScoreAddress[0], PinballScoreWrite, 4, (IntPtr)0); //修改游戏分数
ProcessMemoryWorkApi.CloseHandle(PinballHandle);
}
else
MessageBox.Show("\"3D Pinball\" 还没有运行吧?", "ProcessMemoryWork_Demo");
}
三:相关提示。
刚刚接触C#不久,对OOP也一知半解,写此文只为抛砖引玉,谢谢!
本程序代码测试环境:
WinXP (Professional SP2)
Microsoft Visual Studio 2005 (Installed Edition: C# Express)
Version 8.0.50727.762 (SP.050727-7600)
Microsoft .NET Framework
Version 2.0.50727
《游戏修改器DIY》/《游戏修改器DIY之二》可通过搜索引擎或访问我的Blog获得。
免责声明:本站相关技术文章信息部分来自网络,目的主要是传播更多信息,如果您认为本站的某些信息侵犯了您的版权,请与我们联系,我们会即时妥善的处理,谢谢合作!