Tool dedicated to isohacking for Xenosaga on Playstation 2
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1977 lines
74 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Text;
  6. using Hack.Tools.Common;
  7. namespace Hack.Xenosaga.Process
  8. {
  9. public class evtClass
  10. {
  11. public struct stFile
  12. {
  13. public UInt32 namePos;
  14. public UInt32 nameLength;
  15. public UInt32 filePos;
  16. public UInt32 fileLength;
  17. public string name;
  18. public byte[] file;
  19. }
  20. public UInt32 id { get; private set; }
  21. public UInt16 unkAdr4 { get; private set; }
  22. public UInt16 unkAdr6 { get; private set; }
  23. public int fileSize { get; private set; }
  24. public int adrNames { get; private set; }
  25. public UInt16 unkAdr16 { get; private set; }
  26. public int nbFiles { get; private set; }
  27. public List<stFile> listFiles { get; private set; }
  28. #region Constructors
  29. public evtClass()
  30. { }
  31. public evtClass(string pathName)
  32. {
  33. init(pathName);
  34. }
  35. public evtClass(BinaryReader br)
  36. {
  37. init(br);
  38. }
  39. ~evtClass()
  40. { }
  41. #endregion
  42. #region Privates methods
  43. private byte[] readFileBytes(BinaryReader br, long pos, int size)
  44. {
  45. byte[] file;
  46. long posSave = br.BaseStream.Position;
  47. br.BaseStream.Position = pos;
  48. file = br.ReadBytes(size);
  49. br.BaseStream.Position = posSave;
  50. return file;
  51. }
  52. private string readFileName(BinaryReader br, long pos, int size)
  53. {
  54. string name = "";
  55. long posSave = br.BaseStream.Position;
  56. br.BaseStream.Position = pos;
  57. name = br.BytestoStringAscii(size);
  58. br.BaseStream.Position = posSave;
  59. return name;
  60. }
  61. #endregion
  62. #region Publics methods
  63. /// <summary>
  64. /// Init an evt file (archive)
  65. /// </summary>
  66. /// <param name="pathName">Path of the file</param>
  67. /// <returns></returns>
  68. public bool init(string pathName)
  69. {
  70. bool result = true;
  71. using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open)))
  72. {
  73. result = init(br);
  74. }
  75. return result;
  76. }
  77. /// <summary>
  78. /// Init an evt file (archive)
  79. /// </summary>
  80. /// <param name="br">BinaryReader of the file</param>
  81. /// <returns></returns>
  82. public bool init(BinaryReader br)
  83. {
  84. listFiles = new List<stFile>();
  85. id = br.ReadUInt32();
  86. if (id != 0x30304C46)
  87. {
  88. Trace.WriteLine("ERROR : Not a valid evt file");
  89. return false;
  90. }
  91. unkAdr4 = br.ReadUInt16();
  92. unkAdr6 = br.ReadUInt16();
  93. fileSize = br.ReadInt32();
  94. adrNames = br.ReadInt32();
  95. unkAdr16 = br.ReadUInt16();
  96. nbFiles = br.ReadInt16();
  97. for (int i = 0; i < nbFiles; i++)
  98. {
  99. stFile st = new stFile();
  100. st.namePos = br.ReadUInt32();
  101. st.nameLength = br.ReadUInt32();
  102. st.name = readFileName(br, (long)st.namePos, (int)st.nameLength);
  103. st.filePos = br.ReadUInt32();
  104. st.fileLength = br.ReadUInt32();
  105. st.file = readFileBytes(br, (long)st.filePos, (int)st.fileLength);
  106. listFiles.Add(st);
  107. }
  108. return true;
  109. }
  110. #endregion
  111. }
  112. public class JavaClass
  113. {
  114. public interface iCONSTANT
  115. {
  116. byte tag { get; set; }
  117. }
  118. private class CONSTANT_Class_info : iCONSTANT
  119. {
  120. private byte _tag;
  121. public Int16 name_index;
  122. public CONSTANT_Class_info(byte tag)
  123. {
  124. _tag = tag;
  125. }
  126. public byte tag { get { return _tag; } set { _tag = value; } }
  127. }
  128. private class CONSTANT_Fieldref_info : iCONSTANT
  129. {
  130. private byte _tag;
  131. public Int16 class_index;
  132. public Int16 name_and_type_index;
  133. public CONSTANT_Fieldref_info(byte tag)
  134. {
  135. _tag = tag;
  136. }
  137. public byte tag { get { return _tag; } set { _tag = value; } }
  138. }
  139. private class CONSTANT_Methodref_info : iCONSTANT
  140. {
  141. private byte _tag;
  142. public Int16 class_index;
  143. public Int16 name_and_type_index;
  144. public CONSTANT_Methodref_info(byte tag)
  145. {
  146. _tag = tag;
  147. }
  148. public byte tag { get { return _tag; } set { _tag = value; } }
  149. }
  150. private class CONSTANT_InterfaceMethodref_info : iCONSTANT
  151. {
  152. private byte _tag;
  153. public Int16 class_index;
  154. public Int16 name_and_type_index;
  155. public CONSTANT_InterfaceMethodref_info(byte tag)
  156. {
  157. _tag = tag;
  158. }
  159. public byte tag { get { return _tag; } set { _tag = value; } }
  160. }
  161. private class CONSTANT_String_info : iCONSTANT
  162. {
  163. private byte _tag;
  164. public Int16 string_index;
  165. public CONSTANT_String_info(byte tag)
  166. {
  167. _tag = tag;
  168. }
  169. public byte tag { get { return _tag; } set { _tag = value; } }
  170. }
  171. private class CONSTANT_Integer_info : iCONSTANT
  172. {
  173. private byte _tag;
  174. public Int32 bytes;
  175. public CONSTANT_Integer_info(byte tag)
  176. {
  177. _tag = tag;
  178. }
  179. public byte tag { get { return _tag; } set { _tag = value; } }
  180. }
  181. private class CONSTANT_Float_info : iCONSTANT
  182. {
  183. private byte _tag;
  184. public Int32 bytes;
  185. public CONSTANT_Float_info(byte tag)
  186. {
  187. _tag = tag;
  188. }
  189. public byte tag { get { return _tag; } set { _tag = value; } }
  190. }
  191. private class CONSTANT_Long_info : iCONSTANT
  192. {
  193. private byte _tag;
  194. public Int32 high_bytes;
  195. public Int32 low_bytes;
  196. public CONSTANT_Long_info(byte tag)
  197. {
  198. _tag = tag;
  199. }
  200. public byte tag { get { return _tag; } set { _tag = value; } }
  201. }
  202. private class CONSTANT_Double_info : iCONSTANT
  203. {
  204. private byte _tag;
  205. public Int32 high_bytes;
  206. public Int32 low_bytes;
  207. public CONSTANT_Double_info(byte tag)
  208. {
  209. _tag = tag;
  210. }
  211. public byte tag { get { return _tag; } set { _tag = value; } }
  212. }
  213. private class CONSTANT_NameAndType_info : iCONSTANT
  214. {
  215. private byte _tag;
  216. public Int16 name_index;
  217. public Int16 descriptor_index;
  218. public CONSTANT_NameAndType_info(byte tag)
  219. {
  220. _tag = tag;
  221. }
  222. public byte tag { get { return _tag; } set { _tag = value; } }
  223. }
  224. private class CONSTANT_Utf8_info : iCONSTANT
  225. {
  226. private byte _tag;
  227. public Int16 length { get; set; }
  228. public byte[] bytes { get; set; }
  229. public CONSTANT_Utf8_info(byte tag)
  230. {
  231. _tag = tag;
  232. }
  233. public byte tag { get { return _tag; } set { _tag = value; } }
  234. }
  235. private class CONSTANT_MethodHandle_info : iCONSTANT
  236. {
  237. private byte _tag;
  238. public byte reference_kind;
  239. public Int16 reference_index;
  240. public CONSTANT_MethodHandle_info(byte tag)
  241. {
  242. _tag = tag;
  243. }
  244. public byte tag { get { return _tag; } set { _tag = value; } }
  245. }
  246. private class CONSTANT_MethodType_info : iCONSTANT
  247. {
  248. private byte _tag;
  249. public Int16 descriptor_index;
  250. public CONSTANT_MethodType_info(byte tag)
  251. {
  252. _tag = tag;
  253. }
  254. public byte tag { get { return _tag; } set { _tag = value; } }
  255. }
  256. private class CONSTANT_InvokeDynamic_info : iCONSTANT
  257. {
  258. private byte _tag;
  259. public Int16 bootstrap_method_attr_index;
  260. public Int16 name_and_type_index;
  261. public CONSTANT_InvokeDynamic_info(byte tag)
  262. {
  263. _tag = tag;
  264. }
  265. public byte tag { get { return _tag; } set { _tag = value; } }
  266. }
  267. private struct stField
  268. {
  269. public Int16 access_flags;
  270. public Int16 name_index;
  271. public Int16 descriptor_index;
  272. public Int16 attributes_count;
  273. public Dictionary<int, stAttribut> attributes;
  274. }
  275. private struct stMethod
  276. {
  277. public Int16 access_flags;
  278. public Int16 name_index;
  279. public Int16 descriptor_index;
  280. public Int16 attributes_count;
  281. public Dictionary<int, stAttribut> attributes;
  282. }
  283. private struct stAttribut
  284. {
  285. public Int16 attribute_name_index;
  286. public long attribute_length;
  287. public byte[] info;
  288. public List<stOpcode> infoString;
  289. }
  290. private struct stOpcode
  291. {
  292. public byte opcode;
  293. public string name;
  294. public string type;
  295. public string src_t;
  296. public string dst_t;
  297. public int value;
  298. public int value2;
  299. public int index;
  300. public int count;
  301. public int zero;
  302. public int jumptarget;
  303. public int dim;
  304. }
  305. private byte[] magic;
  306. private Int16 minor_version;
  307. private Int16 major_version;
  308. private Int16 constant_pool_count;
  309. private Dictionary<int, iCONSTANT> constant_pool;
  310. private Int16 access_flags;
  311. private Int16 this_class;
  312. private Int16 super_class;
  313. private Int16 interfaces_count;
  314. private List<Int16> interfaces;
  315. private Int16 fields_count;
  316. private Dictionary<int, stField> fields;
  317. private Int16 methods_count;
  318. private Dictionary<int, stMethod> methods;
  319. private Int16 attributes_count;
  320. private Dictionary<int, stAttribut> attributes;
  321. //---------------------------------------------------------------------
  322. #region Constructors
  323. public JavaClass()
  324. { }
  325. ~JavaClass()
  326. { }
  327. #endregion
  328. //---------------------------------------------------------------------
  329. #region Compilation
  330. private void compilConstants(BinaryWriter bw)
  331. {
  332. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  333. {
  334. bw.Write(constant.Value.tag);
  335. switch (constant.Value.tag)
  336. {
  337. case 1:
  338. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant.Value;
  339. bw.Write(IntToByteArrayBE(stUtf8.length, 2), 0, 2);
  340. bw.Write(stUtf8.bytes);
  341. break;
  342. case 3:
  343. CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant.Value;
  344. bw.Write(IntToByteArrayBE(stInteger.bytes), 0, 4);
  345. break;
  346. case 4:
  347. CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant.Value;
  348. bw.Write(IntToByteArrayBE(stFloat.bytes), 0, 4);
  349. break;
  350. case 5:
  351. CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant.Value;
  352. bw.Write(stLong.high_bytes);
  353. bw.Write(stLong.low_bytes);
  354. break;
  355. case 6:
  356. CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant.Value;
  357. bw.Write(stDouble.high_bytes);
  358. bw.Write(stDouble.low_bytes);
  359. break;
  360. case 7:
  361. CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant.Value;
  362. bw.Write(IntToByteArrayBE(stClass.name_index, 2), 0, 2);
  363. break;
  364. case 8:
  365. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  366. bw.Write(IntToByteArrayBE(stString.string_index, 2), 0, 2);
  367. break;
  368. case 9:
  369. CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant.Value;
  370. bw.Write(IntToByteArrayBE(stFieldref.class_index, 2), 0, 2);
  371. bw.Write(IntToByteArrayBE(stFieldref.name_and_type_index, 2), 0, 2);
  372. break;
  373. case 10:
  374. CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant.Value;
  375. bw.Write(IntToByteArrayBE(stMethodref.class_index, 2), 0, 2);
  376. bw.Write(IntToByteArrayBE(stMethodref.name_and_type_index, 2), 0, 2);
  377. break;
  378. case 11:
  379. CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant.Value;
  380. bw.Write(IntToByteArrayBE(stInterfaceMethodref.class_index, 2), 0, 2);
  381. bw.Write(IntToByteArrayBE(stInterfaceMethodref.name_and_type_index, 2), 0, 2);
  382. break;
  383. case 12:
  384. CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant.Value;
  385. bw.Write(IntToByteArrayBE(stNameAndType.name_index, 2), 0, 2);
  386. bw.Write(IntToByteArrayBE(stNameAndType.descriptor_index, 2), 0, 2);
  387. break;
  388. case 15:
  389. CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant.Value;
  390. bw.Write(stMethodHandle.reference_kind);
  391. bw.Write(IntToByteArrayBE(stMethodHandle.reference_index, 2), 0, 2);
  392. break;
  393. case 16:
  394. CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant.Value;
  395. bw.Write(IntToByteArrayBE(stMethodType.descriptor_index, 2), 0, 2);
  396. break;
  397. case 18:
  398. CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant.Value;
  399. bw.Write(IntToByteArrayBE(stInvokeDynamic.bootstrap_method_attr_index, 2), 0, 2);
  400. bw.Write(IntToByteArrayBE(stInvokeDynamic.name_and_type_index, 2), 0, 2);
  401. break;
  402. }
  403. }
  404. }
  405. private void compilInterfaces(BinaryWriter bw)
  406. {
  407. foreach (Int16 index in interfaces)
  408. {
  409. bw.Write(IntToByteArrayBE(index, 2), 0, 2);
  410. }
  411. }
  412. private void compilFields(BinaryWriter bw)
  413. {
  414. foreach (KeyValuePair<int, stField> field in fields)
  415. {
  416. bw.Write(IntToByteArrayBE(field.Value.access_flags, 2), 0, 2);
  417. bw.Write(IntToByteArrayBE(field.Value.name_index, 2), 0, 2);
  418. bw.Write(IntToByteArrayBE(field.Value.descriptor_index, 2), 0, 2);
  419. bw.Write(IntToByteArrayBE(field.Value.attributes_count, 2), 0, 2);
  420. if (field.Value.attributes_count > 0)
  421. {
  422. foreach (KeyValuePair<int, stAttribut> attribut in field.Value.attributes)
  423. {
  424. bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2);
  425. bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 2), 0, 2);
  426. bw.Write(attribut.Value.info);
  427. }
  428. }
  429. }
  430. }
  431. private void compilMethods(BinaryWriter bw)
  432. {
  433. foreach (KeyValuePair<int, stMethod> method in methods)
  434. {
  435. bw.Write(IntToByteArrayBE(method.Value.access_flags, 2), 0, 2);
  436. bw.Write(IntToByteArrayBE(method.Value.name_index, 2), 0, 2);
  437. bw.Write(IntToByteArrayBE(method.Value.descriptor_index, 2), 0, 2);
  438. bw.Write(IntToByteArrayBE(method.Value.attributes_count, 2), 0, 2);
  439. if (method.Value.attributes_count > 0)
  440. {
  441. foreach (KeyValuePair<int, stAttribut> attribut in method.Value.attributes)
  442. {
  443. bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2);
  444. bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4);
  445. if (attribut.Value.attribute_length > 0)
  446. bw.Write(attribut.Value.info);
  447. }
  448. }
  449. }
  450. }
  451. private void compilAttributes(BinaryWriter bw)
  452. {
  453. foreach (KeyValuePair<int, stAttribut> attribut in attributes)
  454. {
  455. bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2);
  456. bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4);
  457. if (attribut.Value.attribute_length > 0)
  458. bw.Write(attribut.Value.info);
  459. }
  460. }
  461. #endregion
  462. #region Get data
  463. private string getConstantValue(Int16 index, bool replace = false)
  464. {
  465. string value = "";
  466. byte tag = constant_pool[index].tag;
  467. switch (tag)
  468. {
  469. case 1:
  470. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant_pool[index];
  471. if (stUtf8.length > 0)
  472. {
  473. if (replace)
  474. value = Encoding.UTF8.GetString(stUtf8.bytes).Replace("\n", "\\n");
  475. else
  476. value = Encoding.UTF8.GetString(stUtf8.bytes);
  477. }
  478. break;
  479. case 3:
  480. CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant_pool[index];
  481. value = string.Format("{0:D}", stInteger.bytes);
  482. break;
  483. case 4:
  484. CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant_pool[index];
  485. value = BitConverter.ToSingle(BitConverter.GetBytes(stFloat.bytes), 0).ToString();
  486. break;
  487. case 5:
  488. CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant_pool[index];
  489. value = (((long)stLong.high_bytes << 32) + stLong.low_bytes).ToString();
  490. break;
  491. case 6:
  492. CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant_pool[index];
  493. value = BitConverter.ToDouble(BitConverter.GetBytes(((long)stDouble.high_bytes << 32) + stDouble.low_bytes), 0).ToString();
  494. break;
  495. case 7:
  496. CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant_pool[index];
  497. value = getConstantValue(stClass.name_index);
  498. break;
  499. case 8:
  500. CONSTANT_String_info stString = (CONSTANT_String_info)constant_pool[index];
  501. value = getConstantValue(stString.string_index);
  502. break;
  503. case 9:
  504. CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant_pool[index];
  505. value = getConstantValue(stFieldref.class_index) + getConstantValue(stFieldref.name_and_type_index);
  506. break;
  507. case 10:
  508. CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant_pool[index];
  509. value = getConstantValue(stMethodref.class_index) + getConstantValue(stMethodref.name_and_type_index);
  510. break;
  511. case 11:
  512. CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant_pool[index];
  513. value = getConstantValue(stInterfaceMethodref.class_index) + getConstantValue(stInterfaceMethodref.name_and_type_index);
  514. break;
  515. case 12:
  516. CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant_pool[index];
  517. value = getConstantValue(stNameAndType.name_index) + getConstantValue(stNameAndType.descriptor_index);
  518. break;
  519. case 15:
  520. CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant_pool[index];
  521. value = getConstantValue(stMethodHandle.reference_index);
  522. break;
  523. case 16:
  524. CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant_pool[index];
  525. value = getConstantValue(stMethodType.descriptor_index);
  526. break;
  527. case 18:
  528. CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant_pool[index];
  529. value = getConstantValue(stInvokeDynamic.bootstrap_method_attr_index) + getConstantValue(stInvokeDynamic.name_and_type_index);
  530. break;
  531. }
  532. return value;
  533. }
  534. private byte[] getConstantBytes(Int16 index)
  535. {
  536. byte tag = constant_pool[index].tag;
  537. switch (tag)
  538. {
  539. case 1:
  540. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant_pool[index];
  541. if (stUtf8.length > 0)
  542. return stUtf8.bytes;
  543. break;
  544. }
  545. return null;
  546. }
  547. #endregion
  548. #region Read data
  549. private void readConstants(BinaryReader br)
  550. {
  551. constant_pool = new Dictionary<int, iCONSTANT>();
  552. constant_pool_count = br.ReadInt16BE();
  553. constant_pool_count--;
  554. for (int i = 1; i < constant_pool_count+1; i++)
  555. {
  556. byte tag = br.ReadByte();
  557. switch (tag)
  558. {
  559. case 1:
  560. CONSTANT_Utf8_info cUtf8 = new CONSTANT_Utf8_info(tag);
  561. cUtf8.length = br.ReadInt16BE();
  562. if (cUtf8.length > 0)
  563. cUtf8.bytes = br.ReadBytes(cUtf8.length);
  564. constant_pool.Add(i, cUtf8);
  565. break;
  566. case 3:
  567. CONSTANT_Integer_info cInteger = new CONSTANT_Integer_info(tag);
  568. cInteger.bytes = br.ReadInt32BE();
  569. constant_pool.Add(i, cInteger);
  570. break;
  571. case 4:
  572. CONSTANT_Float_info cFloat = new CONSTANT_Float_info(tag);
  573. cFloat.bytes = br.ReadInt32BE();
  574. constant_pool.Add(i, cFloat);
  575. break;
  576. case 5:
  577. CONSTANT_Long_info cLong = new CONSTANT_Long_info(tag);
  578. cLong.high_bytes = br.ReadInt32BE();
  579. cLong.low_bytes = br.ReadInt32BE();
  580. constant_pool.Add(i, cLong);
  581. break;
  582. case 6:
  583. CONSTANT_Double_info cDouble = new CONSTANT_Double_info(tag);
  584. cDouble.high_bytes = br.ReadInt32BE();
  585. cDouble.low_bytes = br.ReadInt32BE();
  586. constant_pool.Add(i, cDouble);
  587. break;
  588. case 7:
  589. CONSTANT_Class_info cClass = new CONSTANT_Class_info(tag);
  590. cClass.name_index = br.ReadInt16BE();
  591. constant_pool.Add(i, cClass);
  592. break;
  593. case 8:
  594. CONSTANT_String_info cString = new CONSTANT_String_info(tag);
  595. cString.string_index = br.ReadInt16BE();
  596. constant_pool.Add(i, cString);
  597. break;
  598. case 9:
  599. CONSTANT_Fieldref_info cFieldref = new CONSTANT_Fieldref_info(tag);
  600. cFieldref.class_index = br.ReadInt16BE();
  601. cFieldref.name_and_type_index = br.ReadInt16BE();
  602. constant_pool.Add(i, cFieldref);
  603. break;
  604. case 10:
  605. CONSTANT_Methodref_info cMethodref = new CONSTANT_Methodref_info(tag);
  606. cMethodref.class_index = br.ReadInt16BE();
  607. cMethodref.name_and_type_index = br.ReadInt16BE();
  608. constant_pool.Add(i, cMethodref);
  609. break;
  610. case 11:
  611. CONSTANT_InterfaceMethodref_info cInterfaceMethodref = new CONSTANT_InterfaceMethodref_info(tag);
  612. cInterfaceMethodref.class_index = br.ReadInt16BE();
  613. cInterfaceMethodref.name_and_type_index = br.ReadInt16BE();
  614. constant_pool.Add(i, cInterfaceMethodref);
  615. break;
  616. case 12:
  617. CONSTANT_NameAndType_info cNameAndType = new CONSTANT_NameAndType_info(tag);
  618. cNameAndType.name_index = br.ReadInt16BE();
  619. cNameAndType.descriptor_index = br.ReadInt16BE();
  620. constant_pool.Add(i, cNameAndType);
  621. break;
  622. case 15:
  623. CONSTANT_MethodHandle_info cMethodHandle = new CONSTANT_MethodHandle_info(tag);
  624. cMethodHandle.reference_kind = br.ReadByte();
  625. cMethodHandle.reference_index = br.ReadInt16BE();
  626. constant_pool.Add(i, cMethodHandle);
  627. break;
  628. case 16:
  629. CONSTANT_MethodType_info cMethodType = new CONSTANT_MethodType_info(tag);
  630. cMethodType.descriptor_index = br.ReadInt16BE();
  631. constant_pool.Add(i, cMethodType);
  632. break;
  633. case 18:
  634. CONSTANT_InvokeDynamic_info cInvokeDynamic = new CONSTANT_InvokeDynamic_info(tag);
  635. cInvokeDynamic.bootstrap_method_attr_index = br.ReadInt16BE();
  636. cInvokeDynamic.name_and_type_index = br.ReadInt16BE();
  637. constant_pool.Add(i, cInvokeDynamic);
  638. break;
  639. default:
  640. Console.WriteLine("(EE) ERREUR code inconnu : {0:X2}", tag);
  641. break;
  642. }
  643. }
  644. }
  645. private void readInterfaces(BinaryReader br)
  646. {
  647. interfaces = new List<Int16>();
  648. interfaces_count = br.ReadInt16BE();
  649. for (int i = 0; i < interfaces_count; i++)
  650. interfaces.Add(br.ReadInt16BE());
  651. }
  652. private void readFields(BinaryReader br)
  653. {
  654. fields = new Dictionary<int, stField>();
  655. fields_count = br.ReadInt16BE();
  656. for (int i = 0; i < fields_count; i++)
  657. {
  658. stField st = new stField();
  659. st.access_flags = br.ReadInt16BE();
  660. st.name_index = br.ReadInt16BE();
  661. st.descriptor_index = br.ReadInt16BE();
  662. st.attributes_count = br.ReadInt16BE();
  663. if (st.attributes_count > 0)
  664. {
  665. st.attributes = new Dictionary<int, stAttribut>();
  666. for (int j = 0; j < st.attributes_count; j++)
  667. {
  668. stAttribut stA = new stAttribut();
  669. readAttributes(br, ref stA);
  670. st.attributes.Add(j + 1, stA);
  671. }
  672. }
  673. fields.Add(i + 1, st);
  674. }
  675. }
  676. private void readMethods(BinaryReader br)
  677. {
  678. methods = new Dictionary<int, stMethod>();
  679. methods_count = br.ReadInt16BE();
  680. for (int i = 0; i < methods_count; i++)
  681. {
  682. stMethod st = new stMethod();
  683. st.access_flags = br.ReadInt16BE();
  684. st.name_index = br.ReadInt16BE();
  685. st.descriptor_index = br.ReadInt16BE();
  686. st.attributes_count = br.ReadInt16BE();
  687. if (st.attributes_count > 0)
  688. {
  689. st.attributes = new Dictionary<int, stAttribut>();
  690. for (int j = 0; j < st.attributes_count; j++)
  691. {
  692. stAttribut stA = new stAttribut();
  693. readAttributes(br, ref stA);
  694. st.attributes.Add(j + 1, stA);
  695. }
  696. }
  697. methods.Add(i + 1, st);
  698. }
  699. }
  700. private void readAttributes(BinaryReader br)
  701. {
  702. attributes = new Dictionary<int, stAttribut>();
  703. attributes_count = br.ReadInt16BE();
  704. for (int i = 0; i < attributes_count; i++)
  705. {
  706. stAttribut st = new stAttribut();
  707. readAttributes(br, ref st);
  708. attributes.Add(i + 1, st);
  709. }
  710. }
  711. private void readAttributes(BinaryReader br, ref stAttribut st)
  712. {
  713. st.attribute_name_index = br.ReadInt16BE();
  714. st.attribute_length = br.ReadInt32BE();
  715. if (st.attribute_length > 0)
  716. {
  717. st.info = new byte[st.attribute_length];
  718. st.info = br.ReadBytes((int)st.attribute_length);
  719. }
  720. }
  721. private int readBytes(byte[] bytes, int nb, ref int num)
  722. {
  723. int value = 0;
  724. for (int i = 0; i < nb; i++)
  725. value = value * 0x100 + bytes[num++];
  726. return value;
  727. }
  728. #endregion
  729. #region Print data
  730. // NOT FINISH //
  731. private void printBytecodeCode(StreamWriter sw, byte[] bytes)
  732. {
  733. List<stOpcode> list = new List<stOpcode>();
  734. string[] s;
  735. byte temp;
  736. int num = 0;
  737. stOpcode st;
  738. sw.Write(string.Format("max_stack = {0:X4}\n", readBytes(bytes, 2, ref num)));
  739. sw.Write(string.Format("{0,60} = {1:X4}\n", "max_locals", readBytes(bytes, 2, ref num)));
  740. sw.Write(string.Format("{0,61} = {1:X8}\n", "code_length", readBytes(bytes, 4, ref num)));
  741. while (num < bytes.Length - 8)
  742. {
  743. st = new stOpcode();
  744. st.opcode = bytes[num++];
  745. byte op = st.opcode;
  746. sw.Write(string.Format("{0,52:X2} ", op));
  747. if (op == 0x00)
  748. //st.name = "NOP";
  749. sw.Write("NOP\n");
  750. else if (op == 0x01)
  751. //st.name = "CONSTNULL";
  752. sw.Write("CONSTNULL\n");
  753. else if (op <= 11)
  754. {
  755. sw.Write("CONST (");
  756. //st.name = "CONST";
  757. if (op <= 0x08)
  758. {
  759. sw.Write(string.Format("I = {0}", op - 3));
  760. //st.type = "I";
  761. //st.value = op - 3;
  762. }
  763. else if (op <= 0x0A)
  764. {
  765. sw.Write(string.Format("L = {0}", op - 9));
  766. //st.type = "L";
  767. //st.value = op - 9;
  768. }
  769. else if (op <= 0x0D)
  770. {
  771. sw.Write(string.Format("F = {0}", op - 0x0B));
  772. //st.type = "F";
  773. //st.value = op - 0x0B;
  774. }
  775. else if (op <= 0x0F)
  776. {
  777. sw.Write(string.Format("D = {0}", op - 0x0E));
  778. //st.type = "D";
  779. //st.value = op - 0x0E;
  780. }
  781. else if (op == 0x10)
  782. {
  783. sw.Write(string.Format("I = {0}", bytes[num++]));
  784. //st.type = "I";
  785. //st.value = bytes[num++];
  786. }
  787. else
  788. {
  789. sw.Write(string.Format("I = {0}", readBytes(bytes, 2, ref num)));
  790. //st.type = "I";
  791. //st.value = bytes[num++] * 0x100 + bytes[num++];
  792. }
  793. sw.Write(")\n");
  794. }
  795. else if (op == 0x12)
  796. {
  797. sw.Write(string.Format("LDC ({0} = 1)\n", bytes[num++].ToString()));
  798. //st.name = "LDC";
  799. //st.type = bytes[num++].ToString();
  800. //st.value = 1;
  801. }
  802. else if (op == 0x13)
  803. {
  804. sw.Write(string.Format("LDC ({0} = 1)\n", readBytes(bytes, 2, ref num).ToString()));
  805. //st.name = "LDC";
  806. //st.type = (bytes[num++] * 0x100 + bytes[num++]).ToString();
  807. //st.value = 1;
  808. }
  809. else if (op == 0x14)
  810. {
  811. sw.Write(string.Format("LDC ({0} = 2)\n", readBytes(bytes, 2, ref num).ToString()));
  812. //st.name = "LDC";
  813. //st.type = (bytes[num++] * 0x100 + bytes[num++]).ToString();
  814. //st.value = 2;
  815. }
  816. else if (op <= 0x2D)
  817. {
  818. s = new string[] { "I", "L", "F", "D", "A" };
  819. sw.Write("LOAD (");
  820. if (op <= 0x19)
  821. {
  822. temp = (byte)(op - 0x15);
  823. //st.type = s[temp];
  824. //st.value = bytes[num++];
  825. sw.Write(string.Format("type={0} value={1}", s[temp], bytes[num++]));
  826. }
  827. else
  828. {
  829. temp = (byte)(op - 0x1A);
  830. //st.type = s[temp/4];
  831. //st.value = temp % 4;
  832. sw.Write(string.Format("type={0} value={1}", s[temp / 4], temp % 4));
  833. }
  834. sw.Write(")\n");
  835. s = null;
  836. }
  837. else if (op <= 0x35)
  838. {
  839. s = new string[] { "I", "L", "F", "D", "A", "B", "C", "S" };
  840. if (s[op - 0x2E] != "A")
  841. {
  842. sw.Write(string.Format("ARRLOAD (type={0})\n", s[op - 0x2E]));
  843. //st.type = s[op - 0x2E];
  844. //st.name = "ARRLOAD";
  845. }
  846. else
  847. sw.Write("ARRLOAD_OBJ\n");
  848. //st.name = "ARRLOAD_OBJ";
  849. s = null;
  850. }
  851. else if (op <= 0x4E)
  852. {
  853. s = new string[] { "I", "L", "F", "D", "A" };
  854. //st.name = "STORE";
  855. sw.Write("STORE");
  856. if (op <= 0x3A)
  857. {
  858. sw.Write(string.Format(" (type={0} value={1})\n", s[op - 0x36], bytes[num++]));
  859. //st.type = s[op - 0x36];
  860. //st.value = bytes[num++];
  861. }
  862. else
  863. {
  864. temp = (byte)(op - 0x3B);
  865. sw.Write(string.Format(" (type={0} value={1})\n", s[temp / 4], temp % 4));
  866. //st.type = s[temp / 4];
  867. //st.value = temp % 4;
  868. }
  869. s = null;
  870. }
  871. else if (op <= 0x56)
  872. {
  873. s = new string[] { "I", "L", "F", "D", "A", "B", "C", "S" };
  874. if (s[op - 0x4F] != "A")
  875. {
  876. sw.Write(string.Format("ARRSTORE (type={0})\n", s[op - 0x4F]));
  877. //st.type = s[op - 0x4F];
  878. //st.name = "ARRSTORE";
  879. }
  880. else
  881. sw.Write("ARRSTORE_OBJ\n");
  882. //st.name = "ARRSTORE_OBJ";
  883. s = null;
  884. }
  885. else if (op == 0x57)
  886. sw.Write("POP\n");
  887. // st.name = "POP";
  888. else if (op == 0x58)
  889. sw.Write("POP2\n");
  890. // st.name = "POP2";
  891. else if (op == 0x59)
  892. sw.Write("DUP\n");
  893. // st.name = "DUP";
  894. else if (op == 0x5A)
  895. sw.Write("DUPX1\n");
  896. // st.name = "DUPX1";
  897. else if (op == 0x5B)
  898. sw.Write("DUPX2\n");
  899. // st.name = "DUPX2";
  900. else if (op == 0x5C)
  901. sw.Write("DUP2\n");
  902. // st.name = "DUP2";
  903. else if (op == 0x5D)
  904. sw.Write("DUP2X1\n");
  905. // st.name = "DUP2X1";
  906. else if (op == 0x5E)
  907. sw.Write("DUP2X2\n");
  908. // st.name = "DUP2X2";
  909. else if (op == 0x5F)
  910. sw.Write("SWAP\n");
  911. // st.name = "SWAP";
  912. else if (op <= 0x77)
  913. {
  914. s = new string[] { "I", "L", "F", "D" };
  915. temp = (byte)(op - 0x60);
  916. switch (temp / 4)
  917. {
  918. case 0:
  919. sw.Write("ADD");
  920. //st.name = "ADD";
  921. break;
  922. case 1:
  923. sw.Write("SUB");
  924. //st.name = "SUB";
  925. break;
  926. case 2:
  927. sw.Write("MUL");
  928. //st.name = "MUL";
  929. break;
  930. case 3:
  931. sw.Write("DIV");
  932. //st.name = "DIV";
  933. break;
  934. case 4:
  935. sw.Write("REM");
  936. //st.name = "REM";
  937. break;
  938. case 5:
  939. sw.Write("NEG");
  940. //st.name = "NEG";
  941. break;
  942. }
  943. sw.Write(string.Format(" (type={0})\n", s[temp % 4]));
  944. //st.type = s[temp % 4];
  945. s = null;
  946. }
  947. else if (op <= 0x83)
  948. {
  949. temp = (byte)(op - 0x78);
  950. switch (temp / 2)
  951. {
  952. case 0:
  953. sw.Write("SHL");
  954. //st.name = "SHL";
  955. break;
  956. case 1:
  957. sw.Write("SHR");
  958. //st.name = "SHR";
  959. break;
  960. case 2:
  961. sw.Write("USHR");
  962. //st.name = "USHR";
  963. break;
  964. case 3:
  965. sw.Write("AND");
  966. //st.name = "AND";
  967. break;
  968. case 4:
  969. sw.Write("OR");
  970. //st.name = "OR";
  971. break;
  972. case 5:
  973. sw.Write("WOR");
  974. //st.name = "WOR";
  975. break;
  976. }
  977. if (temp % 2 == 0)
  978. sw.Write(" (type=I)\n");
  979. //st.type = "I";
  980. else
  981. sw.Write(" (type=L)\n");
  982. //st.type = "L";
  983. }
  984. else if (op == 0x84)
  985. {
  986. sw.Write(string.Format("IINC (type={0} value={1})\n", bytes[num++].ToString(), bytes[num++]));
  987. //st.name = "IINC";
  988. //st.type = bytes[num++].ToString();
  989. //st.value = bytes[num++];
  990. }
  991. else if (op <= 0x90)
  992. {
  993. s = new string[] { "I", "I", "I", "L", "L", "L", "F", "F", "F", "D", "D", "D" };
  994. string[] s2 = new string[] { "L", "F", "D", "I", "F", "D", "I", "L", "D", "I", "L", "F" };
  995. sw.Write(string.Format("CONVERT ({0} -> {1})\n", s[op - 0x85], s2[op - 0x85]));
  996. //st.name = "CONVERT";
  997. //st.src_t = s[op - 0x85];
  998. //st.dst_t = s2[op - 0x85];
  999. s = null;
  1000. s2 = null;
  1001. }
  1002. else if (op <= 0x93)
  1003. {
  1004. sw.Write("TRUNCATE");
  1005. //st.name = "TRUNCATE";
  1006. switch (op - 0x91)
  1007. {
  1008. case 0:
  1009. sw.Write(" (type=B)\n");
  1010. //st.type = "B";
  1011. break;
  1012. case 1:
  1013. sw.Write(" (type=C)\n");
  1014. //st.type = "C";
  1015. break;
  1016. case 2:
  1017. sw.Write(" (type=S)\n");
  1018. //st.type = "S";
  1019. break;
  1020. }
  1021. }
  1022. else if (op == 0x94)
  1023. sw.Write("LCMP\n");
  1024. //st.name = "LCMP";
  1025. else if (op <= 0x98)
  1026. {
  1027. sw.Write("FCMP");
  1028. //st.name = "FCMP";
  1029. temp = (byte)(op - 0x95);
  1030. if (temp / 2 == 0)
  1031. sw.Write(" (type=F");
  1032. //st.type = "F";
  1033. else
  1034. sw.Write(" (type=D");
  1035. //st.type = "D";
  1036. if (temp % 2 == 0)
  1037. sw.Write(" value=-1)\n");
  1038. //st.value = -1;
  1039. else
  1040. sw.Write(" value=1)\n");
  1041. //st.value = 1;
  1042. }
  1043. else if (op <= 0x9E)
  1044. {
  1045. st.name = "IF_I";
  1046. switch (op - 0x99)
  1047. {
  1048. case 0:
  1049. st.type = "eq";
  1050. break;
  1051. case 1:
  1052. st.type = "ne";
  1053. break;
  1054. case 2:
  1055. st.type = "lt";
  1056. break;
  1057. case 3:
  1058. st.type = "ge";
  1059. break;
  1060. case 4:
  1061. st.type = "gt";
  1062. break;
  1063. case 5:
  1064. st.type = "le";
  1065. break;
  1066. }
  1067. sw.Write(string.Format("IF_I (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num)));
  1068. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1069. }
  1070. else if (op <= 0xA4)
  1071. {
  1072. st.name = "IF_ICMP";
  1073. switch (op - 0x9F)
  1074. {
  1075. case 0:
  1076. st.type = "eq";
  1077. break;
  1078. case 1:
  1079. st.type = "ne";
  1080. break;
  1081. case 2:
  1082. st.type = "lt";
  1083. break;
  1084. case 3:
  1085. st.type = "ge";
  1086. break;
  1087. case 4:
  1088. st.type = "gt";
  1089. break;
  1090. case 5:
  1091. st.type = "le";
  1092. break;
  1093. }
  1094. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1095. sw.Write(string.Format("IF_ICMP (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num)));
  1096. }
  1097. else if (op <= 0xA6)
  1098. {
  1099. st.name = "IF_ACMP";
  1100. switch (op - 0xA5)
  1101. {
  1102. case 0:
  1103. st.type = "eq";
  1104. break;
  1105. case 1:
  1106. st.type = "ne";
  1107. break;
  1108. }
  1109. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1110. sw.Write(string.Format("IF_ACMP (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num)));
  1111. }
  1112. else if (op == 0xA7)
  1113. {
  1114. st.name = "GOTO";
  1115. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1116. sw.Write(string.Format("GOTO (value={0})\n", readBytes(bytes, 2, ref num)));
  1117. }
  1118. else if (op == 0xA8)
  1119. {
  1120. st.name = "JSR";
  1121. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1122. sw.Write(string.Format("JSR (value={0})\n", readBytes(bytes, 2, ref num)));
  1123. }
  1124. else if (op == 0xA9)
  1125. {
  1126. st.name = "RET";
  1127. //st.value = bytes[num++];
  1128. sw.Write(string.Format("RET (value={0})\n", bytes[num++]));
  1129. }
  1130. else if (op == 0xAA)
  1131. {
  1132. st.name = "SWITCH";
  1133. sw.Write("SWITCH");
  1134. readBytes(bytes, (3 - num) % 4, ref num);
  1135. sw.Write(" (default={0}", readBytes(bytes, 4, ref num));
  1136. int low = readBytes(bytes, 4, ref num);
  1137. int high = readBytes(bytes, 4, ref num);
  1138. for (int i = 0; i < high - low + 1; i++)
  1139. sw.Write(string.Format(" offset={0}", readBytes(bytes, 4, ref num)));
  1140. sw.Write("\n");
  1141. //st.default = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1142. //st.low = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1143. //st.high = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1144. //st.offset = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1145. }
  1146. else if (op == 0xAB)
  1147. {
  1148. st.name = "SWITCH";
  1149. sw.Write("SWITCH");
  1150. readBytes(bytes, (3 - num) % 4, ref num);
  1151. sw.Write(" (default={0}", readBytes(bytes, 4, ref num));
  1152. int numpairs = readBytes(bytes, 4, ref num);
  1153. for (int i = 0; i < numpairs + 1; i++)
  1154. sw.Write(string.Format(" offset={0}", readBytes(bytes, 4, ref num)));
  1155. sw.Write("\n");
  1156. }
  1157. else if (op <= 0xB1)
  1158. {
  1159. st.name = "RETURN";
  1160. switch (op - 0xAC)
  1161. {
  1162. case 0:
  1163. st.type = "I";
  1164. break;
  1165. case 1:
  1166. st.type = "L";
  1167. break;
  1168. case 2:
  1169. st.type = "F";
  1170. break;
  1171. case 3:
  1172. st.type = "D";
  1173. break;
  1174. case 4:
  1175. st.type = "A";
  1176. break;
  1177. case 5:
  1178. st.type = "None";
  1179. break;
  1180. }
  1181. }
  1182. else if (op == 0xB2)
  1183. sw.Write("GETSTATIC\n");
  1184. //st.name = "GETSTATIC";
  1185. else if (op == 0xB3)
  1186. sw.Write("PUTSTATIC\n");
  1187. //st.name = "PUTSTATIC";
  1188. else if (op == 0xB4)
  1189. sw.Write("GETFIELD\n");
  1190. //st.name = "GETFIELD";
  1191. else if (op == 0xB5)
  1192. sw.Write("PUTFIELD\n");
  1193. //st.name = "PUTFIELD";
  1194. else if (op == 0xB6)
  1195. sw.Write("INVOKEVIRTUAL\n");
  1196. //st.name = "INVOKEVIRTUAL";
  1197. else if (op == 0xB7)
  1198. sw.Write("INVOKESPECIAL\n");
  1199. //st.name = "INVOKESPECIAL";
  1200. else if (op == 0xB8)
  1201. sw.Write("INVOKESTATIC\n");
  1202. //st.name = "INVOKESTATIC";
  1203. else if (op == 0xB9)
  1204. {
  1205. sw.Write(string.Format("INVOKEINTERFACE (index={0} count={1} zero={2})\n", readBytes(bytes, 2, ref num), bytes[num++], bytes[num++]));
  1206. //st.name = "INVOKEINTERFACE";
  1207. //st.index = bytes[num++] * 0x100 + bytes[num++];
  1208. //st.count = bytes[num++];
  1209. //st.zero = bytes[num++];
  1210. }
  1211. else if (op == 0xBA)
  1212. {
  1213. sw.Write(string.Format("INVOKEDYNAMIC (index={0} zero={1})\n", readBytes(bytes, 2, ref num), readBytes(bytes, 2, ref num)));
  1214. //st.name = "INVOKEDYNAMIC";
  1215. //st.index = bytes[num++] * 0x100 + bytes[num++];
  1216. //st.zero = bytes[num++] * 0x100 + bytes[num++];
  1217. }
  1218. else if (op == 0xBB)
  1219. sw.Write("NEW\n");
  1220. //st.name = "NEW";
  1221. else if (op == 0xBC)
  1222. {
  1223. sw.Write(string.Format("NEWARRAY"));
  1224. temp = bytes[num++];
  1225. //st.name = "NEWARRAY";
  1226. switch (temp)
  1227. {
  1228. case 4:
  1229. sw.Write(" (Bool)");
  1230. //st.type = "Bool";
  1231. break;
  1232. case 5:
  1233. sw.Write(" (C)");
  1234. //st.type = "C";
  1235. break;
  1236. case 6:
  1237. sw.Write(" (F)");
  1238. //st.type = "F";
  1239. break;
  1240. case 7:
  1241. sw.Write(" (D)");
  1242. //st.type = "D";
  1243. break;
  1244. case 8:
  1245. sw.Write(" (B)");
  1246. //st.type = "B";
  1247. break;
  1248. case 9:
  1249. sw.Write(" (S)");
  1250. //st.type = "S";
  1251. break;
  1252. case 10:
  1253. sw.Write(" (I)");
  1254. //st.type = "I";
  1255. break;
  1256. case 11:
  1257. sw.Write(" (L)");
  1258. //st.type = "L";
  1259. break;
  1260. }
  1261. sw.Write("\n");
  1262. }
  1263. else if (op == 0xBD)
  1264. sw.Write("ANEWARRAY\n");
  1265. //st.name = "ANEWARRAY";
  1266. else if (op == 0xBE)
  1267. sw.Write("ARRLEN\n");
  1268. //st.name = "ARRLEN";
  1269. else if (op == 0xBF)
  1270. sw.Write("THROW\n");
  1271. //st.name = "THROW";
  1272. else if (op == 0xC0)
  1273. sw.Write("CHECKCAST\n");
  1274. //st.name = "CHECKCAST";
  1275. else if (op == 0xC1)
  1276. sw.Write("INSTANCEOF\n");
  1277. //st.name = "INSTANCEOF";
  1278. else if (op == 0xC2)
  1279. sw.Write("MONENTER\n");
  1280. //st.name = "MONENTER";
  1281. else if (op == 0xC3)
  1282. sw.Write("MONEXIT\n");
  1283. //st.name = "MONEXIT";
  1284. else if (op == 0xC4)
  1285. {
  1286. byte b = bytes[num++];
  1287. if (b >= 0x15 && b < 0x1A)
  1288. {
  1289. sw.Write("LOAD (");
  1290. //st.name = "LOAD";
  1291. switch (b - 0x15)
  1292. {
  1293. case 0:
  1294. sw.Write("I = ");
  1295. //st.type = "I";
  1296. break;
  1297. case 1:
  1298. sw.Write("L = ");
  1299. //st.type = "L";
  1300. break;
  1301. case 2:
  1302. sw.Write("F = ");
  1303. //st.type = "F";
  1304. break;
  1305. case 3:
  1306. sw.Write("D = ");
  1307. //st.type = "D";
  1308. break;
  1309. case 4:
  1310. sw.Write("A = ");
  1311. //st.type = "A";
  1312. break;
  1313. }
  1314. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1315. sw.Write(string.Format("{0})\n", readBytes(bytes, 2, ref num)));
  1316. }
  1317. else if (b >= 0x36 && b < 0x3B)
  1318. {
  1319. sw.Write("STORE (");
  1320. //st.name = "STORE";
  1321. switch (b - 0x36)
  1322. {
  1323. case 0:
  1324. sw.Write("I = ");
  1325. //st.type = "I";
  1326. break;
  1327. case 1:
  1328. sw.Write("L = ");
  1329. //st.type = "L";
  1330. break;
  1331. case 2:
  1332. sw.Write("F = ");
  1333. //st.type = "F";
  1334. break;
  1335. case 3:
  1336. sw.Write("D = ");
  1337. //st.type = "D";
  1338. break;
  1339. case 4:
  1340. sw.Write("A = ");
  1341. //st.type = "A";
  1342. break;
  1343. }
  1344. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1345. sw.Write(string.Format("{0})\n", readBytes(bytes, 2, ref num)));
  1346. }
  1347. else if (b == 0xA9)
  1348. {
  1349. sw.Write(string.Format("RET ({0})\n", readBytes(bytes, 2, ref num)));
  1350. //st.name = "RET";
  1351. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1352. }
  1353. else if (b == 0x84)
  1354. {
  1355. sw.Write(string.Format("IINC ({0} {1})\n", readBytes(bytes, 2, ref num), readBytes(bytes, 2, ref num)));
  1356. //st.name = "IINC";
  1357. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1358. //st.value2 = bytes[num++] * 0x100 + bytes[num++];
  1359. }
  1360. }
  1361. else if (op == 0xC5)
  1362. {
  1363. sw.Write(string.Format("MULTINEWARRAY (index={0} dim={1})\n", readBytes(bytes, 2, ref num), bytes[num++]));
  1364. //st.name = "MULTINEWARRAY";
  1365. //st.index = bytes[num++] * 0x100 + bytes[num++];
  1366. //st.dim = bytes[num++];
  1367. }
  1368. else if (op <= 0xC7)
  1369. {
  1370. sw.Write("IF_A (");
  1371. //st.name = "IF_A";
  1372. if (op - 0xC6 == 0)
  1373. sw.Write(string.Format("eq -> {0})\n", readBytes(bytes, 2, ref num)));
  1374. //st.type = "eq";
  1375. else if (op - 0xC6 == 1)
  1376. sw.Write(string.Format("ne -> {0})\n", readBytes(bytes, 2, ref num)));
  1377. //st.type = "ne";
  1378. //st.jumptarget = bytes[num++] * 0x100 + bytes[num++];
  1379. }
  1380. else if (op == 0xC8)
  1381. {
  1382. sw.Write(string.Format("GOTO ({0})\n", readBytes(bytes, 4, ref num)));
  1383. //st.name = "GOTO";
  1384. //st.value = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1385. }
  1386. else if (op == 0xC9)
  1387. {
  1388. sw.Write(string.Format("JSR ({0})\n", readBytes(bytes, 4, ref num)));
  1389. //st.name = "JSR";
  1390. //st.value = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1391. }
  1392. else
  1393. Console.WriteLine("Bytecode inconnu : {0:X2}", op);
  1394. list.Add(st);
  1395. }
  1396. }
  1397. private void printBytecodeSourceFile(StreamWriter sw, byte[] bytes)
  1398. {
  1399. int num = 0;
  1400. sw.Write(string.Format("sourcefile_index = {0:X4}", readBytes(bytes, 2, ref num)));
  1401. }
  1402. private void printBytecodeInnerClass(StreamWriter sw, byte[] bytes)
  1403. {
  1404. int num = 0;
  1405. int nbClass = readBytes(bytes, 2, ref num);
  1406. sw.Write(string.Format("number_of_classes = {0:X4}\n", nbClass));
  1407. for (int i = 0; i < nbClass; i++)
  1408. {
  1409. sw.Write(string.Format("{0,34:D4} : inner_class_info_index = {1:X4}\n", i + 1, readBytes(bytes, 2, ref num)));
  1410. sw.Write(string.Format("{0,59} = {1:X4}\n", "outer_class_info_index", readBytes(bytes, 2, ref num)));
  1411. sw.Write(string.Format("{0,53} = {1:X4}\n", "inner_name_index", readBytes(bytes, 2, ref num)));
  1412. sw.Write(string.Format("{0,61} = {1:X4}\n", "inner_class_access_flags", readBytes(bytes, 2, ref num)));
  1413. }
  1414. }
  1415. #endregion
  1416. private byte[] IntToByteArrayBE(int value, int size = 4)
  1417. {
  1418. byte[] bytes = BitConverter.GetBytes(value);
  1419. Array.Reverse(bytes, 0, size);
  1420. return bytes;
  1421. }
  1422. //---------------------------------------------------------------------
  1423. public void load(BinaryReader br)
  1424. {
  1425. magic = new byte[4];
  1426. magic = br.ReadBytes(4);
  1427. minor_version = br.ReadInt16BE();
  1428. major_version = br.ReadInt16BE();
  1429. readConstants(br);
  1430. access_flags = br.ReadInt16BE();
  1431. this_class = br.ReadInt16BE();
  1432. super_class = br.ReadInt16BE();
  1433. readInterfaces(br);
  1434. readFields(br);
  1435. readMethods(br);
  1436. readAttributes(br);
  1437. }
  1438. public Dictionary<int, string> getConstantsValue()
  1439. {
  1440. Dictionary<int, string> dict = new Dictionary<int, string>();
  1441. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  1442. {
  1443. if (constant.Value.tag == 8)
  1444. {
  1445. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  1446. dict[constant.Key] = getConstantValue(stString.string_index);
  1447. }
  1448. }
  1449. return dict;
  1450. }
  1451. public Dictionary<int, byte[]> getConstantsBytes()
  1452. {
  1453. Dictionary<int, byte[]> dict = new Dictionary<int, byte[]>();
  1454. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  1455. {
  1456. if (constant.Value.tag == 8)
  1457. {
  1458. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  1459. dict[constant.Key] = getConstantBytes(stString.string_index);
  1460. }
  1461. }
  1462. return dict;
  1463. }
  1464. public MemoryStream compilClass(evtClass.stFile originalFile)
  1465. {
  1466. MemoryStream ms = new MemoryStream();
  1467. using (BinaryWriter bw = new BinaryWriter(ms, Encoding.Default, true))
  1468. {
  1469. bw.Write(this.magic);
  1470. bw.Write(IntToByteArrayBE(this.minor_version, 2), 0, 2);
  1471. bw.Write(IntToByteArrayBE(this.major_version, 2), 0, 2);
  1472. bw.Write(IntToByteArrayBE(this.constant_pool_count+1, 2), 0, 2);
  1473. compilConstants(bw);
  1474. bw.Write(IntToByteArrayBE(this.access_flags, 2), 0, 2);
  1475. bw.Write(IntToByteArrayBE(this.this_class, 2), 0, 2);
  1476. bw.Write(IntToByteArrayBE(this.super_class, 2), 0, 2);
  1477. bw.Write(IntToByteArrayBE(this.interfaces_count, 2), 0, 2);
  1478. compilInterfaces(bw);
  1479. bw.Write(IntToByteArrayBE(this.fields_count, 2), 0, 2);
  1480. compilFields(bw);
  1481. bw.Write(IntToByteArrayBE(this.methods_count, 2), 0, 2);
  1482. compilMethods(bw);
  1483. bw.Write(IntToByteArrayBE(this.attributes_count, 2), 0, 2);
  1484. compilAttributes(bw);
  1485. }
  1486. return ms;
  1487. }
  1488. public void setConstantsBytes(int id, byte[] bytes)
  1489. {
  1490. if (constant_pool.ContainsKey(id))
  1491. {
  1492. if (constant_pool[id].tag == 8)
  1493. {
  1494. CONSTANT_String_info stString = (CONSTANT_String_info)constant_pool[id];
  1495. setConstantsBytes(stString.string_index, bytes);
  1496. }
  1497. else if (constant_pool[id].tag == 1)
  1498. {
  1499. CONSTANT_Utf8_info stUTF8 = (CONSTANT_Utf8_info)constant_pool[id];
  1500. stUTF8.bytes = new byte[bytes.Length];
  1501. Array.Copy(bytes, 0, stUTF8.bytes, 0, bytes.Length);
  1502. //stUTF8.bytes[bytes.Length] = 0;
  1503. }
  1504. }
  1505. }
  1506. public void writeConstants(StreamWriter sw)
  1507. {
  1508. sw.Write(string.Format("[CONSTANTS : {0}]\n", constant_pool_count));
  1509. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  1510. {
  1511. sw.Write(string.Format("{0:X4} : {1:D2} ", constant.Key, constant.Value.tag));
  1512. switch (constant.Value.tag)
  1513. {
  1514. case 1:
  1515. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant.Value;
  1516. sw.Write(string.Format("{0,-18} : {1:X4} ", "Utf8", stUtf8.length));
  1517. if (stUtf8.length > 0)
  1518. sw.Write(Encoding.UTF8.GetString(stUtf8.bytes).Replace("\n", "\\n"));
  1519. sw.Write("\n");
  1520. break;
  1521. case 3:
  1522. CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant.Value;
  1523. sw.Write(string.Format("{0,-18} : {1,-9:X8} ({1})\n", "Integer", stInteger.bytes));
  1524. break;
  1525. case 4:
  1526. CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant.Value;
  1527. sw.Write(string.Format("{0,-18} : {1,-9:X8} ({2})\n", "Float", stFloat.bytes, BitConverter.ToSingle(BitConverter.GetBytes(stFloat.bytes), 0)));
  1528. break;
  1529. case 5:
  1530. CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant.Value;
  1531. sw.Write(string.Format("{0,-18} : {1:X8} {2:X8}\n", "Long", stLong.high_bytes, stLong.low_bytes));
  1532. break;
  1533. case 6:
  1534. CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant.Value;
  1535. sw.Write(string.Format("{0,-18} : {1:X8} {2:X8}\n", "Double", stDouble.high_bytes, stDouble.low_bytes));
  1536. break;
  1537. case 7:
  1538. CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant.Value;
  1539. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Class", stClass.name_index, getConstantValue(stClass.name_index)));
  1540. break;
  1541. case 8:
  1542. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  1543. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "String", stString.string_index, getConstantValue(stString.string_index)));
  1544. break;
  1545. case 9:
  1546. CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant.Value;
  1547. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Fieldref", stFieldref.class_index, getConstantValue(stFieldref.class_index)));
  1548. sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stFieldref.name_and_type_index, getConstantValue(stFieldref.name_and_type_index)));
  1549. break;
  1550. case 10:
  1551. CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant.Value;
  1552. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Methodref", stMethodref.class_index, getConstantValue(stMethodref.class_index)));
  1553. sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stMethodref.name_and_type_index, getConstantValue(stMethodref.name_and_type_index)));
  1554. break;
  1555. case 11:
  1556. CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant.Value;
  1557. sw.Write(string.Format("{0,-18} : {1:X4} {2:X4}\n", "InterfaceMethodref", stInterfaceMethodref.class_index, stInterfaceMethodref.name_and_type_index));
  1558. break;
  1559. case 12:
  1560. CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant.Value;
  1561. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "NameAndType", stNameAndType.name_index, getConstantValue(stNameAndType.name_index)));
  1562. sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stNameAndType.descriptor_index, getConstantValue(stNameAndType.descriptor_index)));
  1563. break;
  1564. case 15:
  1565. CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant.Value;
  1566. sw.Write(string.Format("{0,-18} : {1:X2} {2:X4}\n", "MethodHandle", stMethodHandle.reference_kind, stMethodHandle.reference_index));
  1567. break;
  1568. case 16:
  1569. CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant.Value;
  1570. sw.Write(string.Format("{0,-18} : {1:X4}\n", "MethodType", stMethodType.descriptor_index));
  1571. break;
  1572. case 18:
  1573. CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant.Value;
  1574. sw.Write(string.Format("{0,-18} : {1:X4} {2:X4}\n", "InvokeDynamic", stInvokeDynamic.bootstrap_method_attr_index, stInvokeDynamic.name_and_type_index));
  1575. break;
  1576. }
  1577. }
  1578. sw.Write("\n");
  1579. }
  1580. public void writeInterfaces(StreamWriter sw)
  1581. {
  1582. sw.Write(string.Format("[INTERFACES : {0}]\n", interfaces_count));
  1583. int num = 1;
  1584. foreach (Int16 index in interfaces)
  1585. {
  1586. sw.Write(string.Format("{0:D4} : {1:X4} ({2})\n", num, index, getConstantValue(index)));
  1587. num++;
  1588. }
  1589. sw.Write("\n");
  1590. }
  1591. public void writeFields(StreamWriter sw)
  1592. {
  1593. sw.Write(string.Format("[FIELDS : {0}]\n", fields_count));
  1594. foreach (KeyValuePair<int, stField> field in fields)
  1595. {
  1596. sw.Write(string.Format("{0:D4} : access_flags = {1:X4}\n", field.Key, field.Value.access_flags));
  1597. sw.Write(string.Format(" name_index = {0:X4} ({1})\n", field.Value.name_index, getConstantValue(field.Value.name_index)));
  1598. sw.Write(string.Format(" descriptor_index = {0:X4} ({1})\n", field.Value.descriptor_index, getConstantValue(field.Value.descriptor_index)));
  1599. sw.Write(string.Format(" attributes_count = {0:X4}\n", field.Value.attributes_count));
  1600. if (field.Value.attributes_count > 0)
  1601. {
  1602. foreach (KeyValuePair<int, stAttribut> attribut in field.Value.attributes)
  1603. {
  1604. sw.Write(string.Format(" attributes ({0:D4}) : attribute_name_index = {1:X4} ({2})\n", attribut.Key, attribut.Value.attribute_name_index, getConstantValue(attribut.Value.attribute_name_index)));
  1605. sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length));
  1606. sw.Write(" info = ");
  1607. for (int i = 0; i < attribut.Value.attribute_length; i++)
  1608. sw.Write(string.Format("{0:X2} ", attribut.Value.info[i]));
  1609. sw.Write("\n");
  1610. }
  1611. }
  1612. }
  1613. sw.Write("\n");
  1614. }
  1615. public void writeMethods(StreamWriter sw)
  1616. {
  1617. sw.Write(string.Format("[METHODS : {0}]\n", methods_count));
  1618. foreach (KeyValuePair<int, stMethod> method in methods)
  1619. {
  1620. sw.Write(string.Format("{0:D4} : access_flags = {1:X4}\n", method.Key, method.Value.access_flags));
  1621. sw.Write(string.Format(" name_index = {0:X4} ({1})\n", method.Value.name_index, getConstantValue(method.Value.name_index)));
  1622. sw.Write(string.Format(" descriptor_index = {0:X4} ({1})\n", method.Value.descriptor_index, getConstantValue(method.Value.descriptor_index)));
  1623. sw.Write(string.Format(" attributes_count = {0:X4}\n", method.Value.attributes_count));
  1624. if (method.Value.attributes_count > 0)
  1625. {
  1626. foreach (KeyValuePair<int, stAttribut> attribut in method.Value.attributes)
  1627. {
  1628. sw.Write(string.Format(" attributes ({0:D4}) : attribute_name_index = {1:X4} ({2})\n", attribut.Key, attribut.Value.attribute_name_index, getConstantValue(attribut.Value.attribute_name_index)));
  1629. sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length));
  1630. if (attribut.Value.attribute_length > 0)
  1631. {
  1632. sw.Write(string.Format("{0,31} = ", "info"));
  1633. switch (attribut.Value.attribute_name_index)
  1634. {
  1635. case 0x121:
  1636. printBytecodeCode(sw, attribut.Value.info);
  1637. break;
  1638. case 0x12A:
  1639. printBytecodeInnerClass(sw, attribut.Value.info);
  1640. break;
  1641. case 0x145:
  1642. printBytecodeSourceFile(sw, attribut.Value.info);
  1643. break;
  1644. }
  1645. //for (int i = 0; i < attribut.Value.attribute_length; i++)
  1646. // sw.Write(string.Format("{0:X2} ", attribut.Value.info[i]));
  1647. sw.Write("\n");
  1648. }
  1649. }
  1650. }
  1651. }
  1652. sw.Write("\n");
  1653. }
  1654. public void writeAttributes(StreamWriter sw)
  1655. {
  1656. sw.Write(string.Format("[ATTRIBUTS : {0}]\n", attributes_count));
  1657. foreach (KeyValuePair<int, stAttribut> attribut in attributes)
  1658. {
  1659. sw.Write(string.Format("{0:D4} : attribute_name_index = {1:X4} ({2})\n", attribut.Key, attribut.Value.attribute_name_index, getConstantValue(attribut.Value.attribute_name_index)));
  1660. sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length));
  1661. if (attribut.Value.attribute_length > 0)
  1662. {
  1663. sw.Write(" info = ");
  1664. switch (attribut.Value.attribute_name_index)
  1665. {
  1666. case 0x121:
  1667. printBytecodeCode(sw, attribut.Value.info);
  1668. break;
  1669. case 0x12A:
  1670. printBytecodeInnerClass(sw, attribut.Value.info);
  1671. break;
  1672. case 0x145:
  1673. printBytecodeSourceFile(sw, attribut.Value.info);
  1674. break;
  1675. }
  1676. //for (int i = 0; i < attribut.Value.attribute_length; i++)
  1677. // sw.Write(string.Format("{0:X2} ", attribut.Value.info[i]));
  1678. sw.Write("\n");
  1679. }
  1680. }
  1681. sw.Write("\n");
  1682. }
  1683. }
  1684. }