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.

1979 lines
75 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, 4), 0, 4);
  426. if (attribut.Value.info != null)
  427. bw.Write(attribut.Value.info);
  428. }
  429. }
  430. }
  431. }
  432. private void compilMethods(BinaryWriter bw)
  433. {
  434. foreach (KeyValuePair<int, stMethod> method in methods)
  435. {
  436. bw.Write(IntToByteArrayBE(method.Value.access_flags, 2), 0, 2);
  437. bw.Write(IntToByteArrayBE(method.Value.name_index, 2), 0, 2);
  438. bw.Write(IntToByteArrayBE(method.Value.descriptor_index, 2), 0, 2);
  439. bw.Write(IntToByteArrayBE(method.Value.attributes_count, 2), 0, 2);
  440. if (method.Value.attributes_count > 0)
  441. {
  442. foreach (KeyValuePair<int, stAttribut> attribut in method.Value.attributes)
  443. {
  444. bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2);
  445. bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4);
  446. if (attribut.Value.attribute_length > 0)
  447. bw.Write(attribut.Value.info);
  448. }
  449. }
  450. }
  451. }
  452. private void compilAttributes(BinaryWriter bw)
  453. {
  454. foreach (KeyValuePair<int, stAttribut> attribut in attributes)
  455. {
  456. bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2);
  457. bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4);
  458. if (attribut.Value.attribute_length > 0)
  459. bw.Write(attribut.Value.info);
  460. }
  461. }
  462. #endregion
  463. #region Get data
  464. private string getConstantValue(Int16 index, bool replace = false)
  465. {
  466. string value = "";
  467. byte tag = constant_pool[index].tag;
  468. switch (tag)
  469. {
  470. case 1:
  471. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant_pool[index];
  472. if (stUtf8.length > 0)
  473. {
  474. if (replace)
  475. value = Encoding.UTF8.GetString(stUtf8.bytes).Replace("\n", "\\n");
  476. else
  477. value = Encoding.UTF8.GetString(stUtf8.bytes);
  478. }
  479. break;
  480. case 3:
  481. CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant_pool[index];
  482. value = string.Format("{0:D}", stInteger.bytes);
  483. break;
  484. case 4:
  485. CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant_pool[index];
  486. value = BitConverter.ToSingle(BitConverter.GetBytes(stFloat.bytes), 0).ToString();
  487. break;
  488. case 5:
  489. CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant_pool[index];
  490. value = (((long)stLong.high_bytes << 32) + stLong.low_bytes).ToString();
  491. break;
  492. case 6:
  493. CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant_pool[index];
  494. value = BitConverter.ToDouble(BitConverter.GetBytes(((long)stDouble.high_bytes << 32) + stDouble.low_bytes), 0).ToString();
  495. break;
  496. case 7:
  497. CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant_pool[index];
  498. value = getConstantValue(stClass.name_index);
  499. break;
  500. case 8:
  501. CONSTANT_String_info stString = (CONSTANT_String_info)constant_pool[index];
  502. value = getConstantValue(stString.string_index);
  503. break;
  504. case 9:
  505. CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant_pool[index];
  506. value = getConstantValue(stFieldref.class_index) + getConstantValue(stFieldref.name_and_type_index);
  507. break;
  508. case 10:
  509. CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant_pool[index];
  510. value = getConstantValue(stMethodref.class_index) + getConstantValue(stMethodref.name_and_type_index);
  511. break;
  512. case 11:
  513. CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant_pool[index];
  514. value = getConstantValue(stInterfaceMethodref.class_index) + getConstantValue(stInterfaceMethodref.name_and_type_index);
  515. break;
  516. case 12:
  517. CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant_pool[index];
  518. value = getConstantValue(stNameAndType.name_index) + getConstantValue(stNameAndType.descriptor_index);
  519. break;
  520. case 15:
  521. CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant_pool[index];
  522. value = getConstantValue(stMethodHandle.reference_index);
  523. break;
  524. case 16:
  525. CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant_pool[index];
  526. value = getConstantValue(stMethodType.descriptor_index);
  527. break;
  528. case 18:
  529. CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant_pool[index];
  530. value = getConstantValue(stInvokeDynamic.bootstrap_method_attr_index) + getConstantValue(stInvokeDynamic.name_and_type_index);
  531. break;
  532. }
  533. return value;
  534. }
  535. private byte[] getConstantBytes(Int16 index)
  536. {
  537. byte tag = constant_pool[index].tag;
  538. switch (tag)
  539. {
  540. case 1:
  541. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant_pool[index];
  542. if (stUtf8.length > 0)
  543. return stUtf8.bytes;
  544. break;
  545. }
  546. return null;
  547. }
  548. #endregion
  549. #region Read data
  550. private void readConstants(BinaryReader br)
  551. {
  552. constant_pool = new Dictionary<int, iCONSTANT>();
  553. constant_pool_count = br.ReadInt16BE();
  554. constant_pool_count--;
  555. for (int i = 1; i < constant_pool_count+1; i++)
  556. {
  557. byte tag = br.ReadByte();
  558. switch (tag)
  559. {
  560. case 1:
  561. CONSTANT_Utf8_info cUtf8 = new CONSTANT_Utf8_info(tag);
  562. cUtf8.length = br.ReadInt16BE();
  563. if (cUtf8.length > 0)
  564. cUtf8.bytes = br.ReadBytes(cUtf8.length);
  565. constant_pool.Add(i, cUtf8);
  566. break;
  567. case 3:
  568. CONSTANT_Integer_info cInteger = new CONSTANT_Integer_info(tag);
  569. cInteger.bytes = br.ReadInt32BE();
  570. constant_pool.Add(i, cInteger);
  571. break;
  572. case 4:
  573. CONSTANT_Float_info cFloat = new CONSTANT_Float_info(tag);
  574. cFloat.bytes = br.ReadInt32BE();
  575. constant_pool.Add(i, cFloat);
  576. break;
  577. case 5:
  578. CONSTANT_Long_info cLong = new CONSTANT_Long_info(tag);
  579. cLong.high_bytes = br.ReadInt32BE();
  580. cLong.low_bytes = br.ReadInt32BE();
  581. constant_pool.Add(i, cLong);
  582. break;
  583. case 6:
  584. CONSTANT_Double_info cDouble = new CONSTANT_Double_info(tag);
  585. cDouble.high_bytes = br.ReadInt32BE();
  586. cDouble.low_bytes = br.ReadInt32BE();
  587. constant_pool.Add(i, cDouble);
  588. break;
  589. case 7:
  590. CONSTANT_Class_info cClass = new CONSTANT_Class_info(tag);
  591. cClass.name_index = br.ReadInt16BE();
  592. constant_pool.Add(i, cClass);
  593. break;
  594. case 8:
  595. CONSTANT_String_info cString = new CONSTANT_String_info(tag);
  596. cString.string_index = br.ReadInt16BE();
  597. constant_pool.Add(i, cString);
  598. break;
  599. case 9:
  600. CONSTANT_Fieldref_info cFieldref = new CONSTANT_Fieldref_info(tag);
  601. cFieldref.class_index = br.ReadInt16BE();
  602. cFieldref.name_and_type_index = br.ReadInt16BE();
  603. constant_pool.Add(i, cFieldref);
  604. break;
  605. case 10:
  606. CONSTANT_Methodref_info cMethodref = new CONSTANT_Methodref_info(tag);
  607. cMethodref.class_index = br.ReadInt16BE();
  608. cMethodref.name_and_type_index = br.ReadInt16BE();
  609. constant_pool.Add(i, cMethodref);
  610. break;
  611. case 11:
  612. CONSTANT_InterfaceMethodref_info cInterfaceMethodref = new CONSTANT_InterfaceMethodref_info(tag);
  613. cInterfaceMethodref.class_index = br.ReadInt16BE();
  614. cInterfaceMethodref.name_and_type_index = br.ReadInt16BE();
  615. constant_pool.Add(i, cInterfaceMethodref);
  616. break;
  617. case 12:
  618. CONSTANT_NameAndType_info cNameAndType = new CONSTANT_NameAndType_info(tag);
  619. cNameAndType.name_index = br.ReadInt16BE();
  620. cNameAndType.descriptor_index = br.ReadInt16BE();
  621. constant_pool.Add(i, cNameAndType);
  622. break;
  623. case 15:
  624. CONSTANT_MethodHandle_info cMethodHandle = new CONSTANT_MethodHandle_info(tag);
  625. cMethodHandle.reference_kind = br.ReadByte();
  626. cMethodHandle.reference_index = br.ReadInt16BE();
  627. constant_pool.Add(i, cMethodHandle);
  628. break;
  629. case 16:
  630. CONSTANT_MethodType_info cMethodType = new CONSTANT_MethodType_info(tag);
  631. cMethodType.descriptor_index = br.ReadInt16BE();
  632. constant_pool.Add(i, cMethodType);
  633. break;
  634. case 18:
  635. CONSTANT_InvokeDynamic_info cInvokeDynamic = new CONSTANT_InvokeDynamic_info(tag);
  636. cInvokeDynamic.bootstrap_method_attr_index = br.ReadInt16BE();
  637. cInvokeDynamic.name_and_type_index = br.ReadInt16BE();
  638. constant_pool.Add(i, cInvokeDynamic);
  639. break;
  640. default:
  641. Console.WriteLine("(EE) ERREUR code inconnu : {0:X2}", tag);
  642. break;
  643. }
  644. }
  645. }
  646. private void readInterfaces(BinaryReader br)
  647. {
  648. interfaces = new List<Int16>();
  649. interfaces_count = br.ReadInt16BE();
  650. for (int i = 0; i < interfaces_count; i++)
  651. interfaces.Add(br.ReadInt16BE());
  652. }
  653. private void readFields(BinaryReader br)
  654. {
  655. fields = new Dictionary<int, stField>();
  656. fields_count = br.ReadInt16BE();
  657. for (int i = 0; i < fields_count; i++)
  658. {
  659. stField st = new stField();
  660. st.access_flags = br.ReadInt16BE();
  661. st.name_index = br.ReadInt16BE();
  662. st.descriptor_index = br.ReadInt16BE();
  663. st.attributes_count = br.ReadInt16BE();
  664. if (st.attributes_count > 0)
  665. {
  666. st.attributes = new Dictionary<int, stAttribut>();
  667. for (int j = 0; j < st.attributes_count; j++)
  668. {
  669. stAttribut stA = new stAttribut();
  670. readAttributes(br, ref stA);
  671. st.attributes.Add(j + 1, stA);
  672. }
  673. }
  674. fields.Add(i + 1, st);
  675. }
  676. }
  677. private void readMethods(BinaryReader br)
  678. {
  679. methods = new Dictionary<int, stMethod>();
  680. methods_count = br.ReadInt16BE();
  681. for (int i = 0; i < methods_count; i++)
  682. {
  683. stMethod st = new stMethod();
  684. st.access_flags = br.ReadInt16BE();
  685. st.name_index = br.ReadInt16BE();
  686. st.descriptor_index = br.ReadInt16BE();
  687. st.attributes_count = br.ReadInt16BE();
  688. if (st.attributes_count > 0)
  689. {
  690. st.attributes = new Dictionary<int, stAttribut>();
  691. for (int j = 0; j < st.attributes_count; j++)
  692. {
  693. stAttribut stA = new stAttribut();
  694. readAttributes(br, ref stA);
  695. st.attributes.Add(j + 1, stA);
  696. }
  697. }
  698. methods.Add(i + 1, st);
  699. }
  700. }
  701. private void readAttributes(BinaryReader br)
  702. {
  703. attributes = new Dictionary<int, stAttribut>();
  704. attributes_count = br.ReadInt16BE();
  705. for (int i = 0; i < attributes_count; i++)
  706. {
  707. stAttribut st = new stAttribut();
  708. readAttributes(br, ref st);
  709. attributes.Add(i + 1, st);
  710. }
  711. }
  712. private void readAttributes(BinaryReader br, ref stAttribut st)
  713. {
  714. st.attribute_name_index = br.ReadInt16BE();
  715. st.attribute_length = br.ReadInt32BE();
  716. if (st.attribute_length > 0)
  717. {
  718. st.info = new byte[st.attribute_length];
  719. st.info = br.ReadBytes((int)st.attribute_length);
  720. }
  721. }
  722. private int readBytes(byte[] bytes, int nb, ref int num)
  723. {
  724. int value = 0;
  725. for (int i = 0; i < nb; i++)
  726. value = value * 0x100 + bytes[num++];
  727. return value;
  728. }
  729. #endregion
  730. #region Print data
  731. // NOT FINISH //
  732. private void printBytecodeCode(StreamWriter sw, byte[] bytes)
  733. {
  734. List<stOpcode> list = new List<stOpcode>();
  735. string[] s;
  736. byte temp;
  737. int num = 0;
  738. stOpcode st;
  739. sw.Write(string.Format("max_stack = {0:X4}\n", readBytes(bytes, 2, ref num)));
  740. sw.Write(string.Format("{0,60} = {1:X4}\n", "max_locals", readBytes(bytes, 2, ref num)));
  741. sw.Write(string.Format("{0,61} = {1:X8}\n", "code_length", readBytes(bytes, 4, ref num)));
  742. while (num < bytes.Length - 8)
  743. {
  744. st = new stOpcode();
  745. st.opcode = bytes[num++];
  746. byte op = st.opcode;
  747. sw.Write(string.Format("{0,52:X2} ", op));
  748. if (op == 0x00)
  749. //st.name = "NOP";
  750. sw.Write("NOP\n");
  751. else if (op == 0x01)
  752. //st.name = "CONSTNULL";
  753. sw.Write("CONSTNULL\n");
  754. else if (op <= 11)
  755. {
  756. sw.Write("CONST (");
  757. //st.name = "CONST";
  758. if (op <= 0x08)
  759. {
  760. sw.Write(string.Format("I = {0}", op - 3));
  761. //st.type = "I";
  762. //st.value = op - 3;
  763. }
  764. else if (op <= 0x0A)
  765. {
  766. sw.Write(string.Format("L = {0}", op - 9));
  767. //st.type = "L";
  768. //st.value = op - 9;
  769. }
  770. else if (op <= 0x0D)
  771. {
  772. sw.Write(string.Format("F = {0}", op - 0x0B));
  773. //st.type = "F";
  774. //st.value = op - 0x0B;
  775. }
  776. else if (op <= 0x0F)
  777. {
  778. sw.Write(string.Format("D = {0}", op - 0x0E));
  779. //st.type = "D";
  780. //st.value = op - 0x0E;
  781. }
  782. else if (op == 0x10)
  783. {
  784. sw.Write(string.Format("I = {0}", bytes[num++]));
  785. //st.type = "I";
  786. //st.value = bytes[num++];
  787. }
  788. else
  789. {
  790. sw.Write(string.Format("I = {0}", readBytes(bytes, 2, ref num)));
  791. //st.type = "I";
  792. //st.value = bytes[num++] * 0x100 + bytes[num++];
  793. }
  794. sw.Write(")\n");
  795. }
  796. else if (op == 0x12)
  797. {
  798. sw.Write(string.Format("LDC ({0} = 1)\n", bytes[num++].ToString()));
  799. //st.name = "LDC";
  800. //st.type = bytes[num++].ToString();
  801. //st.value = 1;
  802. }
  803. else if (op == 0x13)
  804. {
  805. sw.Write(string.Format("LDC ({0} = 1)\n", readBytes(bytes, 2, ref num).ToString()));
  806. //st.name = "LDC";
  807. //st.type = (bytes[num++] * 0x100 + bytes[num++]).ToString();
  808. //st.value = 1;
  809. }
  810. else if (op == 0x14)
  811. {
  812. sw.Write(string.Format("LDC ({0} = 2)\n", readBytes(bytes, 2, ref num).ToString()));
  813. //st.name = "LDC";
  814. //st.type = (bytes[num++] * 0x100 + bytes[num++]).ToString();
  815. //st.value = 2;
  816. }
  817. else if (op <= 0x2D)
  818. {
  819. s = new string[] { "I", "L", "F", "D", "A" };
  820. sw.Write("LOAD (");
  821. if (op <= 0x19)
  822. {
  823. temp = (byte)(op - 0x15);
  824. //st.type = s[temp];
  825. //st.value = bytes[num++];
  826. sw.Write(string.Format("type={0} value={1}", s[temp], bytes[num++]));
  827. }
  828. else
  829. {
  830. temp = (byte)(op - 0x1A);
  831. //st.type = s[temp/4];
  832. //st.value = temp % 4;
  833. sw.Write(string.Format("type={0} value={1}", s[temp / 4], temp % 4));
  834. }
  835. sw.Write(")\n");
  836. s = null;
  837. }
  838. else if (op <= 0x35)
  839. {
  840. s = new string[] { "I", "L", "F", "D", "A", "B", "C", "S" };
  841. if (s[op - 0x2E] != "A")
  842. {
  843. sw.Write(string.Format("ARRLOAD (type={0})\n", s[op - 0x2E]));
  844. //st.type = s[op - 0x2E];
  845. //st.name = "ARRLOAD";
  846. }
  847. else
  848. sw.Write("ARRLOAD_OBJ\n");
  849. //st.name = "ARRLOAD_OBJ";
  850. s = null;
  851. }
  852. else if (op <= 0x4E)
  853. {
  854. s = new string[] { "I", "L", "F", "D", "A" };
  855. //st.name = "STORE";
  856. sw.Write("STORE");
  857. if (op <= 0x3A)
  858. {
  859. sw.Write(string.Format(" (type={0} value={1})\n", s[op - 0x36], bytes[num++]));
  860. //st.type = s[op - 0x36];
  861. //st.value = bytes[num++];
  862. }
  863. else
  864. {
  865. temp = (byte)(op - 0x3B);
  866. sw.Write(string.Format(" (type={0} value={1})\n", s[temp / 4], temp % 4));
  867. //st.type = s[temp / 4];
  868. //st.value = temp % 4;
  869. }
  870. s = null;
  871. }
  872. else if (op <= 0x56)
  873. {
  874. s = new string[] { "I", "L", "F", "D", "A", "B", "C", "S" };
  875. if (s[op - 0x4F] != "A")
  876. {
  877. sw.Write(string.Format("ARRSTORE (type={0})\n", s[op - 0x4F]));
  878. //st.type = s[op - 0x4F];
  879. //st.name = "ARRSTORE";
  880. }
  881. else
  882. sw.Write("ARRSTORE_OBJ\n");
  883. //st.name = "ARRSTORE_OBJ";
  884. s = null;
  885. }
  886. else if (op == 0x57)
  887. sw.Write("POP\n");
  888. // st.name = "POP";
  889. else if (op == 0x58)
  890. sw.Write("POP2\n");
  891. // st.name = "POP2";
  892. else if (op == 0x59)
  893. sw.Write("DUP\n");
  894. // st.name = "DUP";
  895. else if (op == 0x5A)
  896. sw.Write("DUPX1\n");
  897. // st.name = "DUPX1";
  898. else if (op == 0x5B)
  899. sw.Write("DUPX2\n");
  900. // st.name = "DUPX2";
  901. else if (op == 0x5C)
  902. sw.Write("DUP2\n");
  903. // st.name = "DUP2";
  904. else if (op == 0x5D)
  905. sw.Write("DUP2X1\n");
  906. // st.name = "DUP2X1";
  907. else if (op == 0x5E)
  908. sw.Write("DUP2X2\n");
  909. // st.name = "DUP2X2";
  910. else if (op == 0x5F)
  911. sw.Write("SWAP\n");
  912. // st.name = "SWAP";
  913. else if (op <= 0x77)
  914. {
  915. s = new string[] { "I", "L", "F", "D" };
  916. temp = (byte)(op - 0x60);
  917. switch (temp / 4)
  918. {
  919. case 0:
  920. sw.Write("ADD");
  921. //st.name = "ADD";
  922. break;
  923. case 1:
  924. sw.Write("SUB");
  925. //st.name = "SUB";
  926. break;
  927. case 2:
  928. sw.Write("MUL");
  929. //st.name = "MUL";
  930. break;
  931. case 3:
  932. sw.Write("DIV");
  933. //st.name = "DIV";
  934. break;
  935. case 4:
  936. sw.Write("REM");
  937. //st.name = "REM";
  938. break;
  939. case 5:
  940. sw.Write("NEG");
  941. //st.name = "NEG";
  942. break;
  943. }
  944. sw.Write(string.Format(" (type={0})\n", s[temp % 4]));
  945. //st.type = s[temp % 4];
  946. s = null;
  947. }
  948. else if (op <= 0x83)
  949. {
  950. temp = (byte)(op - 0x78);
  951. switch (temp / 2)
  952. {
  953. case 0:
  954. sw.Write("SHL");
  955. //st.name = "SHL";
  956. break;
  957. case 1:
  958. sw.Write("SHR");
  959. //st.name = "SHR";
  960. break;
  961. case 2:
  962. sw.Write("USHR");
  963. //st.name = "USHR";
  964. break;
  965. case 3:
  966. sw.Write("AND");
  967. //st.name = "AND";
  968. break;
  969. case 4:
  970. sw.Write("OR");
  971. //st.name = "OR";
  972. break;
  973. case 5:
  974. sw.Write("WOR");
  975. //st.name = "WOR";
  976. break;
  977. }
  978. if (temp % 2 == 0)
  979. sw.Write(" (type=I)\n");
  980. //st.type = "I";
  981. else
  982. sw.Write(" (type=L)\n");
  983. //st.type = "L";
  984. }
  985. else if (op == 0x84)
  986. {
  987. sw.Write(string.Format("IINC (type={0} value={1})\n", bytes[num++].ToString(), bytes[num++]));
  988. //st.name = "IINC";
  989. //st.type = bytes[num++].ToString();
  990. //st.value = bytes[num++];
  991. }
  992. else if (op <= 0x90)
  993. {
  994. s = new string[] { "I", "I", "I", "L", "L", "L", "F", "F", "F", "D", "D", "D" };
  995. string[] s2 = new string[] { "L", "F", "D", "I", "F", "D", "I", "L", "D", "I", "L", "F" };
  996. sw.Write(string.Format("CONVERT ({0} -> {1})\n", s[op - 0x85], s2[op - 0x85]));
  997. //st.name = "CONVERT";
  998. //st.src_t = s[op - 0x85];
  999. //st.dst_t = s2[op - 0x85];
  1000. s = null;
  1001. s2 = null;
  1002. }
  1003. else if (op <= 0x93)
  1004. {
  1005. sw.Write("TRUNCATE");
  1006. //st.name = "TRUNCATE";
  1007. switch (op - 0x91)
  1008. {
  1009. case 0:
  1010. sw.Write(" (type=B)\n");
  1011. //st.type = "B";
  1012. break;
  1013. case 1:
  1014. sw.Write(" (type=C)\n");
  1015. //st.type = "C";
  1016. break;
  1017. case 2:
  1018. sw.Write(" (type=S)\n");
  1019. //st.type = "S";
  1020. break;
  1021. }
  1022. }
  1023. else if (op == 0x94)
  1024. sw.Write("LCMP\n");
  1025. //st.name = "LCMP";
  1026. else if (op <= 0x98)
  1027. {
  1028. sw.Write("FCMP");
  1029. //st.name = "FCMP";
  1030. temp = (byte)(op - 0x95);
  1031. if (temp / 2 == 0)
  1032. sw.Write(" (type=F");
  1033. //st.type = "F";
  1034. else
  1035. sw.Write(" (type=D");
  1036. //st.type = "D";
  1037. if (temp % 2 == 0)
  1038. sw.Write(" value=-1)\n");
  1039. //st.value = -1;
  1040. else
  1041. sw.Write(" value=1)\n");
  1042. //st.value = 1;
  1043. }
  1044. else if (op <= 0x9E)
  1045. {
  1046. st.name = "IF_I";
  1047. switch (op - 0x99)
  1048. {
  1049. case 0:
  1050. st.type = "eq";
  1051. break;
  1052. case 1:
  1053. st.type = "ne";
  1054. break;
  1055. case 2:
  1056. st.type = "lt";
  1057. break;
  1058. case 3:
  1059. st.type = "ge";
  1060. break;
  1061. case 4:
  1062. st.type = "gt";
  1063. break;
  1064. case 5:
  1065. st.type = "le";
  1066. break;
  1067. }
  1068. sw.Write(string.Format("IF_I (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num)));
  1069. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1070. }
  1071. else if (op <= 0xA4)
  1072. {
  1073. st.name = "IF_ICMP";
  1074. switch (op - 0x9F)
  1075. {
  1076. case 0:
  1077. st.type = "eq";
  1078. break;
  1079. case 1:
  1080. st.type = "ne";
  1081. break;
  1082. case 2:
  1083. st.type = "lt";
  1084. break;
  1085. case 3:
  1086. st.type = "ge";
  1087. break;
  1088. case 4:
  1089. st.type = "gt";
  1090. break;
  1091. case 5:
  1092. st.type = "le";
  1093. break;
  1094. }
  1095. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1096. sw.Write(string.Format("IF_ICMP (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num)));
  1097. }
  1098. else if (op <= 0xA6)
  1099. {
  1100. st.name = "IF_ACMP";
  1101. switch (op - 0xA5)
  1102. {
  1103. case 0:
  1104. st.type = "eq";
  1105. break;
  1106. case 1:
  1107. st.type = "ne";
  1108. break;
  1109. }
  1110. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1111. sw.Write(string.Format("IF_ACMP (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num)));
  1112. }
  1113. else if (op == 0xA7)
  1114. {
  1115. st.name = "GOTO";
  1116. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1117. sw.Write(string.Format("GOTO (value={0})\n", readBytes(bytes, 2, ref num)));
  1118. }
  1119. else if (op == 0xA8)
  1120. {
  1121. st.name = "JSR";
  1122. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1123. sw.Write(string.Format("JSR (value={0})\n", readBytes(bytes, 2, ref num)));
  1124. }
  1125. else if (op == 0xA9)
  1126. {
  1127. st.name = "RET";
  1128. //st.value = bytes[num++];
  1129. sw.Write(string.Format("RET (value={0})\n", bytes[num++]));
  1130. }
  1131. else if (op == 0xAA)
  1132. {
  1133. st.name = "SWITCH";
  1134. sw.Write("SWITCH");
  1135. readBytes(bytes, (3 - num) % 4, ref num);
  1136. sw.Write(" (default={0}", readBytes(bytes, 4, ref num));
  1137. int low = readBytes(bytes, 4, ref num);
  1138. int high = readBytes(bytes, 4, ref num);
  1139. for (int i = 0; i < high - low + 1; i++)
  1140. sw.Write(string.Format(" offset={0}", readBytes(bytes, 4, ref num)));
  1141. sw.Write("\n");
  1142. //st.default = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1143. //st.low = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1144. //st.high = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1145. //st.offset = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1146. }
  1147. else if (op == 0xAB)
  1148. {
  1149. st.name = "SWITCH";
  1150. sw.Write("SWITCH");
  1151. readBytes(bytes, (3 - num) % 4, ref num);
  1152. sw.Write(" (default={0}", readBytes(bytes, 4, ref num));
  1153. int numpairs = readBytes(bytes, 4, ref num);
  1154. for (int i = 0; i < numpairs + 1; i++)
  1155. sw.Write(string.Format(" offset={0}", readBytes(bytes, 4, ref num)));
  1156. sw.Write("\n");
  1157. }
  1158. else if (op <= 0xB1)
  1159. {
  1160. st.name = "RETURN";
  1161. switch (op - 0xAC)
  1162. {
  1163. case 0:
  1164. st.type = "I";
  1165. break;
  1166. case 1:
  1167. st.type = "L";
  1168. break;
  1169. case 2:
  1170. st.type = "F";
  1171. break;
  1172. case 3:
  1173. st.type = "D";
  1174. break;
  1175. case 4:
  1176. st.type = "A";
  1177. break;
  1178. case 5:
  1179. st.type = "None";
  1180. break;
  1181. }
  1182. }
  1183. else if (op == 0xB2)
  1184. sw.Write("GETSTATIC\n");
  1185. //st.name = "GETSTATIC";
  1186. else if (op == 0xB3)
  1187. sw.Write("PUTSTATIC\n");
  1188. //st.name = "PUTSTATIC";
  1189. else if (op == 0xB4)
  1190. sw.Write("GETFIELD\n");
  1191. //st.name = "GETFIELD";
  1192. else if (op == 0xB5)
  1193. sw.Write("PUTFIELD\n");
  1194. //st.name = "PUTFIELD";
  1195. else if (op == 0xB6)
  1196. sw.Write("INVOKEVIRTUAL\n");
  1197. //st.name = "INVOKEVIRTUAL";
  1198. else if (op == 0xB7)
  1199. sw.Write("INVOKESPECIAL\n");
  1200. //st.name = "INVOKESPECIAL";
  1201. else if (op == 0xB8)
  1202. sw.Write("INVOKESTATIC\n");
  1203. //st.name = "INVOKESTATIC";
  1204. else if (op == 0xB9)
  1205. {
  1206. sw.Write(string.Format("INVOKEINTERFACE (index={0} count={1} zero={2})\n", readBytes(bytes, 2, ref num), bytes[num++], bytes[num++]));
  1207. //st.name = "INVOKEINTERFACE";
  1208. //st.index = bytes[num++] * 0x100 + bytes[num++];
  1209. //st.count = bytes[num++];
  1210. //st.zero = bytes[num++];
  1211. }
  1212. else if (op == 0xBA)
  1213. {
  1214. sw.Write(string.Format("INVOKEDYNAMIC (index={0} zero={1})\n", readBytes(bytes, 2, ref num), readBytes(bytes, 2, ref num)));
  1215. //st.name = "INVOKEDYNAMIC";
  1216. //st.index = bytes[num++] * 0x100 + bytes[num++];
  1217. //st.zero = bytes[num++] * 0x100 + bytes[num++];
  1218. }
  1219. else if (op == 0xBB)
  1220. sw.Write("NEW\n");
  1221. //st.name = "NEW";
  1222. else if (op == 0xBC)
  1223. {
  1224. sw.Write(string.Format("NEWARRAY"));
  1225. temp = bytes[num++];
  1226. //st.name = "NEWARRAY";
  1227. switch (temp)
  1228. {
  1229. case 4:
  1230. sw.Write(" (Bool)");
  1231. //st.type = "Bool";
  1232. break;
  1233. case 5:
  1234. sw.Write(" (C)");
  1235. //st.type = "C";
  1236. break;
  1237. case 6:
  1238. sw.Write(" (F)");
  1239. //st.type = "F";
  1240. break;
  1241. case 7:
  1242. sw.Write(" (D)");
  1243. //st.type = "D";
  1244. break;
  1245. case 8:
  1246. sw.Write(" (B)");
  1247. //st.type = "B";
  1248. break;
  1249. case 9:
  1250. sw.Write(" (S)");
  1251. //st.type = "S";
  1252. break;
  1253. case 10:
  1254. sw.Write(" (I)");
  1255. //st.type = "I";
  1256. break;
  1257. case 11:
  1258. sw.Write(" (L)");
  1259. //st.type = "L";
  1260. break;
  1261. }
  1262. sw.Write("\n");
  1263. }
  1264. else if (op == 0xBD)
  1265. sw.Write("ANEWARRAY\n");
  1266. //st.name = "ANEWARRAY";
  1267. else if (op == 0xBE)
  1268. sw.Write("ARRLEN\n");
  1269. //st.name = "ARRLEN";
  1270. else if (op == 0xBF)
  1271. sw.Write("THROW\n");
  1272. //st.name = "THROW";
  1273. else if (op == 0xC0)
  1274. sw.Write("CHECKCAST\n");
  1275. //st.name = "CHECKCAST";
  1276. else if (op == 0xC1)
  1277. sw.Write("INSTANCEOF\n");
  1278. //st.name = "INSTANCEOF";
  1279. else if (op == 0xC2)
  1280. sw.Write("MONENTER\n");
  1281. //st.name = "MONENTER";
  1282. else if (op == 0xC3)
  1283. sw.Write("MONEXIT\n");
  1284. //st.name = "MONEXIT";
  1285. else if (op == 0xC4)
  1286. {
  1287. byte b = bytes[num++];
  1288. if (b >= 0x15 && b < 0x1A)
  1289. {
  1290. sw.Write("LOAD (");
  1291. //st.name = "LOAD";
  1292. switch (b - 0x15)
  1293. {
  1294. case 0:
  1295. sw.Write("I = ");
  1296. //st.type = "I";
  1297. break;
  1298. case 1:
  1299. sw.Write("L = ");
  1300. //st.type = "L";
  1301. break;
  1302. case 2:
  1303. sw.Write("F = ");
  1304. //st.type = "F";
  1305. break;
  1306. case 3:
  1307. sw.Write("D = ");
  1308. //st.type = "D";
  1309. break;
  1310. case 4:
  1311. sw.Write("A = ");
  1312. //st.type = "A";
  1313. break;
  1314. }
  1315. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1316. sw.Write(string.Format("{0})\n", readBytes(bytes, 2, ref num)));
  1317. }
  1318. else if (b >= 0x36 && b < 0x3B)
  1319. {
  1320. sw.Write("STORE (");
  1321. //st.name = "STORE";
  1322. switch (b - 0x36)
  1323. {
  1324. case 0:
  1325. sw.Write("I = ");
  1326. //st.type = "I";
  1327. break;
  1328. case 1:
  1329. sw.Write("L = ");
  1330. //st.type = "L";
  1331. break;
  1332. case 2:
  1333. sw.Write("F = ");
  1334. //st.type = "F";
  1335. break;
  1336. case 3:
  1337. sw.Write("D = ");
  1338. //st.type = "D";
  1339. break;
  1340. case 4:
  1341. sw.Write("A = ");
  1342. //st.type = "A";
  1343. break;
  1344. }
  1345. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1346. sw.Write(string.Format("{0})\n", readBytes(bytes, 2, ref num)));
  1347. }
  1348. else if (b == 0xA9)
  1349. {
  1350. sw.Write(string.Format("RET ({0})\n", readBytes(bytes, 2, ref num)));
  1351. //st.name = "RET";
  1352. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1353. }
  1354. else if (b == 0x84)
  1355. {
  1356. sw.Write(string.Format("IINC ({0} {1})\n", readBytes(bytes, 2, ref num), readBytes(bytes, 2, ref num)));
  1357. //st.name = "IINC";
  1358. //st.value = bytes[num++] * 0x100 + bytes[num++];
  1359. //st.value2 = bytes[num++] * 0x100 + bytes[num++];
  1360. }
  1361. }
  1362. else if (op == 0xC5)
  1363. {
  1364. sw.Write(string.Format("MULTINEWARRAY (index={0} dim={1})\n", readBytes(bytes, 2, ref num), bytes[num++]));
  1365. //st.name = "MULTINEWARRAY";
  1366. //st.index = bytes[num++] * 0x100 + bytes[num++];
  1367. //st.dim = bytes[num++];
  1368. }
  1369. else if (op <= 0xC7)
  1370. {
  1371. sw.Write("IF_A (");
  1372. //st.name = "IF_A";
  1373. if (op - 0xC6 == 0)
  1374. sw.Write(string.Format("eq -> {0})\n", readBytes(bytes, 2, ref num)));
  1375. //st.type = "eq";
  1376. else if (op - 0xC6 == 1)
  1377. sw.Write(string.Format("ne -> {0})\n", readBytes(bytes, 2, ref num)));
  1378. //st.type = "ne";
  1379. //st.jumptarget = bytes[num++] * 0x100 + bytes[num++];
  1380. }
  1381. else if (op == 0xC8)
  1382. {
  1383. sw.Write(string.Format("GOTO ({0})\n", readBytes(bytes, 4, ref num)));
  1384. //st.name = "GOTO";
  1385. //st.value = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1386. }
  1387. else if (op == 0xC9)
  1388. {
  1389. sw.Write(string.Format("JSR ({0})\n", readBytes(bytes, 4, ref num)));
  1390. //st.name = "JSR";
  1391. //st.value = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++];
  1392. }
  1393. else
  1394. Console.WriteLine("Bytecode inconnu : {0:X2}", op);
  1395. list.Add(st);
  1396. }
  1397. }
  1398. private void printBytecodeSourceFile(StreamWriter sw, byte[] bytes)
  1399. {
  1400. int num = 0;
  1401. sw.Write(string.Format("sourcefile_index = {0:X4}", readBytes(bytes, 2, ref num)));
  1402. }
  1403. private void printBytecodeInnerClass(StreamWriter sw, byte[] bytes)
  1404. {
  1405. int num = 0;
  1406. int nbClass = readBytes(bytes, 2, ref num);
  1407. sw.Write(string.Format("number_of_classes = {0:X4}\n", nbClass));
  1408. for (int i = 0; i < nbClass; i++)
  1409. {
  1410. sw.Write(string.Format("{0,34:D4} : inner_class_info_index = {1:X4}\n", i + 1, readBytes(bytes, 2, ref num)));
  1411. sw.Write(string.Format("{0,59} = {1:X4}\n", "outer_class_info_index", readBytes(bytes, 2, ref num)));
  1412. sw.Write(string.Format("{0,53} = {1:X4}\n", "inner_name_index", readBytes(bytes, 2, ref num)));
  1413. sw.Write(string.Format("{0,61} = {1:X4}\n", "inner_class_access_flags", readBytes(bytes, 2, ref num)));
  1414. }
  1415. }
  1416. #endregion
  1417. private byte[] IntToByteArrayBE(int value, int size = 4)
  1418. {
  1419. byte[] bytes = BitConverter.GetBytes(value);
  1420. Array.Reverse(bytes, 0, size);
  1421. return bytes;
  1422. }
  1423. //---------------------------------------------------------------------
  1424. public void load(BinaryReader br)
  1425. {
  1426. magic = new byte[4];
  1427. magic = br.ReadBytes(4);
  1428. minor_version = br.ReadInt16BE();
  1429. major_version = br.ReadInt16BE();
  1430. readConstants(br);
  1431. access_flags = br.ReadInt16BE();
  1432. this_class = br.ReadInt16BE();
  1433. super_class = br.ReadInt16BE();
  1434. readInterfaces(br);
  1435. readFields(br);
  1436. readMethods(br);
  1437. readAttributes(br);
  1438. }
  1439. public Dictionary<int, string> getConstantsValue()
  1440. {
  1441. Dictionary<int, string> dict = new Dictionary<int, string>();
  1442. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  1443. {
  1444. if (constant.Value.tag == 8)
  1445. {
  1446. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  1447. dict[constant.Key] = getConstantValue(stString.string_index);
  1448. }
  1449. }
  1450. return dict;
  1451. }
  1452. public Dictionary<int, byte[]> getConstantsBytes()
  1453. {
  1454. Dictionary<int, byte[]> dict = new Dictionary<int, byte[]>();
  1455. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  1456. {
  1457. if (constant.Value.tag == 8)
  1458. {
  1459. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  1460. dict[constant.Key] = getConstantBytes(stString.string_index);
  1461. }
  1462. }
  1463. return dict;
  1464. }
  1465. public MemoryStream compilClass(evtClass.stFile originalFile)
  1466. {
  1467. MemoryStream ms = new MemoryStream();
  1468. using (BinaryWriter bw = new BinaryWriter(ms, Encoding.Default, true))
  1469. {
  1470. bw.Write(this.magic);
  1471. bw.Write(IntToByteArrayBE(this.minor_version, 2), 0, 2);
  1472. bw.Write(IntToByteArrayBE(this.major_version, 2), 0, 2);
  1473. bw.Write(IntToByteArrayBE(this.constant_pool_count+1, 2), 0, 2);
  1474. compilConstants(bw);
  1475. bw.Write(IntToByteArrayBE(this.access_flags, 2), 0, 2);
  1476. bw.Write(IntToByteArrayBE(this.this_class, 2), 0, 2);
  1477. bw.Write(IntToByteArrayBE(this.super_class, 2), 0, 2);
  1478. bw.Write(IntToByteArrayBE(this.interfaces_count, 2), 0, 2);
  1479. compilInterfaces(bw);
  1480. bw.Write(IntToByteArrayBE(this.fields_count, 2), 0, 2);
  1481. compilFields(bw);
  1482. bw.Write(IntToByteArrayBE(this.methods_count, 2), 0, 2);
  1483. compilMethods(bw);
  1484. bw.Write(IntToByteArrayBE(this.attributes_count, 2), 0, 2);
  1485. compilAttributes(bw);
  1486. }
  1487. return ms;
  1488. }
  1489. public void setConstantsBytes(int id, byte[] bytes)
  1490. {
  1491. if (constant_pool.ContainsKey(id))
  1492. {
  1493. if (constant_pool[id].tag == 8)
  1494. {
  1495. CONSTANT_String_info stString = (CONSTANT_String_info)constant_pool[id];
  1496. setConstantsBytes(stString.string_index, bytes);
  1497. }
  1498. else if (constant_pool[id].tag == 1)
  1499. {
  1500. CONSTANT_Utf8_info stUTF8 = (CONSTANT_Utf8_info)constant_pool[id];
  1501. stUTF8.bytes = new byte[bytes.Length];
  1502. stUTF8.length = (short)(bytes.Length);
  1503. Array.Copy(bytes, 0, stUTF8.bytes, 0, bytes.Length);
  1504. }
  1505. }
  1506. }
  1507. public void writeConstants(StreamWriter sw)
  1508. {
  1509. sw.Write(string.Format("[CONSTANTS : {0}]\n", constant_pool_count));
  1510. foreach (KeyValuePair<int, iCONSTANT> constant in constant_pool)
  1511. {
  1512. sw.Write(string.Format("{0:X4} : {1:D2} ", constant.Key, constant.Value.tag));
  1513. switch (constant.Value.tag)
  1514. {
  1515. case 1:
  1516. CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant.Value;
  1517. sw.Write(string.Format("{0,-18} : {1:X4} ", "Utf8", stUtf8.length));
  1518. if (stUtf8.length > 0)
  1519. sw.Write(Encoding.UTF8.GetString(stUtf8.bytes).Replace("\n", "\\n"));
  1520. sw.Write("\n");
  1521. break;
  1522. case 3:
  1523. CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant.Value;
  1524. sw.Write(string.Format("{0,-18} : {1,-9:X8} ({1})\n", "Integer", stInteger.bytes));
  1525. break;
  1526. case 4:
  1527. CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant.Value;
  1528. sw.Write(string.Format("{0,-18} : {1,-9:X8} ({2})\n", "Float", stFloat.bytes, BitConverter.ToSingle(BitConverter.GetBytes(stFloat.bytes), 0)));
  1529. break;
  1530. case 5:
  1531. CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant.Value;
  1532. sw.Write(string.Format("{0,-18} : {1:X8} {2:X8}\n", "Long", stLong.high_bytes, stLong.low_bytes));
  1533. break;
  1534. case 6:
  1535. CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant.Value;
  1536. sw.Write(string.Format("{0,-18} : {1:X8} {2:X8}\n", "Double", stDouble.high_bytes, stDouble.low_bytes));
  1537. break;
  1538. case 7:
  1539. CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant.Value;
  1540. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Class", stClass.name_index, getConstantValue(stClass.name_index)));
  1541. break;
  1542. case 8:
  1543. CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value;
  1544. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "String", stString.string_index, getConstantValue(stString.string_index)));
  1545. break;
  1546. case 9:
  1547. CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant.Value;
  1548. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Fieldref", stFieldref.class_index, getConstantValue(stFieldref.class_index)));
  1549. sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stFieldref.name_and_type_index, getConstantValue(stFieldref.name_and_type_index)));
  1550. break;
  1551. case 10:
  1552. CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant.Value;
  1553. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Methodref", stMethodref.class_index, getConstantValue(stMethodref.class_index)));
  1554. sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stMethodref.name_and_type_index, getConstantValue(stMethodref.name_and_type_index)));
  1555. break;
  1556. case 11:
  1557. CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant.Value;
  1558. sw.Write(string.Format("{0,-18} : {1:X4} {2:X4}\n", "InterfaceMethodref", stInterfaceMethodref.class_index, stInterfaceMethodref.name_and_type_index));
  1559. break;
  1560. case 12:
  1561. CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant.Value;
  1562. sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "NameAndType", stNameAndType.name_index, getConstantValue(stNameAndType.name_index)));
  1563. sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stNameAndType.descriptor_index, getConstantValue(stNameAndType.descriptor_index)));
  1564. break;
  1565. case 15:
  1566. CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant.Value;
  1567. sw.Write(string.Format("{0,-18} : {1:X2} {2:X4}\n", "MethodHandle", stMethodHandle.reference_kind, stMethodHandle.reference_index));
  1568. break;
  1569. case 16:
  1570. CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant.Value;
  1571. sw.Write(string.Format("{0,-18} : {1:X4}\n", "MethodType", stMethodType.descriptor_index));
  1572. break;
  1573. case 18:
  1574. CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant.Value;
  1575. sw.Write(string.Format("{0,-18} : {1:X4} {2:X4}\n", "InvokeDynamic", stInvokeDynamic.bootstrap_method_attr_index, stInvokeDynamic.name_and_type_index));
  1576. break;
  1577. }
  1578. }
  1579. sw.Write("\n");
  1580. }
  1581. public void writeInterfaces(StreamWriter sw)
  1582. {
  1583. sw.Write(string.Format("[INTERFACES : {0}]\n", interfaces_count));
  1584. int num = 1;
  1585. foreach (Int16 index in interfaces)
  1586. {
  1587. sw.Write(string.Format("{0:D4} : {1:X4} ({2})\n", num, index, getConstantValue(index)));
  1588. num++;
  1589. }
  1590. sw.Write("\n");
  1591. }
  1592. public void writeFields(StreamWriter sw)
  1593. {
  1594. sw.Write(string.Format("[FIELDS : {0}]\n", fields_count));
  1595. foreach (KeyValuePair<int, stField> field in fields)
  1596. {
  1597. sw.Write(string.Format("{0:D4} : access_flags = {1:X4}\n", field.Key, field.Value.access_flags));
  1598. sw.Write(string.Format(" name_index = {0:X4} ({1})\n", field.Value.name_index, getConstantValue(field.Value.name_index)));
  1599. sw.Write(string.Format(" descriptor_index = {0:X4} ({1})\n", field.Value.descriptor_index, getConstantValue(field.Value.descriptor_index)));
  1600. sw.Write(string.Format(" attributes_count = {0:X4}\n", field.Value.attributes_count));
  1601. if (field.Value.attributes_count > 0)
  1602. {
  1603. foreach (KeyValuePair<int, stAttribut> attribut in field.Value.attributes)
  1604. {
  1605. 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)));
  1606. sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length));
  1607. sw.Write(" info = ");
  1608. for (int i = 0; i < attribut.Value.attribute_length; i++)
  1609. sw.Write(string.Format("{0:X2} ", attribut.Value.info[i]));
  1610. sw.Write("\n");
  1611. }
  1612. }
  1613. }
  1614. sw.Write("\n");
  1615. }
  1616. public void writeMethods(StreamWriter sw)
  1617. {
  1618. sw.Write(string.Format("[METHODS : {0}]\n", methods_count));
  1619. foreach (KeyValuePair<int, stMethod> method in methods)
  1620. {
  1621. sw.Write(string.Format("{0:D4} : access_flags = {1:X4}\n", method.Key, method.Value.access_flags));
  1622. sw.Write(string.Format(" name_index = {0:X4} ({1})\n", method.Value.name_index, getConstantValue(method.Value.name_index)));
  1623. sw.Write(string.Format(" descriptor_index = {0:X4} ({1})\n", method.Value.descriptor_index, getConstantValue(method.Value.descriptor_index)));
  1624. sw.Write(string.Format(" attributes_count = {0:X4}\n", method.Value.attributes_count));
  1625. if (method.Value.attributes_count > 0)
  1626. {
  1627. foreach (KeyValuePair<int, stAttribut> attribut in method.Value.attributes)
  1628. {
  1629. 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)));
  1630. sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length));
  1631. if (attribut.Value.attribute_length > 0)
  1632. {
  1633. sw.Write(string.Format("{0,31} = ", "info"));
  1634. switch (attribut.Value.attribute_name_index)
  1635. {
  1636. case 0x121:
  1637. printBytecodeCode(sw, attribut.Value.info);
  1638. break;
  1639. case 0x12A:
  1640. printBytecodeInnerClass(sw, attribut.Value.info);
  1641. break;
  1642. case 0x145:
  1643. printBytecodeSourceFile(sw, attribut.Value.info);
  1644. break;
  1645. }
  1646. //for (int i = 0; i < attribut.Value.attribute_length; i++)
  1647. // sw.Write(string.Format("{0:X2} ", attribut.Value.info[i]));
  1648. sw.Write("\n");
  1649. }
  1650. }
  1651. }
  1652. }
  1653. sw.Write("\n");
  1654. }
  1655. public void writeAttributes(StreamWriter sw)
  1656. {
  1657. sw.Write(string.Format("[ATTRIBUTS : {0}]\n", attributes_count));
  1658. foreach (KeyValuePair<int, stAttribut> attribut in attributes)
  1659. {
  1660. 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)));
  1661. sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length));
  1662. if (attribut.Value.attribute_length > 0)
  1663. {
  1664. sw.Write(" info = ");
  1665. switch (attribut.Value.attribute_name_index)
  1666. {
  1667. case 0x121:
  1668. printBytecodeCode(sw, attribut.Value.info);
  1669. break;
  1670. case 0x12A:
  1671. printBytecodeInnerClass(sw, attribut.Value.info);
  1672. break;
  1673. case 0x145:
  1674. printBytecodeSourceFile(sw, attribut.Value.info);
  1675. break;
  1676. }
  1677. //for (int i = 0; i < attribut.Value.attribute_length; i++)
  1678. // sw.Write(string.Format("{0:X2} ", attribut.Value.info[i]));
  1679. sw.Write("\n");
  1680. }
  1681. }
  1682. sw.Write("\n");
  1683. }
  1684. }
  1685. }