火炬之光2_辅助工具 内存读写相关
Posted likehc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了火炬之光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 }
然后就是 窗体上的按钮 相应的 事件
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 火炬之光2 报错,急。。。。急。。。。急