火炬之光2_辅助工具 内存读写相关

一个共公类 Data.cs ,用于存放游戏的 信息,如人物属性,

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Diagnostics;
 4 using System.Linq;
 5 using System.Runtime.InteropServices;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace huojuzhiguang
10 {
11     
12     public class Game
13     {
14         public static String gameName = "Torchlight2";  //游戏的进程名称
15         public static bool findGame = false;
16 
17     }
18     public class Role
19     {
20         public static int Name_Addr;  //人物名称地址
21         public static int Level_Addr;  //等级地址
22         public static int Strength_Addr;  //力量
23         public static int Dexterity_Addr; //敏捷
24         public static int Wit_Addr;    //智力
25         public static int Tizhi_Addr;    //体质
26         public static int ShuXingDian_Addr;    //属性点
27         public static int JiNengDian_Addr;    //技能点
28         public static int Money_Addr;    //金币
29         public static int Move_Addr;    //移动速度
30 
31     }
32     public class ZhuangBei
33     {
34         public static int Name_Addr;  //装备名称
35         public static int wlgj_Addr1;  //物理攻击1
36         public static int wlgj_Addr2;  //物理攻击2
37         public static int wlfy_Addr1;  //物理防御1
38         public static int wlfy_Addr2;  //物理防御2
39         public static int fmcs_Addr;  //附魔次数
40         public static int kongshu_Addr;  //孔数
41         
42     }
43 
44     public class Pet
45     {
46         public static int Level_Addr;  //宠物等级
47         public static int XueLiang_Addr;  //宠物血量
48         public static int MoFa_Addr;  //宠物魔法
49         public static int Jingyan_Addr;  //宠物经验
50         public static int Move_Addr;  //宠物经验
51     }
52 }

写一个共公方法 OperateMemory.cs ,减少窗体内的的代码

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Diagnostics;
  4 using System.Linq;
  5 using System.Runtime.CompilerServices;
  6 using System.Runtime.InteropServices;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 
 10 namespace huojuzhiguang
 11 {
 12     public class OperateMemory
 13     {
 14         /// <summary>
 15         /// 从指定内存中读取字节集数据
 16         /// </summary>
 17         /// <param name="hProcess">进程句柄</param>
 18         /// <param name="pvAddressRemote">内存地址</param>
 19         /// <param name="pvBufferLocal">数据存储变量</param>
 20         /// <param name="dwSize">长度</param>
 21         /// <param name="pdwNumBytesRead">读取长度</param>   
 22 
 23          #region 引入DLL
 24         private const uint PROCESS_ALL_ACCESS = 0x1f0fff;
 25         [DllImport("kernel32.dll")]
 26         private extern static IntPtr OpenProcess(uint dwDesiredAccess,int bInheritHandle,int dwProcessId);
 27 
 28 
 29         [DllImport("kernel32.dll")]
 30         private extern static bool ReadProcessMemory(IntPtr hProcess, UInt32 pvAddressRemote, int[] pvBufferLocal, UInt32 dwSize, Int32[] pdwNumBytesRead);
 31 
 32         [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
 33         private static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, int[] lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);
 34         [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
 35         private static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, int lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);
 36 
 37         #endregion
 38 
 39         private static Process[] p = Process.GetProcessesByName(Game.gameName);  //读取游戏进程
 40         private static IntPtr handle = OpenProcess(0x1F0FFF, 0, p[0].Id);    //获取句柄权限
 41       
 42         /// <summary>
 43         /// 判断游戏是否已运行
 44         /// </summary>
 45         /// <param name="gameName">程序进程名</param>
 46         /// <returns>false 未运行,true已运行</returns>
 47         public static Boolean findGame(String gameName)
 48         {
 49             if (p == null || p.Length < 1)
 50             {
 51                 return Game.findGame = false;                
 52             }
 53             else
 54             {
 55                 return Game.findGame = true;
 56             }
 57 
 58         }
 59        
 60         /// <summary>
 61         /// 读取内存,int默认读取4个字节
 62         /// </summary>
 63         /// <param name="readAddr">读取地址</param>
 64         /// <returns></returns>
 65         public static Int32 readMemory(UInt32 readAddr)
 66         {
 67             int[] result = new int[1];
 68             int[] lpdw = new int[1];
 69             bool b = ReadProcessMemory(handle, readAddr, result, 4, lpdw);
 70             return result[0];
 71         }
 72      
 73         /// <summary>
 74         /// 读取内存,数组为[基址,便宜地址]
 75         /// </summary>
 76         /// <param name="readAddr">读取地址</param>
 77         /// <returns></returns>
 78        public static Int32 readMemory(int[] readAddr)
 79        {
 80            int values = 0;
 81            for (int i = 0; i < readAddr.Length; i++)
 82            {
 83                values = readMemory((uint)(values + readAddr[i]));              
 84            }          
 85            return values;
 86        }
 87 
 88         /// <summary>
 89         /// 读取内存,数组为[基址,便宜地址]
 90         /// </summary>
 91        /// <param name="readAddr">读取地址</param>
 92         /// <param name="addr">数值存放的逻辑地址</param>
 93         /// <returns></returns>
 94        public static Int32 readMemory(int[] readAddr,out int addr)
 95        {
 96            int values = 0;
 97            int temp=0;  //临时存放人物属性的逻辑地址
 98            for (int i = 0; i < readAddr.Length; i++)
 99            {
100                temp = values + readAddr[i];
101                values = readMemory((uint)(values + readAddr[i]));
102            }
103            addr = temp;
104            return values;
105        }
106      
107         /// <summary>
108        ///  写入内存4字节
109         /// </summary>
110        /// <param name="writeAddr">写入地址</param>
111        /// <param name="writeNumber">写入数值</param>
112        public static void writeMemory(UInt32 writeAddr, UInt32 writeNumber)
113        {
114            Process[] p = Process.GetProcessesByName(Game.gameName);
115            IntPtr handle = OpenProcess(0x1F0FFF, 0, p[0].Id);
116            WriteProcessMemory(handle, (IntPtr)writeAddr, new int[] { Convert.ToInt32(writeNumber) }, 4, IntPtr.Zero);
117        }
118 
119         /// <summary>
120        /// 写入内存,类型Byte,1字节
121         /// </summary>
122        /// <param name="writeAddr">写入地址</param>
123        /// <param name="writeNumber">写入数值</param>
124        public static void writeByte(UInt32 writeAddr, UInt32 writeNumber)
125        {
126            WriteProcessMemory(handle, (IntPtr)writeAddr, new int[] { Convert.ToInt32(writeNumber) }, 1, IntPtr.Zero);
127        }
128         
129         /// <summary>
130         /// 读取文本
131         /// </summary>
132        /// <param name="readAddr">读取地址</param>
133        /// <param name="str_length">读取长度</param>
134        /// <returns>读取内存中的 文本内容,文本长度就是偶数,且2位字节表示一个汉字</returns>
135        public static string readText(int[] readAddr, int str_length)
136        {
137            str_length = str_length * 2;//Unicode每个字符占用2个字节
138            int nameAddr;  // 读取每个字节时,放入此临时变量
139            byte[] num_String = new byte[str_length]; //存放读取的内容
140            byte[] arr1 = new byte[str_length]; //存放整理后的内容
141            for (int i = 0; i < str_length; i++)
142            {
143                readMemory(readAddr, out nameAddr).ToString();//此处读取每个字节
144                num_String[i] = (byte)readMemory((uint)nameAddr + (uint)i);
145            }
146            for (int i = 0; i < num_String.Length; i++)
147            {
148                arr1[i] = num_String[i];
149                if (i > 0 && i % 2 == 1)
150                {
151                    swap(ref arr1[i - 1], ref arr1[i]);
152                }
153            }
154            return System.Text.Encoding.BigEndianUnicode.GetString(arr1);
155        }
156 
157         /// <summary>
158        /// 读取float数值
159         /// </summary>
160        /// <param name="readAddr">读取地址</param>
161         /// <returns>/浮点类型的单精度值具有 4 个字节,所以此次数组下标没写成动态的</returns>
162        public static Int32 readMemoryFloat(UInt32 readAddr)
163        {
164            int[] result = new int[1];
165            int[] lpdw = new int[1];
166            bool b = ReadProcessMemory(handle, readAddr, result, 1, lpdw);
167            return result[0];
168        }
169        
170         /// <summary>
171        /// 读取float数值
172         /// </summary>
173        /// <param name="readAddr">读取地址</param>
174        /// <param name="addr">数值存放的逻辑地址</param>
175         /// <returns>/浮点类型的单精度值具有 4 个字节,所以此次数组下标没写成动态的</returns>
176        public static float readMemoryFloat(int[] readAddr, out int addr)
177        {
178            int values = 0;
179            byte[] valuesF = new byte[4];
180            for (int i = 0; i < readAddr.Length - 1; i++)
181            {
182                values = readMemory((uint)(values + readAddr[i]));  //拿到最后偏移地址的上一次地址(后面与得到最后地址,而非数值)
183            }
184            for (int j = 0; j <= 3; j++)
185            {
186                valuesF[j] = (byte)readMemoryFloat((uint)(values + readAddr[readAddr.Length - 1] + j));
187            }
188            addr = values + readAddr[readAddr.Length - 1];
189            float result = BitConverter.ToSingle(valuesF, 0);
190            return result;
191 
192        }
193         /// <summary>
194        /// 写入float数值
195         /// </summary>
196        /// <param name="writeAddr">读取地址</param>
197        /// <param name="value">写入的float数值</param>
198        public static void writeMemoryFloat(UInt32 writeAddr, float value)
199        {
200            byte[] byteArray = BitConverter.GetBytes(value);
201 
202            for (int i = 0; i <= byteArray.Length-1; i++)
203            {
204                writeByte((uint)writeAddr + (uint)i, byteArray[i]);
205            }
206 
207        }
208         
209         //交换数组的两个元素
210        private static void swap(ref byte num1,ref byte num2)
211        {
212            byte temp;
213            temp = num1;
214            num1 = num2;
215            num2 = temp;
216        }
217     }   
218 }
likehc

然后就是 窗体上的按钮 相应的 事件

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.ComponentModel;
  5 using System.Data;
  6 using System.Diagnostics;
  7 using System.Drawing;
  8 using System.Linq;
  9 using System.Text;
 10 using System.Threading.Tasks;
 11 using System.Windows.Forms;
 12 
 13 namespace huojuzhiguang
 14 {
 15     public partial class hjzg : Form
 16     {
 17         public hjzg()
 18         {   
 19             InitializeComponent();
 20         }
 21 
 22         public void btn_readData_Click(object sender, EventArgs e)
 23         {
 24             try
 25             {
 26                 lab_Role_Name.Text = OperateMemory.readText(new[] { 0x0289F22C, 0x34, 0x14, 0x5F0 }, 20);  //角色名称
 27                 lab_Role_SW.Text = (OperateMemory.readText(new[] { 0x0289F22C, 0x34, 0x14, 0x9985c }, 20)); //角色声望
 28                 txt_Role_Move.Text = OperateMemory.readMemoryFloat(new int[] { 0x0289F22C, 0x34, 0x14, 0x2A0 }, out Role.Move_Addr).ToString(); //角色奔跑速度
 29                 txt_Level.Text = OperateMemory.readMemory(new int[] { 0x0289F22C, 0x34, 0x14, 0x110 }, out Role.Level_Addr).ToString(); //等级
 30                 txt_Strength.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x578 }, out Role.Strength_Addr).ToString();//力量
 31                 txt_Dexterity.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x574 }, out Role.Dexterity_Addr).ToString();//敏捷
 32                 txt_Wit.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x580 }, out Role.Wit_Addr).ToString();//智力
 33                 txt_Tizhi.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x57C }, out Role.Tizhi_Addr).ToString();//体质
 34                 txt_ShuXingDian.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x5A8 }, out Role.ShuXingDian_Addr).ToString();//属性点
 35                 txt_JingNengDian.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x5AC }, out Role.JiNengDian_Addr).ToString();//技能点
 36                 txt_Money.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x0249F22C, 0x34, 0x14, 0x590 }, out Role.Money_Addr).ToString();//金币
 37 
 38                 btn_write.Enabled = true;// 保存人物属性按钮
 39                 
 40             }
 41             catch (Exception)
 42             {
 43             }
 44 
 45         }
 46 
 47         private void btn_write_Click(object sender, EventArgs e)
 48         {
 49             try
 50             {
 51                 if (lab_Role_Name.Text.Length <= 0)
 52                 {
 53                     MessageBox.Show("游戏保存错误!");
 54                 }
 55 
 56                 OperateMemory.writeMemory((uint)Role.Level_Addr, (uint)int.Parse(txt_Level.Text));
 57                 OperateMemory.writeMemory((uint)Role.Strength_Addr, (uint)int.Parse(txt_Strength.Text));
 58                 OperateMemory.writeMemory((uint)Role.Dexterity_Addr, (uint)int.Parse(txt_Dexterity.Text));
 59                 OperateMemory.writeMemory((uint)Role.Wit_Addr, (uint)int.Parse(txt_Wit.Text));
 60                 OperateMemory.writeMemory((uint)Role.Tizhi_Addr, (uint)int.Parse(txt_Tizhi.Text));
 61                 OperateMemory.writeMemory((uint)Role.ShuXingDian_Addr, (uint)int.Parse(txt_ShuXingDian.Text)); //属性点
 62                 OperateMemory.writeMemory((uint)Role.JiNengDian_Addr, (uint)int.Parse(txt_JingNengDian.Text)); //技能点
 63                 OperateMemory.writeMemory((uint)Role.Money_Addr, (uint)int.Parse(txt_Money.Text)); //金币
 64                 OperateMemory.writeMemoryFloat((uint)Role.Move_Addr, float.Parse(txt_Role_Move.Text));//角色奔跑速度
 65             }
 66             catch (Exception)
 67             {
 68             }
 69         }
 70 
 71         private void timer_findGame_Tick(object sender, EventArgs e)
 72         {
 73             try
 74             {
 75                 if (OperateMemory.findGame(Game.gameName))
 76                 {
 77                     lab_State.Text = "游戏已运行!";
 78                     if (OperateMemory.readMemory(new int[] { 0x0289F22C, 0x34, 0x14, 0x110 }) >= 1)
 79                     {
 80                         txt_Level.Enabled = true;
 81                         txt_Strength.Enabled = true;
 82                         txt_Dexterity.Enabled = true;
 83                         txt_Wit.Enabled = true;
 84                         txt_Tizhi.Enabled = true;
 85                         txt_ShuXingDian.Enabled = true;
 86                         txt_JingNengDian.Enabled = true;
 87                         txt_Money.Enabled = true; //金币
 88                         txt_Role_Move.Enabled = true;
 89 
 90                         btn_readData.Enabled = true;  //读取人物属性按钮
 91                     }
 92 
 93                 }
 94                 else
 95                 {
 96                     lab_State.Text = "抱歉,游戏未运行!";
 97                     txt_Level.Text = "";
 98                     txt_Level.Enabled = false;
 99 
100                     txt_Strength.Text = "";
101                     txt_Strength.Enabled = false;
102 
103                     txt_Dexterity.Text = "";
104                     txt_Dexterity.Enabled = false;
105 
106                     txt_Wit.Text = "";
107                     txt_Wit.Enabled = false;
108 
109                     txt_Tizhi.Text = "";
110                     txt_Tizhi.Enabled = false;
111 
112                     txt_ShuXingDian.Text = "";
113                     txt_ShuXingDian.Enabled = false;
114 
115                     txt_JingNengDian.Text = "";
116                     txt_JingNengDian.Enabled = false;
117 
118                     txt_Money.Text = "";
119                     txt_Money.Enabled = false;
120 
121                     txt_Role_Move.Text= "";
122                     txt_Role_Move.Enabled = false;
123 
124                     btn_readData.Enabled = false;  //读取人物属性
125                     btn_write.Enabled = false;  //保存人物属性
126 
127                 }
128             }
129             catch (Exception ex)
130             {
131             }
132         }
133 
134         private void btn_ReadZB_Click(object sender, EventArgs e)
135         {
136 
137             try
138             {
139                 txt_ZBName.Text = "";
140                 txt_ZBName.Text = OperateMemory.readText(new[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0xA0 }, 20);
141                 if (txt_ZBName.Text.Length <= 0)
142                 {
143                     MessageBox.Show("请将物品放入附魔窗体内!","头上有小闪电");
144                     return;
145                 }
146                 txt_ZBwlgj.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0x134 }, out ZhuangBei.wlgj_Addr1).ToString();//物理攻击1
147                 txt_ZBwlgj.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0x138 }, out ZhuangBei.wlgj_Addr2).ToString();//物理攻击2
148 
149                 txt_ZBwlfy.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0x140 }, out ZhuangBei.wlfy_Addr1).ToString();//物理防御1
150                 txt_ZBwlfy.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0x13C }, out ZhuangBei.wlfy_Addr2).ToString();//物理防御2
151 
152                 txt_ZBfmcs.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0x148 }, out ZhuangBei.fmcs_Addr).ToString();//附魔次数
153                 com_ZBks.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x03437E04, 0x18, 0x98, 0x1D4 }, out ZhuangBei.kongshu_Addr).ToString();//打孔数
154 
155             }
156             catch (Exception ex)
157             {
158                 
159             }
160         }
161 
162         private void btn_ZBSave_Click(object sender, EventArgs e)
163         {
164             try
165             {
166                 if (txt_ZBName.Text.Length <= 0)
167                 {
168                     MessageBox.Show("请将物品放入附魔窗体内!", "头上有小闪电");
169                     return;
170                 }
171                 OperateMemory.writeMemory((uint)ZhuangBei.wlgj_Addr1, (uint)int.Parse(txt_ZBwlgj.Text));//物理攻击1
172                 OperateMemory.writeMemory((uint)ZhuangBei.wlgj_Addr1, (uint)int.Parse(txt_ZBwlgj.Text));//物理攻击2
173 
174                 OperateMemory.writeMemory((uint)ZhuangBei.wlfy_Addr1, (uint)int.Parse(txt_ZBwlfy.Text));//物理防御1
175                 OperateMemory.writeMemory((uint)ZhuangBei.wlfy_Addr2, (uint)int.Parse(txt_ZBwlfy.Text));//物理防御2
176 
177                 OperateMemory.writeMemory((uint)ZhuangBei.fmcs_Addr, (uint)int.Parse(txt_ZBfmcs.Text));//附魔次数
178                 OperateMemory.writeMemory((uint)ZhuangBei.kongshu_Addr, (uint)int.Parse(com_ZBks.Text));//打孔数
179             }
180             catch (Exception)
181             {
182             }
183         }
184         private void btn_CWread_Click(object sender, EventArgs e)
185         {
186             try
187             {
188                 lab_Pet_Name.Text = OperateMemory.readText(new[] { 0x00400000 + 0x31C6674, 0x14, 0x3b5f0 }, 20);
189                 txt_CWLevel.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x31C6674, 0x14, 0x3b110 }, out Pet.Level_Addr).ToString(); //宠物等级
190                 txt_Pet_XueL.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x31C6674, 0x14, 0x3b564 }, out Pet.XueLiang_Addr).ToString(); //宠物血量
191                 txt_Pet_MF.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x31C6674, 0x14, 0x3b588 }, out Pet.MoFa_Addr).ToString(); //宠物魔法
192                 txt_CWJingyan.Text = OperateMemory.readMemory(new int[] { 0x00400000 + 0x31C6674, 0x14, 0x3b594 }, out Pet.Jingyan_Addr).ToString(); //宠物经验
193                 txt_Pet_Move.Text = OperateMemory.readMemoryFloat(new int[] { 0x00400000 + 0x31C6674, 0x14, 0x3b2a0 }, out Pet.Move_Addr).ToString(); //宠物移动速度
194             }
195             catch (Exception ex)
196             {
197                 
198             }
199         }
200 
201         private void btn_CWsave_Click(object sender, EventArgs e)
202         {
203             try
204             {
205                 if (lab_Pet_Name.Text.Length <= 0)
206                 {
207                     MessageBox.Show("游戏保存错误!");
208                 }
209 
210                 OperateMemory.writeMemory((uint)Pet.Level_Addr, (uint)int.Parse(txt_CWLevel.Text));//等级
211                 OperateMemory.writeMemory((uint)Pet.XueLiang_Addr, (uint)int.Parse(txt_Pet_XueL.Text));//血量
212                 OperateMemory.writeMemory((uint)Pet.MoFa_Addr, (uint)int.Parse(txt_Pet_MF.Text));//魔法
213                 OperateMemory.writeMemory((uint)Pet.Jingyan_Addr, (uint)int.Parse(txt_CWJingyan.Text));
214                 OperateMemory.writeMemoryFloat((uint)Pet.Move_Addr, float.Parse(txt_Pet_Move.Text));//角色奔跑速度
215             }
216             catch (Exception)
217             {
218             }
219         }
220 
221     }
222 }
likehc

游戏修改截图  虐boss啦

原文地址:https://www.cnblogs.com/likehc/p/5966684.html