public static Instruction ParseInstruction(System.IO.BinaryReader br,Assembly asm,Function func) { Instructions op = (Instructions)br.ReadInt16(); Instruction insn = new Instruction(); insn.Assembly = asm; insn.Function = func; insn.Inst = op; switch (op) { case Instructions.BneLocal: case Instructions.BgeLocal: case Instructions.BltLocal: case Instructions.BgtLocal: case Instructions.BneField: case Instructions.BeqField: case Instructions.BneFieldLocal: case Instructions.BgtField: insn.Operand1 = br.ReadInt32(); insn.Operand2 = br.ReadInt32(); insn.Operand3 = br.ReadInt32(); insn.BranchTarget.Add(insn.Operand3); insn.StartNewBlock = true; break; case Instructions.Jmp: insn.Operand1 = br.ReadInt32(); insn.BranchTarget.Add(insn.Operand1); insn.EndBlock = true; break; case Instructions.BrFalse: case Instructions.BrTrue: insn.Operand1 = br.ReadInt32(); insn.BranchTarget.Add(insn.Operand1); insn.StartNewBlock = true; break; case Instructions.Switch: case Instructions.SwitchS: insn.Operand1 = br.ReadInt32(); Switch swi = asm.SwitchTables[insn.Operand1]; foreach (int i in swi.SwitchTable.Values) insn.BranchTarget.Add(i); if (swi.DefaultCase != -1) insn.BranchTarget.Add(swi.DefaultCase); break; case Instructions.Push: case Instructions.CallMethod: case Instructions.Call: case Instructions.RefGlobal: case Instructions.RefLocal: case Instructions.PushS: case Instructions.AssertFunc: case Instructions.AssertFile: case Instructions.CallSys: case Instructions.EndOfFunc: case Instructions.StructDelLocal: case Instructions.PushField: case Instructions.IncLocal: case Instructions.DecLocal: case Instructions.ArraySizeField: case Instructions.ArraySizeGlobal: case Instructions.PushLocal2: case Instructions.PushSLocal: case Instructions.AssignSConst: case Instructions.PushSField: case Instructions.ArrayStructRef: case Instructions.PushSGlobal: case Instructions.AssignSLocal: case Instructions.StringEmptyLocal: case Instructions.StringEmptyField: case Instructions.StructRef: case Instructions.AssignSField: case Instructions.Msg: insn.Operand1 = br.ReadInt32(); break; case Instructions.PushF: insn.Operand1F = br.ReadSingle(); break; case Instructions.BrFalseField: case Instructions.BNotEmptyField: case Instructions.BneS: insn.Operand1 = br.ReadInt32(); insn.Operand2 = br.ReadInt32(); insn.BranchTarget.Add(insn.Operand2); insn.StartNewBlock = true; break; case Instructions.StructCreateLocal: case Instructions.AssignLocal: case Instructions.AssignField: case Instructions.CallHLL: case Instructions.AssignFieldLocal: case Instructions.AssignGlobalLocal: case Instructions.AssignLocalField: case Instructions.ArrayPushBackLocal: case Instructions.AssignGlobal: case Instructions.GeField: case Instructions.EqlSLocal: case Instructions.NeqSLocal: case Instructions.EqlSFieldLocal: case Instructions.AssignSFieldLocal: case Instructions.PushStructRefField: case Instructions.ArrayPushBackFieldLocal: case Instructions.AssignArrayLocalField: case Instructions.ArrayPushBackLocalString: case Instructions.ArrayPushBackGlobalLocalRef: case Instructions.ArrayPushBackFieldLocalRef: case Instructions.AssignFieldLocalITOB: case Instructions.ArrayPushBackGlobalLocal: case Instructions.MinLocal: case Instructions.NeqFieldS: case Instructions.NeqSFieldLocal: case Instructions.AssignSLocalLocal: insn.Operand1 = br.ReadInt32(); insn.Operand2 = br.ReadInt32(); break; case Instructions.LtOrGeLocal: insn.Operand1 = br.ReadInt32(); insn.Operand2 = br.ReadInt32(); insn.Operand3 = br.ReadInt32(); break; case Instructions.Ret: insn.EndBlock = true; break; case Instructions.PushSP: case Instructions.Le: default: break; } return insn; }
public static Assembly FromAIN(string path) { Assembly asm = new Assembly(); System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open); System.IO.BinaryReader br = new System.IO.BinaryReader(fs); fs.Position = 8; uint size = br.ReadUInt32(); uint compressedSize = br.ReadUInt32(); byte[] buf; byte[] dst = new byte[size]; buf = br.ReadBytes((int)compressedSize); fixed (byte* ptr = buf) { fixed (byte* ptr2 = dst) { uncompress(ptr2, &size, ptr, compressedSize); } } fs.Close(); System.IO.MemoryStream ms = new System.IO.MemoryStream(dst); br = new System.IO.BinaryReader(ms); while (ms.Position < ms.Length) { string trunk = Encoding.ASCII.GetString(br.ReadBytes(4)); switch (trunk) { case "VERS": asm.Version = br.ReadInt32(); if (asm.Version != 6) { throw new NotSupportedException("本SDK仅支持版本为:6的反编译"); } break; case "KEYC": asm.Keyc = br.ReadInt32(); break; case "CODE": asm.CodeBuffer = br.ReadBytes(br.ReadInt32()); break; case "FUNC": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { Function func = new Function(); func.Address = br.ReadInt32(); func.Assembly = asm; func.Name = ReadString(br); func.U1 = br.ReadInt32(); func.ReturnType = (VarTypes)br.ReadInt32(); func.StructID = br.ReadInt32(); func.ArgCount = br.ReadInt32(); func.TotalLocalCount = br.ReadInt32(); func.U4 = br.ReadInt32(); for (int j = 0; j < func.TotalLocalCount; j++) { Variable arg = new Variable(); arg.Name = ReadString(br); arg.Assembly = asm; arg.VarType = (VarTypes)br.ReadInt32(); arg.StructID = br.ReadInt32(); arg.Dimension = br.ReadInt32(); if (j < func.ArgCount) func.Arguments.Add(arg); func.LocalVariables.Add(arg); } asm.Functions.Add(func); } } break; case "GLOB": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { Variable var = new Variable(); var.Name = ReadString(br); var.Assembly = asm; var.VarType = (VarTypes)br.ReadInt32(); var.StructID = br.ReadInt32(); var.Dimension = br.ReadInt32(); var.U3 = br.ReadInt32(); asm.global.Add(var); } } break; case "GSET": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { Variable var = asm.global[br.ReadInt32()]; VarTypes type = (VarTypes)br.ReadInt32(); switch (type) { case VarTypes.Float: var.FloatVal = br.ReadSingle(); break; case VarTypes.String: var.StringVal = ReadString(br); break; case VarTypes.Bool: var.BoolVal = br.ReadInt32() == 1; break; default: var.IntVal = br.ReadInt32(); break; } } } break; case "STRT": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { Struct str = new Struct(); str.Name = ReadString(br); int func = br.ReadInt32(); if (func != -1) str.Constructor = asm.func[func]; func = br.ReadInt32(); if (func != -1) str.Destructor = asm.func[func]; str.VarCount = br.ReadInt32(); for (int j = 0; j < str.VarCount; j++) { Variable arg = new Variable(); arg.Name = ReadString(br); arg.Assembly = asm; arg.VarType = (VarTypes)br.ReadInt32(); arg.StructID = br.ReadInt32(); arg.Dimension = br.ReadInt32(); str.Variables.Add(arg); } asm.structs.Add(str); } } break; case "MSG0": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { asm.msgs.Add(ReadString(br)); } } break; case "MAIN": asm.EntryPoint = asm.func[br.ReadInt32()]; break; case "MSGF": asm.MessageFunction = asm.func[br.ReadInt32()]; break; case "HLL0": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { string name = ReadString(br); Hll hll = new Hll(); hll.Name = name; int count2 = br.ReadInt32(); for (int j = 0; j < count2; j++) { Function func = new Function(); func.Name = ReadString(br); func.ReturnType = (VarTypes)br.ReadInt32(); func.TotalLocalCount = br.ReadInt32(); func.ArgCount = func.TotalLocalCount; for (int k = 0; k < func.TotalLocalCount; k++) { Variable arg = new Variable(); arg.Assembly = asm; arg.Name = ReadString(br); arg.VarType = (VarTypes)br.ReadInt32(); func.Arguments.Add(arg); } hll.Functions.Add(func); } asm.hlls.Add(hll); } } break; case "SWI0": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { Switch swi = new Switch(); swi.SwitchType = (SwitchTypes)br.ReadInt32(); swi.DefaultCase = br.ReadInt32(); int count2 = br.ReadInt32(); for (int j = 0; j < count2; j++) { swi.SwitchTable.Add(br.ReadInt32(), br.ReadInt32()); } asm.switches.Add(swi); } } break; case "GVER": asm.GVersion = br.ReadInt32(); break; case "STR0": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { string str = ReadString(br); asm.strings.Add(str); } } break; case "FNAM": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { string str = ReadString(br); asm.fname.Add(str); } } break; case "OJMP": { int funcID = br.ReadInt32(); if (funcID >= 0) asm.JumpFunction = asm.func[funcID]; } break; case "FNCT": { int len = br.ReadInt32(); int count = br.ReadInt32(); for (int i = 0; i < count; i++) { Function func = new Function(); func.Name = ReadString(br); func.ReturnType = (VarTypes)br.ReadInt32(); func.StructID = br.ReadInt32(); func.ArgCount = br.ReadInt32(); func.TotalLocalCount = br.ReadInt32(); for (int j = 0; j < func.TotalLocalCount; j++) { Variable arg = new Variable(); arg.Name = ReadString(br); arg.VarType = (VarTypes)br.ReadInt32(); arg.StructID = br.ReadInt32(); arg.Dimension = br.ReadInt32(); func.Arguments.Add(arg); } asm.fnct.Add(func); } } break; case "OBJG": { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { string str = ReadString(br); asm.objg.Add(str); } } break; default: throw new ArgumentException(string.Format("{0}文件中包含未知的Trunk:{1}", path, trunk)); } } return asm; }
public static string GetTypeName(this VarTypes type, Assembly asm, int StructID, int dimension) { string name = ""; try { switch (type) { case VarTypes.StrucRef: name = "ref " + asm.Structures[StructID].Name; break; case VarTypes.Struct: name = asm.Structures[StructID].Name; break; case VarTypes.ArrayStruct: name = asm.Structures[StructID].Name + dimension.GetDimension(); break; case VarTypes.IntRef: name = "ref int"; break; case VarTypes.FloatRef: name = "ref float"; break; case VarTypes.StringRef: name = "ref string"; break; case VarTypes.ArrayIntRef: name = "ref int" + dimension.GetDimension(); break; case VarTypes.ArrayFloatRef: name = "ref float" + dimension.GetDimension(); break; case VarTypes.ArrayStringRef: name = "ref string" + dimension.GetDimension(); break; case VarTypes.ArrayStructRef: name = "ref " + asm.Structures[StructID].Name + dimension.GetDimension(); break; case VarTypes.ArrayInt: name = "int" + dimension.GetDimension(); break; case VarTypes.ArrayFloat: name = "float" + dimension.GetDimension(); break; case VarTypes.ArrayString: name = "string" + dimension.GetDimension(); break; case VarTypes.ArrayBool: name = "bool" + dimension.GetDimension(); break; case VarTypes.ArrayDelegate: name = "delegate" + dimension.GetDimension(); break; default: name = type.ToString().ToLower(); break; } } catch { name = type.ToString().ToLower(); } return name; }