C#內存操作 (轉)

最近閒來無事發現周圍的朋友都在玩《植物大戰殭屍》的遊戲!於是動了製作這遊戲工具的念頭!雖然在網上同類工具很多 但是用C#寫的我幾乎看不到!所以我想用C#寫一個!
  首先用CE或者OD或者其他反彙編工具找出遊戲的內存基址!
  遊戲內存基址:base = 0x006A9EC0
  遊戲陽光地址:[base+0x768]+0x5560
  遊戲金錢地址:[base+0x82C]+0x28
  遊戲關卡地址:[base+0x82C]+0x24 //關卡如:A-B 實際值爲:(A-1)×10+B
至於如何獲取這些地址不在我們這論壇研究的範圍中!
對了我是用工具vs2008編寫的!
新建窗體:
C# code
using System; using System.Drawing; using System.Text; using System.Windows.Forms; namespace PlantsVsZombiesTool { /// <summary> /// /// </summary> public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } //啓動無線陽光 private void btnGet_Click(object sender, EventArgs e) { if (Helper.GetPidByProcessName(processName) == 0) { MessageBox.Show("哥們啓用之前遊戲總該運行吧!"); return; } if (btnGet.Text == "啓用-陽光無限") { timer1.Enabled = true; btnGet.Text = "關閉-陽光無限"; } else { timer1.Enabled = false; btnGet.Text = "啓用-陽光無限"; } } private void timer1_Tick(object sender, EventArgs e) { if (Helper.GetPidByProcessName(processName) == 0) { timer1.Enabled = false; btnGet.Text = "啓用-陽光無限"; } int address = ReadMemoryValue(baseAddress); //讀取基址(該地址不會改變) address = address + 0x768; //獲取2級地址 address = ReadMemoryValue(address); address = address + 0x5560; //獲取存放陽光數值的地址 WriteMemory(address, 0x1869F); //寫入數據到地址(0x1869F表示99999) timer1.Interval = 1000; } //啓動無線金錢 private void btnMoney_Click(object sender, EventArgs e) { if (Helper.GetPidByProcessName(processName) == 0) { MessageBox.Show("哥們啓用之前遊戲總該運行吧!"); return; } if (btnMoney.Text == "啓用-金錢無限") { timer2.Enabled = true; btnMoney.Text = "關閉-金錢無限"; } else { timer2.Enabled = false; btnMoney.Text = "啓用-金錢無限"; } } private void timer2_Tick(object sender, EventArgs e) { if (Helper.GetPidByProcessName(processName) == 0) { timer2.Enabled = false; btnMoney.Text = "啓用-金錢無限"; } int address = ReadMemoryValue(baseAddress); //讀取基址(該地址不會改變) address = address + 0x82C; //獲取2級地址 address = ReadMemoryValue(address); address = address + 0x28; //得到金錢地址 WriteMemory(address, 0x1869F); //寫入數據到地址(0x1869F表示99999) timer2.Interval = 1000; } private void btnGo_Click(object sender, EventArgs e) { if (Helper.GetPidByProcessName(processName) == 0) { MessageBox.Show("哥們啓用之前遊戲總該運行吧!"); return; } int address = ReadMemoryValue(baseAddress); //讀取基址(該地址不會改變) address = address + 0x82C; //獲取2級地址 address = ReadMemoryValue(address); address = address + 0x24; int lev = 1; try { lev = int.Parse(txtLev.Text.Trim()); } catch { MessageBox.Show("輸入的關卡格式不真確!默認設置爲1"); } WriteMemory(address, lev); } //讀取制定內存中的值 public int ReadMemoryValue(int baseAdd) { return Helper.ReadMemoryValue(baseAdd, processName); } //將值寫入指定內存中 public void WriteMemory(int baseAdd, int value) { Helper.WriteMemoryValue(baseAdd, processName, value); } private int baseAddress = 0x006A9EC0; //遊戲內存基址 private string processName = "PlantsVsZombies"; //遊戲進程名字 } }


下面這個類是整個工具的核心

C# code
using System; using System.Text; using System.Diagnostics; using System.Runtime.InteropServices; namespace PlantsVsZombiesTool { public abstract class Helper { [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")] public static extern bool ReadProcessMemory ( IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesRead ); [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")] public static extern IntPtr OpenProcess ( int dwDesiredAccess, bool bInheritHandle, int dwProcessId ); [DllImport("kernel32.dll")] private static extern void CloseHandle ( IntPtr hObject ); //寫內存 [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")] public static extern bool WriteProcessMemory ( IntPtr hProcess, IntPtr lpBaseAddress, int[] lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten ); //獲取窗體的進程標識ID public static int GetPid(string windowTitle) { int rs = 0; Process[] arrayProcess = Process.GetProcesses(); foreach (Process p in arrayProcess) { if (p.MainWindowTitle.IndexOf(windowTitle) != -1) { rs = p.Id; break; } } return rs; } //根據進程名獲取PID public static int GetPidByProcessName(string processName) { Process[] arrayProcess = Process.GetProcessesByName(processName); foreach (Process p in arrayProcess) { return p.Id; } return 0; } //根據窗體標題查找窗口句柄(支持模糊匹配) public static IntPtr FindWindow(string title) { Process[] ps = Process.GetProcesses(); foreach (Process p in ps) { if (p.MainWindowTitle.IndexOf(title) != -1) { return p.MainWindowHandle; } } return IntPtr.Zero; } //讀取內存中的值 public static int ReadMemoryValue(int baseAddress,string processName) { try { byte[] buffer = new byte[4]; IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); //獲取緩衝區地址 IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero); //將制定內存中的值讀入緩衝區 CloseHandle(hProcess); return Marshal.ReadInt32(byteAddress); } catch { return 0; } } //將值寫入指定內存地址中 public static void WriteMemoryValue(int baseAddress, string processName, int value) { IntPtr hProcess = OpenProcess(0x1F0FFF, false, GetPidByProcessName(processName)); //0x1F0FFF 最高權限 WriteProcessMemory(hProcess, (IntPtr)baseAddress, new int[] { value }, 4, IntPtr.Zero); CloseHandle(hProcess); } } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章