LDasm.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace DotNetDetour
  4. {
  5. /// <summary>
  6. /// 用于计算汇编指令长度,使用的是BlackBone的LDasm.c中的算法,我把他翻译成C#了
  7. /// </summary>
  8. public unsafe class LDasm
  9. {
  10. const int F_INVALID = 0x01;
  11. const int F_PREFIX = 0x02;
  12. const int F_REX = 0x04;
  13. const int F_MODRM = 0x08;
  14. const int F_SIB = 0x10;
  15. const int F_DISP = 0x20;
  16. const int F_IMM = 0x40;
  17. const int F_RELATIVE = 0x80;
  18. const int OP_NONE = 0x00;
  19. const int OP_INVALID = 0x80;
  20. const int OP_DATA_I8 = 0x01;
  21. const int OP_DATA_I16 = 0x02;
  22. const int OP_DATA_I16_I32 = 0x04;
  23. const int OP_DATA_I16_I32_I64 = 0x08;
  24. const int OP_EXTENDED = 0x10;
  25. const int OP_RELATIVE = 0x20;
  26. const int OP_MODRM = 0x40;
  27. const int OP_PREFIX = 0x80;
  28. struct ldasm_data
  29. {
  30. public byte flags;
  31. public byte rex;
  32. public byte modrm;
  33. public byte sib;
  34. public byte opcd_offset;
  35. public byte opcd_size;
  36. public byte disp_offset;
  37. public byte disp_size;
  38. public byte imm_offset;
  39. public byte imm_size;
  40. }
  41. static byte[] flags_table =
  42. {
  43. /* 00 */ OP_MODRM,
  44. /* 01 */ OP_MODRM,
  45. /* 02 */ OP_MODRM,
  46. /* 03 */ OP_MODRM,
  47. /* 04 */ OP_DATA_I8,
  48. /* 05 */ OP_DATA_I16_I32,
  49. /* 06 */ OP_NONE,
  50. /* 07 */ OP_NONE,
  51. /* 08 */ OP_MODRM,
  52. /* 09 */ OP_MODRM,
  53. /* 0A */ OP_MODRM,
  54. /* 0B */ OP_MODRM,
  55. /* 0C */ OP_DATA_I8,
  56. /* 0D */ OP_DATA_I16_I32,
  57. /* 0E */ OP_NONE,
  58. /* 0F */ OP_NONE,
  59. /* 10 */ OP_MODRM,
  60. /* 11 */ OP_MODRM,
  61. /* 12 */ OP_MODRM,
  62. /* 13 */ OP_MODRM,
  63. /* 14 */ OP_DATA_I8,
  64. /* 15 */ OP_DATA_I16_I32,
  65. /* 16 */ OP_NONE,
  66. /* 17 */ OP_NONE,
  67. /* 18 */ OP_MODRM,
  68. /* 19 */ OP_MODRM,
  69. /* 1A */ OP_MODRM,
  70. /* 1B */ OP_MODRM,
  71. /* 1C */ OP_DATA_I8,
  72. /* 1D */ OP_DATA_I16_I32,
  73. /* 1E */ OP_NONE,
  74. /* 1F */ OP_NONE,
  75. /* 20 */ OP_MODRM,
  76. /* 21 */ OP_MODRM,
  77. /* 22 */ OP_MODRM,
  78. /* 23 */ OP_MODRM,
  79. /* 24 */ OP_DATA_I8,
  80. /* 25 */ OP_DATA_I16_I32,
  81. /* 26 */ OP_PREFIX,
  82. /* 27 */ OP_NONE,
  83. /* 28 */ OP_MODRM,
  84. /* 29 */ OP_MODRM,
  85. /* 2A */ OP_MODRM,
  86. /* 2B */ OP_MODRM,
  87. /* 2C */ OP_DATA_I8,
  88. /* 2D */ OP_DATA_I16_I32,
  89. /* 2E */ OP_PREFIX,
  90. /* 2F */ OP_NONE,
  91. /* 30 */ OP_MODRM,
  92. /* 31 */ OP_MODRM,
  93. /* 32 */ OP_MODRM,
  94. /* 33 */ OP_MODRM,
  95. /* 34 */ OP_DATA_I8,
  96. /* 35 */ OP_DATA_I16_I32,
  97. /* 36 */ OP_PREFIX,
  98. /* 37 */ OP_NONE,
  99. /* 38 */ OP_MODRM,
  100. /* 39 */ OP_MODRM,
  101. /* 3A */ OP_MODRM,
  102. /* 3B */ OP_MODRM,
  103. /* 3C */ OP_DATA_I8,
  104. /* 3D */ OP_DATA_I16_I32,
  105. /* 3E */ OP_PREFIX,
  106. /* 3F */ OP_NONE,
  107. /* 40 */ OP_NONE,
  108. /* 41 */ OP_NONE,
  109. /* 42 */ OP_NONE,
  110. /* 43 */ OP_NONE,
  111. /* 44 */ OP_NONE,
  112. /* 45 */ OP_NONE,
  113. /* 46 */ OP_NONE,
  114. /* 47 */ OP_NONE,
  115. /* 48 */ OP_NONE,
  116. /* 49 */ OP_NONE,
  117. /* 4A */ OP_NONE,
  118. /* 4B */ OP_NONE,
  119. /* 4C */ OP_NONE,
  120. /* 4D */ OP_NONE,
  121. /* 4E */ OP_NONE,
  122. /* 4F */ OP_NONE,
  123. /* 50 */ OP_NONE,
  124. /* 51 */ OP_NONE,
  125. /* 52 */ OP_NONE,
  126. /* 53 */ OP_NONE,
  127. /* 54 */ OP_NONE,
  128. /* 55 */ OP_NONE,
  129. /* 56 */ OP_NONE,
  130. /* 57 */ OP_NONE,
  131. /* 58 */ OP_NONE,
  132. /* 59 */ OP_NONE,
  133. /* 5A */ OP_NONE,
  134. /* 5B */ OP_NONE,
  135. /* 5C */ OP_NONE,
  136. /* 5D */ OP_NONE,
  137. /* 5E */ OP_NONE,
  138. /* 5F */ OP_NONE,
  139. /* 60 */ OP_NONE,
  140. /* 61 */ OP_NONE,
  141. /* 62 */ OP_MODRM,
  142. /* 63 */ OP_MODRM,
  143. /* 64 */ OP_PREFIX,
  144. /* 65 */ OP_PREFIX,
  145. /* 66 */ OP_PREFIX,
  146. /* 67 */ OP_PREFIX,
  147. /* 68 */ OP_DATA_I16_I32,
  148. /* 69 */ OP_MODRM | OP_DATA_I16_I32,
  149. /* 6A */ OP_DATA_I8,
  150. /* 6B */ OP_MODRM | OP_DATA_I8,
  151. /* 6C */ OP_NONE,
  152. /* 6D */ OP_NONE,
  153. /* 6E */ OP_NONE,
  154. /* 6F */ OP_NONE,
  155. /* 70 */ OP_RELATIVE | OP_DATA_I8,
  156. /* 71 */ OP_RELATIVE | OP_DATA_I8,
  157. /* 72 */ OP_RELATIVE | OP_DATA_I8,
  158. /* 73 */ OP_RELATIVE | OP_DATA_I8,
  159. /* 74 */ OP_RELATIVE | OP_DATA_I8,
  160. /* 75 */ OP_RELATIVE | OP_DATA_I8,
  161. /* 76 */ OP_RELATIVE | OP_DATA_I8,
  162. /* 77 */ OP_RELATIVE | OP_DATA_I8,
  163. /* 78 */ OP_RELATIVE | OP_DATA_I8,
  164. /* 79 */ OP_RELATIVE | OP_DATA_I8,
  165. /* 7A */ OP_RELATIVE | OP_DATA_I8,
  166. /* 7B */ OP_RELATIVE | OP_DATA_I8,
  167. /* 7C */ OP_RELATIVE | OP_DATA_I8,
  168. /* 7D */ OP_RELATIVE | OP_DATA_I8,
  169. /* 7E */ OP_RELATIVE | OP_DATA_I8,
  170. /* 7F */ OP_RELATIVE | OP_DATA_I8,
  171. /* 80 */ OP_MODRM | OP_DATA_I8,
  172. /* 81 */ OP_MODRM | OP_DATA_I16_I32,
  173. /* 82 */ OP_MODRM | OP_DATA_I8,
  174. /* 83 */ OP_MODRM | OP_DATA_I8,
  175. /* 84 */ OP_MODRM,
  176. /* 85 */ OP_MODRM,
  177. /* 86 */ OP_MODRM,
  178. /* 87 */ OP_MODRM,
  179. /* 88 */ OP_MODRM,
  180. /* 89 */ OP_MODRM,
  181. /* 8A */ OP_MODRM,
  182. /* 8B */ OP_MODRM,
  183. /* 8C */ OP_MODRM,
  184. /* 8D */ OP_MODRM,
  185. /* 8E */ OP_MODRM,
  186. /* 8F */ OP_MODRM,
  187. /* 90 */ OP_NONE,
  188. /* 91 */ OP_NONE,
  189. /* 92 */ OP_NONE,
  190. /* 93 */ OP_NONE,
  191. /* 94 */ OP_NONE,
  192. /* 95 */ OP_NONE,
  193. /* 96 */ OP_NONE,
  194. /* 97 */ OP_NONE,
  195. /* 98 */ OP_NONE,
  196. /* 99 */ OP_NONE,
  197. /* 9A */ OP_DATA_I16 | OP_DATA_I16_I32,
  198. /* 9B */ OP_NONE,
  199. /* 9C */ OP_NONE,
  200. /* 9D */ OP_NONE,
  201. /* 9E */ OP_NONE,
  202. /* 9F */ OP_NONE,
  203. /* A0 */ OP_DATA_I8,
  204. /* A1 */ OP_DATA_I16_I32_I64,
  205. /* A2 */ OP_DATA_I8,
  206. /* A3 */ OP_DATA_I16_I32_I64,
  207. /* A4 */ OP_NONE,
  208. /* A5 */ OP_NONE,
  209. /* A6 */ OP_NONE,
  210. /* A7 */ OP_NONE,
  211. /* A8 */ OP_DATA_I8,
  212. /* A9 */ OP_DATA_I16_I32,
  213. /* AA */ OP_NONE,
  214. /* AB */ OP_NONE,
  215. /* AC */ OP_NONE,
  216. /* AD */ OP_NONE,
  217. /* AE */ OP_NONE,
  218. /* AF */ OP_NONE,
  219. /* B0 */ OP_DATA_I8,
  220. /* B1 */ OP_DATA_I8,
  221. /* B2 */ OP_DATA_I8,
  222. /* B3 */ OP_DATA_I8,
  223. /* B4 */ OP_DATA_I8,
  224. /* B5 */ OP_DATA_I8,
  225. /* B6 */ OP_DATA_I8,
  226. /* B7 */ OP_DATA_I8,
  227. /* B8 */ OP_DATA_I16_I32_I64,
  228. /* B9 */ OP_DATA_I16_I32_I64,
  229. /* BA */ OP_DATA_I16_I32_I64,
  230. /* BB */ OP_DATA_I16_I32_I64,
  231. /* BC */ OP_DATA_I16_I32_I64,
  232. /* BD */ OP_DATA_I16_I32_I64,
  233. /* BE */ OP_DATA_I16_I32_I64,
  234. /* BF */ OP_DATA_I16_I32_I64,
  235. /* C0 */ OP_MODRM | OP_DATA_I8,
  236. /* C1 */ OP_MODRM | OP_DATA_I8,
  237. /* C2 */ OP_DATA_I16,
  238. /* C3 */ OP_NONE,
  239. /* C4 */ OP_MODRM,
  240. /* C5 */ OP_MODRM,
  241. /* C6 */ OP_MODRM | OP_DATA_I8,
  242. /* C7 */ OP_MODRM | OP_DATA_I16_I32,
  243. /* C8 */ OP_DATA_I8 | OP_DATA_I16,
  244. /* C9 */ OP_NONE,
  245. /* CA */ OP_DATA_I16,
  246. /* CB */ OP_NONE,
  247. /* CC */ OP_NONE,
  248. /* CD */ OP_DATA_I8,
  249. /* CE */ OP_NONE,
  250. /* CF */ OP_NONE,
  251. /* D0 */ OP_MODRM,
  252. /* D1 */ OP_MODRM,
  253. /* D2 */ OP_MODRM,
  254. /* D3 */ OP_MODRM,
  255. /* D4 */ OP_DATA_I8,
  256. /* D5 */ OP_DATA_I8,
  257. /* D6 */ OP_NONE,
  258. /* D7 */ OP_NONE,
  259. /* D8 */ OP_MODRM,
  260. /* D9 */ OP_MODRM,
  261. /* DA */ OP_MODRM,
  262. /* DB */ OP_MODRM,
  263. /* DC */ OP_MODRM,
  264. /* DD */ OP_MODRM,
  265. /* DE */ OP_MODRM,
  266. /* DF */ OP_MODRM,
  267. /* E0 */ OP_RELATIVE | OP_DATA_I8,
  268. /* E1 */ OP_RELATIVE | OP_DATA_I8,
  269. /* E2 */ OP_RELATIVE | OP_DATA_I8,
  270. /* E3 */ OP_RELATIVE | OP_DATA_I8,
  271. /* E4 */ OP_DATA_I8,
  272. /* E5 */ OP_DATA_I8,
  273. /* E6 */ OP_DATA_I8,
  274. /* E7 */ OP_DATA_I8,
  275. /* E8 */ OP_RELATIVE | OP_DATA_I16_I32,
  276. /* E9 */ OP_RELATIVE | OP_DATA_I16_I32,
  277. /* EA */ OP_DATA_I16 | OP_DATA_I16_I32,
  278. /* EB */ OP_RELATIVE | OP_DATA_I8,
  279. /* EC */ OP_NONE,
  280. /* ED */ OP_NONE,
  281. /* EE */ OP_NONE,
  282. /* EF */ OP_NONE,
  283. /* F0 */ OP_PREFIX,
  284. /* F1 */ OP_NONE,
  285. /* F2 */ OP_PREFIX,
  286. /* F3 */ OP_PREFIX,
  287. /* F4 */ OP_NONE,
  288. /* F5 */ OP_NONE,
  289. /* F6 */ OP_MODRM,
  290. /* F7 */ OP_MODRM,
  291. /* F8 */ OP_NONE,
  292. /* F9 */ OP_NONE,
  293. /* FA */ OP_NONE,
  294. /* FB */ OP_NONE,
  295. /* FC */ OP_NONE,
  296. /* FD */ OP_NONE,
  297. /* FE */ OP_MODRM,
  298. /* FF */ OP_MODRM
  299. };
  300. static byte[] flags_table_ex =
  301. {
  302. /* 0F00 */ OP_MODRM,
  303. /* 0F01 */ OP_MODRM,
  304. /* 0F02 */ OP_MODRM,
  305. /* 0F03 */ OP_MODRM,
  306. /* 0F04 */ OP_INVALID,
  307. /* 0F05 */ OP_NONE,
  308. /* 0F06 */ OP_NONE,
  309. /* 0F07 */ OP_NONE,
  310. /* 0F08 */ OP_NONE,
  311. /* 0F09 */ OP_NONE,
  312. /* 0F0A */ OP_INVALID,
  313. /* 0F0B */ OP_NONE,
  314. /* 0F0C */ OP_INVALID,
  315. /* 0F0D */ OP_MODRM,
  316. /* 0F0E */ OP_INVALID,
  317. /* 0F0F */ OP_MODRM | OP_DATA_I8, //3Dnow
  318. /* 0F10 */ OP_MODRM,
  319. /* 0F11 */ OP_MODRM,
  320. /* 0F12 */ OP_MODRM,
  321. /* 0F13 */ OP_MODRM,
  322. /* 0F14 */ OP_MODRM,
  323. /* 0F15 */ OP_MODRM,
  324. /* 0F16 */ OP_MODRM,
  325. /* 0F17 */ OP_MODRM,
  326. /* 0F18 */ OP_MODRM,
  327. /* 0F19 */ OP_INVALID,
  328. /* 0F1A */ OP_INVALID,
  329. /* 0F1B */ OP_INVALID,
  330. /* 0F1C */ OP_INVALID,
  331. /* 0F1D */ OP_INVALID,
  332. /* 0F1E */ OP_INVALID,
  333. /* 0F1F */ OP_NONE,
  334. /* 0F20 */ OP_MODRM,
  335. /* 0F21 */ OP_MODRM,
  336. /* 0F22 */ OP_MODRM,
  337. /* 0F23 */ OP_MODRM,
  338. /* 0F24 */ OP_MODRM | OP_EXTENDED, //SSE5
  339. /* 0F25 */ OP_INVALID,
  340. /* 0F26 */ OP_MODRM,
  341. /* 0F27 */ OP_INVALID,
  342. /* 0F28 */ OP_MODRM,
  343. /* 0F29 */ OP_MODRM,
  344. /* 0F2A */ OP_MODRM,
  345. /* 0F2B */ OP_MODRM,
  346. /* 0F2C */ OP_MODRM,
  347. /* 0F2D */ OP_MODRM,
  348. /* 0F2E */ OP_MODRM,
  349. /* 0F2F */ OP_MODRM,
  350. /* 0F30 */ OP_NONE,
  351. /* 0F31 */ OP_NONE,
  352. /* 0F32 */ OP_NONE,
  353. /* 0F33 */ OP_NONE,
  354. /* 0F34 */ OP_NONE,
  355. /* 0F35 */ OP_NONE,
  356. /* 0F36 */ OP_INVALID,
  357. /* 0F37 */ OP_NONE,
  358. /* 0F38 */ OP_MODRM | OP_EXTENDED,
  359. /* 0F39 */ OP_INVALID,
  360. /* 0F3A */ OP_MODRM | OP_EXTENDED | OP_DATA_I8,
  361. /* 0F3B */ OP_INVALID,
  362. /* 0F3C */ OP_INVALID,
  363. /* 0F3D */ OP_INVALID,
  364. /* 0F3E */ OP_INVALID,
  365. /* 0F3F */ OP_INVALID,
  366. /* 0F40 */ OP_MODRM,
  367. /* 0F41 */ OP_MODRM,
  368. /* 0F42 */ OP_MODRM,
  369. /* 0F43 */ OP_MODRM,
  370. /* 0F44 */ OP_MODRM,
  371. /* 0F45 */ OP_MODRM,
  372. /* 0F46 */ OP_MODRM,
  373. /* 0F47 */ OP_MODRM,
  374. /* 0F48 */ OP_MODRM,
  375. /* 0F49 */ OP_MODRM,
  376. /* 0F4A */ OP_MODRM,
  377. /* 0F4B */ OP_MODRM,
  378. /* 0F4C */ OP_MODRM,
  379. /* 0F4D */ OP_MODRM,
  380. /* 0F4E */ OP_MODRM,
  381. /* 0F4F */ OP_MODRM,
  382. /* 0F50 */ OP_MODRM,
  383. /* 0F51 */ OP_MODRM,
  384. /* 0F52 */ OP_MODRM,
  385. /* 0F53 */ OP_MODRM,
  386. /* 0F54 */ OP_MODRM,
  387. /* 0F55 */ OP_MODRM,
  388. /* 0F56 */ OP_MODRM,
  389. /* 0F57 */ OP_MODRM,
  390. /* 0F58 */ OP_MODRM,
  391. /* 0F59 */ OP_MODRM,
  392. /* 0F5A */ OP_MODRM,
  393. /* 0F5B */ OP_MODRM,
  394. /* 0F5C */ OP_MODRM,
  395. /* 0F5D */ OP_MODRM,
  396. /* 0F5E */ OP_MODRM,
  397. /* 0F5F */ OP_MODRM,
  398. /* 0F60 */ OP_MODRM,
  399. /* 0F61 */ OP_MODRM,
  400. /* 0F62 */ OP_MODRM,
  401. /* 0F63 */ OP_MODRM,
  402. /* 0F64 */ OP_MODRM,
  403. /* 0F65 */ OP_MODRM,
  404. /* 0F66 */ OP_MODRM,
  405. /* 0F67 */ OP_MODRM,
  406. /* 0F68 */ OP_MODRM,
  407. /* 0F69 */ OP_MODRM,
  408. /* 0F6A */ OP_MODRM,
  409. /* 0F6B */ OP_MODRM,
  410. /* 0F6C */ OP_MODRM,
  411. /* 0F6D */ OP_MODRM,
  412. /* 0F6E */ OP_MODRM,
  413. /* 0F6F */ OP_MODRM,
  414. /* 0F70 */ OP_MODRM | OP_DATA_I8,
  415. /* 0F71 */ OP_MODRM | OP_DATA_I8,
  416. /* 0F72 */ OP_MODRM | OP_DATA_I8,
  417. /* 0F73 */ OP_MODRM | OP_DATA_I8,
  418. /* 0F74 */ OP_MODRM,
  419. /* 0F75 */ OP_MODRM,
  420. /* 0F76 */ OP_MODRM,
  421. /* 0F77 */ OP_NONE,
  422. /* 0F78 */ OP_MODRM,
  423. /* 0F79 */ OP_MODRM,
  424. /* 0F7A */ OP_INVALID,
  425. /* 0F7B */ OP_INVALID,
  426. /* 0F7C */ OP_MODRM,
  427. /* 0F7D */ OP_MODRM,
  428. /* 0F7E */ OP_MODRM,
  429. /* 0F7F */ OP_MODRM,
  430. /* 0F80 */ OP_RELATIVE | OP_DATA_I16_I32,
  431. /* 0F81 */ OP_RELATIVE | OP_DATA_I16_I32,
  432. /* 0F82 */ OP_RELATIVE | OP_DATA_I16_I32,
  433. /* 0F83 */ OP_RELATIVE | OP_DATA_I16_I32,
  434. /* 0F84 */ OP_RELATIVE | OP_DATA_I16_I32,
  435. /* 0F85 */ OP_RELATIVE | OP_DATA_I16_I32,
  436. /* 0F86 */ OP_RELATIVE | OP_DATA_I16_I32,
  437. /* 0F87 */ OP_RELATIVE | OP_DATA_I16_I32,
  438. /* 0F88 */ OP_RELATIVE | OP_DATA_I16_I32,
  439. /* 0F89 */ OP_RELATIVE | OP_DATA_I16_I32,
  440. /* 0F8A */ OP_RELATIVE | OP_DATA_I16_I32,
  441. /* 0F8B */ OP_RELATIVE | OP_DATA_I16_I32,
  442. /* 0F8C */ OP_RELATIVE | OP_DATA_I16_I32,
  443. /* 0F8D */ OP_RELATIVE | OP_DATA_I16_I32,
  444. /* 0F8E */ OP_RELATIVE | OP_DATA_I16_I32,
  445. /* 0F8F */ OP_RELATIVE | OP_DATA_I16_I32,
  446. /* 0F90 */ OP_MODRM,
  447. /* 0F91 */ OP_MODRM,
  448. /* 0F92 */ OP_MODRM,
  449. /* 0F93 */ OP_MODRM,
  450. /* 0F94 */ OP_MODRM,
  451. /* 0F95 */ OP_MODRM,
  452. /* 0F96 */ OP_MODRM,
  453. /* 0F97 */ OP_MODRM,
  454. /* 0F98 */ OP_MODRM,
  455. /* 0F99 */ OP_MODRM,
  456. /* 0F9A */ OP_MODRM,
  457. /* 0F9B */ OP_MODRM,
  458. /* 0F9C */ OP_MODRM,
  459. /* 0F9D */ OP_MODRM,
  460. /* 0F9E */ OP_MODRM,
  461. /* 0F9F */ OP_MODRM,
  462. /* 0FA0 */ OP_NONE,
  463. /* 0FA1 */ OP_NONE,
  464. /* 0FA2 */ OP_NONE,
  465. /* 0FA3 */ OP_MODRM,
  466. /* 0FA4 */ OP_MODRM | OP_DATA_I8,
  467. /* 0FA5 */ OP_MODRM,
  468. /* 0FA6 */ OP_INVALID,
  469. /* 0FA7 */ OP_INVALID,
  470. /* 0FA8 */ OP_NONE,
  471. /* 0FA9 */ OP_NONE,
  472. /* 0FAA */ OP_NONE,
  473. /* 0FAB */ OP_MODRM,
  474. /* 0FAC */ OP_MODRM | OP_DATA_I8,
  475. /* 0FAD */ OP_MODRM,
  476. /* 0FAE */ OP_MODRM,
  477. /* 0FAF */ OP_MODRM,
  478. /* 0FB0 */ OP_MODRM,
  479. /* 0FB1 */ OP_MODRM,
  480. /* 0FB2 */ OP_MODRM,
  481. /* 0FB3 */ OP_MODRM,
  482. /* 0FB4 */ OP_MODRM,
  483. /* 0FB5 */ OP_MODRM,
  484. /* 0FB6 */ OP_MODRM,
  485. /* 0FB7 */ OP_MODRM,
  486. /* 0FB8 */ OP_MODRM,
  487. /* 0FB9 */ OP_MODRM,
  488. /* 0FBA */ OP_MODRM | OP_DATA_I8,
  489. /* 0FBB */ OP_MODRM,
  490. /* 0FBC */ OP_MODRM,
  491. /* 0FBD */ OP_MODRM,
  492. /* 0FBE */ OP_MODRM,
  493. /* 0FBF */ OP_MODRM,
  494. /* 0FC0 */ OP_MODRM,
  495. /* 0FC1 */ OP_MODRM,
  496. /* 0FC2 */ OP_MODRM | OP_DATA_I8,
  497. /* 0FC3 */ OP_MODRM,
  498. /* 0FC4 */ OP_MODRM | OP_DATA_I8,
  499. /* 0FC5 */ OP_MODRM | OP_DATA_I8,
  500. /* 0FC6 */ OP_MODRM | OP_DATA_I8,
  501. /* 0FC7 */ OP_MODRM,
  502. /* 0FC8 */ OP_NONE,
  503. /* 0FC9 */ OP_NONE,
  504. /* 0FCA */ OP_NONE,
  505. /* 0FCB */ OP_NONE,
  506. /* 0FCC */ OP_NONE,
  507. /* 0FCD */ OP_NONE,
  508. /* 0FCE */ OP_NONE,
  509. /* 0FCF */ OP_NONE,
  510. /* 0FD0 */ OP_MODRM,
  511. /* 0FD1 */ OP_MODRM,
  512. /* 0FD2 */ OP_MODRM,
  513. /* 0FD3 */ OP_MODRM,
  514. /* 0FD4 */ OP_MODRM,
  515. /* 0FD5 */ OP_MODRM,
  516. /* 0FD6 */ OP_MODRM,
  517. /* 0FD7 */ OP_MODRM,
  518. /* 0FD8 */ OP_MODRM,
  519. /* 0FD9 */ OP_MODRM,
  520. /* 0FDA */ OP_MODRM,
  521. /* 0FDB */ OP_MODRM,
  522. /* 0FDC */ OP_MODRM,
  523. /* 0FDD */ OP_MODRM,
  524. /* 0FDE */ OP_MODRM,
  525. /* 0FDF */ OP_MODRM,
  526. /* 0FE0 */ OP_MODRM,
  527. /* 0FE1 */ OP_MODRM,
  528. /* 0FE2 */ OP_MODRM,
  529. /* 0FE3 */ OP_MODRM,
  530. /* 0FE4 */ OP_MODRM,
  531. /* 0FE5 */ OP_MODRM,
  532. /* 0FE6 */ OP_MODRM,
  533. /* 0FE7 */ OP_MODRM,
  534. /* 0FE8 */ OP_MODRM,
  535. /* 0FE9 */ OP_MODRM,
  536. /* 0FEA */ OP_MODRM,
  537. /* 0FEB */ OP_MODRM,
  538. /* 0FEC */ OP_MODRM,
  539. /* 0FED */ OP_MODRM,
  540. /* 0FEE */ OP_MODRM,
  541. /* 0FEF */ OP_MODRM,
  542. /* 0FF0 */ OP_MODRM,
  543. /* 0FF1 */ OP_MODRM,
  544. /* 0FF2 */ OP_MODRM,
  545. /* 0FF3 */ OP_MODRM,
  546. /* 0FF4 */ OP_MODRM,
  547. /* 0FF5 */ OP_MODRM,
  548. /* 0FF6 */ OP_MODRM,
  549. /* 0FF7 */ OP_MODRM,
  550. /* 0FF8 */ OP_MODRM,
  551. /* 0FF9 */ OP_MODRM,
  552. /* 0FFA */ OP_MODRM,
  553. /* 0FFB */ OP_MODRM,
  554. /* 0FFC */ OP_MODRM,
  555. /* 0FFD */ OP_MODRM,
  556. /* 0FFE */ OP_MODRM,
  557. /* 0FFF */ OP_INVALID,
  558. };
  559. static byte cflags(byte op)
  560. {
  561. return flags_table[op];
  562. }
  563. static byte cflags_ex(byte op)
  564. {
  565. return flags_table_ex[op];
  566. }
  567. /// <summary>
  568. /// 计算大于等于 size 字节的最少指令的长度
  569. /// </summary>
  570. /// <param name="code"></param>
  571. /// <returns></returns>
  572. public static uint SizeofMinNumByte(void* code, int size)
  573. {
  574. if (IsARM())
  575. return (uint)((size + 3) / 4) * 4; // 此为 jit 模式下的长度,不再支持 thumb
  576. uint Length;
  577. byte* pOpcode;
  578. uint Result = 0;
  579. ldasm_data data = new ldasm_data();
  580. bool is64 = IntPtr.Size == 8;
  581. do
  582. {
  583. Length = ldasm(code, data, is64);
  584. pOpcode = (byte*)code + data.opcd_offset;
  585. Result += Length;
  586. if (Result >= size)
  587. break;
  588. if ((Length == 1) && (*pOpcode == 0xCC))
  589. break;
  590. code = (void*)((ulong)code + Length);
  591. } while (Length>0);
  592. return Result;
  593. }
  594. static bool? s_isArm;
  595. public static bool IsARM()
  596. {
  597. if(s_isArm.HasValue)
  598. return s_isArm.Value;
  599. var arch = RuntimeInformation.ProcessArchitecture;
  600. s_isArm = arch == Architecture.Arm || arch == Architecture.Arm64;
  601. return s_isArm.Value;
  602. }
  603. public static bool IsArm32()
  604. {
  605. return IsARM() && IntPtr.Size == 4;
  606. }
  607. public static bool IsArm64()
  608. {
  609. return IsARM() && IntPtr.Size == 8;
  610. }
  611. static bool? s_isiOS;
  612. public static bool IsiOS()
  613. {
  614. if(s_isiOS.HasValue)
  615. return s_isiOS.Value;
  616. s_isiOS = UnityEngine.SystemInfo.operatingSystem.ToLower().Contains("ios");
  617. return s_isiOS.Value;
  618. }
  619. static bool? s_isIL2CPP;
  620. public static bool IsIL2CPP()
  621. {
  622. if (s_isIL2CPP.HasValue)
  623. return s_isIL2CPP.Value;
  624. try
  625. {
  626. byte[] ilBody = typeof(LDasm).GetMethod("IsIL2CPP").GetMethodBody().GetILAsByteArray();
  627. if (ilBody == null || ilBody.Length == 0)
  628. s_isIL2CPP = true;
  629. else
  630. s_isIL2CPP = false;
  631. }
  632. catch
  633. {
  634. s_isIL2CPP = true;
  635. }
  636. return s_isIL2CPP.Value;
  637. }
  638. public static bool IsThumb(IntPtr code)
  639. {
  640. return IsArm32() && ((long)code & 0x1) == 0x1;
  641. }
  642. /// <summary>
  643. /// 计算 thumb 指令长度
  644. /// </summary>
  645. /// <param name="code"></param>
  646. /// <param name="size"></param>
  647. /// <returns></returns>
  648. public static uint CalcARMThumbMinLen(void* code, int size)
  649. {
  650. uint len = 0;
  651. ushort* ins = (ushort*)code;
  652. while (true)
  653. {
  654. if (len >= size)
  655. return len;
  656. if (((*ins >> 13) & 3) == 3)
  657. {
  658. ins += 2;
  659. len += 4;
  660. }
  661. else
  662. {
  663. ins++;
  664. len += 2;
  665. }
  666. }
  667. }
  668. static uint ldasm(void* code, ldasm_data ld, bool is64)
  669. {
  670. byte* p = (byte*)code;
  671. byte s, op, f;
  672. byte rexw, pr_66, pr_67;
  673. s = rexw = pr_66 = pr_67 = 0;
  674. /* dummy check */
  675. if ((int)code==0)
  676. return 0;
  677. /* init output data */
  678. //memset(ld, 0, sizeof(ldasm_data));
  679. /* phase 1: parse prefixies */
  680. while ((cflags(*p) & OP_PREFIX)!=0)
  681. {
  682. if (*p == 0x66)
  683. pr_66 = 1;
  684. if (*p == 0x67)
  685. pr_67 = 1;
  686. p++; s++;
  687. ld.flags |= F_PREFIX;
  688. if (s == 15)
  689. {
  690. ld.flags |= F_INVALID;
  691. return s;
  692. }
  693. }
  694. /* parse REX prefix */
  695. if (is64 && *p >> 4 == 4)
  696. {
  697. ld.rex = *p;
  698. rexw = (byte)((ld.rex >> 3) & 1);
  699. ld.flags |= F_REX;
  700. p++; s++;
  701. }
  702. /* can be only one REX prefix */
  703. if (is64 && *p >> 4 == 4)
  704. {
  705. ld.flags |= F_INVALID;
  706. s++;
  707. return s;
  708. }
  709. /* phase 2: parse opcode */
  710. ld.opcd_offset = (byte)(p - (byte*)code);
  711. ld.opcd_size = 1;
  712. op = *p++; s++;
  713. /* is 2 byte opcode? */
  714. if (op == 0x0F)
  715. {
  716. op = *p++; s++;
  717. ld.opcd_size++;
  718. f = cflags_ex(op);
  719. if ((f & OP_INVALID)!=0)
  720. {
  721. ld.flags |= F_INVALID;
  722. return s;
  723. }
  724. /* for SSE instructions */
  725. if ((f & OP_EXTENDED)!=0)
  726. {
  727. op = *p++; s++;
  728. ld.opcd_size++;
  729. }
  730. }
  731. else {
  732. f = cflags(op);
  733. /* pr_66 = pr_67 for opcodes A0-A3 */
  734. if (op >= 0xA0 && op <= 0xA3)
  735. pr_66 = pr_67;
  736. }
  737. /* phase 3: parse ModR/M, SIB and DISP */
  738. if ((f & OP_MODRM)!=0)
  739. {
  740. byte mod = (byte)(*p >> 6);
  741. byte ro = (byte)((*p & 0x38) >> 3);
  742. byte rm = (byte)(*p & 7);
  743. ld.modrm = *p++; s++;
  744. ld.flags |= F_MODRM;
  745. /* in F6,F7 opcodes immediate data present if R/O == 0 */
  746. if (op == 0xF6 && (ro == 0 || ro == 1))
  747. f |= OP_DATA_I8;
  748. if (op == 0xF7 && (ro == 0 || ro == 1))
  749. f |= OP_DATA_I16_I32_I64;
  750. /* is SIB byte exist? */
  751. if (mod != 3 && rm == 4 && !(!is64 && pr_67!=0))
  752. {
  753. ld.sib = *p++; s++;
  754. ld.flags |= F_SIB;
  755. /* if base == 5 and mod == 0 */
  756. if ((ld.sib & 7) == 5 && mod == 0)
  757. {
  758. ld.disp_size = 4;
  759. }
  760. }
  761. switch (mod)
  762. {
  763. case 0:
  764. if (is64)
  765. {
  766. if (rm == 5)
  767. {
  768. ld.disp_size = 4;
  769. if (is64)
  770. ld.flags |= F_RELATIVE;
  771. }
  772. }
  773. else if (pr_67!=0)
  774. {
  775. if (rm == 6)
  776. ld.disp_size = 2;
  777. }
  778. else {
  779. if (rm == 5)
  780. ld.disp_size = 4;
  781. }
  782. break;
  783. case 1:
  784. ld.disp_size = 1;
  785. break;
  786. case 2:
  787. if (is64)
  788. ld.disp_size = 4;
  789. else if (pr_67!=0)
  790. ld.disp_size = 2;
  791. else
  792. ld.disp_size = 4;
  793. break;
  794. }
  795. if (ld.disp_size>0)
  796. {
  797. ld.disp_offset = (byte)(p - (byte*)code);
  798. p += ld.disp_size;
  799. s += ld.disp_size;
  800. ld.flags |= F_DISP;
  801. }
  802. }
  803. /* phase 4: parse immediate data */
  804. if (rexw!=0 && (f & OP_DATA_I16_I32_I64)!=0)
  805. ld.imm_size = 8;
  806. else if ((f & OP_DATA_I16_I32)!=0 || (f & OP_DATA_I16_I32_I64)!=0)
  807. ld.imm_size = (byte)(4 - (pr_66 << 1));
  808. /* if exist, add OP_DATA_I16 and OP_DATA_I8 size */
  809. ld.imm_size += (byte)(f & 3);
  810. if ((ld.imm_size)!=0)
  811. {
  812. s += ld.imm_size;
  813. ld.imm_offset = (byte)(p - (byte*)code);
  814. ld.flags |= F_IMM;
  815. if ((f & OP_RELATIVE)!=0)
  816. ld.flags |= F_RELATIVE;
  817. }
  818. /* instruction is too long */
  819. if (s > 15)
  820. ld.flags |= F_INVALID;
  821. return s;
  822. }
  823. }
  824. }