C#编写的<植物大战僵尸>作弊器源码【转】
首先用CE或者OD或者其他反汇编工具找出游戏的内存基址!
游戏内存基址:base = 0x006A9EC0
游戏阳光地址:[base+0x768]+0x5560
游戏金钱地址:[base+0x82C]+0x28
游戏关卡地址:[base+0x82C]+0x24 //关卡如:A-B 实际值为:(A-1)×10+B
至于如何获取这些地址不在我们这论坛研究的范围中!
新建窗体:
1: using System;
2: using System.Drawing;
3: using System.Text;
4: using System.Windows.Forms;
5:
6: namespace PlantsVsZombiesTool
7: {
8: /// <summary>
9: ///
10: /// </summary>
11: public partial class Form1 : Form
12: {
13: public Form1()
14: {
15: InitializeComponent();
16: }
17:
18: private void Form1_Load(object sender, EventArgs e)
19: {
20:
21: }
22:
23: //启动无线阳光
24: private void btnGet_Click(object sender, EventArgs e)
25: {
26: if (Helper.GetPidByProcessName(processName) == 0)
27: {
28: MessageBox.Show("哥们启用之前游戏总该运行吧!");
29: return;
30: }
31: if (btnGet.Text == "启用-阳光无限")
32: {
33: timer1.Enabled = true;
34: btnGet.Text = "关闭-阳光无限";
35: }
36: else
37: {
38: timer1.Enabled = false;
39: btnGet.Text = "启用-阳光无限";
40: }
41: }
42:
43: private void timer1_Tick(object sender, EventArgs e)
44: {
45:
46: if (Helper.GetPidByProcessName(processName) == 0)
47: {
48: timer1.Enabled = false;
49: btnGet.Text = "启用-阳光无限";
50: }
51: int address = ReadMemoryValue(baseAddress); //读取基址(该地址不会改变)
52: address = address + 0x768; //获取2级地址
53: address = ReadMemoryValue(address);
54: address = address + 0x5560; //获取存放阳光数值的地址
55: WriteMemory(address, 0x1869F); //写入数据到地址(0x1869F表示99999)
56: timer1.Interval = 1000;
57: }
58:
59: //启动无线金钱
60: private void btnMoney_Click(object sender, EventArgs e)
61: {
62:
63: if (Helper.GetPidByProcessName(processName) == 0)
64: {
65: MessageBox.Show("哥们启用之前游戏总该运行吧!");
66: return;
67: }
68: if (btnMoney.Text == "启用-金钱无限")
69: {
70: timer2.Enabled = true;
71: btnMoney.Text = "关闭-金钱无限";
72: }
73: else
74: {
75: timer2.Enabled = false;
76: btnMoney.Text = "启用-金钱无限";
77: }
78: }
79:
80: private void timer2_Tick(object sender, EventArgs e)
81: {
82: if (Helper.GetPidByProcessName(processName) == 0)
83: {
84: timer2.Enabled = false;
85: btnMoney.Text = "启用-金钱无限";
86: }
87: int address = ReadMemoryValue(baseAddress); //读取基址(该地址不会改变)
88: address = address + 0x82C; //获取2级地址
89: address = ReadMemoryValue(address);
90: address = address + 0x28; //得到金钱地址
91: WriteMemory(address, 0x1869F); //写入数据到地址(0x1869F表示99999)
92: timer2.Interval = 1000;
93: }
94:
95: private void btnGo_Click(object sender, EventArgs e)
96: {
97: if (Helper.GetPidByProcessName(processName) == 0)
98: {
99: MessageBox.Show("哥们启用之前游戏总该运行吧!");
100: return;
101: }
102: int address = ReadMemoryValue(baseAddress); //读取基址(该地址不会改变)
103: address = address + 0x82C; //获取2级地址
104: address = ReadMemoryValue(address);
105: address = address + 0x24;
106: int lev = 1;
107: try
108: {
109: lev = int.Parse(txtLev.Text.Trim());
110: }
111: catch
112: {
113: MessageBox.Show("输入的关卡格式不真确!默认设置为1");
114: }
115:
116: WriteMemory(address, lev);
117:
118: }
119:
120: //读取制定内存中的值
121: public int ReadMemoryValue(int baseAdd)
122: {
123: return Helper.ReadMemoryValue(baseAdd, processName);
124: }
125:
126: //将值写入指定内存中
127: public void WriteMemory(int baseAdd, int value)
128: {
129: Helper.WriteMemoryValue(baseAdd, processName, value);
130: }
131:
132: private int baseAddress = 0x006A9EC0; //游戏内存基址
133: private string processName = "PlantsVsZombies"; //游戏进程名字
134: }
135: }
下面这个类是整个工具的核心
1: using System;
2: using System.Text;
3:
4: using System.Diagnostics;
5: using System.Runtime.InteropServices;
6:
7: namespace PlantsVsZombiesTool
8: {
9:
10: public abstract class Helper
11: {
12: [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
13: public static extern bool ReadProcessMemory
14: (
15: IntPtr hProcess,
16: IntPtr lpBaseAddress,
17: IntPtr lpBuffer,
18: int nSize,
19: IntPtr lpNumberOfBytesRead
20: );
21:
22: [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
23: public static extern IntPtr OpenProcess
24: (
25: int dwDesiredAccess,
26: bool bInheritHandle,
27: int dwProcessId
28: );
29:
30: [DllImport("kernel32.dll")]
31: private static extern void CloseHandle
32: (
33: IntPtr hObject
34: );
35:
36: //写内存
37: [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
38: public static extern bool WriteProcessMemory
39: (
40: IntPtr hProcess,
41: IntPtr lpBaseAddress,
42: int[] lpBuffer,
43: int nSize,
44: IntPtr lpNumberOfBytesWritten
45: );
46:
47: //获取窗体的进程标识ID
48: public static int GetPid(string windowTitle)
49: {
50: int rs = 0;
51: Process[] arrayProcess = Process.GetProcesses();
52: foreach (Process p in arrayProcess)
53: {
54: if (p.MainWindowTitle.IndexOf(windowTitle) != -1)
55: {
56: rs = p.Id;
57: break;
58: }
59: }
60:
61: return rs;
62: }
63:
64: //根据进程名获取PID
65: public static int GetPidByProcessName(string processName)
66: {
67: Process[] arrayProcess = Process.GetProcessesByName(processName);
68:
69: foreach (Process p in arrayProcess)
70: {
71: return p.Id;
72: }
73: return 0;
74: }
75:
76: //根据窗体标题查找窗口句柄(支持模糊匹配)
77: public static IntPtr FindWindow(string title)
78: {
79: Process[] ps = Process.GetProcesses();
80: foreach (Process p in ps)
81: {
82: if (p.MainWindowTitle.IndexOf(title) != -1)
83: {
84: return p.MainWindowHandle;
85: }
86: }
87: return IntPtr.Zero;
88: }
89:
90: //读取内存中的值
91: public static int ReadMemoryValue(int baseAddress,string processName)
92: {
93: try
94: {
95: byte[] buffer = new byte[4];
96: IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //获取缓冲区地址
97: IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName));
98: ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //将制定内存中的值读入缓冲区
99: CloseHandle(hProcess);
100: return Marshal.ReadInt32(byteAddress);
101: }
102: catch
103: {
104: return 0;
105: }
106: }
107:
108: //将值写入指定内存地址中
109: public static void WriteMemoryValue(int baseAddress, string processName, int value)
110: {
111: IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高权限
112: WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero);
113: CloseHandle(hProcess);
114: }
115: }
116: }