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

1977 lines
74 KiB

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<stFile> 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
/// <summary>
/// Init an evt file (archive)
/// </summary>
/// <param name="pathName">Path of the file</param>
/// <returns></returns>
public bool init(string pathName)
{
bool result = true;
using (BinaryReader br = new BinaryReader(File.Open(pathName, FileMode.Open)))
{
result = init(br);
}
return result;
}
/// <summary>
/// Init an evt file (archive)
/// </summary>
/// <param name="br">BinaryReader of the file</param>
/// <returns></returns>
public bool init(BinaryReader br)
{
listFiles = new List<stFile>();
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<int, stAttribut> attributes;
}
private struct stMethod
{
public Int16 access_flags;
public Int16 name_index;
public Int16 descriptor_index;
public Int16 attributes_count;
public Dictionary<int, stAttribut> attributes;
}
private struct stAttribut
{
public Int16 attribute_name_index;
public long attribute_length;
public byte[] info;
public List<stOpcode> 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<int, iCONSTANT> constant_pool;
private Int16 access_flags;
private Int16 this_class;
private Int16 super_class;
private Int16 interfaces_count;
private List<Int16> interfaces;
private Int16 fields_count;
private Dictionary<int, stField> fields;
private Int16 methods_count;
private Dictionary<int, stMethod> methods;
private Int16 attributes_count;
private Dictionary<int, stAttribut> attributes;
//---------------------------------------------------------------------
#region Constructors
public JavaClass()
{ }
~JavaClass()
{ }
#endregion
//---------------------------------------------------------------------
#region Compilation
private void compilConstants(BinaryWriter bw)
{
foreach (KeyValuePair<int, iCONSTANT> 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<int, stField> 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<int, stAttribut> 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<int, stMethod> 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<int, stAttribut> 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<int, stAttribut> 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<int, iCONSTANT>();
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<Int16>();
interfaces_count = br.ReadInt16BE();
for (int i = 0; i < interfaces_count; i++)
interfaces.Add(br.ReadInt16BE());
}
private void readFields(BinaryReader br)
{
fields = new Dictionary<int, stField>();
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<int, stAttribut>();
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<int, stMethod>();
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<int, stAttribut>();
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<int, stAttribut>();
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<stOpcode> list = new List<stOpcode>();
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<int, string> getConstantsValue()
{
Dictionary<int, string> dict = new Dictionary<int, string>();
foreach (KeyValuePair<int, iCONSTANT> 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<int, byte[]> getConstantsBytes()
{
Dictionary<int, byte[]> dict = new Dictionary<int, byte[]>();
foreach (KeyValuePair<int, iCONSTANT> 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<int, iCONSTANT> 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<int, stField> 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<int, stAttribut> 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<int, stMethod> 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<int, stAttribut> 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<int, stAttribut> 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");
}
}
}