fork download
  1. using System;
  2.  
  3. namespace Tibia.Util
  4. {
  5. /// <summary>
  6. /// Helper methods for reading memory.
  7. /// </summary>
  8. public static class Memory
  9. {
  10. /// <summary>
  11. /// Read a specified number of bytes from a process.
  12. /// </summary>
  13. /// <param name="handle"></param>
  14. /// <param name="address"></param>
  15. /// <param name="bytesToRead"></param>
  16. /// <returns></returns>
  17. public static byte[] ReadBytes(IntPtr handle, long address, uint bytesToRead)
  18. {
  19. IntPtr ptrBytesRead;
  20. byte[] buffer = new byte[bytesToRead];
  21.  
  22. Util.WinApi.ReadProcessMemory(handle, new IntPtr(address), buffer, bytesToRead, out ptrBytesRead);
  23.  
  24. return buffer;
  25. }
  26.  
  27. /// <summary>
  28. /// Read a byte from memory.
  29. /// </summary>
  30. /// <param name="handle"></param>
  31. /// <param name="address"></param>
  32. /// <returns></returns>
  33. public static byte ReadByte(IntPtr handle, long address)
  34. {
  35. return ReadBytes(handle, address, 1)[0];
  36. }
  37.  
  38. /// <summary>
  39. /// Read a short from memory (16-bits).
  40. /// </summary>
  41. /// <param name="handle"></param>
  42. /// <param name="address"></param>
  43. /// <returns></returns>
  44. public static short ReadInt16(IntPtr handle, long address)
  45. {
  46. return BitConverter.ToInt16(ReadBytes(handle, address, 2), 0);
  47. }
  48.  
  49. /// <summary>
  50. /// Read a ushort from memory (16-bits).
  51. /// </summary>
  52. /// <param name="handle"></param>
  53. /// <param name="address"></param>
  54. /// <returns></returns>
  55. public static ushort ReadUInt16(IntPtr handle, long address)
  56. {
  57. return BitConverter.ToUInt16(ReadBytes(handle, address, 2), 0);
  58. }
  59.  
  60. [Obsolete("Please use ReadInt16")]
  61. public static short ReadShort(IntPtr handle, long address)
  62. {
  63. return BitConverter.ToInt16(ReadBytes(handle, address, 2), 0);
  64. }
  65.  
  66. /// <summary>
  67. /// Read an integer from the process (32-bits)
  68. /// </summary>
  69. /// <param name="handle"></param>
  70. /// <param name="address"></param>
  71. /// <returns></returns>
  72. public static int ReadInt32(IntPtr handle, long address)
  73. {
  74. return BitConverter.ToInt32(ReadBytes(handle, address, 4), 0);
  75. }
  76.  
  77. /// <summary>
  78. /// Read an uinteger from the process (32-bits)
  79. /// </summary>
  80. /// <param name="handle"></param>
  81. /// <param name="address"></param>
  82. /// <returns></returns>
  83. public static uint ReadUInt32(IntPtr handle, long address)
  84. {
  85. return BitConverter.ToUInt32(ReadBytes(handle, address, 4), 0);
  86. }
  87.  
  88. /// <summary>
  89. /// Read an unsigned long from the process (64-bits)
  90. /// </summary>
  91. /// <param name="handle"></param>
  92. /// <param name="address"></param>
  93. /// <returns></returns>
  94. public static ulong ReadUInt64(IntPtr handle, long address)
  95. {
  96. return BitConverter.ToUInt64(ReadBytes(handle, address, 8), 0);
  97. }
  98.  
  99. [Obsolete("Please use ReadInt32.")]
  100. public static int ReadInt(IntPtr handle, long address)
  101. {
  102. return BitConverter.ToInt32(ReadBytes(handle, address, 4), 0);
  103. }
  104.  
  105. /// <summary>
  106. /// Read a 32-bit double from the process
  107. /// </summary>
  108. /// <param name="handle"></param>
  109. /// <param name="address"></param>
  110. /// <returns></returns>
  111. public static double ReadDouble(IntPtr handle, long address)
  112. {
  113. return BitConverter.ToDouble(ReadBytes(handle, address, 8), 0);
  114. }
  115.  
  116. /// <summary>
  117. /// Read a string from memmory. Splits at 00 and returns first section to avoid junk. Uses default length of 255. Use ReadString(IntPtr handle, long address, int length) to read longer strings, such as the RSA key.
  118. /// </summary>
  119. /// <param name="handle"></param>
  120. /// <param name="address"></param>
  121. /// <returns></returns>
  122. public static string ReadString(IntPtr handle, long address)
  123. {
  124. return ReadString(handle, address, 0);
  125. }
  126.  
  127. /// <summary>
  128. /// Read a string from memmory. Splits at 00 and returns first section to avoid junk.
  129. /// </summary>
  130. /// <param name="handle"></param>
  131. /// <param name="address"></param>
  132. /// <param name="length">the length of the bytes to read</param>
  133. /// <returns></returns>
  134. public static string ReadString(IntPtr handle, long address, uint length)
  135. {
  136. if (length > 0)
  137. {
  138. byte[] buffer;
  139. buffer = ReadBytes(handle, address, length);
  140. return System.Text.ASCIIEncoding.Default.GetString(buffer).Split(new Char())[0];
  141. }
  142. else
  143. {
  144. string s = "";
  145. byte temp = ReadByte(handle, address++);
  146. while (temp != 0)
  147. {
  148. s += (char)temp;
  149. temp = ReadByte(handle, address++);
  150. }
  151. return s;
  152. }
  153. }
  154.  
  155. /// <summary>
  156. /// Write a specified number of bytes to a process.
  157. /// </summary>
  158. /// <param name="handle"></param>
  159. /// <param name="address"></param>
  160. /// <param name="bytes"></param>
  161. /// <param name="length"></param>
  162. /// <returns></returns>
  163. public static bool WriteBytes(IntPtr handle, long address, byte[] bytes, uint length)
  164. {
  165. IntPtr bytesWritten;
  166.  
  167. // Write to memory
  168. int result = Util.WinApi.WriteProcessMemory(handle, new IntPtr(address), bytes, length, out bytesWritten);
  169.  
  170. return result != 0;
  171. }
  172.  
  173. /// <summary>
  174. /// Write an integer (32-bits) to memory.
  175. /// </summary>
  176. /// <param name="handle"></param>
  177. /// <param name="address"></param>
  178. /// <param name="value"></param>
  179. /// <returns></returns>
  180. public static bool WriteInt32(IntPtr handle, long address, int value)
  181. {
  182. return WriteBytes(handle, address, BitConverter.GetBytes(value), 4);
  183. }
  184.  
  185. /// <summary>
  186. /// Write an uinteger (32-bits) to memory.
  187. /// </summary>
  188. /// <param name="handle"></param>
  189. /// <param name="address"></param>
  190. /// <param name="value"></param>
  191. /// <returns></returns>
  192. public static bool WriteUInt32(IntPtr handle, long address, uint value)
  193. {
  194. return WriteBytes(handle, address, BitConverter.GetBytes(value), 4);
  195. }
  196.  
  197. /// <summary>
  198. /// Write an unsigned long (64-bits) to memory.
  199. /// </summary>
  200. /// <param name="handle"></param>
  201. /// <param name="address"></param>
  202. /// <param name="value"></param>
  203. /// <returns></returns>
  204. public static bool WriteUInt64(IntPtr handle, long address, ulong value)
  205. {
  206. return WriteBytes(handle, address, BitConverter.GetBytes(value), 8);
  207. }
  208.  
  209. /// <summary>
  210. /// Write an integer (16-bits) to memory.
  211. /// </summary>
  212. /// <param name="handle"></param>
  213. /// <param name="address"></param>
  214. /// <param name="value"></param>
  215. /// <returns></returns>
  216. public static bool WriteInt16(IntPtr handle, long address, short value)
  217. {
  218. return WriteBytes(handle, address, BitConverter.GetBytes(value), 2);
  219. }
  220.  
  221. /// <summary>
  222. /// Write an uinteger (16-bits) to memory.
  223. /// </summary>
  224. /// <param name="handle"></param>
  225. /// <param name="address"></param>
  226. /// <param name="value"></param>
  227. /// <returns></returns>
  228. public static bool WriteUInt16(IntPtr handle, long address, ushort value)
  229. {
  230. return WriteBytes(handle, address, BitConverter.GetBytes(value), 2);
  231. }
  232.  
  233. [Obsolete("Please use WriteInt32.")]
  234. public static bool WriteInt(IntPtr handle, long address, int value)
  235. {
  236. byte[] bytes = BitConverter.GetBytes(value);
  237. return WriteBytes(handle, address, bytes, 4);
  238. }
  239.  
  240. /// <summary>
  241. /// Write a double value to memory.
  242. /// </summary>
  243. /// <param name="handle"></param>
  244. /// <param name="address"></param>
  245. /// <param name="value"></param>
  246. /// <returns></returns>
  247. public static bool WriteDouble(IntPtr handle, long address, double value)
  248. {
  249. byte[] bytes = BitConverter.GetBytes(value);
  250. return WriteBytes(handle, address, bytes, 8);
  251. }
  252.  
  253. /// <summary>
  254. /// Write a byte to memory.
  255. /// </summary>
  256. /// <param name="handle"></param>
  257. /// <param name="address"></param>
  258. /// <param name="value"></param>
  259. /// <returns></returns>
  260. public static bool WriteByte(IntPtr handle, long address, byte value)
  261. {
  262. return WriteBytes(handle, address, new byte[] { value }, 1);
  263. }
  264.  
  265. /// <summary>
  266. /// Write a string to memory without using econding.
  267. /// </summary>
  268. /// <param name="handle"></param>
  269. /// <param name="address"></param>
  270. /// <param name="str"></param>
  271. /// <returns></returns>
  272. public static bool WriteStringNoEncoding(IntPtr handle, long address, string str)
  273. {
  274. str += '\0';
  275. byte[] bytes = str.ToByteArray();
  276. return WriteBytes(handle, address, bytes, (uint)bytes.Length);
  277. }
  278.  
  279. /// <summary>
  280. /// Write a string to memory.
  281. /// </summary>
  282. /// <param name="handle"></param>
  283. /// <param name="address"></param>
  284. /// <param name="str"></param>
  285. /// <returns></returns>
  286. public static bool WriteString(IntPtr handle, long address, string str)
  287. {
  288. str += '\0';
  289. byte[] bytes = System.Text.ASCIIEncoding.Default.GetBytes(str);
  290. return WriteBytes(handle, address, bytes, (uint)bytes.Length);
  291. }
  292.  
  293. /// <summary>
  294. /// Set the RSA key. Different from WriteString because must overcome protection.
  295. /// </summary>
  296. /// <param name="handle"></param>
  297. /// <param name="address"></param>
  298. /// <param name="newKey"></param>
  299. /// <returns></returns>
  300. public static bool WriteRSA(IntPtr handle, long address, string newKey)
  301. {
  302. IntPtr bytesWritten;
  303. int result;
  304. WinApi.MemoryProtection oldProtection = 0;
  305.  
  306. System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
  307. byte[] bytes = enc.GetBytes(newKey);
  308.  
  309. // Make it so we can write to the memory block
  310. WinApi.VirtualProtectEx(
  311. handle,
  312. new IntPtr(address),
  313. new IntPtr(bytes.Length),
  314. WinApi.MemoryProtection.ExecuteReadWrite, ref oldProtection);
  315.  
  316. // Write to memory
  317. result = WinApi.WriteProcessMemory(handle, new IntPtr(address), bytes, (uint)bytes.Length, out bytesWritten);
  318.  
  319. // Put the protection back on the memory block
  320. WinApi.VirtualProtectEx(handle, new IntPtr(address), new IntPtr(bytes.Length), oldProtection, ref oldProtection);
  321.  
  322. return (result != 0);
  323. }
  324. }
  325. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cs(22,18): error CS0234: The type or namespace name `WinApi' does not exist in the namespace `Tibia.Util'. Are you missing an assembly reference?
prog.cs(168,31): error CS0234: The type or namespace name `WinApi' does not exist in the namespace `Tibia.Util'. Are you missing an assembly reference?
prog.cs(275,32): error CS1061: Type `string' does not contain a definition for `ToByteArray' and no extension method `ToByteArray' of type `string' could be found (are you missing a using directive or an assembly reference?)
prog.cs(304,13): error CS0246: The type or namespace name `WinApi' could not be found. Are you missing a using directive or an assembly reference?
Compilation failed: 4 error(s), 0 warnings
stdout
Standard output is empty