using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using Hack.Tools.Common; namespace Hack.Xenosaga.Process { public class evtClass { public struct stFile { public UInt32 namePos; public UInt32 nameLength; public UInt32 filePos; public UInt32 fileLength; public string name; public byte[] file; } public UInt32 id { get; private set; } public UInt16 unkAdr4 { get; private set; } public UInt16 unkAdr6 { get; private set; } public int fileSize { get; private set; } public int adrNames { get; private set; } public UInt16 unkAdr16 { get; private set; } public int nbFiles { get; private set; } public List listFiles { get; private set; } #region Constructors public evtClass() { } public evtClass(string pathName) { init(pathName); } public evtClass(BinaryReader br) { init(br); } ~evtClass() { } #endregion #region Privates methods private byte[] readFileBytes(BinaryReader br, long pos, int size) { byte[] file; long posSave = br.BaseStream.Position; br.BaseStream.Position = pos; file = br.ReadBytes(size); br.BaseStream.Position = posSave; return file; } private string readFileName(BinaryReader br, long pos, int size) { string name = ""; long posSave = br.BaseStream.Position; br.BaseStream.Position = pos; name = br.BytestoStringAscii(size); br.BaseStream.Position = posSave; return name; } #endregion #region Publics methods /// /// Init an evt file (archive) /// /// Path of the file /// public bool init(string pathName) { bool result = true; using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open))) { result = init(br); } return result; } /// /// Init an evt file (archive) /// /// BinaryReader of the file /// public bool init(BinaryReader br) { listFiles = new List(); id = br.ReadUInt32(); if (id != 0x30304C46) { Trace.WriteLine("ERROR : Not a valid evt file"); return false; } unkAdr4 = br.ReadUInt16(); unkAdr6 = br.ReadUInt16(); fileSize = br.ReadInt32(); adrNames = br.ReadInt32(); unkAdr16 = br.ReadUInt16(); nbFiles = br.ReadInt16(); for (int i = 0; i < nbFiles; i++) { stFile st = new stFile(); st.namePos = br.ReadUInt32(); st.nameLength = br.ReadUInt32(); st.name = readFileName(br, (long)st.namePos, (int)st.nameLength); st.filePos = br.ReadUInt32(); st.fileLength = br.ReadUInt32(); st.file = readFileBytes(br, (long)st.filePos, (int)st.fileLength); listFiles.Add(st); } return true; } #endregion } public class JavaClass { public interface iCONSTANT { byte tag { get; set; } } private class CONSTANT_Class_info : iCONSTANT { private byte _tag; public Int16 name_index; public CONSTANT_Class_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Fieldref_info : iCONSTANT { private byte _tag; public Int16 class_index; public Int16 name_and_type_index; public CONSTANT_Fieldref_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Methodref_info : iCONSTANT { private byte _tag; public Int16 class_index; public Int16 name_and_type_index; public CONSTANT_Methodref_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_InterfaceMethodref_info : iCONSTANT { private byte _tag; public Int16 class_index; public Int16 name_and_type_index; public CONSTANT_InterfaceMethodref_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_String_info : iCONSTANT { private byte _tag; public Int16 string_index; public CONSTANT_String_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Integer_info : iCONSTANT { private byte _tag; public Int32 bytes; public CONSTANT_Integer_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Float_info : iCONSTANT { private byte _tag; public Int32 bytes; public CONSTANT_Float_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Long_info : iCONSTANT { private byte _tag; public Int32 high_bytes; public Int32 low_bytes; public CONSTANT_Long_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Double_info : iCONSTANT { private byte _tag; public Int32 high_bytes; public Int32 low_bytes; public CONSTANT_Double_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_NameAndType_info : iCONSTANT { private byte _tag; public Int16 name_index; public Int16 descriptor_index; public CONSTANT_NameAndType_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_Utf8_info : iCONSTANT { private byte _tag; public Int16 length { get; set; } public byte[] bytes { get; set; } public CONSTANT_Utf8_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_MethodHandle_info : iCONSTANT { private byte _tag; public byte reference_kind; public Int16 reference_index; public CONSTANT_MethodHandle_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_MethodType_info : iCONSTANT { private byte _tag; public Int16 descriptor_index; public CONSTANT_MethodType_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private class CONSTANT_InvokeDynamic_info : iCONSTANT { private byte _tag; public Int16 bootstrap_method_attr_index; public Int16 name_and_type_index; public CONSTANT_InvokeDynamic_info(byte tag) { _tag = tag; } public byte tag { get { return _tag; } set { _tag = value; } } } private struct stField { public Int16 access_flags; public Int16 name_index; public Int16 descriptor_index; public Int16 attributes_count; public Dictionary attributes; } private struct stMethod { public Int16 access_flags; public Int16 name_index; public Int16 descriptor_index; public Int16 attributes_count; public Dictionary attributes; } private struct stAttribut { public Int16 attribute_name_index; public long attribute_length; public byte[] info; public List infoString; } private struct stOpcode { public byte opcode; public string name; public string type; public string src_t; public string dst_t; public int value; public int value2; public int index; public int count; public int zero; public int jumptarget; public int dim; } private byte[] magic; private Int16 minor_version; private Int16 major_version; private Int16 constant_pool_count; private Dictionary constant_pool; private Int16 access_flags; private Int16 this_class; private Int16 super_class; private Int16 interfaces_count; private List interfaces; private Int16 fields_count; private Dictionary fields; private Int16 methods_count; private Dictionary methods; private Int16 attributes_count; private Dictionary attributes; //--------------------------------------------------------------------- #region Constructors public JavaClass() { } ~JavaClass() { } #endregion //--------------------------------------------------------------------- #region Compilation private void compilConstants(BinaryWriter bw) { foreach (KeyValuePair constant in constant_pool) { bw.Write(constant.Value.tag); switch (constant.Value.tag) { case 1: CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant.Value; bw.Write(IntToByteArrayBE(stUtf8.length, 2), 0, 2); bw.Write(stUtf8.bytes); break; case 3: CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant.Value; bw.Write(IntToByteArrayBE(stInteger.bytes), 0, 4); break; case 4: CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant.Value; bw.Write(IntToByteArrayBE(stFloat.bytes), 0, 4); break; case 5: CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant.Value; bw.Write(stLong.high_bytes); bw.Write(stLong.low_bytes); break; case 6: CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant.Value; bw.Write(stDouble.high_bytes); bw.Write(stDouble.low_bytes); break; case 7: CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant.Value; bw.Write(IntToByteArrayBE(stClass.name_index, 2), 0, 2); break; case 8: CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value; bw.Write(IntToByteArrayBE(stString.string_index, 2), 0, 2); break; case 9: CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant.Value; bw.Write(IntToByteArrayBE(stFieldref.class_index, 2), 0, 2); bw.Write(IntToByteArrayBE(stFieldref.name_and_type_index, 2), 0, 2); break; case 10: CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant.Value; bw.Write(IntToByteArrayBE(stMethodref.class_index, 2), 0, 2); bw.Write(IntToByteArrayBE(stMethodref.name_and_type_index, 2), 0, 2); break; case 11: CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant.Value; bw.Write(IntToByteArrayBE(stInterfaceMethodref.class_index, 2), 0, 2); bw.Write(IntToByteArrayBE(stInterfaceMethodref.name_and_type_index, 2), 0, 2); break; case 12: CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant.Value; bw.Write(IntToByteArrayBE(stNameAndType.name_index, 2), 0, 2); bw.Write(IntToByteArrayBE(stNameAndType.descriptor_index, 2), 0, 2); break; case 15: CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant.Value; bw.Write(stMethodHandle.reference_kind); bw.Write(IntToByteArrayBE(stMethodHandle.reference_index, 2), 0, 2); break; case 16: CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant.Value; bw.Write(IntToByteArrayBE(stMethodType.descriptor_index, 2), 0, 2); break; case 18: CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant.Value; bw.Write(IntToByteArrayBE(stInvokeDynamic.bootstrap_method_attr_index, 2), 0, 2); bw.Write(IntToByteArrayBE(stInvokeDynamic.name_and_type_index, 2), 0, 2); break; } } } private void compilInterfaces(BinaryWriter bw) { foreach (Int16 index in interfaces) { bw.Write(IntToByteArrayBE(index, 2), 0, 2); } } private void compilFields(BinaryWriter bw) { foreach (KeyValuePair field in fields) { bw.Write(IntToByteArrayBE(field.Value.access_flags, 2), 0, 2); bw.Write(IntToByteArrayBE(field.Value.name_index, 2), 0, 2); bw.Write(IntToByteArrayBE(field.Value.descriptor_index, 2), 0, 2); bw.Write(IntToByteArrayBE(field.Value.attributes_count, 2), 0, 2); if (field.Value.attributes_count > 0) { foreach (KeyValuePair attribut in field.Value.attributes) { bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2); bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 2), 0, 2); bw.Write(attribut.Value.info); } } } } private void compilMethods(BinaryWriter bw) { foreach (KeyValuePair method in methods) { bw.Write(IntToByteArrayBE(method.Value.access_flags, 2), 0, 2); bw.Write(IntToByteArrayBE(method.Value.name_index, 2), 0, 2); bw.Write(IntToByteArrayBE(method.Value.descriptor_index, 2), 0, 2); bw.Write(IntToByteArrayBE(method.Value.attributes_count, 2), 0, 2); if (method.Value.attributes_count > 0) { foreach (KeyValuePair attribut in method.Value.attributes) { bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2); bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4); if (attribut.Value.attribute_length > 0) bw.Write(attribut.Value.info); } } } } private void compilAttributes(BinaryWriter bw) { foreach (KeyValuePair attribut in attributes) { bw.Write(IntToByteArrayBE(attribut.Value.attribute_name_index, 2), 0, 2); bw.Write(IntToByteArrayBE((int)attribut.Value.attribute_length, 4), 0, 4); if (attribut.Value.attribute_length > 0) bw.Write(attribut.Value.info); } } #endregion #region Get data private string getConstantValue(Int16 index, bool replace = false) { string value = ""; byte tag = constant_pool[index].tag; switch (tag) { case 1: CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant_pool[index]; if (stUtf8.length > 0) { if (replace) value = Encoding.UTF8.GetString(stUtf8.bytes).Replace("\n", "\\n"); else value = Encoding.UTF8.GetString(stUtf8.bytes); } break; case 3: CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant_pool[index]; value = string.Format("{0:D}", stInteger.bytes); break; case 4: CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant_pool[index]; value = BitConverter.ToSingle(BitConverter.GetBytes(stFloat.bytes), 0).ToString(); break; case 5: CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant_pool[index]; value = (((long)stLong.high_bytes << 32) + stLong.low_bytes).ToString(); break; case 6: CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant_pool[index]; value = BitConverter.ToDouble(BitConverter.GetBytes(((long)stDouble.high_bytes << 32) + stDouble.low_bytes), 0).ToString(); break; case 7: CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant_pool[index]; value = getConstantValue(stClass.name_index); break; case 8: CONSTANT_String_info stString = (CONSTANT_String_info)constant_pool[index]; value = getConstantValue(stString.string_index); break; case 9: CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant_pool[index]; value = getConstantValue(stFieldref.class_index) + getConstantValue(stFieldref.name_and_type_index); break; case 10: CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant_pool[index]; value = getConstantValue(stMethodref.class_index) + getConstantValue(stMethodref.name_and_type_index); break; case 11: CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant_pool[index]; value = getConstantValue(stInterfaceMethodref.class_index) + getConstantValue(stInterfaceMethodref.name_and_type_index); break; case 12: CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant_pool[index]; value = getConstantValue(stNameAndType.name_index) + getConstantValue(stNameAndType.descriptor_index); break; case 15: CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant_pool[index]; value = getConstantValue(stMethodHandle.reference_index); break; case 16: CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant_pool[index]; value = getConstantValue(stMethodType.descriptor_index); break; case 18: CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant_pool[index]; value = getConstantValue(stInvokeDynamic.bootstrap_method_attr_index) + getConstantValue(stInvokeDynamic.name_and_type_index); break; } return value; } private byte[] getConstantBytes(Int16 index) { byte tag = constant_pool[index].tag; switch (tag) { case 1: CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant_pool[index]; if (stUtf8.length > 0) return stUtf8.bytes; break; } return null; } #endregion #region Read data private void readConstants(BinaryReader br) { constant_pool = new Dictionary(); constant_pool_count = br.ReadInt16BE(); constant_pool_count--; for (int i = 1; i < constant_pool_count+1; i++) { byte tag = br.ReadByte(); switch (tag) { case 1: CONSTANT_Utf8_info cUtf8 = new CONSTANT_Utf8_info(tag); cUtf8.length = br.ReadInt16BE(); if (cUtf8.length > 0) cUtf8.bytes = br.ReadBytes(cUtf8.length); constant_pool.Add(i, cUtf8); break; case 3: CONSTANT_Integer_info cInteger = new CONSTANT_Integer_info(tag); cInteger.bytes = br.ReadInt32BE(); constant_pool.Add(i, cInteger); break; case 4: CONSTANT_Float_info cFloat = new CONSTANT_Float_info(tag); cFloat.bytes = br.ReadInt32BE(); constant_pool.Add(i, cFloat); break; case 5: CONSTANT_Long_info cLong = new CONSTANT_Long_info(tag); cLong.high_bytes = br.ReadInt32BE(); cLong.low_bytes = br.ReadInt32BE(); constant_pool.Add(i, cLong); break; case 6: CONSTANT_Double_info cDouble = new CONSTANT_Double_info(tag); cDouble.high_bytes = br.ReadInt32BE(); cDouble.low_bytes = br.ReadInt32BE(); constant_pool.Add(i, cDouble); break; case 7: CONSTANT_Class_info cClass = new CONSTANT_Class_info(tag); cClass.name_index = br.ReadInt16BE(); constant_pool.Add(i, cClass); break; case 8: CONSTANT_String_info cString = new CONSTANT_String_info(tag); cString.string_index = br.ReadInt16BE(); constant_pool.Add(i, cString); break; case 9: CONSTANT_Fieldref_info cFieldref = new CONSTANT_Fieldref_info(tag); cFieldref.class_index = br.ReadInt16BE(); cFieldref.name_and_type_index = br.ReadInt16BE(); constant_pool.Add(i, cFieldref); break; case 10: CONSTANT_Methodref_info cMethodref = new CONSTANT_Methodref_info(tag); cMethodref.class_index = br.ReadInt16BE(); cMethodref.name_and_type_index = br.ReadInt16BE(); constant_pool.Add(i, cMethodref); break; case 11: CONSTANT_InterfaceMethodref_info cInterfaceMethodref = new CONSTANT_InterfaceMethodref_info(tag); cInterfaceMethodref.class_index = br.ReadInt16BE(); cInterfaceMethodref.name_and_type_index = br.ReadInt16BE(); constant_pool.Add(i, cInterfaceMethodref); break; case 12: CONSTANT_NameAndType_info cNameAndType = new CONSTANT_NameAndType_info(tag); cNameAndType.name_index = br.ReadInt16BE(); cNameAndType.descriptor_index = br.ReadInt16BE(); constant_pool.Add(i, cNameAndType); break; case 15: CONSTANT_MethodHandle_info cMethodHandle = new CONSTANT_MethodHandle_info(tag); cMethodHandle.reference_kind = br.ReadByte(); cMethodHandle.reference_index = br.ReadInt16BE(); constant_pool.Add(i, cMethodHandle); break; case 16: CONSTANT_MethodType_info cMethodType = new CONSTANT_MethodType_info(tag); cMethodType.descriptor_index = br.ReadInt16BE(); constant_pool.Add(i, cMethodType); break; case 18: CONSTANT_InvokeDynamic_info cInvokeDynamic = new CONSTANT_InvokeDynamic_info(tag); cInvokeDynamic.bootstrap_method_attr_index = br.ReadInt16BE(); cInvokeDynamic.name_and_type_index = br.ReadInt16BE(); constant_pool.Add(i, cInvokeDynamic); break; default: Console.WriteLine("(EE) ERREUR code inconnu : {0:X2}", tag); break; } } } private void readInterfaces(BinaryReader br) { interfaces = new List(); interfaces_count = br.ReadInt16BE(); for (int i = 0; i < interfaces_count; i++) interfaces.Add(br.ReadInt16BE()); } private void readFields(BinaryReader br) { fields = new Dictionary(); fields_count = br.ReadInt16BE(); for (int i = 0; i < fields_count; i++) { stField st = new stField(); st.access_flags = br.ReadInt16BE(); st.name_index = br.ReadInt16BE(); st.descriptor_index = br.ReadInt16BE(); st.attributes_count = br.ReadInt16BE(); if (st.attributes_count > 0) { st.attributes = new Dictionary(); for (int j = 0; j < st.attributes_count; j++) { stAttribut stA = new stAttribut(); readAttributes(br, ref stA); st.attributes.Add(j + 1, stA); } } fields.Add(i + 1, st); } } private void readMethods(BinaryReader br) { methods = new Dictionary(); methods_count = br.ReadInt16BE(); for (int i = 0; i < methods_count; i++) { stMethod st = new stMethod(); st.access_flags = br.ReadInt16BE(); st.name_index = br.ReadInt16BE(); st.descriptor_index = br.ReadInt16BE(); st.attributes_count = br.ReadInt16BE(); if (st.attributes_count > 0) { st.attributes = new Dictionary(); for (int j = 0; j < st.attributes_count; j++) { stAttribut stA = new stAttribut(); readAttributes(br, ref stA); st.attributes.Add(j + 1, stA); } } methods.Add(i + 1, st); } } private void readAttributes(BinaryReader br) { attributes = new Dictionary(); attributes_count = br.ReadInt16BE(); for (int i = 0; i < attributes_count; i++) { stAttribut st = new stAttribut(); readAttributes(br, ref st); attributes.Add(i + 1, st); } } private void readAttributes(BinaryReader br, ref stAttribut st) { st.attribute_name_index = br.ReadInt16BE(); st.attribute_length = br.ReadInt32BE(); if (st.attribute_length > 0) { st.info = new byte[st.attribute_length]; st.info = br.ReadBytes((int)st.attribute_length); } } private int readBytes(byte[] bytes, int nb, ref int num) { int value = 0; for (int i = 0; i < nb; i++) value = value * 0x100 + bytes[num++]; return value; } #endregion #region Print data // NOT FINISH // private void printBytecodeCode(StreamWriter sw, byte[] bytes) { List list = new List(); string[] s; byte temp; int num = 0; stOpcode st; sw.Write(string.Format("max_stack = {0:X4}\n", readBytes(bytes, 2, ref num))); sw.Write(string.Format("{0,60} = {1:X4}\n", "max_locals", readBytes(bytes, 2, ref num))); sw.Write(string.Format("{0,61} = {1:X8}\n", "code_length", readBytes(bytes, 4, ref num))); while (num < bytes.Length - 8) { st = new stOpcode(); st.opcode = bytes[num++]; byte op = st.opcode; sw.Write(string.Format("{0,52:X2} ", op)); if (op == 0x00) //st.name = "NOP"; sw.Write("NOP\n"); else if (op == 0x01) //st.name = "CONSTNULL"; sw.Write("CONSTNULL\n"); else if (op <= 11) { sw.Write("CONST ("); //st.name = "CONST"; if (op <= 0x08) { sw.Write(string.Format("I = {0}", op - 3)); //st.type = "I"; //st.value = op - 3; } else if (op <= 0x0A) { sw.Write(string.Format("L = {0}", op - 9)); //st.type = "L"; //st.value = op - 9; } else if (op <= 0x0D) { sw.Write(string.Format("F = {0}", op - 0x0B)); //st.type = "F"; //st.value = op - 0x0B; } else if (op <= 0x0F) { sw.Write(string.Format("D = {0}", op - 0x0E)); //st.type = "D"; //st.value = op - 0x0E; } else if (op == 0x10) { sw.Write(string.Format("I = {0}", bytes[num++])); //st.type = "I"; //st.value = bytes[num++]; } else { sw.Write(string.Format("I = {0}", readBytes(bytes, 2, ref num))); //st.type = "I"; //st.value = bytes[num++] * 0x100 + bytes[num++]; } sw.Write(")\n"); } else if (op == 0x12) { sw.Write(string.Format("LDC ({0} = 1)\n", bytes[num++].ToString())); //st.name = "LDC"; //st.type = bytes[num++].ToString(); //st.value = 1; } else if (op == 0x13) { sw.Write(string.Format("LDC ({0} = 1)\n", readBytes(bytes, 2, ref num).ToString())); //st.name = "LDC"; //st.type = (bytes[num++] * 0x100 + bytes[num++]).ToString(); //st.value = 1; } else if (op == 0x14) { sw.Write(string.Format("LDC ({0} = 2)\n", readBytes(bytes, 2, ref num).ToString())); //st.name = "LDC"; //st.type = (bytes[num++] * 0x100 + bytes[num++]).ToString(); //st.value = 2; } else if (op <= 0x2D) { s = new string[] { "I", "L", "F", "D", "A" }; sw.Write("LOAD ("); if (op <= 0x19) { temp = (byte)(op - 0x15); //st.type = s[temp]; //st.value = bytes[num++]; sw.Write(string.Format("type={0} value={1}", s[temp], bytes[num++])); } else { temp = (byte)(op - 0x1A); //st.type = s[temp/4]; //st.value = temp % 4; sw.Write(string.Format("type={0} value={1}", s[temp / 4], temp % 4)); } sw.Write(")\n"); s = null; } else if (op <= 0x35) { s = new string[] { "I", "L", "F", "D", "A", "B", "C", "S" }; if (s[op - 0x2E] != "A") { sw.Write(string.Format("ARRLOAD (type={0})\n", s[op - 0x2E])); //st.type = s[op - 0x2E]; //st.name = "ARRLOAD"; } else sw.Write("ARRLOAD_OBJ\n"); //st.name = "ARRLOAD_OBJ"; s = null; } else if (op <= 0x4E) { s = new string[] { "I", "L", "F", "D", "A" }; //st.name = "STORE"; sw.Write("STORE"); if (op <= 0x3A) { sw.Write(string.Format(" (type={0} value={1})\n", s[op - 0x36], bytes[num++])); //st.type = s[op - 0x36]; //st.value = bytes[num++]; } else { temp = (byte)(op - 0x3B); sw.Write(string.Format(" (type={0} value={1})\n", s[temp / 4], temp % 4)); //st.type = s[temp / 4]; //st.value = temp % 4; } s = null; } else if (op <= 0x56) { s = new string[] { "I", "L", "F", "D", "A", "B", "C", "S" }; if (s[op - 0x4F] != "A") { sw.Write(string.Format("ARRSTORE (type={0})\n", s[op - 0x4F])); //st.type = s[op - 0x4F]; //st.name = "ARRSTORE"; } else sw.Write("ARRSTORE_OBJ\n"); //st.name = "ARRSTORE_OBJ"; s = null; } else if (op == 0x57) sw.Write("POP\n"); // st.name = "POP"; else if (op == 0x58) sw.Write("POP2\n"); // st.name = "POP2"; else if (op == 0x59) sw.Write("DUP\n"); // st.name = "DUP"; else if (op == 0x5A) sw.Write("DUPX1\n"); // st.name = "DUPX1"; else if (op == 0x5B) sw.Write("DUPX2\n"); // st.name = "DUPX2"; else if (op == 0x5C) sw.Write("DUP2\n"); // st.name = "DUP2"; else if (op == 0x5D) sw.Write("DUP2X1\n"); // st.name = "DUP2X1"; else if (op == 0x5E) sw.Write("DUP2X2\n"); // st.name = "DUP2X2"; else if (op == 0x5F) sw.Write("SWAP\n"); // st.name = "SWAP"; else if (op <= 0x77) { s = new string[] { "I", "L", "F", "D" }; temp = (byte)(op - 0x60); switch (temp / 4) { case 0: sw.Write("ADD"); //st.name = "ADD"; break; case 1: sw.Write("SUB"); //st.name = "SUB"; break; case 2: sw.Write("MUL"); //st.name = "MUL"; break; case 3: sw.Write("DIV"); //st.name = "DIV"; break; case 4: sw.Write("REM"); //st.name = "REM"; break; case 5: sw.Write("NEG"); //st.name = "NEG"; break; } sw.Write(string.Format(" (type={0})\n", s[temp % 4])); //st.type = s[temp % 4]; s = null; } else if (op <= 0x83) { temp = (byte)(op - 0x78); switch (temp / 2) { case 0: sw.Write("SHL"); //st.name = "SHL"; break; case 1: sw.Write("SHR"); //st.name = "SHR"; break; case 2: sw.Write("USHR"); //st.name = "USHR"; break; case 3: sw.Write("AND"); //st.name = "AND"; break; case 4: sw.Write("OR"); //st.name = "OR"; break; case 5: sw.Write("WOR"); //st.name = "WOR"; break; } if (temp % 2 == 0) sw.Write(" (type=I)\n"); //st.type = "I"; else sw.Write(" (type=L)\n"); //st.type = "L"; } else if (op == 0x84) { sw.Write(string.Format("IINC (type={0} value={1})\n", bytes[num++].ToString(), bytes[num++])); //st.name = "IINC"; //st.type = bytes[num++].ToString(); //st.value = bytes[num++]; } else if (op <= 0x90) { s = new string[] { "I", "I", "I", "L", "L", "L", "F", "F", "F", "D", "D", "D" }; string[] s2 = new string[] { "L", "F", "D", "I", "F", "D", "I", "L", "D", "I", "L", "F" }; sw.Write(string.Format("CONVERT ({0} -> {1})\n", s[op - 0x85], s2[op - 0x85])); //st.name = "CONVERT"; //st.src_t = s[op - 0x85]; //st.dst_t = s2[op - 0x85]; s = null; s2 = null; } else if (op <= 0x93) { sw.Write("TRUNCATE"); //st.name = "TRUNCATE"; switch (op - 0x91) { case 0: sw.Write(" (type=B)\n"); //st.type = "B"; break; case 1: sw.Write(" (type=C)\n"); //st.type = "C"; break; case 2: sw.Write(" (type=S)\n"); //st.type = "S"; break; } } else if (op == 0x94) sw.Write("LCMP\n"); //st.name = "LCMP"; else if (op <= 0x98) { sw.Write("FCMP"); //st.name = "FCMP"; temp = (byte)(op - 0x95); if (temp / 2 == 0) sw.Write(" (type=F"); //st.type = "F"; else sw.Write(" (type=D"); //st.type = "D"; if (temp % 2 == 0) sw.Write(" value=-1)\n"); //st.value = -1; else sw.Write(" value=1)\n"); //st.value = 1; } else if (op <= 0x9E) { st.name = "IF_I"; switch (op - 0x99) { case 0: st.type = "eq"; break; case 1: st.type = "ne"; break; case 2: st.type = "lt"; break; case 3: st.type = "ge"; break; case 4: st.type = "gt"; break; case 5: st.type = "le"; break; } sw.Write(string.Format("IF_I (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num))); //st.value = bytes[num++] * 0x100 + bytes[num++]; } else if (op <= 0xA4) { st.name = "IF_ICMP"; switch (op - 0x9F) { case 0: st.type = "eq"; break; case 1: st.type = "ne"; break; case 2: st.type = "lt"; break; case 3: st.type = "ge"; break; case 4: st.type = "gt"; break; case 5: st.type = "le"; break; } //st.value = bytes[num++] * 0x100 + bytes[num++]; sw.Write(string.Format("IF_ICMP (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num))); } else if (op <= 0xA6) { st.name = "IF_ACMP"; switch (op - 0xA5) { case 0: st.type = "eq"; break; case 1: st.type = "ne"; break; } //st.value = bytes[num++] * 0x100 + bytes[num++]; sw.Write(string.Format("IF_ACMP (type={0} value={1})\n", st.type, readBytes(bytes, 2, ref num))); } else if (op == 0xA7) { st.name = "GOTO"; //st.value = bytes[num++] * 0x100 + bytes[num++]; sw.Write(string.Format("GOTO (value={0})\n", readBytes(bytes, 2, ref num))); } else if (op == 0xA8) { st.name = "JSR"; //st.value = bytes[num++] * 0x100 + bytes[num++]; sw.Write(string.Format("JSR (value={0})\n", readBytes(bytes, 2, ref num))); } else if (op == 0xA9) { st.name = "RET"; //st.value = bytes[num++]; sw.Write(string.Format("RET (value={0})\n", bytes[num++])); } else if (op == 0xAA) { st.name = "SWITCH"; sw.Write("SWITCH"); readBytes(bytes, (3 - num) % 4, ref num); sw.Write(" (default={0}", readBytes(bytes, 4, ref num)); int low = readBytes(bytes, 4, ref num); int high = readBytes(bytes, 4, ref num); for (int i = 0; i < high - low + 1; i++) sw.Write(string.Format(" offset={0}", readBytes(bytes, 4, ref num))); sw.Write("\n"); //st.default = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++]; //st.low = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++]; //st.high = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++]; //st.offset = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++]; } else if (op == 0xAB) { st.name = "SWITCH"; sw.Write("SWITCH"); readBytes(bytes, (3 - num) % 4, ref num); sw.Write(" (default={0}", readBytes(bytes, 4, ref num)); int numpairs = readBytes(bytes, 4, ref num); for (int i = 0; i < numpairs + 1; i++) sw.Write(string.Format(" offset={0}", readBytes(bytes, 4, ref num))); sw.Write("\n"); } else if (op <= 0xB1) { st.name = "RETURN"; switch (op - 0xAC) { case 0: st.type = "I"; break; case 1: st.type = "L"; break; case 2: st.type = "F"; break; case 3: st.type = "D"; break; case 4: st.type = "A"; break; case 5: st.type = "None"; break; } } else if (op == 0xB2) sw.Write("GETSTATIC\n"); //st.name = "GETSTATIC"; else if (op == 0xB3) sw.Write("PUTSTATIC\n"); //st.name = "PUTSTATIC"; else if (op == 0xB4) sw.Write("GETFIELD\n"); //st.name = "GETFIELD"; else if (op == 0xB5) sw.Write("PUTFIELD\n"); //st.name = "PUTFIELD"; else if (op == 0xB6) sw.Write("INVOKEVIRTUAL\n"); //st.name = "INVOKEVIRTUAL"; else if (op == 0xB7) sw.Write("INVOKESPECIAL\n"); //st.name = "INVOKESPECIAL"; else if (op == 0xB8) sw.Write("INVOKESTATIC\n"); //st.name = "INVOKESTATIC"; else if (op == 0xB9) { sw.Write(string.Format("INVOKEINTERFACE (index={0} count={1} zero={2})\n", readBytes(bytes, 2, ref num), bytes[num++], bytes[num++])); //st.name = "INVOKEINTERFACE"; //st.index = bytes[num++] * 0x100 + bytes[num++]; //st.count = bytes[num++]; //st.zero = bytes[num++]; } else if (op == 0xBA) { sw.Write(string.Format("INVOKEDYNAMIC (index={0} zero={1})\n", readBytes(bytes, 2, ref num), readBytes(bytes, 2, ref num))); //st.name = "INVOKEDYNAMIC"; //st.index = bytes[num++] * 0x100 + bytes[num++]; //st.zero = bytes[num++] * 0x100 + bytes[num++]; } else if (op == 0xBB) sw.Write("NEW\n"); //st.name = "NEW"; else if (op == 0xBC) { sw.Write(string.Format("NEWARRAY")); temp = bytes[num++]; //st.name = "NEWARRAY"; switch (temp) { case 4: sw.Write(" (Bool)"); //st.type = "Bool"; break; case 5: sw.Write(" (C)"); //st.type = "C"; break; case 6: sw.Write(" (F)"); //st.type = "F"; break; case 7: sw.Write(" (D)"); //st.type = "D"; break; case 8: sw.Write(" (B)"); //st.type = "B"; break; case 9: sw.Write(" (S)"); //st.type = "S"; break; case 10: sw.Write(" (I)"); //st.type = "I"; break; case 11: sw.Write(" (L)"); //st.type = "L"; break; } sw.Write("\n"); } else if (op == 0xBD) sw.Write("ANEWARRAY\n"); //st.name = "ANEWARRAY"; else if (op == 0xBE) sw.Write("ARRLEN\n"); //st.name = "ARRLEN"; else if (op == 0xBF) sw.Write("THROW\n"); //st.name = "THROW"; else if (op == 0xC0) sw.Write("CHECKCAST\n"); //st.name = "CHECKCAST"; else if (op == 0xC1) sw.Write("INSTANCEOF\n"); //st.name = "INSTANCEOF"; else if (op == 0xC2) sw.Write("MONENTER\n"); //st.name = "MONENTER"; else if (op == 0xC3) sw.Write("MONEXIT\n"); //st.name = "MONEXIT"; else if (op == 0xC4) { byte b = bytes[num++]; if (b >= 0x15 && b < 0x1A) { sw.Write("LOAD ("); //st.name = "LOAD"; switch (b - 0x15) { case 0: sw.Write("I = "); //st.type = "I"; break; case 1: sw.Write("L = "); //st.type = "L"; break; case 2: sw.Write("F = "); //st.type = "F"; break; case 3: sw.Write("D = "); //st.type = "D"; break; case 4: sw.Write("A = "); //st.type = "A"; break; } //st.value = bytes[num++] * 0x100 + bytes[num++]; sw.Write(string.Format("{0})\n", readBytes(bytes, 2, ref num))); } else if (b >= 0x36 && b < 0x3B) { sw.Write("STORE ("); //st.name = "STORE"; switch (b - 0x36) { case 0: sw.Write("I = "); //st.type = "I"; break; case 1: sw.Write("L = "); //st.type = "L"; break; case 2: sw.Write("F = "); //st.type = "F"; break; case 3: sw.Write("D = "); //st.type = "D"; break; case 4: sw.Write("A = "); //st.type = "A"; break; } //st.value = bytes[num++] * 0x100 + bytes[num++]; sw.Write(string.Format("{0})\n", readBytes(bytes, 2, ref num))); } else if (b == 0xA9) { sw.Write(string.Format("RET ({0})\n", readBytes(bytes, 2, ref num))); //st.name = "RET"; //st.value = bytes[num++] * 0x100 + bytes[num++]; } else if (b == 0x84) { sw.Write(string.Format("IINC ({0} {1})\n", readBytes(bytes, 2, ref num), readBytes(bytes, 2, ref num))); //st.name = "IINC"; //st.value = bytes[num++] * 0x100 + bytes[num++]; //st.value2 = bytes[num++] * 0x100 + bytes[num++]; } } else if (op == 0xC5) { sw.Write(string.Format("MULTINEWARRAY (index={0} dim={1})\n", readBytes(bytes, 2, ref num), bytes[num++])); //st.name = "MULTINEWARRAY"; //st.index = bytes[num++] * 0x100 + bytes[num++]; //st.dim = bytes[num++]; } else if (op <= 0xC7) { sw.Write("IF_A ("); //st.name = "IF_A"; if (op - 0xC6 == 0) sw.Write(string.Format("eq -> {0})\n", readBytes(bytes, 2, ref num))); //st.type = "eq"; else if (op - 0xC6 == 1) sw.Write(string.Format("ne -> {0})\n", readBytes(bytes, 2, ref num))); //st.type = "ne"; //st.jumptarget = bytes[num++] * 0x100 + bytes[num++]; } else if (op == 0xC8) { sw.Write(string.Format("GOTO ({0})\n", readBytes(bytes, 4, ref num))); //st.name = "GOTO"; //st.value = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++]; } else if (op == 0xC9) { sw.Write(string.Format("JSR ({0})\n", readBytes(bytes, 4, ref num))); //st.name = "JSR"; //st.value = bytes[num++] * 0x1000000 + bytes[num++] * 0x10000 + bytes[num++] * 0x100 + bytes[num++]; } else Console.WriteLine("Bytecode inconnu : {0:X2}", op); list.Add(st); } } private void printBytecodeSourceFile(StreamWriter sw, byte[] bytes) { int num = 0; sw.Write(string.Format("sourcefile_index = {0:X4}", readBytes(bytes, 2, ref num))); } private void printBytecodeInnerClass(StreamWriter sw, byte[] bytes) { int num = 0; int nbClass = readBytes(bytes, 2, ref num); sw.Write(string.Format("number_of_classes = {0:X4}\n", nbClass)); for (int i = 0; i < nbClass; i++) { sw.Write(string.Format("{0,34:D4} : inner_class_info_index = {1:X4}\n", i + 1, readBytes(bytes, 2, ref num))); sw.Write(string.Format("{0,59} = {1:X4}\n", "outer_class_info_index", readBytes(bytes, 2, ref num))); sw.Write(string.Format("{0,53} = {1:X4}\n", "inner_name_index", readBytes(bytes, 2, ref num))); sw.Write(string.Format("{0,61} = {1:X4}\n", "inner_class_access_flags", readBytes(bytes, 2, ref num))); } } #endregion private byte[] IntToByteArrayBE(int value, int size = 4) { byte[] bytes = BitConverter.GetBytes(value); Array.Reverse(bytes, 0, size); return bytes; } //--------------------------------------------------------------------- public void load(BinaryReader br) { magic = new byte[4]; magic = br.ReadBytes(4); minor_version = br.ReadInt16BE(); major_version = br.ReadInt16BE(); readConstants(br); access_flags = br.ReadInt16BE(); this_class = br.ReadInt16BE(); super_class = br.ReadInt16BE(); readInterfaces(br); readFields(br); readMethods(br); readAttributes(br); } public Dictionary getConstantsValue() { Dictionary dict = new Dictionary(); foreach (KeyValuePair constant in constant_pool) { if (constant.Value.tag == 8) { CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value; dict[constant.Key] = getConstantValue(stString.string_index); } } return dict; } public Dictionary getConstantsBytes() { Dictionary dict = new Dictionary(); foreach (KeyValuePair constant in constant_pool) { if (constant.Value.tag == 8) { CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value; dict[constant.Key] = getConstantBytes(stString.string_index); } } return dict; } public MemoryStream compilClass(evtClass.stFile originalFile) { MemoryStream ms = new MemoryStream(); using (BinaryWriter bw = new BinaryWriter(ms, Encoding.Default, true)) { bw.Write(this.magic); bw.Write(IntToByteArrayBE(this.minor_version, 2), 0, 2); bw.Write(IntToByteArrayBE(this.major_version, 2), 0, 2); bw.Write(IntToByteArrayBE(this.constant_pool_count+1, 2), 0, 2); compilConstants(bw); bw.Write(IntToByteArrayBE(this.access_flags, 2), 0, 2); bw.Write(IntToByteArrayBE(this.this_class, 2), 0, 2); bw.Write(IntToByteArrayBE(this.super_class, 2), 0, 2); bw.Write(IntToByteArrayBE(this.interfaces_count, 2), 0, 2); compilInterfaces(bw); bw.Write(IntToByteArrayBE(this.fields_count, 2), 0, 2); compilFields(bw); bw.Write(IntToByteArrayBE(this.methods_count, 2), 0, 2); compilMethods(bw); bw.Write(IntToByteArrayBE(this.attributes_count, 2), 0, 2); compilAttributes(bw); } return ms; } public void setConstantsBytes(int id, byte[] bytes) { if (constant_pool.ContainsKey(id)) { if (constant_pool[id].tag == 8) { CONSTANT_String_info stString = (CONSTANT_String_info)constant_pool[id]; setConstantsBytes(stString.string_index, bytes); } else if (constant_pool[id].tag == 1) { CONSTANT_Utf8_info stUTF8 = (CONSTANT_Utf8_info)constant_pool[id]; stUTF8.bytes = new byte[bytes.Length]; Array.Copy(bytes, 0, stUTF8.bytes, 0, bytes.Length); //stUTF8.bytes[bytes.Length] = 0; } } } public void writeConstants(StreamWriter sw) { sw.Write(string.Format("[CONSTANTS : {0}]\n", constant_pool_count)); foreach (KeyValuePair constant in constant_pool) { sw.Write(string.Format("{0:X4} : {1:D2} ", constant.Key, constant.Value.tag)); switch (constant.Value.tag) { case 1: CONSTANT_Utf8_info stUtf8 = (CONSTANT_Utf8_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X4} ", "Utf8", stUtf8.length)); if (stUtf8.length > 0) sw.Write(Encoding.UTF8.GetString(stUtf8.bytes).Replace("\n", "\\n")); sw.Write("\n"); break; case 3: CONSTANT_Integer_info stInteger = (CONSTANT_Integer_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X8} ({1})\n", "Integer", stInteger.bytes)); break; case 4: CONSTANT_Float_info stFloat = (CONSTANT_Float_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X8} ({2})\n", "Float", stFloat.bytes, BitConverter.ToSingle(BitConverter.GetBytes(stFloat.bytes), 0))); break; case 5: CONSTANT_Long_info stLong = (CONSTANT_Long_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X8} {2:X8}\n", "Long", stLong.high_bytes, stLong.low_bytes)); break; case 6: CONSTANT_Double_info stDouble = (CONSTANT_Double_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X8} {2:X8}\n", "Double", stDouble.high_bytes, stDouble.low_bytes)); break; case 7: CONSTANT_Class_info stClass = (CONSTANT_Class_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Class", stClass.name_index, getConstantValue(stClass.name_index))); break; case 8: CONSTANT_String_info stString = (CONSTANT_String_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "String", stString.string_index, getConstantValue(stString.string_index))); break; case 9: CONSTANT_Fieldref_info stFieldref = (CONSTANT_Fieldref_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Fieldref", stFieldref.class_index, getConstantValue(stFieldref.class_index))); sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stFieldref.name_and_type_index, getConstantValue(stFieldref.name_and_type_index))); break; case 10: CONSTANT_Methodref_info stMethodref = (CONSTANT_Methodref_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "Methodref", stMethodref.class_index, getConstantValue(stMethodref.class_index))); sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stMethodref.name_and_type_index, getConstantValue(stMethodref.name_and_type_index))); break; case 11: CONSTANT_InterfaceMethodref_info stInterfaceMethodref = (CONSTANT_InterfaceMethodref_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X4} {2:X4}\n", "InterfaceMethodref", stInterfaceMethodref.class_index, stInterfaceMethodref.name_and_type_index)); break; case 12: CONSTANT_NameAndType_info stNameAndType = (CONSTANT_NameAndType_info)constant.Value; sw.Write(string.Format("{0,-18} : {1,-9:X4} ({2})\n", "NameAndType", stNameAndType.name_index, getConstantValue(stNameAndType.name_index))); sw.Write(string.Format("{0,31}{1,-9:X4} ({2})\n", " ", stNameAndType.descriptor_index, getConstantValue(stNameAndType.descriptor_index))); break; case 15: CONSTANT_MethodHandle_info stMethodHandle = (CONSTANT_MethodHandle_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X2} {2:X4}\n", "MethodHandle", stMethodHandle.reference_kind, stMethodHandle.reference_index)); break; case 16: CONSTANT_MethodType_info stMethodType = (CONSTANT_MethodType_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X4}\n", "MethodType", stMethodType.descriptor_index)); break; case 18: CONSTANT_InvokeDynamic_info stInvokeDynamic = (CONSTANT_InvokeDynamic_info)constant.Value; sw.Write(string.Format("{0,-18} : {1:X4} {2:X4}\n", "InvokeDynamic", stInvokeDynamic.bootstrap_method_attr_index, stInvokeDynamic.name_and_type_index)); break; } } sw.Write("\n"); } public void writeInterfaces(StreamWriter sw) { sw.Write(string.Format("[INTERFACES : {0}]\n", interfaces_count)); int num = 1; foreach (Int16 index in interfaces) { sw.Write(string.Format("{0:D4} : {1:X4} ({2})\n", num, index, getConstantValue(index))); num++; } sw.Write("\n"); } public void writeFields(StreamWriter sw) { sw.Write(string.Format("[FIELDS : {0}]\n", fields_count)); foreach (KeyValuePair field in fields) { sw.Write(string.Format("{0:D4} : access_flags = {1:X4}\n", field.Key, field.Value.access_flags)); sw.Write(string.Format(" name_index = {0:X4} ({1})\n", field.Value.name_index, getConstantValue(field.Value.name_index))); sw.Write(string.Format(" descriptor_index = {0:X4} ({1})\n", field.Value.descriptor_index, getConstantValue(field.Value.descriptor_index))); sw.Write(string.Format(" attributes_count = {0:X4}\n", field.Value.attributes_count)); if (field.Value.attributes_count > 0) { foreach (KeyValuePair attribut in field.Value.attributes) { 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))); sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length)); sw.Write(" info = "); for (int i = 0; i < attribut.Value.attribute_length; i++) sw.Write(string.Format("{0:X2} ", attribut.Value.info[i])); sw.Write("\n"); } } } sw.Write("\n"); } public void writeMethods(StreamWriter sw) { sw.Write(string.Format("[METHODS : {0}]\n", methods_count)); foreach (KeyValuePair method in methods) { sw.Write(string.Format("{0:D4} : access_flags = {1:X4}\n", method.Key, method.Value.access_flags)); sw.Write(string.Format(" name_index = {0:X4} ({1})\n", method.Value.name_index, getConstantValue(method.Value.name_index))); sw.Write(string.Format(" descriptor_index = {0:X4} ({1})\n", method.Value.descriptor_index, getConstantValue(method.Value.descriptor_index))); sw.Write(string.Format(" attributes_count = {0:X4}\n", method.Value.attributes_count)); if (method.Value.attributes_count > 0) { foreach (KeyValuePair attribut in method.Value.attributes) { 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))); sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length)); if (attribut.Value.attribute_length > 0) { sw.Write(string.Format("{0,31} = ", "info")); switch (attribut.Value.attribute_name_index) { case 0x121: printBytecodeCode(sw, attribut.Value.info); break; case 0x12A: printBytecodeInnerClass(sw, attribut.Value.info); break; case 0x145: printBytecodeSourceFile(sw, attribut.Value.info); break; } //for (int i = 0; i < attribut.Value.attribute_length; i++) // sw.Write(string.Format("{0:X2} ", attribut.Value.info[i])); sw.Write("\n"); } } } } sw.Write("\n"); } public void writeAttributes(StreamWriter sw) { sw.Write(string.Format("[ATTRIBUTS : {0}]\n", attributes_count)); foreach (KeyValuePair attribut in attributes) { 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))); sw.Write(string.Format(" attribute_length = {0:X8}\n", attribut.Value.attribute_length)); if (attribut.Value.attribute_length > 0) { sw.Write(" info = "); switch (attribut.Value.attribute_name_index) { case 0x121: printBytecodeCode(sw, attribut.Value.info); break; case 0x12A: printBytecodeInnerClass(sw, attribut.Value.info); break; case 0x145: printBytecodeSourceFile(sw, attribut.Value.info); break; } //for (int i = 0; i < attribut.Value.attribute_length; i++) // sw.Write(string.Format("{0:X2} ", attribut.Value.info[i])); sw.Write("\n"); } } sw.Write("\n"); } } }