private void loadOPCodes(LuaFunction function) { // Go through all op codes for (int i = 0; i < function.opcodesCount; i++) { // Make a new OP Code object LuaOPCode opCode = new LuaOPCode(); // Read + asign all data opCode.A = this.inputReader.ReadByte(); int cValue = this.inputReader.ReadByte(); byte flags = this.inputReader.ReadByte(); if (GetBit(flags, 0) == 1) { cValue += 256; } opCode.C = cValue; this.inputReader.Seek(-1, SeekOrigin.Current); opCode.B = this.inputReader.ReadByte() >> 1; byte flagsB = this.inputReader.ReadByte(); if (GetBit(flagsB, 0) == 1) { opCode.B += 128; } /*if (GetBit(flagsB, 1) == 1) * opCode.B += 256;*/ opCode.Bx = (opCode.B * 512) + opCode.C; opCode.sBx = opCode.Bx - 65536 + 1; this.inputReader.Seek(-1, SeekOrigin.Current); opCode.OPCode = this.inputReader.ReadByte() >> 1; // Add it to the list function.OPCodes.Add(opCode); } }
private void disassembleOPCodes(LuaFunction function, int index) { // Add the parameter opcodes because they arent included for (int i = 0; i < function.parameterCount; i++) { function.Registers[i] = "arg" + i; function.DisassembleStrings.Add(String.Format("r({0}) = arg{0}", i)); } for (int i = 0; i < function.OPCodes.Count; i++) { LuaOPCode opCode = function.OPCodes[i]; try { switch (opCode.OPCode) { case 0x0: LuaStrings.ConnectWithDot(function, opCode); break; case 0x1: LuaConditions.IfIsTrueFalse(function, opCode); break; case 0x2: case 0x4C: LuaFunctions.CallFunctionWithParameters(function, opCode, i); break; case 0x16: LuaFunctions.CallFunctionWithParameters(function, opCode, i, true); break; case 0x4: LuaConditions.IfIsEqual(function, opCode); break; case 0x5: LuaConditions.IfIsEqualBackwards(function, opCode); break; case 0x6: LuaRegisters.GlobalRegisterToRegister(function, opCode); break; case 0x7: LuaRegisters.RegisterToRegister(function, opCode); break; case 0x8: LuaStrings.ConnectWithColon(function, opCode); break; case 0x9: LuaOperators.Return(function, opCode, i); break; case 0xA: LuaTables.GetIndex(function, opCode); break; case 0xD: LuaRegisters.BooleanToRegister(function, opCode); break; case 0xE: LuaLoops.StartForEachLoop(function, opCode); break; case 0xF: LuaStrings.SetField(function, opCode, i); break; case 0x10: LuaTables.SetTable(function, opCode); break; case 0x11: LuaTables.SetTableBackwards(function, opCode); break; case 0x19: LuaRegisters.LocalConstantToRegister(function, opCode); break; case 0x1A: LuaRegisters.NilToRegister(function, opCode); break; case 0x1B: LuaRegisters.RegisterToGlobal(function, opCode); break; case 0x1C: LuaConditions.SkipLines(function, opCode, i); break; case 0x26: LuaFunctions.GetUpValue(function, opCode); break; case 0x27: LuaOperators.SetupVal(function, opCode); break; case 0x28: LuaOperators.Add(function, opCode); break; case 0x29: LuaOperators.AddBackWards(function, opCode); break; case 0x2A: LuaOperators.Subtract(function, opCode); break; case 0x2B: LuaOperators.SubtractBackWards(function, opCode); break; case 0x2C: LuaOperators.Multiply(function, opCode); break; case 0x2D: LuaOperators.MultiplyBackWards(function, opCode); break; case 0x2E: LuaOperators.Divide(function, opCode); break; case 0x2F: LuaOperators.DivideBackWards(function, opCode); break; case 0x30: LuaOperators.Modulo(function, opCode); break; case 0x31: LuaOperators.ModuloBackWards(function, opCode); break; case 0x32: LuaOperators.Power(function, opCode); break; case 0x33: LuaOperators.PowerBackWards(function, opCode); break; case 0x34: LuaTables.EmptyTable(function, opCode); break; case 0x35: LuaOperators.UnaryMinus(function, opCode); break; case 0x36: LuaConditions.Not(function, opCode); break; case 0x37: LuaOperators.Length(function, opCode); break; case 0x38: LuaConditions.LargerThan(function, opCode); break; case 0x39: LuaConditions.LargerThanBackwards(function, opCode); break; case 0x3A: LuaConditions.LargerOrEqualThan(function, opCode); break; case 0x3B: LuaConditions.LargerOrEqualThanBackwards(function, opCode); break; case 0x3C: LuaOperators.ShiftLeft(function, opCode); break; case 0x3D: LuaOperators.ShiftLeftBackwards(function, opCode); break; case 0x40: LuaOperators.BinaryAnd(function, opCode); break; case 0x42: LuaOperators.BinaryOr(function, opCode); break; case 0x44: LuaStrings.ConnectWithDoubleDot(function, opCode); break; case 0x45: LuaOperators.TestSet(function, opCode); break; case 0x46: LuaLoops.StartForLoop(function, opCode); break; case 0x47: LuaLoops.EndForLoop(function, opCode, i); break; case 0x48: LuaTables.SetList(function, opCode); break; case 0x49: LuaOperators.Close(function, opCode); break; case 0x4A: LuaFunctions.Closure(function, opCode); break; case 0x4B: LuaOperators.VarArg(function, opCode); break; case 0x4D: LuaFunctions.CallFunctionWithoutParameters(function, opCode); break; case 0x4F: LuaConditions.IfIsTrueFalse(function, opCode); break; case 0x50: LuaOperators.NotR1(function, opCode); break; case 0x51: LuaStrings.ConnectWithDot(function, opCode); break; case 0x52: LuaStrings.SetField(function, opCode, i); break; case 0x54: if (function.doingUpvals >= 0) { if (opCode.A == 1) { function.DisassembleStrings.Add(String.Format("r({0}).upval({1}) = r({2}) // {3}", function.doingUpvals, function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Count, opCode.C, function.Registers[opCode.C])); } else if (opCode.A == 2) { function.DisassembleStrings.Add(String.Format("r({0}).upval({1}) = upval({2}) // {3}", function.doingUpvals, function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Count, opCode.C, function.UpvalsStrings[opCode.C])); } else { Console.WriteLine("Trying to get to do upvalue on level " + opCode.A); errors++; } } else { function.DisassembleStrings.Add(String.Format("data({0}, {1}, {2}, {3})", opCode.A, opCode.C, opCode.B, opCode.OPCode)); } break; default: function.DisassembleStrings.Add(String.Format("Unknown data(A:{0}, B:{1}, C:{2}, Bx:{3}, sBx:{4}, X:{5})", opCode.A, opCode.B, opCode.C, opCode.Bx, opCode.sBx, opCode.OPCode)); break; } if ((opCode.OPCode == 0xF || opCode.OPCode == 0x52) && function.getName() == "__INIT__") { if (this.game == Game.BlackOps4 && function.Registers[opCode.A].Length == 14) { if (function.Registers[opCode.A] == "LUI.createMenu") { fakeName = function.Strings[opCode.B].String; } } else if (this.game == Game.BlackOps4 && function.Registers[opCode.A].Length > 3) { if ((function.Registers[opCode.A].Substring(0, 4) == "CoD." || function.Registers[opCode.A].Substring(0, 4) == "LUI." || function.Registers[opCode.A].Substring(0, 6) == "Lobby.") && (function.Strings[opCode.B].String == "new")) { fakeName = function.Registers[opCode.A].Substring(4); } } else if (this.game == Game.BlackOps4 && function.Registers[opCode.A].Length < 4) { if ((function.Registers[opCode.A] == "CoD" || function.Registers[opCode.A] == "LUI") && (function.Registers[opCode.C] == "table0")) { fakeName = function.Strings[opCode.B].String; } } } if (function.doingUpvals >= 0) { if (opCode.OPCode == 0x4A) { continue; } if (opCode.OPCode == 0x54) { if (opCode.A == 1) { function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Add(function.Registers[opCode.C]); } else if (opCode.A == 2) { function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Add(function.UpvalsStrings[opCode.C]); } } else { function.doingUpvals = -1; } } } catch { Console.WriteLine("Error occured while disassembling A: {3}, B: {4}, C: {5} OPcode: {0:X} at line {1} in function {2}", opCode.OPCode, i, function.getName(), opCode.A, opCode.B, opCode.C); function.DisassembleStrings.Add(String.Format("Unknown data(A:{0}, B:{1}, C:{2}, Bx:{3}, sBx:{4}, X:{5})", opCode.A, opCode.B, opCode.C, opCode.Bx, opCode.sBx, opCode.OPCode)); errors++; } } }