Guest User

Untitled

a guest
Jan 19th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.54 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Runtime.ConstrainedExecution;
  7. using System.Runtime.InteropServices;
  8. using System.Security;
  9. using System.Text;
  10. using System.Text.RegularExpressions;
  11. using System.Threading.Tasks;
  12.  
  13. namespace FFXIVRadar
  14. {
  15.  
  16.  
  17. static class FFXIVServerScanner
  18. {
  19.  
  20. private static readonly Dictionary<string, string> PatternDictionary = new Dictionary<string, string>()
  21. {
  22. //{ "MACRO", "00015B677465715D" },
  23. { "CHARACTER", "46465849565F434852??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????ED8C8CEC9DB4EB8490ED8C90ED8380ECA7803134" }
  24. };
  25.  
  26.  
  27. //private static readonly uint MACRO_START = 0x0012;
  28. //private static readonly uint MACRO_LEN = 0x0668;
  29. //private static readonly uint MACRO_LINE = 0x0068;
  30. //private static readonly uint MACRO_LINELEN = 0x10;
  31. private static readonly uint CHAR_POS = 0x184;
  32. private static readonly uint SERVER_POS = 0x204;
  33.  
  34. private static readonly Dictionary<string, Regex> RegexDict = new Dictionary<string, Regex>()
  35. {
  36. { "MAP",
  37. new Regex(@"%MAP\(MAP\:([0-9]+),IMG\:([0-9]+),X\:([0-9.]+),Y\:([0-9.]+)(?:,Z\:([0-9.]+)|)\)%", RegexOptions.Compiled) },
  38. { "ITEM",
  39. new Regex(@"%ITEM\(NO:([0-9]+)(?:,DISPLAY:([0-9]+)|),HQ:([Tt](?:rue|)|[Ff](?:alse|))\)%", RegexOptions.Compiled) },
  40. { "HEX",
  41. new Regex(@"HEX\(([^)]+)\)", RegexOptions.Compiled) }
  42. };
  43.  
  44. private static Process currentProcess = null;
  45. private static IntPtr currentHandle = IntPtr.Zero;
  46. private static IntPtr CharPointer = IntPtr.Zero;
  47.  
  48. public static Tuple<string, string> Scan(Process ffxivProcess)
  49. {
  50. if (currentProcess != null && currentProcess.Id != ffxivProcess.Id)
  51. {
  52. CloseHandle(currentHandle);
  53. currentHandle = IntPtr.Zero;
  54. }
  55.  
  56. if (currentHandle == IntPtr.Zero)
  57. {
  58. currentHandle = OpenProcess(0x1F0FFF, false, ffxivProcess.Id);
  59. currentProcess = ffxivProcess;
  60. CharPointer = IntPtr.Zero;
  61. }
  62.  
  63. var character = GetCharacter(ffxivProcess, currentHandle);
  64. var server = GetServerInfo(ffxivProcess, currentHandle);
  65.  
  66. return character == null || server == null ? null : Tuple.Create(character, server);
  67. }
  68.  
  69. private static string GetCharacter(Process process, IntPtr handle)
  70. {
  71. var chrPtr = CharPointer != IntPtr.Zero ? CharPointer : FindByMainModule(process, handle, PatternDictionary["CHARACTER"]);
  72. if (chrPtr == IntPtr.Zero) return null;
  73. CharPointer = chrPtr;
  74. var chruni = new List<byte>();
  75. var chr = Read(handle, new IntPtr(chrPtr.ToInt64() + CHAR_POS), 0, 24);
  76.  
  77. foreach (var c in chr)
  78. {
  79. if (c == 0x00) break;
  80. chruni.Add(c);
  81. }
  82.  
  83. var text = Encoding.UTF8.GetString(chruni.ToArray());
  84.  
  85. Debug.WriteLine("[PID: " + process.Id + " CHARNAME: " + text + "]");
  86. return text;
  87. }
  88.  
  89. private static string GetServerInfo(Process process, IntPtr handle)
  90. {
  91. var chrPtr = CharPointer != IntPtr.Zero ? CharPointer : FindByMainModule(process, handle, PatternDictionary["CHARACTER"]);
  92. if (chrPtr == IntPtr.Zero) return null;
  93. CharPointer = chrPtr;
  94. var chruni = new List<byte>();
  95. var chr = Read(handle, new IntPtr(chrPtr.ToInt64() + SERVER_POS), 0, 96);
  96.  
  97. foreach (var c in chr)
  98. {
  99. if (c == 0x00) break;
  100. chruni.Add(c);
  101. }
  102.  
  103. var text = Encoding.UTF8.GetString(chruni.ToArray());
  104. Debug.WriteLine(text);
  105. var sp = text.Split('\n');
  106. foreach (var e in sp)
  107. {
  108. if (e.Contains("서버:"))
  109. {
  110. return e.Replace("서버:", "").Trim();
  111. }
  112. }
  113.  
  114. return null;
  115. }
  116.  
  117.  
  118. /// <summary>
  119. /// 메모리 패턴으로 포인트 찾기. 패턴을 지정하지 않은 경우 문자열 값으로 초기화 가능 ///
  120. /// </summary>
  121. /// <param name="pattern"></param>
  122. /// <returns></returns>
  123. public static IntPtr FindByMainModule(Process process, IntPtr handle, string pattern)
  124. {
  125. return FindByMainModule(process, handle, new MemoryPattern(pattern));
  126. }
  127.  
  128. /// <summary>
  129. /// 메모리 패턴으로 포인트 찾기 ///
  130. /// </summary>
  131. /// <param name="mp"></param>
  132. /// <returns></returns>
  133. private static IntPtr FindByMainModule(Process process, IntPtr handle, MemoryPattern memoryPattern)
  134. {
  135. var ModuleAddr = process.MainModule.BaseAddress;
  136. var ModuleSize = process.MainModule.ModuleMemorySize;
  137. var patternBuffer = new byte[memoryPattern.Length];
  138. var buffer = new byte[0x1000];
  139.  
  140. var read = IntPtr.Zero;
  141. var seek = ModuleAddr;
  142. var index = 0;
  143. var readmax = ModuleAddr.ToInt64() + ModuleSize - memoryPattern.Length;
  144. try
  145. {
  146. while (seek.ToInt64() < readmax)
  147. {
  148. read = new IntPtr(Math.Min(ModuleSize - (read.ToInt64() + memoryPattern.Length), 0x1000));
  149. if (ReadProcessMemory(handle, seek, buffer, read, out read))
  150. {
  151. index = SearchPattern(buffer, memoryPattern);
  152. if (index != -1)
  153. {
  154. return new IntPtr(seek.ToInt64() + index);
  155. }
  156. }
  157. seek = new IntPtr(seek.ToInt64() + read.ToInt64() - memoryPattern.Length + 1);
  158. }
  159. }
  160. catch (Exception ex)
  161. {
  162. Debug.WriteLine(ex);
  163. }
  164. return IntPtr.Zero;
  165. }
  166.  
  167. /// <summary>
  168. /// 패턴을 찾는 함수 (바이트 배열로 직접 찾기) ///
  169. /// </summary>
  170. /// <param name="buffer"></param>
  171. /// <param name="patternArray"></param>
  172. /// <returns></returns>
  173. private static int SearchPattern(byte[] buffer, byte?[] patternArray)
  174. {
  175. int i, j;
  176. // buff loop
  177. for (i = 0; i < buffer.Length - patternArray.Length; i++)
  178. {
  179. for (j = 0; j < patternArray.Length; j++)
  180. if (patternArray[j].HasValue && buffer[i + j] != patternArray[j].Value) // null 이 아니면서 값이 다른 경우 비교를 중지
  181. break;
  182.  
  183. if (j == patternArray.Length) // 끝까지 같았으면 위치 반환
  184. return i;
  185. }
  186.  
  187. return -1; // 아니면 -1
  188. }
  189.  
  190. /// <summary>
  191. /// 패턴을 찾는 함수 ///
  192. /// </summary>
  193. /// <param name="buffer"></param>
  194. /// <param name="mp"></param>
  195. /// <returns></returns>
  196. private static int SearchPattern(byte[] buffer, MemoryPattern mp)
  197. {
  198. return SearchPattern(buffer, mp.ToNullableByteArray());
  199. }
  200.  
  201. /// <summary>
  202. /// 프로세서의 메모리 영역을 지정해 메모리를 읽어옴 ///
  203. /// </summary>
  204. /// <param name="ptr">읽기 시작할 위치</param>
  205. /// <param name="start">추가값</param>
  206. /// <param name="length">길이</param>
  207. /// <returns></returns>
  208. private static byte[] Read(IntPtr handle, IntPtr ptr, int start, int length)
  209. {
  210. var b = new byte[length];
  211. var size = new IntPtr(length);
  212.  
  213. if (!ReadProcessMemory(handle, ptr, b, size, out size))
  214. {
  215. Debug.WriteLine("Can't Access Process Memory");
  216. }
  217. return b;
  218. }
  219.  
  220.  
  221.  
  222. //DLL IMPORT
  223.  
  224. [DllImport("kernel32.dll", SetLastError = true)]
  225. private static extern IntPtr OpenProcess(int AccFlag, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int procID);
  226.  
  227. [DllImport("kernel32.dll", SetLastError = true)]
  228. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  229. [SuppressUnmanagedCodeSecurity]
  230. [return: MarshalAs(UnmanagedType.Bool)]
  231. static extern bool CloseHandle(IntPtr hObject);
  232.  
  233. [DllImport("kernel32.dll", SetLastError = true)]
  234. [return: MarshalAs(UnmanagedType.Bool)]
  235. private static extern bool ReadProcessMemory(IntPtr proc, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, IntPtr bsize, out IntPtr lpNumberOfBytesRead);
  236.  
  237.  
  238. //
  239. private class MemoryPattern
  240. {
  241. public List<PatternData> Pattern { get; set; }
  242. public long Length { get; private set; }
  243. public MemoryPattern(string pattern)
  244. {
  245. Pattern = new List<PatternData>();
  246. var bytearray = new Regex(@"[0-9A-Fa-f]{2}|\*\*|\?\?", RegexOptions.Compiled);
  247. var array = bytearray.Matches(pattern);
  248.  
  249. var tmpbyte = new List<byte>();
  250. var skiplen = 0;
  251.  
  252. Length = array.Count;
  253.  
  254. for (var x = 0; x < array.Count; x++)
  255. {
  256. Match i = array[x];
  257. if (i.Value != "??" && i.Value != "**" && skiplen == 0)
  258. {
  259. tmpbyte.Add(byte.Parse(i.Value, System.Globalization.NumberStyles.AllowHexSpecifier));
  260. }
  261. else if (i.Value != "??" && i.Value != "**" && skiplen > 0)
  262. {
  263. var ptn = new PatternData();
  264.  
  265. ptn.NextSkipLength = skiplen;
  266. ptn.Data = tmpbyte.ToArray();
  267. Pattern.Add(ptn);
  268.  
  269. tmpbyte.Clear();
  270. skiplen = 0;
  271.  
  272. tmpbyte.Add(byte.Parse(i.Value, System.Globalization.NumberStyles.AllowHexSpecifier));
  273. }
  274. else
  275. {
  276. skiplen++;
  277. }
  278. }
  279.  
  280. var lastpattern = new PatternData();
  281.  
  282. lastpattern.NextSkipLength = skiplen;
  283. lastpattern.Data = tmpbyte.ToArray();
  284. Pattern.Add(lastpattern);
  285. tmpbyte.Clear();
  286. }
  287.  
  288. public byte?[] ToNullableByteArray()
  289. {
  290. var l = new List<byte?>();
  291. foreach (var i in Pattern)
  292. {
  293. foreach (var b in i.Data)
  294. l.Add(b);
  295.  
  296. if (i.NextSkipLength == 0) continue;
  297. for (var x = 0; x < i.NextSkipLength; x++)
  298. l.Add(null);
  299. }
  300.  
  301. return l.ToArray();
  302. }
  303. }
  304. private class PatternData
  305. {
  306. public byte[] Data { get; set; }
  307. public int NextSkipLength { get; set; }
  308. }
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315. }
  316. }
Add Comment
Please, Sign In to add comment