├── .gitattributes ├── .gitignore ├── LICENSE ├── LuaDecompiler ├── LuaDecompiler.sln ├── LuaDecompiler │ ├── App.config │ ├── FodyWeavers.xml │ ├── FodyWeavers.xsd │ ├── LuaDecompile │ │ ├── LuaConditions.cs │ │ ├── LuaDecompile.cs │ │ ├── LuaFunctions.cs │ │ ├── LuaLoops.cs │ │ ├── LuaOperators.cs │ │ ├── LuaRegisters.cs │ │ ├── LuaStrings.cs │ │ └── LuaTables.cs │ ├── LuaDecompiler.csproj │ ├── LuaFile.cs │ ├── LuaOPCodes │ │ ├── LuaConditions.cs │ │ ├── LuaFunctions.cs │ │ ├── LuaLoops.cs │ │ ├── LuaOperators.cs │ │ ├── LuaRegisters.cs │ │ ├── LuaStrings.cs │ │ └── LuaTables.cs │ ├── PackageIndex.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Util │ │ └── IOExtensions.cs │ ├── bin │ │ ├── Debug │ │ │ ├── LuaDecompiler.exe │ │ │ ├── LuaDecompiler.exe.config │ │ │ ├── LuaDecompiler.pdb │ │ │ └── PackageIndex │ │ │ │ ├── bo4_enums.csv │ │ │ │ ├── bo4_enums.wni │ │ │ │ ├── bo4_functions.csv │ │ │ │ ├── bo4_functions.wni │ │ │ │ ├── bo4_localizedstrings.wni │ │ │ │ ├── bo4_materials.csv │ │ │ │ └── bo4_materials.wni │ │ └── Release │ │ │ ├── LZ4.dll │ │ │ ├── LuaDecompiler.exe │ │ │ ├── LuaDecompiler.exe.config │ │ │ └── LuaDecompiler.pdb │ ├── obj │ │ ├── Debug │ │ │ ├── Costura │ │ │ │ ├── 52747D9E753E828D68B3C52748C212865F641B34.costura.costura.dll.compressed │ │ │ │ └── 69D940D640B27E8C29C43802DEBD1C8357CF7D9B.costura.lz4.dll.compressed │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ ├── LuaDecompiler.csproj.CopyComplete │ │ │ ├── LuaDecompiler.csproj.CoreCompileInputs.cache │ │ │ ├── LuaDecompiler.csproj.FileListAbsolute.txt │ │ │ ├── LuaDecompiler.csproj.Fody.CopyLocal.cache │ │ │ ├── LuaDecompiler.csprojAssemblyReference.cache │ │ │ ├── LuaDecompiler.exe │ │ │ ├── LuaDecompiler.pdb │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ └── Release │ │ │ ├── LuaDecompiler.csproj.CopyComplete │ │ │ ├── LuaDecompiler.csproj.CoreCompileInputs.cache │ │ │ ├── LuaDecompiler.csproj.FileListAbsolute.txt │ │ │ ├── LuaDecompiler.exe │ │ │ ├── LuaDecompiler.pdb │ │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ └── packages.config └── packages │ ├── Costura.Fody.3.3.0 │ ├── .signature.p7s │ ├── Costura.Fody.3.3.0.nupkg │ ├── build │ │ └── Costura.Fody.props │ ├── lib │ │ └── net40 │ │ │ ├── Costura.dll │ │ │ └── Costura.xml │ ├── netclassicweaver │ │ ├── Costura.Fody.dll │ │ ├── Costura.Fody.pdb │ │ └── Costura.Fody.xcf │ └── netstandardweaver │ │ ├── Costura.Fody.dll │ │ ├── Costura.Fody.pdb │ │ └── Costura.Fody.xcf │ └── Fody.3.3.5 │ ├── .signature.p7s │ ├── Fody.3.3.5.nupkg │ ├── build │ └── Fody.targets │ ├── netclassictask │ ├── Fody.dll │ ├── FodyCommon.dll │ ├── FodyHelpers.dll │ ├── FodyIsolated.dll │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Mdb.pdb │ ├── Mono.Cecil.Pdb.dll │ ├── Mono.Cecil.Pdb.pdb │ ├── Mono.Cecil.Rocks.dll │ ├── Mono.Cecil.Rocks.pdb │ ├── Mono.Cecil.dll │ └── Mono.Cecil.pdb │ └── netstandardtask │ ├── Fody.dll │ ├── FodyCommon.dll │ ├── FodyHelpers.dll │ ├── FodyIsolated.dll │ ├── Mono.Cecil.Mdb.dll │ ├── Mono.Cecil.Mdb.pdb │ ├── Mono.Cecil.Pdb.dll │ ├── Mono.Cecil.Pdb.pdb │ ├── Mono.Cecil.Rocks.dll │ ├── Mono.Cecil.Rocks.pdb │ ├── Mono.Cecil.dll │ └── Mono.Cecil.pdb └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | LuaDecompiler/.vs/LuaDecompiler/v15/Server/sqlite3/storage.ide 3 | LuaDecompiler/.vs/LuaDecompiler/v15/.suo 4 | LuaDecompiler/.vs/LuaDecompiler/v15/Server/sqlite3/db.lock 5 | LuaDecompiler/.vs/LuaDecompiler/v15/Server/sqlite3/storage.ide-shm 6 | LuaDecompiler/.vs/LuaDecompiler/v15/Server/sqlite3/storage.ide-wal 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jari 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2050 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LuaDecompiler", "LuaDecompiler\LuaDecompiler.csproj", "{72464C94-B88B-40C9-BE51-C183E7D4AAC6}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {72464C94-B88B-40C9-BE51-C183E7D4AAC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {72464C94-B88B-40C9-BE51-C183E7D4AAC6}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {72464C94-B88B-40C9-BE51-C183E7D4AAC6}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {72464C94-B88B-40C9-BE51-C183E7D4AAC6}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {9B6CB41C-5E74-4C6F-8FF0-994097E3382C} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 23 | 24 | 25 | 26 | 27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 28 | 29 | 30 | 31 | 32 | The order of preloaded assemblies, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | 38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 39 | 40 | 41 | 42 | 43 | Controls if .pdbs for reference assemblies are also embedded. 44 | 45 | 46 | 47 | 48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 49 | 50 | 51 | 52 | 53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 54 | 55 | 56 | 57 | 58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 59 | 60 | 61 | 62 | 63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 64 | 65 | 66 | 67 | 68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 69 | 70 | 71 | 72 | 73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 74 | 75 | 76 | 77 | 78 | A list of unmanaged 32 bit assembly names to include, delimited with |. 79 | 80 | 81 | 82 | 83 | A list of unmanaged 64 bit assembly names to include, delimited with |. 84 | 85 | 86 | 87 | 88 | The order of preloaded assemblies, delimited with |. 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 97 | 98 | 99 | 100 | 101 | A comma-separated list of error codes that can be safely ignored in assembly verification. 102 | 103 | 104 | 105 | 106 | 'false' to turn off automatic generation of the XML Schema file. 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaConditions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaConditions 10 | { 11 | private static string orString { get; set; } 12 | private static int codeBlockStart { get; set; } 13 | 14 | public static LuaDecompiler.DecompiledOPCode IfIsTrueFalse(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 15 | { 16 | try 17 | { 18 | if (orString.Length < 1) 19 | { 20 | orString = ""; 21 | codeBlockStart = -1; 22 | } 23 | } 24 | catch 25 | { 26 | 27 | codeBlockStart = -1; 28 | } 29 | string neworstring = orString; 30 | orString = ""; 31 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("if {2}{0}{1} then", 32 | (opCode.C == 1) ? "not " : "", 33 | function.Registers[opCode.A], neworstring), getSkipLines(function, index + 1)); 34 | } 35 | 36 | public static LuaDecompiler.DecompiledOPCode IfIsEqual(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 37 | { 38 | return doCondition(function, index, "==", "~="); 39 | } 40 | 41 | public static LuaDecompiler.DecompiledOPCode Not(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 42 | { 43 | string returnVal = function.getNewReturnVal(); 44 | LuaDecompiler.DecompiledOPCode str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = not {1}", 45 | returnVal, 46 | function.Registers[opCode.B])); 47 | function.Registers[opCode.A] = returnVal; 48 | return str; 49 | } 50 | 51 | public static LuaDecompiler.DecompiledOPCode IfIsEqualBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 52 | { 53 | return doConditionBackward(function, index, "==", "~="); 54 | } 55 | 56 | public static LuaDecompiler.DecompiledOPCode LessThan(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 57 | { 58 | return doCondition(function, index, "<", ">="); 59 | } 60 | 61 | public static LuaDecompiler.DecompiledOPCode LessThanBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 62 | { 63 | return doConditionBackward(function, index, "<", ">="); 64 | } 65 | 66 | public static LuaDecompiler.DecompiledOPCode LessOrEqualThan(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 67 | { 68 | return doCondition(function, index, "<=", ">"); 69 | } 70 | 71 | public static LuaDecompiler.DecompiledOPCode LessOrEqualThanBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 72 | { 73 | return doConditionBackward(function, index, "<=", ">"); 74 | } 75 | 76 | private static LuaDecompiler.DecompiledOPCode doCondition(LuaFile.LuaFunction function, int index, string Oper, string OperFalse) 77 | { 78 | LuaFile.LuaOPCode opCode = function.OPCodes[index]; 79 | try 80 | { 81 | if (orString.Length < 1) 82 | { 83 | orString = ""; 84 | codeBlockStart = -1; 85 | } 86 | } 87 | catch 88 | { 89 | orString = ""; 90 | codeBlockStart = -1; 91 | } 92 | bool conditionToReg = false; 93 | if (function.OPCodes.Count > index + 3) 94 | { 95 | if(function.OPCodes[index + 2].OPCode == 0xD && function.OPCodes[index + 3].OPCode == 0xD) 96 | { 97 | conditionToReg = true; 98 | } 99 | } 100 | /*Console.WriteLine("now: " + index); 101 | Console.WriteLine("next: " + (function.OPCodes[index + getSkipLines(function, index + 1) + 1].OPCode));*/ 102 | //Console.WriteLine("next: " + isConditioOpCode(function.OPCodes[index + getSkipLines(function, index + 1)].OPCode)); 103 | if (isConditioOpCode(function.OPCodes[index + getSkipLines(function, index + 1)].OPCode)) 104 | { 105 | if (orString.Length < 1) 106 | orString = ""; 107 | string cond = "or"; 108 | /*if (index + getSkipLines(function, index + 1) < codeBlockStart) 109 | { 110 | cond = "and"; 111 | opCode.A = (byte)(1 - opCode.A); 112 | } 113 | else 114 | cond = "or";*/ 115 | string old = Oper; 116 | Oper = OperFalse; 117 | OperFalse = old; 118 | if (opCode.C > 255) 119 | orString += String.Format("{0} {2} {1} {3} ", function.Registers[opCode.B], function.Strings[opCode.C - 256].getString(), (opCode.A == 0) ? Oper : OperFalse, cond); 120 | else 121 | orString += String.Format("{0} {2} {1} {3} ", function.Registers[opCode.B], function.Registers[opCode.C], (opCode.A == 0) ? Oper : OperFalse, cond); 122 | 123 | if (codeBlockStart == -1) 124 | codeBlockStart = index + getSkipLines(function, index + 1); 125 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.orCondition, orString); 126 | } 127 | LuaDecompiler.DecompiledOPCode str; 128 | int elseLines = 0; 129 | if (function.OPCodes[index + getSkipLines(function, index + 1) + 1].OPCode == 0x1C) 130 | { 131 | if (!isConditioOpCode(function.OPCodes[index + getSkipLines(function, index + 1) - 2].OPCode)) 132 | { 133 | elseLines = getSkipLines(function, index + getSkipLines(function, index + 1) + 1); 134 | } 135 | } 136 | if (opCode.C > 255) 137 | { 138 | if (conditionToReg) 139 | { 140 | string returnVal = function.getNewReturnVal(); 141 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.conditionToReg, String.Format("local {4} = ({3}{0} {2} {1})", 142 | function.Registers[opCode.B], 143 | function.Strings[opCode.C - 256].getString(), 144 | (opCode.A == 0) ? Oper : OperFalse, orString, returnVal)); 145 | function.Registers[function.OPCodes[index + 2].A] = returnVal; 146 | } 147 | else 148 | { 149 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("if {3}{0} {2} {1} then", 150 | function.Registers[opCode.B], 151 | function.Strings[opCode.C - 256].getString(), 152 | (opCode.A == 0) ? Oper : OperFalse, orString), getSkipLines(function, index + 1), elseLines); 153 | } 154 | } 155 | else 156 | { 157 | if (conditionToReg) 158 | { 159 | string returnVal = function.getNewReturnVal(); 160 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.conditionToReg, String.Format("local {4} = ({3}{0} {2} {1})", 161 | function.Registers[opCode.B], 162 | function.Registers[opCode.C], 163 | (opCode.A == 0) ? Oper : OperFalse, orString, returnVal)); 164 | function.Registers[function.OPCodes[index + 2].A] = returnVal; 165 | } 166 | else 167 | { 168 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("if {3}{0} {2} {1} then", 169 | function.Registers[opCode.B], 170 | function.Registers[opCode.C], 171 | (opCode.A == 0) ? Oper : OperFalse, orString), getSkipLines(function, index + 1), elseLines); 172 | } 173 | } 174 | if (orString.Length > 0) 175 | orString = ""; 176 | codeBlockStart = -1; 177 | return str; 178 | } 179 | 180 | public static bool isConditioOpCode(int opCode) 181 | { 182 | if ((opCode >= 0x38 && opCode <= 0x3B) || opCode == 0x4F || opCode == 0x4 || opCode == 0x5 || opCode == 0x1) 183 | return true; 184 | return false; 185 | } 186 | 187 | private static LuaDecompiler.DecompiledOPCode doConditionBackward(LuaFile.LuaFunction function, int index, string Oper, string OperFalse) 188 | { 189 | LuaFile.LuaOPCode opCode = function.OPCodes[index]; 190 | try 191 | { 192 | if (orString.Length < 1) 193 | { 194 | orString = ""; 195 | codeBlockStart = -1; 196 | } 197 | } 198 | catch 199 | { 200 | orString = ""; 201 | codeBlockStart = -1; 202 | } 203 | bool conditionToReg = false; 204 | if (function.OPCodes.Count > index + 3) 205 | { 206 | if (function.OPCodes[index + 2].OPCode == 0xD && function.OPCodes[index + 3].OPCode == 0xD) 207 | { 208 | Console.WriteLine("conditionToReg"); 209 | conditionToReg = true; 210 | } 211 | } 212 | if (function.OPCodes.Count > index + 3) 213 | { 214 | if(function.OPCodes[index + 2].OPCode == 0xD && function.OPCodes[index + 3].OPCode == 0xD) 215 | { 216 | if(function.OPCodes[index + 2].C == 1) 217 | { 218 | LuaDecompiler.DecompiledOPCode stri; 219 | string returnVal = function.getNewReturnVal(); 220 | if (opCode.C > 255) 221 | { 222 | stri = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{4} = ({3}{0} {2} {1})", 223 | function.Registers[opCode.B], 224 | function.Strings[opCode.C - 256].getString(), 225 | (opCode.A == 0) ? Oper : OperFalse, orString, returnVal)); 226 | } 227 | else 228 | { 229 | stri = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{4} = ({3}{0} {2} {1})", 230 | function.Strings[opCode.B].getString(), 231 | function.Registers[opCode.C], 232 | (opCode.A == 0) ? Oper : OperFalse, orString, returnVal)); 233 | } 234 | function.Registers[function.OPCodes[index + 2].A] = returnVal; 235 | return stri; 236 | } 237 | } 238 | } 239 | /*Console.WriteLine("now: " + index); 240 | Console.WriteLine("now: " + (index + getSkipLines(function, index + 1))); 241 | Console.WriteLine("now: " + function.OPCodes[index + 1].OPCode); 242 | Console.WriteLine("next: " + (function.OPCodes[index + getSkipLines(function, index + 1) + 1].OPCode));*/ 243 | //Console.WriteLine("next: " + isConditioOpCode(function.OPCodes[index + getSkipLines(function, index + 1)].OPCode)); 244 | 245 | if (isConditioOpCode(function.OPCodes[index + getSkipLines(function, index + 1)].OPCode)) 246 | { 247 | if (orString.Length < 1) 248 | orString = ""; 249 | string cond = "or"; 250 | /*if (index + getSkipLines(function, index + 1) < codeBlockStart) 251 | { 252 | cond = "and"; 253 | opCode.A = (byte)(1 - opCode.A); 254 | } 255 | else 256 | cond = "or";*/ 257 | string old = Oper; 258 | Oper = OperFalse; 259 | OperFalse = old; 260 | if (opCode.C > 255) 261 | orString += String.Format("{0} {2} {1} {3} ", function.Registers[opCode.B], function.Strings[opCode.C - 256].getString(), (opCode.A == 0) ? Oper : OperFalse, cond); 262 | else 263 | orString += String.Format("{0} {2} {1} {3} ", function.Strings[opCode.B].getString(), function.Registers[opCode.C], (opCode.A == 0) ? Oper : OperFalse, cond); 264 | if (codeBlockStart == -1) 265 | codeBlockStart = index + getSkipLines(function, index + 1); 266 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.orCondition, orString); 267 | } 268 | if (function.OPCodes[index + getSkipLines(function, index + 1) - 1].OPCode == 0x1C) 269 | { 270 | if (!isConditioOpCode(function.OPCodes[index + getSkipLines(function, index + 1) - 2].OPCode)) 271 | { 272 | 273 | } 274 | } 275 | LuaDecompiler.DecompiledOPCode str; 276 | if (opCode.C > 255) 277 | { 278 | if (conditionToReg) 279 | { 280 | string returnVal = function.getNewReturnVal(); 281 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("local {4} = ({3}{0} {2} {1})", 282 | function.Registers[opCode.B], 283 | function.Strings[opCode.C - 256].getString(), 284 | (opCode.A == 0) ? Oper : OperFalse, orString, returnVal)); 285 | function.Registers[function.OPCodes[index + 2].A] = returnVal; 286 | } 287 | else 288 | { 289 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("if {3}{0} {2} {1} then", 290 | function.Registers[opCode.B], 291 | function.Strings[opCode.C - 256].getString(), 292 | (opCode.A == 0) ? Oper : OperFalse, orString), getSkipLines(function, index + 1)); 293 | } 294 | } 295 | else 296 | { 297 | if (conditionToReg) 298 | { 299 | string returnVal = function.getNewReturnVal(); 300 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("local {4} = ({3}{0} {2} {1})", 301 | function.Strings[opCode.B].getString(), 302 | function.Registers[opCode.C], 303 | (opCode.A == 0) ? Oper : OperFalse, orString, returnVal)); 304 | function.Registers[function.OPCodes[index + 2].A] = returnVal; 305 | } 306 | else 307 | { 308 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.skipLines, String.Format("if {3}{0} {2} {1} then", 309 | function.Strings[opCode.B].getString(), 310 | function.Registers[opCode.C], 311 | (opCode.A == 0) ? Oper : OperFalse, orString), getSkipLines(function, index + 1)); 312 | } 313 | } 314 | if (orString.Length > 0) 315 | orString = ""; 316 | codeBlockStart = -1; 317 | return str; 318 | } 319 | 320 | private static int getSkipLines(LuaFile.LuaFunction function, int index) 321 | { 322 | if (function.OPCodes[index].B == 0) 323 | return function.OPCodes[index].C + 1; 324 | else 325 | return function.OPCodes[index].sBx; 326 | } 327 | 328 | public static LuaDecompiler.DecompiledOPCode SkipLines(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 329 | { 330 | if(index + getSkipLines(function, index) < function.OPCodes.Count) 331 | { 332 | if (function.OPCodes[index + getSkipLines(function, index) + 1].OPCode == 0xE) 333 | { 334 | int startPos = index + getSkipLines(function, index) + 2 + getSkipLines(function, index + getSkipLines(function, index) + 2); 335 | if (index == startPos) 336 | { 337 | int baseVal = function.OPCodes[index + opCode.C + 2].A + 3; 338 | function.Registers[baseVal] = "index" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 339 | function.Registers[baseVal + 1] = "value" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 340 | function.forLoopCount++; 341 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.forEach, String.Format("for {0},{1} in {2}, {3}, {4} do", 342 | function.Registers[baseVal], function.Registers[baseVal + 1], function.Registers[baseVal - 3], function.Registers[baseVal - 2] 343 | , function.Registers[baseVal - 1]), getSkipLines(function, index)); 344 | } 345 | } 346 | } 347 | if(index + getSkipLines(function, index) < function.OPCodes.Count) 348 | { 349 | if (function.OPCodes[index + getSkipLines(function, index)].OPCode == 0x1C) 350 | { 351 | if(isConditioOpCode(function.OPCodes[index - 1].OPCode) && !isConditioOpCode(function.OPCodes[index + getSkipLines(function, index) - 1].OPCode)) 352 | { 353 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.Else, "", getSkipLines(function, index), getSkipLines(function, index + getSkipLines(function, index))); 354 | } 355 | } 356 | } 357 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.empty, ""); 358 | } 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaDecompile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.IO; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaDecompiler 10 | { 11 | private StreamWriter outputWriter { get; set; } 12 | private LuaFile luaFile { get; set; } 13 | 14 | public LuaDecompiler(LuaFile luaFile) 15 | { 16 | this.luaFile = luaFile; 17 | } 18 | 19 | public enum opCodeType { String, skipLines, FunctionClosure, empty, orCondition, forEach, Else, conditionToReg } 20 | 21 | public class DecompiledOPCode 22 | { 23 | public opCodeType opcodeType { get; set; } 24 | public string OpString { get; set; } 25 | public int skipLines { get; set; } 26 | public int elseLines { get; set; } 27 | public DecompiledOPCode(opCodeType type, string str) 28 | { 29 | this.opcodeType = type; 30 | this.OpString = str; 31 | } 32 | public DecompiledOPCode(opCodeType type, string str, int skipLines) 33 | { 34 | this.opcodeType = type; 35 | this.OpString = str; 36 | this.skipLines = skipLines; 37 | } 38 | public DecompiledOPCode(opCodeType type, string str, int skipLines, int elseLines) 39 | { 40 | this.opcodeType = type; 41 | this.OpString = str; 42 | this.skipLines = skipLines; 43 | this.elseLines = elseLines; 44 | } 45 | } 46 | 47 | public void Decompile(string outputFile) 48 | { 49 | // Check if we found a better name (Bo4 hashes) 50 | if (luaFile.fakeName != "") 51 | //outputFile = Path.GetDirectoryName(outputFile) + "\\export/" + luaFile.fakeName + ".lua"; 52 | outputFile = Path.GetDirectoryName(outputFile) + luaFile.fakeName + ".lua"; 53 | //else 54 | //outputFile = Path.GetDirectoryName(outputFile) + "\\export/" + Path.GetFileNameWithoutExtension(outputFile) + ".lua"; 55 | // Make a new StreamWriter 56 | this.outputWriter = new StreamWriter(outputFile + "dc"); 57 | outputWriter.WriteLine("-- Decompiled by LuaDecompiler by JariK\n"); 58 | 59 | foreach(LuaFile.LuaFunction function in luaFile.Functions) 60 | { 61 | resetValues(function); 62 | } 63 | // Start the decompile with the init function 64 | functionDecompile(luaFile.Functions[0], 0, true); 65 | // Close the StreamWriter so it saves 66 | outputWriter.Close(); 67 | } 68 | 69 | private void resetValues(LuaFile.LuaFunction function) 70 | { 71 | function.returnValCount = 0; 72 | function.tableCount = 0; 73 | function.forLoopCount = 0; 74 | } 75 | 76 | private void functionDecompile(LuaFile.LuaFunction function, int functionLevel, bool skipHeader = false) 77 | { 78 | // Check if we need to write the name of the function ( not with init ) 79 | if (!skipHeader) 80 | { 81 | writeWithTabs(functionLevel - 1, ""); 82 | // Check if we have a local function or global 83 | string funcName = function.getName(true).Substring(0, 4); 84 | if (funcName != "LUI." && funcName.Substring(0, 4) != "CoD.") 85 | outputWriter.Write("local "); 86 | // Write the function name 87 | outputWriter.Write("function " + function.getName(true) + "("); 88 | // Add all the arguments 89 | int index = 0, jj = 0; 90 | while(index < function.parameterCount) 91 | { 92 | if(function.UpvalsStrings.Contains("arg" + jj)) 93 | { 94 | jj++; 95 | continue; 96 | } 97 | function.Registers[index] = "arg" + jj; 98 | outputWriter.Write(((index > 0) ? ", " : "") + "arg" + jj++); 99 | index++; 100 | } 101 | if (function.usesVarArg) 102 | { 103 | if (function.parameterCount > 0) 104 | outputWriter.Write(", "); 105 | outputWriter.Write("..."); 106 | } 107 | outputWriter.Write(")\n"); 108 | } 109 | 110 | List ifLevels = new List(); 111 | List elseLevels = new List(); 112 | for (int i = 0; i < function.OPCodes.Count; i++) 113 | { 114 | DecompiledOPCode opcode = decompileOPCode(function, i, functionLevel); 115 | int skipLineAfter = 0; 116 | if (opcode.opcodeType == opCodeType.String) 117 | { 118 | writeWithTabs(functionLevel + ifLevels.Count, opcode.OpString + "\n"); 119 | } 120 | else if(opcode.opcodeType == opCodeType.FunctionClosure && function.getName() != "__INIT__" && function.lastFunctionClosure > -1) 121 | { 122 | functionDecompile(function.subFunctions[function.lastFunctionClosure], functionLevel + 1); 123 | } 124 | else if(opcode.opcodeType == opCodeType.skipLines || opcode.opcodeType == opCodeType.forEach) 125 | { 126 | writeWithTabs(functionLevel + ifLevels.Count, opcode.OpString + "\n"); 127 | ifLevels.Add(opcode.skipLines + 2); 128 | } 129 | else if(opcode.opcodeType == opCodeType.Else) 130 | { 131 | if(ifLevels.Count > 0) 132 | ifLevels.RemoveAt(ifLevels.Count - 1); 133 | ifLevels.Add(opcode.skipLines + 1 + opcode.elseLines); 134 | elseLevels.Add(opcode.skipLines); 135 | } 136 | else if(opcode.opcodeType == opCodeType.conditionToReg) 137 | { 138 | writeWithTabs(functionLevel + ifLevels.Count, opcode.OpString + "\n"); 139 | skipLineAfter += 3; 140 | } 141 | 142 | for(int k = 0; k < skipLineAfter + 1; k++) 143 | { 144 | if (k > 0) 145 | i++; 146 | for (int j = 0; j < ifLevels.Count; j++) 147 | { 148 | ifLevels[j]--; 149 | if (ifLevels[j] <= 0) 150 | { 151 | ifLevels.RemoveAt(j); 152 | writeWithTabs(functionLevel + ifLevels.Count, "end\n"); 153 | } 154 | } 155 | for (int j = 0; j < elseLevels.Count; j++) 156 | { 157 | elseLevels[j]--; 158 | if (elseLevels[j] <= 0) 159 | { 160 | elseLevels.RemoveAt(j); 161 | writeWithTabs(functionLevel + ifLevels.Count - 1, "else\n"); 162 | } 163 | } 164 | } 165 | } 166 | 167 | // Add the end of the function (not init) 168 | if (!skipHeader) 169 | { 170 | writeWithTabs(functionLevel - 1, "end\n"); 171 | } 172 | outputWriter.Write("\n"); 173 | 174 | // Print the other functions that are part of init 175 | if (function.getName() == "__INIT__") 176 | { 177 | for (int i = 0; i < function.subFunctions.Count; i++) 178 | { 179 | functionDecompile(function.subFunctions[i], functionLevel + 1); 180 | } 181 | } 182 | } 183 | 184 | public void doFunctionClosure(LuaFile.LuaFunction function, int functionLevel) 185 | { 186 | functionDecompile(function.subFunctions[function.lastFunctionClosure], functionLevel + 1); 187 | } 188 | 189 | private DecompiledOPCode decompileOPCode(LuaFile.LuaFunction function, int index, int functionLevel) 190 | { 191 | DecompiledOPCode DecompileString = new DecompiledOPCode(opCodeType.empty, ""); 192 | LuaFile.LuaOPCode opCode = function.OPCodes[index]; 193 | try 194 | { 195 | switch (opCode.OPCode) 196 | { 197 | case 0x0: LuaDecompile.LuaStrings.ConnectWithDot(function, opCode); break; 198 | case 0x1: DecompileString = LuaDecompile.LuaConditions.IfIsTrueFalse(function, opCode, index); break; 199 | case 0x2: case 0x4C: DecompileString = LuaDecompile.LuaFunctions.CallFunctionWithParameters(function, opCode, index); break; 200 | case 0x16: DecompileString = LuaDecompile.LuaFunctions.CallFunctionWithParameters(function, opCode, index, true); break; 201 | case 0x4: DecompileString = LuaDecompile.LuaConditions.IfIsEqual(function, opCode, index); break; 202 | case 0x5: DecompileString = LuaDecompile.LuaConditions.IfIsEqualBackwards(function, opCode, index); break; 203 | case 0x6: LuaDecompile.LuaRegisters.GlobalRegisterToRegister(function, opCode); break; 204 | case 0x7: LuaDecompile.LuaRegisters.RegisterToRegister(function, opCode); break; 205 | case 0x8: LuaDecompile.LuaStrings.ConnectWithColon(function, opCode); break; 206 | case 0x9: DecompileString = LuaDecompile.LuaOperators.Return(function, opCode, index); break; 207 | case 0xA: LuaDecompile.LuaTables.GetIndex(function, opCode); break; 208 | case 0xD: LuaDecompile.LuaRegisters.BooleanToRegister(function, opCode, index); break; 209 | //case 0xE: Console.WriteLine("Foreach"); break; 210 | case 0xF: DecompileString = LuaDecompile.LuaStrings.SetField(function, opCode, index); break; 211 | case 0x10: DecompileString = LuaDecompile.LuaTables.SetTable(function, opCode); break; 212 | case 0x11: DecompileString = LuaDecompile.LuaTables.SetTableBackwards(function, opCode); break; 213 | case 0x19: LuaDecompile.LuaRegisters.LocalConstantToRegister(function, opCode); break; 214 | case 0x1A: LuaDecompile.LuaRegisters.NilToRegister(function, opCode); break; 215 | case 0x1B: DecompileString = LuaDecompile.LuaRegisters.RegisterToGlobal(function, opCode); break; 216 | case 0x1C: DecompileString = LuaDecompile.LuaConditions.SkipLines(function, opCode, index); break; 217 | case 0x26: LuaDecompile.LuaFunctions.GetUpValue(function, opCode); break; 218 | case 0x27: DecompileString = LuaDecompile.LuaOperators.SetupVal(function, opCode); break; 219 | case 0x28: DecompileString = LuaDecompile.LuaOperators.Add(function, opCode); break; 220 | case 0x29: DecompileString = LuaDecompile.LuaOperators.AddBackWards(function, opCode); break; 221 | case 0x2A: DecompileString = LuaDecompile.LuaOperators.Subtract(function, opCode); break; 222 | case 0x2B: DecompileString = LuaDecompile.LuaOperators.SubtractBackWards(function, opCode); break; 223 | case 0x2C: DecompileString = LuaDecompile.LuaOperators.Multiply(function, opCode); break; 224 | case 0x2D: DecompileString = LuaDecompile.LuaOperators.MultiplyBackWards(function, opCode); break; 225 | case 0x2E: DecompileString = LuaDecompile.LuaOperators.Divide(function, opCode); break; 226 | case 0x2F: DecompileString = LuaDecompile.LuaOperators.DivideBackWards(function, opCode); break; 227 | case 0x30: DecompileString = LuaDecompile.LuaOperators.Modulo(function, opCode); break; 228 | case 0x31: DecompileString = LuaDecompile.LuaOperators.ModuloBackWards(function, opCode); break; 229 | case 0x32: DecompileString = LuaDecompile.LuaOperators.Power(function, opCode); break; 230 | case 0x33: DecompileString = LuaDecompile.LuaOperators.PowerBackWards(function, opCode); break; 231 | case 0x34: DecompileString = LuaDecompile.LuaTables.EmptyTable(function, opCode); break; 232 | case 0x35: LuaDecompile.LuaOperators.UnaryMinus(function, opCode); break; 233 | case 0x36: DecompileString = LuaDecompile.LuaConditions.Not(function, opCode); break; 234 | case 0x37: LuaDecompile.LuaOperators.Length(function, opCode); break; 235 | case 0x38: DecompileString = LuaDecompile.LuaConditions.LessThan(function, opCode, index); break; 236 | case 0x39: DecompileString = LuaDecompile.LuaConditions.LessThanBackwards(function, opCode, index); break; 237 | case 0x3A: DecompileString = LuaDecompile.LuaConditions.LessOrEqualThan(function, opCode, index); break; 238 | case 0x3B: DecompileString = LuaDecompile.LuaConditions.LessOrEqualThanBackwards(function, opCode, index); break; 239 | case 0x3C: DecompileString = LuaDecompile.LuaOperators.ShiftLeft(function, opCode); break; 240 | case 0x3D: DecompileString = LuaDecompile.LuaOperators.ShiftLeftBackwards(function, opCode); break; 241 | case 0x40: DecompileString = LuaDecompile.LuaOperators.BinaryAnd(function, opCode); break; 242 | case 0x42: DecompileString = LuaDecompile.LuaOperators.BinaryOr(function, opCode); break; 243 | case 0x44: LuaDecompile.LuaStrings.ConnectWithDoubleDot(function, opCode); break; 244 | case 0x45: DecompileString = LuaDecompile.LuaOperators.TestSet(function, opCode); break; 245 | case 0x46: DecompileString = LuaDecompile.LuaLoops.StartForLoop(function, opCode); break; 246 | case 0x48: DecompileString = LuaDecompile.LuaTables.SetList(function, opCode); break; 247 | case 0x49: LuaDecompile.LuaOperators.Close(function, opCode); break; 248 | case 0x4A: LuaDecompile.LuaFunctions.Closure(function, opCode, index, functionLevel, this); break; 249 | case 0x4B: LuaDecompile.LuaOperators.VarArg(function, opCode); break; 250 | case 0x4D: DecompileString = LuaDecompile.LuaFunctions.CallFunctionWithoutParameters(function, opCode, index); break; 251 | case 0x4F: DecompileString = LuaDecompile.LuaConditions.IfIsTrueFalse(function, opCode, index); break; 252 | case 0x50: DecompileString = LuaDecompile.LuaOperators.NotR1(function, opCode); break; 253 | case 0x51: LuaDecompile.LuaStrings.ConnectWithDot(function, opCode); break; 254 | case 0x52: DecompileString = LuaDecompile.LuaStrings.SetField(function, opCode, index); break; 255 | case 0x54: 256 | if (function.doingUpvals >= 0) 257 | { 258 | if (opCode.A == 1) 259 | { 260 | function.DisassembleStrings.Add(String.Format("r({0}).upval({1}) = r({2}) // {3}", 261 | function.doingUpvals, 262 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Count, 263 | opCode.C, 264 | function.Registers[opCode.C])); 265 | } 266 | else if (opCode.A == 2) 267 | { 268 | function.DisassembleStrings.Add(String.Format("r({0}).upval({1}) = upval({2}) // {3}", 269 | function.doingUpvals, 270 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Count, 271 | opCode.C, 272 | function.UpvalsStrings[opCode.C])); 273 | } 274 | else 275 | { 276 | Console.WriteLine("Trying to get to do upvalue on level " + opCode.A); 277 | } 278 | } 279 | else 280 | { 281 | function.DisassembleStrings.Add(String.Format("data({0}, {1}, {2}, {3})", 282 | opCode.A, 283 | opCode.C, 284 | opCode.B, 285 | opCode.OPCode)); 286 | } 287 | break; 288 | } 289 | if (opCode.OPCode == 0xF && function.getName() == "__INIT__") 290 | { 291 | if (luaFile.game == LuaFile.Game.BlackOps4 && function.Registers[opCode.A].Length > 3) 292 | { 293 | if ((function.Registers[opCode.A].Substring(0, 4) == "CoD." || function.Registers[opCode.A].Substring(0, 4) == "LUI.") && 294 | function.Strings[opCode.B].String == "new") 295 | { 296 | luaFile.fakeName = function.Registers[opCode.A].Substring(4); 297 | } 298 | } 299 | } 300 | if (function.doingUpvals >= 0) 301 | { 302 | if (opCode.OPCode != 0x4A) 303 | { 304 | if (opCode.OPCode == 0x54) 305 | { 306 | if (opCode.A == 1) 307 | { 308 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Add(function.Registers[opCode.C]); 309 | } 310 | else if (opCode.A == 2) 311 | { 312 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Add(function.UpvalsStrings[opCode.C]); 313 | } 314 | if(function.OPCodes[index + 1].OPCode != 0x54 && function.getName() != "__INIT__") 315 | doFunctionClosure(function, functionLevel); 316 | } 317 | else 318 | { 319 | function.doingUpvals = -1; 320 | } 321 | } 322 | } 323 | } 324 | catch 325 | { 326 | Console.WriteLine("Error occured while disassembling A: {3}, B: {4}, C: {5} OPcode: {0:X} at line {1} in function {2}", opCode.OPCode, index, function.getName(), opCode.A, opCode.B, opCode.C); 327 | } 328 | return DecompileString; 329 | } 330 | 331 | private void writeWithTabs(int index, string text) 332 | { 333 | string str = ""; 334 | for (int i = 0; i < index; i++) 335 | str += "\t"; 336 | outputWriter.Write(str + text); 337 | } 338 | } 339 | } 340 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaFunctions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaFunctions 10 | { 11 | public static void Closure(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index, int functionLevel, LuaDecompiler luaDecomp) 12 | { 13 | function.Registers[opCode.A] = String.Format("__FUNC_{0:X}_", function.subFunctions[opCode.Bx].beginPosition); 14 | function.doingUpvals = opCode.A; 15 | function.lastFunctionClosure = opCode.Bx; 16 | if (function.OPCodes[index + 1].OPCode != 0x54 && function.getName() != "__INIT__") 17 | luaDecomp.doFunctionClosure(function, functionLevel); 18 | } 19 | 20 | public static void GetUpValue(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 21 | { 22 | function.Registers[opCode.A] = function.UpvalsStrings[opCode.B]; 23 | } 24 | 25 | public static LuaDecompiler.DecompiledOPCode CallFunctionWithParameters(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index, bool tailCall = false) 26 | { 27 | string funcName = function.Registers[opCode.A]; 28 | int parameterCount = opCode.B - 1; 29 | int returnValues = opCode.C - 1; 30 | if (returnValues < 0) 31 | { 32 | returnValues = 0; 33 | tailCall = true; 34 | } 35 | 36 | string parameterRegisters = ""; 37 | string parametersString = ""; 38 | if (parameterCount > 0) 39 | { 40 | parameterRegisters += opCode.A + 1; 41 | for (int j = opCode.A + 2; j <= opCode.A + parameterCount; j++) 42 | { 43 | parameterRegisters += ", " + j; 44 | } 45 | if (funcName.Contains(":") && opCode.A + 2 <= opCode.A + parameterCount) 46 | { 47 | parametersString += function.Registers[opCode.A + 2]; 48 | for (int j = opCode.A + 3; j <= opCode.A + parameterCount; j++) 49 | { 50 | parametersString += ", " + function.Registers[j]; 51 | } 52 | } 53 | else 54 | { 55 | parametersString += function.Registers[opCode.A + 1]; 56 | for (int j = opCode.A + 2; j <= opCode.A + parameterCount; j++) 57 | { 58 | parametersString += ", " + function.Registers[j]; 59 | } 60 | } 61 | } 62 | else if (parameterCount != 0) 63 | { 64 | parameterRegisters += opCode.A + 1; 65 | for (int j = opCode.A + 2; j <= function.OPCodes[index - 1].A; j++) 66 | { 67 | parameterRegisters += ", " + j; 68 | } 69 | 70 | int startpoint = 2; 71 | parametersString = function.Registers[opCode.A + 1]; 72 | if (funcName.Contains(":")) 73 | { 74 | parametersString = function.Registers[opCode.A + 2]; 75 | startpoint = 3; 76 | } 77 | for (int j = opCode.A + startpoint; j <= function.OPCodes[index - 1].A; j++) 78 | { 79 | parametersString += ", " + function.Registers[j]; 80 | } 81 | } 82 | if (returnValues > 0) 83 | { 84 | function.Registers[opCode.A] = funcName + "(" + parametersString + ")"; 85 | string returnRegisters = opCode.A.ToString(); 86 | string returnVal = function.getNewReturnVal(); 87 | string returnStrings = returnVal; 88 | function.Registers[opCode.A] = returnVal; 89 | if (returnValues > 1) 90 | { 91 | for (int j = opCode.A + 1; j < opCode.A + returnValues; j++) 92 | { 93 | returnRegisters += ", " + j.ToString(); 94 | returnVal = function.getNewReturnVal(); 95 | returnStrings += ", " + returnVal; 96 | function.Registers[j] = returnVal; 97 | } 98 | } 99 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = {1}({2})", 100 | returnStrings, 101 | funcName, 102 | parametersString)); 103 | } 104 | else 105 | { 106 | function.Registers[opCode.A] = funcName + "(" + parametersString + ")"; 107 | if(function.OPCodes[index + 1].OPCode == 0x2 || function.OPCodes[index + 1].OPCode == 0x4C || function.OPCodes[index + 1].OPCode == 0x16) 108 | { 109 | if(function.OPCodes[index + 1].B == 0) 110 | { 111 | 112 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.empty, ""); 113 | } 114 | } 115 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0}{1}({2})", 116 | (tailCall) ? "return " : "", 117 | funcName, 118 | parametersString)); 119 | } 120 | } 121 | 122 | public static LuaDecompiler.DecompiledOPCode CallFunctionWithoutParameters(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 123 | { 124 | if (opCode.C > 1) 125 | { 126 | string returnRegisters = opCode.A.ToString(); 127 | int oldStartCount = function.returnValCount; 128 | string returnStrings = function.getNewReturnVal(); 129 | if (opCode.C > 2) 130 | { 131 | for (int j = opCode.A + 1; j < opCode.A + opCode.C - 1; j++) 132 | { 133 | returnRegisters += ", " + j.ToString(); 134 | string returnVal = function.getNewReturnVal(); 135 | returnStrings += ", " + returnVal; 136 | //function.Registers[j] = returnVal; 137 | } 138 | } 139 | LuaDecompiler.DecompiledOPCode str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = {1}()", 140 | returnStrings, 141 | function.Registers[opCode.A])); 142 | function.returnValCount = oldStartCount; 143 | function.Registers[opCode.A] = function.getNewReturnVal(); 144 | if (opCode.C > 2) 145 | { 146 | for (int j = opCode.A + 1; j < opCode.A + opCode.C - 1; j++) 147 | { 148 | function.Registers[j] = function.getNewReturnVal(); 149 | } 150 | } 151 | return str; 152 | } 153 | else 154 | { 155 | if (function.OPCodes[index + 1].OPCode == 0x2 || function.OPCodes[index + 1].OPCode == 0x4C || function.OPCodes[index + 1].OPCode == 0x16) 156 | { 157 | if (function.OPCodes[index + 1].B == 0) 158 | { 159 | function.Registers[opCode.A] = String.Format("{0}()", function.Registers[opCode.A]); 160 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.empty, ""); 161 | } 162 | } 163 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0}()", 164 | function.Registers[opCode.A])); 165 | } 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaLoops.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaLoops 10 | { 11 | public static LuaDecompiler.DecompiledOPCode StartForLoop(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | function.Registers[opCode.A + 3] = "index" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 14 | function.forLoopCount++; 15 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.forEach, String.Format("for {3}={0}, {1}, {2} do", 16 | function.Registers[opCode.A], 17 | function.Registers[opCode.A + 1], 18 | function.Registers[opCode.A + 2], 19 | function.Registers[opCode.A + 3]), opCode.C + 2); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaOperators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaOperators 10 | { 11 | public static LuaDecompiler.DecompiledOPCode Return(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 12 | { 13 | if (index > 0) 14 | { 15 | if (function.OPCodes[index - 1].OPCode == 0x16) 16 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.empty, ""); 17 | } 18 | if (opCode.B > 1) 19 | { 20 | string registers = opCode.A.ToString(); 21 | string returns = function.Registers[opCode.A]; 22 | for (int i = opCode.A + 1; i <= opCode.A + opCode.B - 2; i++) 23 | { 24 | registers += ", " + i; 25 | returns += ", " + function.Registers[i]; 26 | } 27 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, "return " + returns); 28 | } 29 | else 30 | { 31 | if (index < function.OPCodes.Count - 1) 32 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, "return"); 33 | } 34 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.empty, ""); 35 | } 36 | 37 | public static void Length(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 38 | { 39 | function.Registers[opCode.A] = "#" + function.Registers[opCode.B]; 40 | } 41 | 42 | public static LuaDecompiler.DecompiledOPCode Add(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 43 | { 44 | return DoOperator(function, opCode, "+"); 45 | } 46 | 47 | public static LuaDecompiler.DecompiledOPCode AddBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 48 | { 49 | return DoOperatorBackWards(function, opCode, "+"); 50 | } 51 | 52 | public static LuaDecompiler.DecompiledOPCode Subtract(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 53 | { 54 | return DoOperator(function, opCode, "-"); 55 | } 56 | 57 | public static LuaDecompiler.DecompiledOPCode SubtractBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 58 | { 59 | return DoOperatorBackWards(function, opCode, "-"); 60 | } 61 | 62 | public static LuaDecompiler.DecompiledOPCode Multiply(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 63 | { 64 | return DoOperator(function, opCode, "*"); 65 | } 66 | 67 | public static LuaDecompiler.DecompiledOPCode MultiplyBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 68 | { 69 | return DoOperatorBackWards(function, opCode, "*"); 70 | } 71 | 72 | public static LuaDecompiler.DecompiledOPCode Divide(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 73 | { 74 | return DoOperator(function, opCode, "/"); 75 | } 76 | 77 | public static LuaDecompiler.DecompiledOPCode DivideBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 78 | { 79 | return DoOperatorBackWards(function, opCode, "/"); 80 | } 81 | 82 | public static LuaDecompiler.DecompiledOPCode Modulo(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 83 | { 84 | return DoOperator(function, opCode, "%"); 85 | } 86 | 87 | public static LuaDecompiler.DecompiledOPCode ModuloBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 88 | { 89 | return DoOperatorBackWards(function, opCode, "%"); 90 | } 91 | 92 | public static LuaDecompiler.DecompiledOPCode Power(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 93 | { 94 | return DoOperator(function, opCode, "^"); 95 | } 96 | 97 | public static LuaDecompiler.DecompiledOPCode PowerBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 98 | { 99 | return DoOperatorBackWards(function, opCode, "^"); 100 | } 101 | 102 | public static LuaDecompiler.DecompiledOPCode DoOperator(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, string Operator) 103 | { 104 | LuaDecompiler.DecompiledOPCode str; 105 | string returnVal = function.getNewReturnVal(); 106 | if (opCode.C > 255) 107 | { 108 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = {1} {2} {3}", 109 | returnVal, 110 | function.Strings[opCode.C - 256].String, 111 | Operator, 112 | function.Registers[opCode.B])); 113 | } 114 | else 115 | { 116 | str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = {1} {2} {3}", 117 | returnVal, 118 | function.Registers[opCode.C], 119 | Operator, 120 | function.Registers[opCode.B])); 121 | } 122 | 123 | function.Registers[opCode.A] = returnVal; 124 | return str; 125 | } 126 | 127 | public static LuaDecompiler.DecompiledOPCode DoOperatorBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, string Operator) 128 | { 129 | string returnVal = function.getNewReturnVal(); 130 | LuaDecompiler.DecompiledOPCode str = new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = {1} {2} {3}", 131 | returnVal, 132 | function.Strings[opCode.B].String, 133 | Operator, 134 | function.Registers[opCode.C])); 135 | function.Registers[opCode.A] = returnVal; 136 | return str; 137 | } 138 | 139 | public static void UnaryMinus(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 140 | { 141 | function.Registers[opCode.A] = "-" + function.Registers[opCode.B]; 142 | } 143 | 144 | public static LuaDecompiler.DecompiledOPCode ShiftLeft(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 145 | { 146 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String,"-- Unhandled OP: (OPCODE_LEFT_SHIFT)"); 147 | } 148 | 149 | public static LuaDecompiler.DecompiledOPCode ShiftLeftBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 150 | { 151 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String,"-- Unhandled OP: (OPCODE_LEFT_SHIFT_BK)"); 152 | } 153 | 154 | public static LuaDecompiler.DecompiledOPCode BinaryAnd(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 155 | { 156 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String,"-- Unhandled OP: (OPCODE_BIT_AND)"); 157 | } 158 | 159 | public static LuaDecompiler.DecompiledOPCode BinaryOr(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 160 | { 161 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String,"-- Unhandled OP: (OPCODE_BIT_OR)"); 162 | } 163 | 164 | public static LuaDecompiler.DecompiledOPCode TestSet(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 165 | { 166 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String,"-- Unhandled OP: (OPCODE_TESTSET)"); 167 | } 168 | 169 | public static void Close(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 170 | { 171 | function.Registers[opCode.A] = ""; 172 | } 173 | 174 | public static void VarArg(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 175 | { 176 | 177 | function.Registers[opCode.A] = "..."; 178 | } 179 | 180 | public static LuaDecompiler.DecompiledOPCode NotR1(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 181 | { 182 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String,"-- Unhandled OP: (OPCODE_NOT_R1)"); 183 | } 184 | 185 | public static LuaDecompiler.DecompiledOPCode SetupVal(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 186 | { 187 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, "-- Unhandled OP: (OPCODE_SETUPVAL)"); 188 | } 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaRegisters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaRegisters 10 | { 11 | public static void RegisterToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | function.Registers[opCode.A] = function.Registers[opCode.B]; 14 | } 15 | 16 | public static void GlobalRegisterToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 17 | { 18 | function.Registers[opCode.A] = function.Strings[opCode.Bx].String; 19 | } 20 | 21 | public static LuaDecompiler.DecompiledOPCode RegisterToGlobal(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 22 | { 23 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0} = {1}", 24 | function.Strings[opCode.Bx].String, 25 | function.Registers[opCode.A])); 26 | } 27 | 28 | public static void BooleanToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 29 | { 30 | if(index > 2) 31 | { 32 | if(LuaConditions.isConditioOpCode(function.OPCodes[index - 2].OPCode)) 33 | { 34 | if(function.OPCodes[index].C == 1) 35 | { 36 | return; 37 | } 38 | } 39 | else if (LuaConditions.isConditioOpCode(function.OPCodes[index - 3].OPCode)) 40 | { 41 | if (function.OPCodes[index - 1].C == 1) 42 | { 43 | return; 44 | } 45 | } 46 | } 47 | if (opCode.B == 0) 48 | function.Registers[opCode.A] = "false"; 49 | else 50 | function.Registers[opCode.A] = "true"; 51 | } 52 | 53 | public static void NilToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 54 | { 55 | for (int i = opCode.A; i <= (opCode.B); i++) 56 | { 57 | function.Registers[i] = "nil"; 58 | } 59 | } 60 | 61 | public static void LocalConstantToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 62 | { 63 | function.Registers[opCode.A] = function.Strings[opCode.Bx].getString(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaStrings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaStrings 10 | { 11 | public static void ConnectWithDot(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | function.Registers[opCode.A] = function.Registers[opCode.B] + "." + function.Strings[opCode.C].String; 14 | } 15 | 16 | public static LuaDecompiler.DecompiledOPCode SetField(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index, bool isString = false) 17 | { 18 | if (opCode.C > 255) 19 | { 20 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, (String.Format("{0}.{1} = {2}", 21 | function.Registers[opCode.A], 22 | function.Strings[opCode.B].String, 23 | function.Strings[opCode.C - 256].getString()))); 24 | } 25 | else 26 | { 27 | if (function.Registers[opCode.C].Contains("__FUNC") 28 | && (function.OPCodes[index - 1].OPCode == 0x4A || function.OPCodes[index - 1].OPCode == 0x54) 29 | && (function.Registers[opCode.A].Substring(0, 3) == "CoD" || function.Registers[opCode.A].Substring(0, 3) == "LUI")) 30 | { 31 | for (int i = index; i > 0; i--) 32 | { 33 | if (function.OPCodes[i].OPCode == 0x4A) 34 | { 35 | function.subFunctions[function.OPCodes[i].Bx].functionName = function.Registers[opCode.A] + "." + function.Strings[opCode.B].String; 36 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.empty, ""); 37 | } 38 | } 39 | } 40 | else 41 | { 42 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, (String.Format("{0}.{1} = {2}", 43 | function.Registers[opCode.A], 44 | function.Strings[opCode.B].String, 45 | function.Registers[opCode.C]))); 46 | } 47 | 48 | } 49 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, "idk"); 50 | } 51 | 52 | public static void ConnectWithDoubleDot(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 53 | { 54 | string output = "(" + function.Registers[opCode.B]; 55 | for (int i = opCode.B + 1; i <= opCode.C; i++) 56 | { 57 | output += " .. " + function.Registers[i]; 58 | } 59 | output += ")"; 60 | function.Registers[opCode.A] = output; 61 | } 62 | 63 | public static void ConnectWithColon(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 64 | { 65 | if (opCode.C > 255) 66 | { 67 | function.Registers[opCode.A] = function.Registers[opCode.B] + ":" + function.Strings[opCode.C - 256].String; 68 | } 69 | else 70 | { 71 | function.Registers[opCode.A] = function.Registers[opCode.B] + ":" + function.Registers[opCode.C]; 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompile/LuaTables.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler.LuaDecompile 8 | { 9 | class LuaTables 10 | { 11 | public static void GetIndex(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | if (opCode.C > 255) 14 | { 15 | function.Registers[opCode.A] = function.Registers[opCode.B] + "[" + function.Strings[opCode.C - 256].String + "]"; 16 | } 17 | else 18 | { 19 | function.Registers[opCode.A] = function.Registers[opCode.B] + "[" + function.Registers[opCode.C] + "]"; 20 | } 21 | } 22 | 23 | public static LuaDecompiler.DecompiledOPCode SetTable(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 24 | { 25 | if (opCode.C > 255) 26 | { 27 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0}[{1}] = {2}", 28 | function.Registers[opCode.A], 29 | function.Registers[opCode.B], 30 | function.Strings[opCode.C - 256].getString())); 31 | } 32 | else 33 | { 34 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0}[{1}] = {2}", 35 | function.Registers[opCode.A], 36 | function.Registers[opCode.B], 37 | function.Registers[opCode.C])); 38 | } 39 | } 40 | 41 | public static LuaDecompiler.DecompiledOPCode SetTableBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 42 | { 43 | if (opCode.C > 255) 44 | { 45 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0}[{1}] = {2}", 46 | function.Registers[opCode.A], 47 | function.Strings[opCode.B].getString(), 48 | function.Strings[opCode.C - 256].getString())); 49 | } 50 | else 51 | { 52 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0}[{1}] = {2}", 53 | function.Registers[opCode.A], 54 | function.Strings[opCode.B].getString(), 55 | function.Registers[opCode.C])); 56 | } 57 | } 58 | 59 | public static LuaDecompiler.DecompiledOPCode EmptyTable(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 60 | { 61 | while(function.UpvalsStrings.Contains("table" + function.tableCount)) 62 | { 63 | function.tableCount++; 64 | } 65 | function.Registers[opCode.A] = "table" + function.tableCount++; 66 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("local {0} = {1}", 67 | function.Registers[opCode.A], "{}")); 68 | } 69 | 70 | public static LuaDecompiler.DecompiledOPCode SetList(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 71 | { 72 | string tableString = "{"; 73 | string tableRegisters = ""; 74 | if (opCode.B > 0) 75 | { 76 | tableString += function.Registers[opCode.A + 1]; 77 | tableRegisters += opCode.A + 1; 78 | if (opCode.B > 1) 79 | { 80 | for (int j = opCode.A + 2; j <= opCode.A + opCode.B; j++) 81 | { 82 | tableString += ", " + function.Registers[j]; 83 | tableRegisters += ", " + j; 84 | } 85 | } 86 | } 87 | tableString += "}"; 88 | function.Registers[opCode.A] = function.Registers[opCode.A]; 89 | return new LuaDecompiler.DecompiledOPCode(LuaDecompiler.opCodeType.String, String.Format("{0} = {1}", 90 | function.Registers[opCode.A], 91 | tableString)); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaDecompiler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {72464C94-B88B-40C9-BE51-C183E7D4AAC6} 9 | Exe 10 | LuaDecompiler 11 | LuaDecompiler 12 | v4.6.1 13 | 512 14 | true 15 | true 16 | 17 | 18 | 19 | 20 | x64 21 | true 22 | full 23 | false 24 | bin\Debug\ 25 | DEBUG;TRACE 26 | prompt 27 | 4 28 | true 29 | 30 | 31 | AnyCPU 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | 39 | 40 | 41 | ..\packages\Costura.Fody.3.3.0\lib\net40\Costura.dll 42 | 43 | 44 | C:\Users\Jari\Desktop\temp\CoDDataDumper\CoDDataDumper\LZ4.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | public class LuaFile 10 | { 11 | private BinaryReader inputReader { get; } 12 | private StreamWriter outputWriter { get; set; } 13 | public string fakeName { get; set; } 14 | public static int errors { get; set; } 15 | 16 | // This makes the program not crash when it gets bo2 files but op codes are different 17 | public bool exportBlackOps2 = false; 18 | 19 | public Game game { get; set; } 20 | 21 | public enum Game { BlackOps4, BlackOps3 }; 22 | 23 | public enum StringType { nullptr, hash, boolean, String, number} 24 | 25 | public class LuaFunction 26 | { 27 | public int upvalsCount { get; set; } 28 | public int registerCount { get; set; } 29 | public int opcodesCount { get; set; } 30 | public int parameterCount { get; set; } 31 | public bool usesVarArg { get; set; } 32 | public long beginPosition { get; set; } 33 | public long endPosition { get; set; } 34 | public int subFunctionsCount { get; set; } 35 | public int tableCount { get; set; } 36 | public int returnValCount { get; set; } 37 | public int forLoopCount { get; set; } 38 | public int doingUpvals { get; set; } 39 | public int lastFunctionClosure { get; set; } 40 | public LuaFunction superFunction { get; set; } 41 | public List subFunctions { get; set; } 42 | public List OPCodes { get; set; } 43 | public List Strings { get; set; } 44 | public List DisassembleStrings { get; set; } 45 | public List UpvalsStrings { get; set; } 46 | public List foreachPositions { get; set; } 47 | public string[] Registers { get; set; } 48 | public string functionName { get; set; } 49 | 50 | public LuaFunction(int registerCount) 51 | { 52 | this.registerCount = registerCount; 53 | OPCodes = new List(); 54 | Strings = new List(); 55 | subFunctions = new List(); 56 | DisassembleStrings = new List(); 57 | UpvalsStrings = new List(); 58 | foreachPositions = new List(); 59 | Registers = new string[registerCount]; 60 | for (int i = 0; i < registerCount; i++) 61 | Registers[i] = ""; 62 | functionName = ""; 63 | tableCount = 0; 64 | returnValCount = 0; 65 | forLoopCount = 0; 66 | forLoopCount = -1; 67 | lastFunctionClosure = -1; 68 | } 69 | 70 | public string getNewReturnVal() 71 | { 72 | while(this.UpvalsStrings.Contains("returnval" + this.returnValCount)) 73 | { 74 | this.returnValCount++; 75 | } 76 | return "returnval" + this.returnValCount++; 77 | } 78 | 79 | public string getName(bool getFakeName = false) 80 | { 81 | if (beginPosition <= 0x101) 82 | return "__INIT__"; 83 | else if (getFakeName && functionName != "") 84 | return functionName; 85 | else 86 | return string.Format("__FUNC_{0:X}_", this.beginPosition); 87 | } 88 | 89 | public string toString() 90 | { 91 | string output = String.Format("; Opcodes: 0x{0:X}\n; Constants: 0x{1:X}\n; Registers: 0x{2:X}\n; Upvals: 0x{3:X}", 92 | this.opcodesCount, this.Strings.Count, this.registerCount, this.upvalsCount); 93 | if(this.superFunction != null) 94 | output += String.Format("\n; SuperFunction: {0}", this.superFunction.getName()); 95 | output += String.Format("\nfunction {0}(", getName()); 96 | if(this.parameterCount > 0) 97 | { 98 | output += "arg0"; 99 | for(int i = 1; i < parameterCount; i++) 100 | output += ", arg" + i; 101 | } 102 | if (this.usesVarArg) 103 | { 104 | if(this.parameterCount > 0) 105 | output += ", "; 106 | output += "..."; 107 | } 108 | output += ")"; 109 | for (int i = 0; i < this.Strings.Count; i++) 110 | { 111 | output += String.Format("\n\t.const\t[{0}]\t{1}: {2}", i, 112 | (this.Strings[i].StringType == StringType.String) ? "\"" + this.Strings[i].String + "\"" : this.Strings[i].String, 113 | this.Strings[i].StringType); 114 | } 115 | foreach(String DisassembleString in this.DisassembleStrings) 116 | { 117 | output += "\n\t" + DisassembleString; 118 | } 119 | output += "\nend\n"; 120 | return output; 121 | } 122 | } 123 | 124 | // TODO: change the switch with opcodes to a dictionary 125 | /*public static Dictionary> opCodeIndices = new Dictionary>() 126 | { 127 | { 0x0, new Func(LuaStrings.ConnectWithDot) } 128 | };*/ 129 | 130 | public class LuaOPCode 131 | { 132 | // All instructions have an opcode in the last 6 bits. 133 | //Instructions can have the following fields: 134 | // `A' : 8 bits 135 | // `B' : 9 bits 136 | // `C' : 9 bits 137 | // `Bx' : 18 bits (`B' and `C' together) 138 | // `sBx' : signed Bx 139 | public byte A { get; set; } 140 | public int B { get; set; } 141 | public int C { get; set; } 142 | public int Bx { get; set; } 143 | public int sBx { get; set; } 144 | public int OPCode { get; set; } 145 | } 146 | 147 | public class LuaString 148 | { 149 | public StringType StringType { get; set; } 150 | public string String { get; set; } 151 | 152 | public string getString() 153 | { 154 | if (StringType == StringType.String && String != "nil") 155 | return "\"" + String + "\""; 156 | else 157 | return String; 158 | } 159 | } 160 | 161 | public List Functions { get; set;} 162 | 163 | public LuaFile(String fileName) 164 | { 165 | this.inputReader = new BinaryReader(new FileStream(fileName, FileMode.Open)); 166 | Functions = new List(); 167 | searchGameVersion(); 168 | fakeName = ""; 169 | } 170 | 171 | public void Disassemble() 172 | { 173 | LuaFunction funcion = this.loadFunction(); 174 | for(int i = 0; i < this.Functions[0].subFunctionsCount; i++) 175 | { 176 | this.handleSubFunctions(this.Functions[0]); 177 | } 178 | 179 | for (int i = 0; i < this.Functions.Count; i++) 180 | this.disassembleOPCodes(this.Functions[i], i); 181 | } 182 | 183 | private void handleSubFunctions(LuaFunction function) 184 | { 185 | LuaFunction subFunction = loadFunction(this.inputReader.BaseStream.Position); 186 | subFunction.superFunction = function; 187 | 188 | function.subFunctions.Add(subFunction); 189 | for (int i = 0; i < subFunction.subFunctionsCount; i++) 190 | { 191 | this.handleSubFunctions(subFunction); 192 | } 193 | } 194 | 195 | public void WriteDisassemble(String outputFile) 196 | { 197 | if (fakeName != "") 198 | { 199 | //File.AppendAllText(@"names.csv", Path.GetFileNameWithoutExtension(outputFile).Replace("LuaFile_", "") + "," + fakeName + Environment.NewLine); 200 | //outputFile = Path.GetDirectoryName(outputFile) + "\\export/" + fakeName + ".lua"; 201 | outputFile = Path.GetDirectoryName(outputFile) + fakeName + ".lua"; 202 | } 203 | /*else 204 | { 205 | //outputFile = Path.GetDirectoryName(outputFile) + "\\export/" + Path.GetFileNameWithoutExtension(outputFile) + ".lua"; 206 | }*/ 207 | this.outputWriter = new StreamWriter(outputFile + "dec"); 208 | outputWriter.WriteLine("; Disassembled by LuaDecompiler by JariK\n"); 209 | for(int i=0; i < this.Functions.Count; i++) 210 | { 211 | outputWriter.WriteLine(this.Functions[i].toString()); 212 | } 213 | outputWriter.Close(); 214 | } 215 | 216 | private void searchGameVersion() 217 | { 218 | inputReader.Seek(0xF6 , SeekOrigin.Begin); 219 | string bo4CheckString = inputReader.ReadFixedString(6); 220 | if (bo4CheckString == "TXHASH") 221 | this.game = Game.BlackOps4; 222 | else 223 | this.game = Game.BlackOps3; 224 | inputReader.Seek(0, SeekOrigin.Begin); 225 | } 226 | 227 | private LuaFunction loadFunction(long location = 0) 228 | { 229 | // Go to the start of the function 230 | if(location == 0) 231 | inputReader.Seek((game == Game.BlackOps3 ? 0xF2 : 0x101), SeekOrigin.Begin); 232 | 233 | // Begin position 234 | long beginPosition = inputReader.BaseStream.Position; 235 | 236 | // Get some info about this function 237 | int upvalsCount = inputReader.ReadInt32(); 238 | int parameterCount = inputReader.ReadByte(); 239 | if (beginPosition < 0x110) 240 | parameterCount = 0; 241 | 242 | // VarArg bytes if 243 | bool usesVarArg = false; 244 | if (beginPosition > 0x110) 245 | { 246 | int varArgBytes = inputReader.ReadInt32(); 247 | if(varArgBytes != 0) 248 | { 249 | usesVarArg = true; 250 | } 251 | } 252 | 253 | // Get some info about this function 254 | int registerCount = inputReader.ReadInt32(); 255 | int opcodesCount = inputReader.ReadInt32(); 256 | 257 | // Create a new function object 258 | LuaFunction function = new LuaFunction(registerCount); 259 | function.beginPosition = beginPosition; 260 | function.opcodesCount = opcodesCount; 261 | function.upvalsCount = upvalsCount; 262 | function.parameterCount = parameterCount; 263 | function.usesVarArg = usesVarArg; 264 | 265 | // Some unknown bytes (BO3 and BO4) 266 | if(!exportBlackOps2) 267 | inputReader.ReadBytes(4); 268 | 269 | // Add extra bytes to make it line up 270 | int extra = 4 - ((int)this.inputReader.BaseStream.Position % 4); 271 | if(extra > 0 && extra < 4) 272 | inputReader.ReadBytes(extra); 273 | 274 | // Load all OP Codes 275 | this.loadOPCodes(function); 276 | 277 | // Load all function strings 278 | this.loadFunctionStrings(function); 279 | 280 | float endingByte = inputReader.ReadInt32(); 281 | float endingSingle = inputReader.ReadSingle(); 282 | function.subFunctionsCount = inputReader.ReadInt32(); 283 | 284 | function.endPosition = inputReader.BaseStream.Position; 285 | 286 | Functions.Add(function); 287 | 288 | return function; 289 | } 290 | 291 | private void loadOPCodes(LuaFunction function) 292 | { 293 | // Go through all op codes 294 | for (int i = 0; i < function.opcodesCount; i++) 295 | { 296 | // Make a new OP Code object 297 | LuaOPCode opCode = new LuaOPCode(); 298 | // Read + asign all data 299 | opCode.A = this.inputReader.ReadByte(); 300 | 301 | int cValue = this.inputReader.ReadByte(); 302 | byte flags = this.inputReader.ReadByte(); 303 | if (GetBit(flags, 0) == 1) 304 | cValue += 256; 305 | opCode.C = cValue; 306 | 307 | this.inputReader.Seek(-1, SeekOrigin.Current); 308 | opCode.B = this.inputReader.ReadByte() >> 1; 309 | byte flagsB = this.inputReader.ReadByte(); 310 | if (GetBit(flagsB, 0) == 1) 311 | opCode.B += 128; 312 | /*if (GetBit(flagsB, 1) == 1) 313 | opCode.B += 256;*/ 314 | 315 | opCode.Bx = (opCode.B * 512) + opCode.C; 316 | opCode.sBx = opCode.Bx - 65536 + 1; 317 | 318 | this.inputReader.Seek(-1, SeekOrigin.Current); 319 | opCode.OPCode = this.inputReader.ReadByte() >> 1; 320 | // Add it to the list 321 | function.OPCodes.Add(opCode); 322 | } 323 | } 324 | 325 | public static byte GetBit(long input, int bit) 326 | { 327 | return (byte)((input >> bit) & 1); 328 | } 329 | 330 | private void loadFunctionStrings(LuaFunction function) 331 | { 332 | // Get the number of strings + loop 333 | int stringCount = this.inputReader.ReadInt32(); 334 | for (int i = 0; i < stringCount; i++) 335 | { 336 | // Make a new lua string object 337 | LuaString str = new LuaString(); 338 | // Get the type 339 | int strType = inputReader.ReadByte(); 340 | switch (strType) 341 | { 342 | case 1: 343 | str.String = (inputReader.ReadByte() == 1) ? "true" : "false"; 344 | str.StringType = StringType.boolean; 345 | break; 346 | case 3: 347 | str.String = inputReader.ReadSingle().ToString("0.000000"); 348 | str.StringType = StringType.number; 349 | break; 350 | case 4: 351 | int StringLength = inputReader.ReadInt32() - 1; 352 | if (!exportBlackOps2) 353 | inputReader.ReadInt32(); 354 | str.String = inputReader.ReadNullTerminatedString(); 355 | str.StringType = StringType.String; 356 | break; 357 | case 0xD: 358 | string HashString; 359 | ulong assetHash = inputReader.ReadUInt64() & 0xFFFFFFFFFFFFFFF; 360 | if (!Program.AssetNameCache.Entries.TryGetValue(assetHash, out HashString)) 361 | { 362 | str.String = String.Format("0x{0:X}", assetHash); 363 | str.StringType = StringType.hash; 364 | } 365 | else 366 | { 367 | str.String = HashString; 368 | str.StringType = StringType.String; 369 | } 370 | break; 371 | case 0: 372 | str.String = "nil"; 373 | str.StringType = StringType.nullptr; 374 | break; 375 | } 376 | // Add it to the list 377 | function.Strings.Add(str); 378 | } 379 | } 380 | 381 | private void disassembleOPCodes(LuaFunction function, int index) 382 | { 383 | // Add the parameter opcodes because they arent included 384 | for (int i = 0; i < function.parameterCount; i++) 385 | { 386 | function.Registers[i] = "arg" + i; 387 | function.DisassembleStrings.Add(String.Format("r({0}) = arg{0}", 388 | i)); 389 | } 390 | for (int i = 0; i < function.OPCodes.Count; i++) 391 | { 392 | LuaOPCode opCode = function.OPCodes[i]; 393 | try 394 | { 395 | switch (opCode.OPCode) 396 | { 397 | case 0x0: LuaStrings.ConnectWithDot(function, opCode); break; 398 | case 0x1: LuaConditions.IfIsTrueFalse(function, opCode); break; 399 | case 0x2: case 0x4C: LuaFunctions.CallFunctionWithParameters(function, opCode, i); break; 400 | case 0x16: LuaFunctions.CallFunctionWithParameters(function, opCode, i, true); break; 401 | case 0x4: LuaConditions.IfIsEqual(function, opCode); break; 402 | case 0x5: LuaConditions.IfIsEqualBackwards(function, opCode); break; 403 | case 0x6: LuaRegisters.GlobalRegisterToRegister(function, opCode); break; 404 | case 0x7: LuaRegisters.RegisterToRegister(function, opCode); break; 405 | case 0x8: LuaStrings.ConnectWithColon(function, opCode); break; 406 | case 0x9: LuaOperators.Return(function, opCode, i); break; 407 | case 0xA: LuaTables.GetIndex(function, opCode); break; 408 | case 0xD: LuaRegisters.BooleanToRegister(function, opCode); break; 409 | case 0xE: LuaLoops.StartForEachLoop(function, opCode); break; 410 | case 0xF: LuaStrings.SetField(function, opCode, i); break; 411 | case 0x10: LuaTables.SetTable(function, opCode); break; 412 | case 0x11: LuaTables.SetTableBackwards(function, opCode); break; 413 | case 0x19: LuaRegisters.LocalConstantToRegister(function, opCode); break; 414 | case 0x1A: LuaRegisters.NilToRegister(function, opCode); break; 415 | case 0x1B: LuaRegisters.RegisterToGlobal(function, opCode); break; 416 | case 0x1C: LuaConditions.SkipLines(function, opCode, i); break; 417 | case 0x26: LuaFunctions.GetUpValue(function, opCode); break; 418 | case 0x27: LuaOperators.SetupVal(function, opCode); break; 419 | case 0x28: LuaOperators.Add(function, opCode); break; 420 | case 0x29: LuaOperators.AddBackWards(function, opCode); break; 421 | case 0x2A: LuaOperators.Subtract(function, opCode); break; 422 | case 0x2B: LuaOperators.SubtractBackWards(function, opCode); break; 423 | case 0x2C: LuaOperators.Multiply(function, opCode); break; 424 | case 0x2D: LuaOperators.MultiplyBackWards(function, opCode); break; 425 | case 0x2E: LuaOperators.Divide(function, opCode); break; 426 | case 0x2F: LuaOperators.DivideBackWards(function, opCode); break; 427 | case 0x30: LuaOperators.Modulo(function, opCode); break; 428 | case 0x31: LuaOperators.ModuloBackWards(function, opCode); break; 429 | case 0x32: LuaOperators.Power(function, opCode); break; 430 | case 0x33: LuaOperators.PowerBackWards(function, opCode); break; 431 | case 0x34: LuaTables.EmptyTable(function, opCode); break; 432 | case 0x35: LuaOperators.UnaryMinus(function, opCode); break; 433 | case 0x36: LuaConditions.Not(function, opCode); break; 434 | case 0x37: LuaOperators.Length(function, opCode); break; 435 | case 0x38: LuaConditions.LargerThan(function, opCode); break; 436 | case 0x39: LuaConditions.LargerThanBackwards(function, opCode); break; 437 | case 0x3A: LuaConditions.LargerOrEqualThan(function, opCode); break; 438 | case 0x3B: LuaConditions.LargerOrEqualThanBackwards(function, opCode); break; 439 | case 0x3C: LuaOperators.ShiftLeft(function, opCode); break; 440 | case 0x3D: LuaOperators.ShiftLeftBackwards(function, opCode); break; 441 | case 0x40: LuaOperators.BinaryAnd(function, opCode); break; 442 | case 0x42: LuaOperators.BinaryOr(function, opCode); break; 443 | case 0x44: LuaStrings.ConnectWithDoubleDot(function, opCode); break; 444 | case 0x45: LuaOperators.TestSet(function, opCode); break; 445 | case 0x46: LuaLoops.StartForLoop(function, opCode); break; 446 | case 0x47: LuaLoops.EndForLoop(function, opCode, i); break; 447 | case 0x48: LuaTables.SetList(function, opCode); break; 448 | case 0x49: LuaOperators.Close(function, opCode); break; 449 | case 0x4A: LuaFunctions.Closure(function, opCode); break; 450 | case 0x4B: LuaOperators.VarArg(function, opCode); break; 451 | case 0x4D: LuaFunctions.CallFunctionWithoutParameters(function, opCode); break; 452 | case 0x4F: LuaConditions.IfIsTrueFalse(function, opCode); break; 453 | case 0x50: LuaOperators.NotR1(function, opCode); break; 454 | case 0x51: LuaStrings.ConnectWithDot(function, opCode); break; 455 | case 0x52: LuaStrings.SetField(function, opCode, i ); break; 456 | case 0x54: 457 | if (function.doingUpvals >= 0) 458 | { 459 | if(opCode.A == 1) 460 | { 461 | function.DisassembleStrings.Add(String.Format("r({0}).upval({1}) = r({2}) // {3}", 462 | function.doingUpvals, 463 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Count, 464 | opCode.C, 465 | function.Registers[opCode.C])); 466 | } 467 | else if (opCode.A == 2) 468 | { 469 | function.DisassembleStrings.Add(String.Format("r({0}).upval({1}) = upval({2}) // {3}", 470 | function.doingUpvals, 471 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Count, 472 | opCode.C, 473 | function.UpvalsStrings[opCode.C])); 474 | } 475 | else 476 | { 477 | Console.WriteLine("Trying to get to do upvalue on level " + opCode.A); 478 | errors++; 479 | } 480 | } 481 | else 482 | { 483 | function.DisassembleStrings.Add(String.Format("data({0}, {1}, {2}, {3})", 484 | opCode.A, 485 | opCode.C, 486 | opCode.B, 487 | opCode.OPCode)); 488 | } 489 | break; 490 | default: 491 | function.DisassembleStrings.Add(String.Format("Unknown data(A:{0}, B:{1}, C:{2}, Bx:{3}, sBx:{4}, X:{5})", 492 | opCode.A, 493 | opCode.B, 494 | opCode.C, 495 | opCode.Bx, 496 | opCode.sBx, 497 | opCode.OPCode)); 498 | break; 499 | } 500 | if ((opCode.OPCode == 0xF || opCode.OPCode == 0x52) && function.getName() == "__INIT__") 501 | { 502 | if (this.game == Game.BlackOps4 && function.Registers[opCode.A].Length == 14) 503 | { 504 | if(function.Registers[opCode.A] == "LUI.createMenu") 505 | fakeName = function.Strings[opCode.B].String; 506 | } 507 | else if (this.game == Game.BlackOps4 && function.Registers[opCode.A].Length > 3) 508 | { 509 | 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.") && 510 | (function.Strings[opCode.B].String == "new")) 511 | { 512 | fakeName = function.Registers[opCode.A].Substring(4); 513 | } 514 | } 515 | else if (this.game == Game.BlackOps4 && function.Registers[opCode.A].Length < 4) 516 | { 517 | if ((function.Registers[opCode.A] == "CoD" || function.Registers[opCode.A] == "LUI") && 518 | (function.Registers[opCode.C] == "table0")) 519 | { 520 | fakeName = function.Strings[opCode.B].String; 521 | } 522 | } 523 | } 524 | if (function.doingUpvals >= 0) 525 | { 526 | if (opCode.OPCode == 0x4A) 527 | continue; 528 | if (opCode.OPCode == 0x54) 529 | { 530 | if(opCode.A == 1) 531 | { 532 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Add(function.Registers[opCode.C]); 533 | } 534 | else if(opCode.A == 2) 535 | { 536 | function.subFunctions[function.lastFunctionClosure].UpvalsStrings.Add(function.UpvalsStrings[opCode.C]); 537 | } 538 | } 539 | else 540 | function.doingUpvals = -1; 541 | } 542 | } 543 | catch 544 | { 545 | 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); 546 | function.DisassembleStrings.Add(String.Format("Unknown data(A:{0}, B:{1}, C:{2}, Bx:{3}, sBx:{4}, X:{5})", 547 | opCode.A, 548 | opCode.B, 549 | opCode.C, 550 | opCode.Bx, 551 | opCode.sBx, 552 | opCode.OPCode)); 553 | errors++; 554 | } 555 | } 556 | 557 | } 558 | } 559 | } 560 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaConditions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaConditions 10 | { 11 | public static void IfIsTrueFalse(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | function.DisassembleStrings.Add(String.Format("if r({0}) == {1}, skip next opcode // if {2}{3} then skip next line", 14 | opCode.A, 15 | (opCode.C == 1) ? "false" : "true", 16 | (opCode.C == 1) ? "not " : "", 17 | function.Registers[opCode.A])); 18 | } 19 | 20 | public static void IfIsEqual(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 21 | { 22 | if(opCode.C > 255) 23 | { 24 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) == c[{1}], skip next opcode // if {4}{2} == {3} then skip next line", 25 | opCode.B, 26 | opCode.C - 256, 27 | function.Registers[opCode.B], 28 | function.Strings[opCode.C - 256].getString(), 29 | (opCode.A == 1) ? "not " : "")); 30 | } 31 | else 32 | { 33 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) == r({1}), skip next opcode // if {4}{2} == {3} then skip next line", 34 | opCode.B, 35 | opCode.C, 36 | function.Registers[opCode.B], 37 | function.Registers[opCode.C], 38 | (opCode.A == 1) ? "not " : "")); 39 | } 40 | } 41 | 42 | public static void SkipLines(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 43 | { 44 | string suffix = ""; 45 | if (opCode.B == 0) 46 | { 47 | if (function.OPCodes[index + opCode.C + 2].OPCode == 0xE && !function.foreachPositions.Contains(index + opCode.C + 2)) 48 | { 49 | int baseVal = function.OPCodes[index + opCode.C + 2].A + 3; 50 | function.Registers[baseVal] = "index" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 51 | function.Registers[baseVal + 1] = "value" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 52 | function.forLoopCount++; 53 | suffix = " + start of foreach loop"; 54 | function.foreachPositions.Add(index + opCode.C + 2); 55 | } 56 | function.DisassembleStrings.Add(String.Format("skip the next [{0}] opcodes // advance {0} lines{1}", 57 | opCode.C + 1, 58 | suffix)); 59 | } 60 | else 61 | { 62 | if (function.OPCodes[index + opCode.sBx + 1].OPCode == 0xE && !function.foreachPositions.Contains(index + opCode.sBx + 1)) 63 | { 64 | int baseVal = function.OPCodes[index + opCode.sBx + 1].A + 3; 65 | function.Registers[baseVal] = "index" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 66 | function.Registers[baseVal + 1] = "value" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 67 | function.forLoopCount++; 68 | suffix = " + start of foreach loop"; 69 | function.foreachPositions.Add(index + opCode.sBx + 1); 70 | } 71 | function.DisassembleStrings.Add(String.Format("skip the next [{0}] opcodes // advance {0} lines", 72 | opCode.sBx)); 73 | } 74 | 75 | 76 | } 77 | 78 | public static void Not(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 79 | { 80 | function.DisassembleStrings.Add(String.Format("r({0}) = not r({1}) // {2} = not {3}", 81 | opCode.A, 82 | opCode.B, 83 | "returnval" + function.returnValCount, 84 | function.Registers[opCode.B])); 85 | function.Registers[opCode.A] = function.getNewReturnVal(); 86 | } 87 | 88 | public static void IfIsEqualBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 89 | { 90 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_EQ_BK)"); 91 | } 92 | 93 | public static void LargerThan(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 94 | { 95 | if (opCode.C > 255) 96 | { 97 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) > c[{1}], skip next opcode // if {4}{2} > {3} then skip next line", 98 | opCode.B, 99 | opCode.C - 256, 100 | function.Registers[opCode.B], 101 | function.Strings[opCode.C - 256].getString(), 102 | (opCode.A == 1) ? "not " : "")); 103 | } 104 | else 105 | { 106 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) > r({1}), skip next opcode // if {4}{2} > {3} then skip next line", 107 | opCode.B, 108 | opCode.C, 109 | function.Registers[opCode.B], 110 | function.Registers[opCode.C], 111 | (opCode.A == 0) ? "not " : "")); 112 | } 113 | } 114 | 115 | public static void LargerThanBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 116 | { 117 | if (opCode.C > 255) 118 | { 119 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) > c[{1}], skip next opcode // if {4}{2} > {3} then skip next line", 120 | opCode.B, 121 | opCode.C - 256, 122 | function.Strings[opCode.B].getString(), 123 | function.Strings[opCode.C - 256].getString(), 124 | (opCode.A == 0) ? "not " : "")); 125 | } 126 | else 127 | { 128 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) > c[{1}], skip next opcode // if {4}{2} > {3} then skip next line", 129 | opCode.B, 130 | opCode.C, 131 | function.Strings[opCode.B].getString(), 132 | function.Registers[opCode.C], 133 | (opCode.A == 0) ? "not " : "")); 134 | } 135 | } 136 | 137 | public static void LargerOrEqualThan(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 138 | { 139 | if (opCode.C > 255) 140 | { 141 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) >= c[{1}], skip next opcode // if {4}{2} >= {3} then skip next line", 142 | opCode.B, 143 | opCode.C - 256, 144 | function.Registers[opCode.B], 145 | function.Strings[opCode.C - 256].getString(), 146 | (opCode.A == 1) ? "not " : "")); 147 | } 148 | else 149 | { 150 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) >= r({1}), skip next opcode // if {4}{2} >= {3} then skip next line", 151 | opCode.B, 152 | opCode.C, 153 | function.Registers[opCode.B], 154 | function.Registers[opCode.C], 155 | (opCode.A == 0) ? "not " : "")); 156 | } 157 | } 158 | 159 | public static void LargerOrEqualThanBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 160 | { 161 | if (opCode.C > 255) 162 | { 163 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) >= c[{1}], skip next opcode // if {4}{2} >= {3} then skip next line", 164 | opCode.B, 165 | opCode.C - 256, 166 | function.Strings[opCode.B].getString(), 167 | function.Strings[opCode.C - 256].getString(), 168 | (opCode.A == 0) ? "not " : "")); 169 | } 170 | else 171 | { 172 | function.DisassembleStrings.Add(String.Format("if {4}r({0}) >= c[{1}], skip next opcode // if {4}{2} >= {3} then skip next line", 173 | opCode.B, 174 | opCode.C, 175 | function.Strings[opCode.B].getString(), 176 | function.Registers[opCode.C], 177 | (opCode.A == 0) ? "not " : "")); 178 | } 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaFunctions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaFunctions 10 | { 11 | public static void Closure(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | function.Registers[opCode.A] = String.Format("__FUNC_{0:X}_", function.subFunctions[opCode.Bx].beginPosition); 14 | function.doingUpvals = opCode.A; 15 | function.lastFunctionClosure = opCode.Bx; 16 | function.DisassembleStrings.Add(String.Format("r({0}) = closure({1}) // {2}", 17 | opCode.A, 18 | opCode.Bx, 19 | function.Registers[opCode.A])); 20 | } 21 | 22 | public static void GetUpValue(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 23 | { 24 | function.Registers[opCode.A] = function.UpvalsStrings[opCode.B]; 25 | function.DisassembleStrings.Add(String.Format("r({0}) = upval({1}) // {2}", 26 | opCode.A, 27 | opCode.B, 28 | function.UpvalsStrings[opCode.B])); 29 | } 30 | 31 | public static void CallFunctionWithParameters(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index, bool tailCall = false) 32 | { 33 | string funcName = function.Registers[opCode.A]; 34 | int parameterCount = opCode.B - 1; 35 | int returnValues = opCode.C - 1; 36 | if (returnValues < 0) 37 | { 38 | returnValues = 0; 39 | tailCall = true; 40 | } 41 | 42 | string parameterRegisters = ""; 43 | string parametersString = ""; 44 | if (parameterCount > 0) 45 | { 46 | parameterRegisters += opCode.A + 1; 47 | for (int j = opCode.A + 2; j <= opCode.A + parameterCount; j++) 48 | { 49 | parameterRegisters += ", " + j; 50 | } 51 | if (funcName.Contains(":") && opCode.A + 2 <= opCode.A + parameterCount) 52 | { 53 | parametersString += function.Registers[opCode.A + 2]; 54 | for (int j = opCode.A + 3; j <= opCode.A + parameterCount; j++) 55 | { 56 | parametersString += ", " + function.Registers[j]; 57 | } 58 | } 59 | else 60 | { 61 | parametersString += function.Registers[opCode.A + 1]; 62 | for (int j = opCode.A + 2; j <= opCode.A + parameterCount; j++) 63 | { 64 | parametersString += ", " + function.Registers[j]; 65 | } 66 | } 67 | } 68 | else if(parameterCount != 0) 69 | { 70 | parameterRegisters += opCode.A + 1; 71 | for (int j = opCode.A + 2; j <= function.OPCodes[index - 1].A; j++) 72 | { 73 | parameterRegisters += ", " + j; 74 | } 75 | 76 | int startpoint = 2; 77 | parametersString = function.Registers[opCode.A + 1]; 78 | if (funcName.Contains(":")) 79 | { 80 | parametersString = function.Registers[opCode.A + 2]; 81 | startpoint = 3; 82 | } 83 | for (int j = opCode.A + startpoint; j <= function.OPCodes[index - 1].A; j++) 84 | { 85 | parametersString += ", " + function.Registers[j]; 86 | } 87 | } 88 | if (returnValues > 0) 89 | { 90 | string returnRegisters = opCode.A.ToString(); 91 | string returnStrings = "returnval" + function.returnValCount; 92 | function.Registers[opCode.A] = function.getNewReturnVal(); 93 | if (returnValues > 1) 94 | { 95 | for (int j = opCode.A + 1; j < opCode.A + returnValues; j++) 96 | { 97 | returnRegisters += ", " + j.ToString(); 98 | returnStrings += ", returnval" + function.returnValCount; 99 | function.Registers[j] = function.getNewReturnVal(); 100 | } 101 | } 102 | function.DisassembleStrings.Add(String.Format("r({0}) = call r({1}) with r({2}) // {3} = {4}({5})", 103 | returnRegisters, 104 | opCode.A, 105 | parameterRegisters, 106 | returnStrings, 107 | funcName, 108 | parametersString)); 109 | } 110 | else 111 | { 112 | function.Registers[opCode.A] = funcName + "(" + parametersString + ")"; 113 | function.DisassembleStrings.Add(String.Format("{5}call r({0}) with r({1}) // {3}({4})", 114 | opCode.A, 115 | parameterRegisters, 116 | function.Registers[opCode.A], 117 | funcName, 118 | parametersString, 119 | (tailCall) ? "return " : "")); 120 | } 121 | } 122 | 123 | public static void CallFunctionWithoutParameters(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 124 | { 125 | if (opCode.C > 1) 126 | { 127 | string returnRegisters = opCode.A.ToString(); 128 | string returnStrings = function.getNewReturnVal(); 129 | if (opCode.C > 2) 130 | { 131 | for (int j = opCode.A + 1; j < opCode.A + opCode.C - 1; j++) 132 | { 133 | returnRegisters += ", " + j.ToString(); 134 | returnStrings += ", returnval" + function.returnValCount; 135 | function.Registers[j] = function.getNewReturnVal(); 136 | } 137 | } 138 | function.DisassembleStrings.Add(String.Format("r({0}) = call r({1}) // {2} = {3}()", 139 | returnRegisters, 140 | opCode.A, 141 | returnStrings, 142 | function.Registers[opCode.A])); 143 | for (int j = opCode.A; j < opCode.A + opCode.C - 1; j++) 144 | function.returnValCount--; 145 | function.Registers[opCode.A] = function.getNewReturnVal(); 146 | if (opCode.C > 2) 147 | { 148 | for (int j = opCode.A + 1; j < opCode.A + opCode.C - 1; j++) 149 | { 150 | function.Registers[j] = function.getNewReturnVal(); 151 | } 152 | } 153 | } 154 | else 155 | { 156 | function.DisassembleStrings.Add(String.Format("call r({0}) // {1}()", 157 | opCode.A, 158 | function.Registers[opCode.A])); 159 | } 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaLoops.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaLoops 10 | { 11 | public static void StartForLoop(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | function.Registers[opCode.A + 3] = "index" + ((function.forLoopCount > 0) ? function.forLoopCount.ToString() : ""); 14 | function.forLoopCount++; 15 | function.DisassembleStrings.Add(String.Format("for {6}=r({0}), {6} < r({1}), r({2}) do // for {6}={3}, {4}, {5} do", 16 | opCode.A, opCode.A + 1, opCode.A + 2, 17 | function.Registers[opCode.A], 18 | function.Registers[opCode.A + 1], 19 | function.Registers[opCode.A + 2], 20 | function.Registers[opCode.A + 3])); 21 | } 22 | 23 | public static void EndForLoop(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 24 | { 25 | if (opCode.B == 0) 26 | { 27 | function.DisassembleStrings.Add(String.Format("skip the next [{0}] opcodes // advance {0} lines", 28 | opCode.C + 1)); 29 | } 30 | else 31 | { 32 | function.DisassembleStrings.Add(String.Format("skip the next [{0}] opcodes // advance {0} lines", 33 | opCode.sBx)); 34 | } 35 | } 36 | 37 | public static void StartForEachLoop(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 38 | { 39 | function.DisassembleStrings.Add(String.Format("Start a foreach loop with val r({0}), stop: r({1}), inc: r({2}) // use these values: {3} and {4}", 40 | opCode.A, 41 | opCode.A + 1, 42 | opCode.A + 2, 43 | function.Registers[opCode.A + 3], 44 | function.Registers[opCode.A + 4])); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaOperators.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaOperators 10 | { 11 | public static void Return(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index) 12 | { 13 | if (index > 0) 14 | { 15 | if(function.OPCodes[index - 1].OPCode == 0x16) 16 | opCode.B = 1; 17 | } 18 | if (opCode.B > 1) 19 | { 20 | string registers = opCode.A.ToString(); 21 | string returns = function.Registers[opCode.A]; 22 | for(int i = opCode.A + 1; i <= opCode.A + opCode.B - 2; i++) 23 | { 24 | registers += ", " + i; 25 | returns += ", " + function.Registers[i]; 26 | } 27 | function.DisassembleStrings.Add(String.Format("return r({0}) // {1}", registers, returns)); 28 | } 29 | else 30 | { 31 | function.DisassembleStrings.Add("return"); 32 | } 33 | } 34 | 35 | public static void Length(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 36 | { 37 | function.Registers[opCode.A] = "#" + function.Registers[opCode.B]; 38 | function.DisassembleStrings.Add(String.Format("r({0}) = len(r({1})) // {2}", 39 | opCode.A, 40 | opCode.B, 41 | function.Registers[opCode.B])); 42 | } 43 | 44 | public static void Add(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 45 | { 46 | DoOperator(function, opCode, "+"); 47 | } 48 | 49 | public static void AddBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 50 | { 51 | DoOperatorBackWards(function, opCode, "+"); 52 | } 53 | 54 | public static void Subtract(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 55 | { 56 | DoOperator(function, opCode, "-"); 57 | } 58 | 59 | public static void SubtractBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 60 | { 61 | DoOperatorBackWards(function, opCode, "-"); 62 | } 63 | 64 | public static void Multiply(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 65 | { 66 | DoOperator(function, opCode, "*"); 67 | } 68 | 69 | public static void MultiplyBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 70 | { 71 | DoOperatorBackWards(function, opCode, "*"); 72 | } 73 | 74 | public static void Divide(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 75 | { 76 | DoOperator(function, opCode, "/"); 77 | } 78 | 79 | public static void DivideBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 80 | { 81 | DoOperatorBackWards(function, opCode, "/"); 82 | } 83 | 84 | public static void Modulo(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 85 | { 86 | DoOperator(function, opCode, "%"); 87 | } 88 | 89 | public static void ModuloBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 90 | { 91 | DoOperatorBackWards(function, opCode, "%"); 92 | } 93 | 94 | public static void Power(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 95 | { 96 | DoOperator(function, opCode, "^"); 97 | } 98 | 99 | public static void PowerBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 100 | { 101 | DoOperatorBackWards(function, opCode, "^"); 102 | } 103 | 104 | public static void DoOperator(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, string Operator) 105 | { 106 | if (opCode.C > 255) 107 | { 108 | function.DisassembleStrings.Add(String.Format("r({0}) = c[{1}] {6} r({2}) // {3} = {4} {6} {5}", 109 | opCode.A, 110 | opCode.C - 256, 111 | opCode.B, 112 | "returnval" + function.returnValCount, 113 | function.Strings[opCode.C - 256].String, 114 | function.Registers[opCode.B], 115 | Operator)); 116 | } 117 | else 118 | { 119 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1}) {6} r({2}) // {3} = {4} {6} {5}", 120 | opCode.A, 121 | opCode.C, 122 | opCode.B, 123 | "returnval" + function.returnValCount, 124 | function.Registers[opCode.C], 125 | function.Registers[opCode.B], 126 | Operator)); 127 | } 128 | 129 | function.Registers[opCode.A] = function.getNewReturnVal(); 130 | } 131 | 132 | public static void DoOperatorBackWards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, string Operator) 133 | { 134 | function.DisassembleStrings.Add(String.Format("r({0}) = c({2}) {6} r({1}) // {3} = {5} {6} {4}", 135 | opCode.A, 136 | opCode.C, 137 | opCode.B, 138 | "returnval" + function.returnValCount, 139 | function.Registers[opCode.C], 140 | function.Strings[opCode.B].String, 141 | Operator)); 142 | function.Registers[opCode.A] = function.getNewReturnVal(); 143 | } 144 | 145 | public static void UnaryMinus(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 146 | { 147 | function.Registers[opCode.A] = "-" + function.Registers[opCode.B]; 148 | function.DisassembleStrings.Add(String.Format("r({0}) = -r({1}) // {2} ", 149 | opCode.A, 150 | opCode.B, 151 | function.Registers[opCode.A])); 152 | } 153 | 154 | public static void ShiftLeft(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 155 | { 156 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_LEFT_SHIFT)"); 157 | } 158 | 159 | public static void ShiftLeftBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 160 | { 161 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_LEFT_SHIFT_BK)"); 162 | } 163 | 164 | public static void BinaryAnd(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 165 | { 166 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_BIT_AND)"); 167 | } 168 | 169 | public static void BinaryOr(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 170 | { 171 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_BIT_OR)"); 172 | } 173 | 174 | public static void TestSet(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 175 | { 176 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_TESTSET)"); 177 | } 178 | 179 | public static void Close(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 180 | { 181 | function.Registers[opCode.A] = ""; 182 | function.DisassembleStrings.Add(String.Format("r({0}) = null", opCode.A)); 183 | } 184 | 185 | public static void VarArg(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 186 | { 187 | function.Registers[opCode.A] = "..."; 188 | function.DisassembleStrings.Add(String.Format("r({0}) = VarArg // {1} ", 189 | opCode.A, 190 | function.Registers[opCode.A])); 191 | } 192 | 193 | public static void NotR1(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 194 | { 195 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_NOT_R1)"); 196 | } 197 | 198 | public static void SetupVal(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 199 | { 200 | function.DisassembleStrings.Add("; Unhandled OP: (OPCODE_SETUPVAL)"); 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaRegisters.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaRegisters 10 | { 11 | /// 12 | /// Puts a register value in another register 13 | /// 14 | /// 15 | /// 16 | public static void RegisterToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 17 | { 18 | function.Registers[opCode.A] = function.Registers[opCode.B]; 19 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1}) // {2}", 20 | opCode.A, 21 | opCode.B, 22 | function.Registers[opCode.A])); 23 | } 24 | 25 | public static void GlobalRegisterToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 26 | { 27 | function.Registers[opCode.A] = function.Strings[opCode.Bx].String; 28 | function.DisassembleStrings.Add(String.Format("r({0}) = g[{1}] // {2}", 29 | opCode.A, 30 | opCode.Bx, 31 | function.Strings[opCode.Bx].getString())); 32 | } 33 | 34 | public static void RegisterToGlobal(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 35 | { 36 | function.DisassembleStrings.Add(String.Format("g[c[{0}]] = r({1}) // {2} = {3}", 37 | opCode.Bx, 38 | opCode.A, 39 | function.Strings[opCode.Bx].String, 40 | function.Registers[opCode.A])); 41 | } 42 | 43 | public static void BooleanToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 44 | { 45 | if (opCode.B == 0) 46 | function.Registers[opCode.A] = "false"; 47 | else 48 | function.Registers[opCode.A] = "true"; 49 | function.DisassembleStrings.Add(String.Format("r({0}) = {1}{2}", 50 | opCode.A, 51 | function.Registers[opCode.A], 52 | (opCode.C == 1) ? " // skip next opcode" : "")); 53 | } 54 | 55 | public static void NilToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 56 | { 57 | for (int i = opCode.A; i <= (opCode.B); i++) 58 | { 59 | function.Registers[i] = "nil"; 60 | } 61 | if ((opCode.B) > opCode.A) 62 | function.DisassembleStrings.Add(String.Format("r({0} to {1}) inclusive = nil", opCode.A, opCode.B)); 63 | else 64 | function.DisassembleStrings.Add(String.Format("r({0}) = nil", opCode.A)); 65 | } 66 | 67 | public static void LocalConstantToRegister(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 68 | { 69 | function.Registers[opCode.A] = function.Strings[opCode.Bx].getString(); 70 | function.DisassembleStrings.Add(String.Format("r({0}) = c[{1}] // {2}", 71 | opCode.A, 72 | opCode.Bx, 73 | function.Registers[opCode.A])); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaStrings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaStrings 10 | { 11 | /// 12 | /// Connects a register value and a constant value with a . 13 | /// 14 | /// 15 | /// 16 | public static void ConnectWithDot(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 17 | { 18 | function.Registers[opCode.A] = function.Registers[opCode.B] + "." + function.Strings[opCode.C].String; 19 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1}).field({2}) // {3}", 20 | opCode.A, 21 | opCode.B, 22 | opCode.C, 23 | function.Registers[opCode.A])); 24 | } 25 | 26 | public static void SetField(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode, int index, bool isString = false) 27 | { 28 | if(opCode.C > 255) 29 | { 30 | if (function.Strings[opCode.C - 256].StringType == LuaFile.StringType.String) 31 | isString = true; 32 | function.DisassembleStrings.Add(String.Format("r({0}).field(c[{1}]) = c[{2}] // {3}.{4} = {5}", 33 | opCode.A, 34 | opCode.B, 35 | opCode.C - 256, 36 | function.Registers[opCode.A], 37 | function.Strings[opCode.B].String, 38 | function.Strings[opCode.C - 256].getString())); 39 | } 40 | else 41 | { 42 | if (function.Registers[opCode.C].Contains("__FUNC") 43 | && (function.OPCodes[index - 1].OPCode == 0x4A || function.OPCodes[index - 1].OPCode == 0x54) 44 | && (function.Registers[opCode.A].Substring(0, 3) == "CoD" || function.Registers[opCode.A].Substring(0, 3) == "LUI")) 45 | { 46 | for(int i = index; i > 0; i--) 47 | { 48 | if(function.OPCodes[i].OPCode == 0x4A) 49 | { 50 | function.subFunctions[function.OPCodes[i].Bx].functionName = function.Registers[opCode.A] + "." + function.Strings[opCode.B].String; 51 | break; 52 | } 53 | } 54 | } 55 | function.DisassembleStrings.Add(String.Format("r({0}).field(c[{1}]) = r({2}) // {3}.{4} = {5}", 56 | opCode.A, 57 | opCode.B, 58 | opCode.C, 59 | function.Registers[opCode.A], 60 | function.Strings[opCode.B].String, 61 | (isString) ? "\"" + function.Registers[opCode.C] + "\"" : function.Registers[opCode.C])); 62 | 63 | } 64 | } 65 | 66 | /// 67 | /// Connects 2 register values with a double . 68 | /// 69 | /// 70 | /// 71 | public static void ConnectWithDoubleDot(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 72 | { 73 | string output = "(" + function.Registers[opCode.B]; 74 | string registers = "r(" + opCode.B + ")"; 75 | for (int i = opCode.B + 1; i <= opCode.C; i++) 76 | { 77 | output += " .. " + function.Registers[i]; 78 | registers += "..r(" + i + ")"; 79 | } 80 | output += ")"; 81 | function.Registers[opCode.A] = output; 82 | function.DisassembleStrings.Add(String.Format("r({0}) = {1} // {2}", 83 | opCode.A, 84 | registers, 85 | function.Registers[opCode.A])); 86 | } 87 | 88 | /// 89 | /// Connects a register value and a constant value with a : 90 | /// 91 | /// 92 | /// 93 | public static void ConnectWithColon(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 94 | { 95 | if (opCode.C > 255) 96 | { 97 | function.Registers[opCode.A] = function.Registers[opCode.B] + ":" + function.Strings[opCode.C - 256].String; 98 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1}):c[{2}] // {3}", 99 | opCode.A, 100 | opCode.B, 101 | opCode.C - 256, 102 | function.Registers[opCode.A])); 103 | } 104 | else 105 | { 106 | 107 | function.Registers[opCode.A] = function.Registers[opCode.B] + ":" + function.Registers[opCode.C]; 108 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1}):r({2}) // {3}", 109 | opCode.A, 110 | opCode.B, 111 | opCode.C, 112 | function.Registers[opCode.A])); 113 | } 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/LuaOPCodes/LuaTables.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class LuaTables 10 | { 11 | public static void GetIndex(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 12 | { 13 | if (opCode.C > 255) 14 | { 15 | function.Registers[opCode.A] = function.Registers[opCode.B] + "[" + function.Strings[opCode.C - 256].String + "]"; 16 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1})[c[{2}]] // {3}", 17 | opCode.A, 18 | opCode.B, 19 | opCode.C - 256, 20 | function.Registers[opCode.A])); 21 | } 22 | else 23 | { 24 | function.Registers[opCode.A] = function.Registers[opCode.B] + "[" + function.Registers[opCode.C] + "]"; 25 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1})[r({2})] // {3}", 26 | opCode.A, 27 | opCode.B, 28 | opCode.C, 29 | function.Registers[opCode.A])); 30 | } 31 | } 32 | 33 | public static void SetTable(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 34 | { 35 | if (opCode.C > 255) 36 | { 37 | function.DisassembleStrings.Add(String.Format("r({0})[c[{1}]] = c[{2}] // {3}[{4}] = {5}", 38 | opCode.A, 39 | opCode.B, 40 | opCode.C - 256, 41 | function.Registers[opCode.A], 42 | function.Registers[opCode.B], 43 | function.Strings[opCode.C - 256].getString())); 44 | } 45 | else 46 | { 47 | function.DisassembleStrings.Add(String.Format("r({0})[c[{1}]] = c[{2}] // {3}[{4}] = {5}", 48 | opCode.A, 49 | opCode.B, 50 | opCode.C, 51 | function.Registers[opCode.A], 52 | function.Registers[opCode.B], 53 | function.Registers[opCode.C])); 54 | } 55 | } 56 | 57 | public static void SetTableBackwards(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 58 | { 59 | if (opCode.C > 255) 60 | { 61 | function.DisassembleStrings.Add(String.Format("r({0})[c[{1}]] = c[{2}] // {3}[{4}] = {5}", 62 | opCode.A, 63 | opCode.B, 64 | opCode.C - 256, 65 | function.Registers[opCode.A], 66 | function.Strings[opCode.B].getString(), 67 | function.Strings[opCode.C - 256].getString())); 68 | } 69 | else 70 | { 71 | function.DisassembleStrings.Add(String.Format("r({0})[c[{1}]] = r({2}) // {3}[{4}] = {5}", 72 | opCode.A, 73 | opCode.B, 74 | opCode.C, 75 | function.Registers[opCode.A], 76 | function.Strings[opCode.B].getString(), 77 | function.Registers[opCode.C])); 78 | } 79 | } 80 | 81 | public static void EmptyTable(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 82 | { 83 | function.Registers[opCode.A] = "table" + function.tableCount; 84 | function.tableCount++; 85 | function.DisassembleStrings.Add(String.Format("r({0}) = {4} // {3} = {4} Index: {2} Hash: {1}", 86 | opCode.A, 87 | opCode.C, 88 | opCode.B, 89 | function.Registers[opCode.A], "{}")); 90 | } 91 | 92 | public static void SetList(LuaFile.LuaFunction function, LuaFile.LuaOPCode opCode) 93 | { 94 | string tableString = "{"; 95 | string tableRegisters = ""; 96 | if (opCode.B > 0) 97 | { 98 | tableString += function.Registers[opCode.A + 1]; 99 | tableRegisters += opCode.A + 1; 100 | if (opCode.B > 1) 101 | { 102 | for (int j = opCode.A + 2; j <= opCode.A + opCode.B; j++) 103 | { 104 | tableString += ", " + function.Registers[j]; 105 | tableRegisters += ", " + j; 106 | } 107 | } 108 | } 109 | tableString += "}"; 110 | function.Registers[opCode.A] = function.Registers[opCode.A]; 111 | 112 | function.DisassembleStrings.Add(String.Format("r({0}) = r({1}) // {2} = {3}", 113 | opCode.A, 114 | tableRegisters, 115 | function.Registers[opCode.A], 116 | tableString)); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/PackageIndex.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using LZ4; 7 | 8 | namespace LuaDecompiler 9 | { 10 | /// 11 | /// A class to handle Greyhound/Wraith Package Index Files 12 | /// 13 | class PackageIndex 14 | { 15 | /// 16 | /// Package Entries 17 | /// 18 | public Dictionary Entries = new Dictionary(); 19 | 20 | /// 21 | /// Loads Package Index File 22 | /// 23 | /// Path to Package file 24 | public bool Load(string filePath) 25 | { 26 | using (BinaryReader reader = new BinaryReader(File.OpenRead(filePath))) 27 | { 28 | // Check Magic 29 | if (reader.ReadInt32() != 0x20494E57) 30 | { 31 | return false; 32 | } 33 | else 34 | { 35 | // Version / Count 36 | int version = reader.ReadInt16(); 37 | int count = reader.ReadInt32(); 38 | 39 | // Buffer Sizes 40 | int compressedSize = reader.ReadInt32(); 41 | int decompressedSize = reader.ReadInt32(); 42 | 43 | // Decode the Buffer 44 | byte[] buffer = LZ4Codec.Decode(reader.ReadBytes(compressedSize), 0, compressedSize, decompressedSize); 45 | 46 | // Read the package 47 | using (BinaryReader internalReader = new BinaryReader(new MemoryStream(buffer))) 48 | // Loop Count 49 | for (int i = 0; i < count; i++) 50 | // Read ID and String 51 | Entries[internalReader.ReadUInt64() & 0xFFFFFFFFFFFFFFF] = ReadNullTerminatedString(internalReader); 52 | } 53 | } 54 | 55 | return true; 56 | } 57 | 58 | /// 59 | /// Saves compressed Package Index file 60 | /// 61 | /// Path to save Package file to 62 | public void Save(string filePath) 63 | { 64 | using (var fileWriter = new BinaryWriter(File.Create(filePath))) 65 | { 66 | // Write Magic 67 | fileWriter.Write(0x20494E57); 68 | 69 | // Write Version / Count 70 | fileWriter.Write((short)1); 71 | fileWriter.Write(Entries.Count); 72 | 73 | // Create compressed output 74 | using (var compressedWriter = new BinaryWriter(new MemoryStream())) 75 | { 76 | // Write Each Entry with ID and String 77 | foreach (var entry in Entries) 78 | { 79 | compressedWriter.Write(entry.Key); 80 | compressedWriter.Write(Encoding.UTF8.GetBytes(entry.Value)); 81 | compressedWriter.Write((byte)0); 82 | } 83 | 84 | // Get Length 85 | int decompressedSize = (int)compressedWriter.BaseStream.Length; 86 | 87 | // Compress Buffer 88 | byte[] buffer = LZ4Codec.EncodeHC(((MemoryStream)compressedWriter.BaseStream).ToArray(), 0, decompressedSize); 89 | 90 | // Write Lengths 91 | fileWriter.Write(buffer.Length); 92 | fileWriter.Write(decompressedSize); 93 | 94 | // Write compressed buffer 95 | fileWriter.Write(buffer); 96 | } 97 | 98 | } 99 | } 100 | 101 | /// 102 | /// Reads a string terminated by a null byte 103 | /// 104 | /// Read String 105 | private static string ReadNullTerminatedString(BinaryReader br, int maxSize = -1) 106 | { 107 | // Create String Builder 108 | StringBuilder str = new StringBuilder(); 109 | // Current Byte Read 110 | int byteRead; 111 | // Size of String 112 | int size = 0; 113 | // Loop Until we hit terminating null character 114 | while ((byteRead = br.BaseStream.ReadByte()) != 0x0 && size++ != maxSize) 115 | str.Append(Convert.ToChar(byteRead)); 116 | // Ship back Result 117 | return str.ToString(); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace LuaDecompiler 8 | { 9 | class Program 10 | { 11 | public static PackageIndex AssetNameCache; 12 | 13 | static void Main(string[] args) 14 | { 15 | 16 | AssetNameCache = new PackageIndex(); 17 | AssetNameCache.Load(AppDomain.CurrentDomain.BaseDirectory + "\\PackageIndex\\bo4_localizedstrings.wni"); 18 | AssetNameCache.Load(AppDomain.CurrentDomain.BaseDirectory + "\\PackageIndex\\bo4_enums.wni"); 19 | AssetNameCache.Load(AppDomain.CurrentDomain.BaseDirectory + "\\PackageIndex\\bo4_functions.wni"); 20 | AssetNameCache.Load(AppDomain.CurrentDomain.BaseDirectory + "\\PackageIndex\\bo4_materials.wni"); 21 | Console.WriteLine("Bo3/4 Lua Disassembler by JariK"); 22 | LuaFile.errors = 0; 23 | string[] files = new string[1]; 24 | if (args.Length == 0) 25 | { 26 | Console.WriteLine("Give the folder that you want to decompile: "); 27 | string folder = Console.ReadLine(); 28 | if (Directory.Exists(folder)) 29 | { 30 | files = Directory.GetFiles(folder, "*.lua*", SearchOption.AllDirectories); 31 | } 32 | } 33 | else 34 | { 35 | files = args.Where(x => (Path.GetExtension(x) == ".lua" || Path.GetExtension(x) == ".luac") && File.Exists(x)).ToArray(); 36 | } 37 | 38 | foreach (string fileName in files) 39 | { 40 | if(Path.GetExtension(fileName) != ".lua" && Path.GetExtension(fileName) != ".luac") 41 | { 42 | continue; 43 | } 44 | Console.WriteLine("Exporting file: " + Path.GetFileName(fileName)); 45 | LuaFile luaFile = new LuaFile(fileName); 46 | luaFile.Disassemble(); 47 | luaFile.WriteDisassemble(fileName); 48 | LuaDecompiler lua = new LuaDecompiler(luaFile); 49 | lua.Decompile(fileName); 50 | } 51 | if(LuaFile.errors > 0 || files.Length > 1) 52 | Console.ReadLine(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("LuaDecompiler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("LuaDecompiler")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("72464c94-b88b-40c9-be51-c183e7d4aac6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/Util/IOExtensions.cs: -------------------------------------------------------------------------------- 1 | // ------------------------------------------------------------------------ 2 | // PhilLibX - My Utility Library 3 | // Copyright(c) 2018 Philip/Scobalula 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | // ------------------------------------------------------------------------ 23 | // File: IO/IOExtensions.cs 24 | // Author: Philip/Scobalula 25 | // Description: IO Utilities/Extensions for reading null terminated strings, scanning files, etc. 26 | using System; 27 | using System.Collections.Generic; 28 | using System.IO; 29 | using System.Text; 30 | 31 | namespace LuaDecompiler 32 | { 33 | /// 34 | /// IO Utilities/Extensions 35 | /// 36 | static class IOExtensions 37 | { 38 | /// 39 | /// Reads a string terminated by a null byte 40 | /// 41 | /// Read String 42 | public static string ReadNullTerminatedString(this BinaryReader br, int maxSize = -1) 43 | { 44 | // Create String Builder 45 | StringBuilder str = new StringBuilder(); 46 | // Current Byte Read 47 | int byteRead; 48 | // Size of String 49 | int size = 0; 50 | // Loop Until we hit terminating null character 51 | while ((byteRead = br.BaseStream.ReadByte()) != 0x0 && size++ != maxSize) 52 | str.Append(Convert.ToChar(byteRead)); 53 | // Ship back Result 54 | return str.ToString(); 55 | } 56 | 57 | /// 58 | /// Reads a string of fixed size 59 | /// 60 | /// Size of string in bytes 61 | /// Read String 62 | public static string ReadFixedString(this BinaryReader br, int numBytes) 63 | { 64 | // Purge Null Bytes and Return 65 | return Encoding.ASCII.GetString(br.ReadBytes(numBytes)).TrimEnd('\0'); 66 | } 67 | 68 | /// 69 | /// Sets the position of the Base Stream 70 | /// 71 | /// 72 | /// Offset to seek to. 73 | /// Seek Origin 74 | public static void Seek(this BinaryReader br, long offset, SeekOrigin seekOrigin) 75 | { 76 | // Set stream position 77 | br.BaseStream.Seek(offset, seekOrigin); 78 | } 79 | 80 | /// 81 | /// Finds occurences of a string in the stream 82 | /// 83 | /// Reader to use for scanning 84 | /// String Needle to search for 85 | /// Stops at first result 86 | /// Resulting offsets 87 | public static long[] FindString(this BinaryReader br, string needle, bool firstOccurence = false) 88 | { 89 | // Convert to bytes and scan 90 | return br.FindBytes(Encoding.ASCII.GetBytes(needle), firstOccurence); 91 | } 92 | 93 | /// 94 | /// Finds occurences of bytes in the stream 95 | /// 96 | /// Reader to use for scanning 97 | /// Byte Array Needle to search for 98 | /// Stops at first result 99 | /// Resulting offsets 100 | public static long[] FindBytes(this BinaryReader br, byte[] needle, bool firstOccurence = false) 101 | { 102 | // List of offsets in file. 103 | List offsets = new List(); 104 | 105 | // Buffer 106 | byte[] buffer = new byte[1048576]; 107 | 108 | // Bytes Read 109 | int bytesRead = 0; 110 | 111 | // Starting Offset 112 | long readBegin = br.BaseStream.Position; 113 | 114 | // Needle Index 115 | int needleIndex = 0; 116 | 117 | // Byte Array Index 118 | int bufferIndex = 0; 119 | 120 | // Read chunk of file 121 | while ((bytesRead = br.BaseStream.Read(buffer, 0, buffer.Length)) != 0) 122 | { 123 | // Loop through byte array 124 | for (bufferIndex = 0; bufferIndex < bytesRead; bufferIndex++) 125 | { 126 | // Check if current bytes match 127 | if (needle[needleIndex] == buffer[bufferIndex]) 128 | { 129 | // Increment 130 | needleIndex++; 131 | 132 | // Check if we have a match 133 | if (needleIndex == needle.Length) 134 | { 135 | // Add Offset 136 | offsets.Add(readBegin + bufferIndex + 1 - needle.Length); 137 | 138 | // Reset Index 139 | needleIndex = 0; 140 | 141 | // If only first occurence, end search 142 | if (firstOccurence) 143 | return offsets.ToArray(); 144 | } 145 | } 146 | else 147 | { 148 | // Reset Index 149 | needleIndex = 0; 150 | } 151 | } 152 | // Set next offset 153 | readBegin += bytesRead; 154 | } 155 | // Return offsets as an array 156 | return offsets.ToArray(); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/LuaDecompiler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/bin/Debug/LuaDecompiler.exe -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/LuaDecompiler.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/LuaDecompiler.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/bin/Debug/LuaDecompiler.pdb -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_enums.csv: -------------------------------------------------------------------------------- 1 | 7f032c2ef103a1a,UIVisibilityBit -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_enums.wni: -------------------------------------------------------------------------------- 1 | WNI  -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_functions.csv: -------------------------------------------------------------------------------- 1 | f9f1239cfd921fe,Localize -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_functions.wni: -------------------------------------------------------------------------------- 1 | WNI  -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_localizedstrings.wni: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_localizedstrings.wni -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_materials.csv: -------------------------------------------------------------------------------- 1 | 910274ca3518744,uie_wipe 2 | 4e6ce42e0799f57,ui_add -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Debug/PackageIndex/bo4_materials.wni: -------------------------------------------------------------------------------- 1 | WNI  -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Release/LZ4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/bin/Release/LZ4.dll -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Release/LuaDecompiler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/bin/Release/LuaDecompiler.exe -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Release/LuaDecompiler.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/bin/Release/LuaDecompiler.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/bin/Release/LuaDecompiler.pdb -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/Costura/52747D9E753E828D68B3C52748C212865F641B34.costura.costura.dll.compressed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/Costura/52747D9E753E828D68B3C52748C212865F641B34.costura.costura.dll.compressed -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/Costura/69D940D640B27E8C29C43802DEBD1C8357CF7D9B.costura.lz4.dll.compressed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/Costura/69D940D640B27E8C29C43802DEBD1C8357CF7D9B.costura.lz4.dll.compressed -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csproj.CopyComplete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csproj.CopyComplete -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | 088bce7458baf603c01b1955df9e693afddd9d93 2 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe.config 2 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe 3 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.pdb 4 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csprojAssemblyReference.cache 5 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csproj.CoreCompileInputs.cache 6 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.exe 7 | E:\ReverseEngineering\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.pdb 8 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe.config 9 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe 10 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.pdb 11 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csprojAssemblyReference.cache 12 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csproj.CoreCompileInputs.cache 13 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.exe 14 | C:\Users\HP Workstation\Desktop\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.pdb 15 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe.config 16 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe 17 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.pdb 18 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csprojAssemblyReference.cache 19 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csproj.CoreCompileInputs.cache 20 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.exe 21 | E:\ReverseEngineering\LuaDecompiler\CoD-Bo3-4-Lua-Disassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.pdb 22 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe.config 23 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe 24 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.pdb 25 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csprojAssemblyReference.cache 26 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csproj.CoreCompileInputs.cache 27 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.exe 28 | C:\Users\HP Workstation\Documents\GitHub\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.pdb 29 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe.config 30 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.exe 31 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Debug\LuaDecompiler.pdb 32 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csprojAssemblyReference.cache 33 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.csproj.CoreCompileInputs.cache 34 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.exe 35 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Debug\LuaDecompiler.pdb 36 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csproj.Fody.CopyLocal.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csproj.Fody.CopyLocal.cache -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csprojAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.csprojAssemblyReference.cache -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.exe -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/LuaDecompiler.pdb -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.csproj.CopyComplete: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.csproj.CopyComplete -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.csproj.CoreCompileInputs.cache: -------------------------------------------------------------------------------- 1 | fdd5bc9f95b9c172b6176e2c0f1e80a340ec2bb5 2 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Release\LuaDecompiler.exe.config 2 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Release\LuaDecompiler.exe 3 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Release\LuaDecompiler.pdb 4 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\bin\Release\LZ4.dll 5 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Release\LuaDecompiler.csproj.CoreCompileInputs.cache 6 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Release\LuaDecompiler.csproj.CopyComplete 7 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Release\LuaDecompiler.exe 8 | E:\ReverseEngineering\T7-8-LuaDissassembler\LuaDecompiler\LuaDecompiler\obj\Release\LuaDecompiler.pdb 9 | -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.exe -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Release/LuaDecompiler.pdb -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/LuaDecompiler/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /LuaDecompiler/LuaDecompiler/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/.signature.p7s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/.signature.p7s -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/Costura.Fody.3.3.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/Costura.Fody.3.3.0.nupkg -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/build/Costura.Fody.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netclassicweaver 5 | netstandardweaver 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/lib/net40/Costura.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/lib/net40/Costura.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/lib/net40/Costura.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Costura 5 | 6 | 7 | 8 | 9 | Contains methods for interacting with the Costura system. 10 | 11 | 12 | 13 | 14 | Call this to Initialize the Costura system. 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/netclassicweaver/Costura.Fody.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/netclassicweaver/Costura.Fody.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/netclassicweaver/Costura.Fody.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/netclassicweaver/Costura.Fody.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/netclassicweaver/Costura.Fody.xcf: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 7 | 8 | 9 | 10 | 11 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 12 | 13 | 14 | 15 | 16 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 17 | 18 | 19 | 20 | 21 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 22 | 23 | 24 | 25 | 26 | The order of preloaded assemblies, delimited with line breaks. 27 | 28 | 29 | 30 | 31 | 32 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 33 | 34 | 35 | 36 | 37 | Controls if .pdbs for reference assemblies are also embedded. 38 | 39 | 40 | 41 | 42 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 43 | 44 | 45 | 46 | 47 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 48 | 49 | 50 | 51 | 52 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 53 | 54 | 55 | 56 | 57 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 58 | 59 | 60 | 61 | 62 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 63 | 64 | 65 | 66 | 67 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 68 | 69 | 70 | 71 | 72 | A list of unmanaged 32 bit assembly names to include, delimited with |. 73 | 74 | 75 | 76 | 77 | A list of unmanaged 64 bit assembly names to include, delimited with |. 78 | 79 | 80 | 81 | 82 | The order of preloaded assemblies, delimited with |. 83 | 84 | 85 | -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/netstandardweaver/Costura.Fody.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/netstandardweaver/Costura.Fody.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/netstandardweaver/Costura.Fody.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Costura.Fody.3.3.0/netstandardweaver/Costura.Fody.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Costura.Fody.3.3.0/netstandardweaver/Costura.Fody.xcf: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 7 | 8 | 9 | 10 | 11 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 12 | 13 | 14 | 15 | 16 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 17 | 18 | 19 | 20 | 21 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 22 | 23 | 24 | 25 | 26 | The order of preloaded assemblies, delimited with line breaks. 27 | 28 | 29 | 30 | 31 | 32 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 33 | 34 | 35 | 36 | 37 | Controls if .pdbs for reference assemblies are also embedded. 38 | 39 | 40 | 41 | 42 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 43 | 44 | 45 | 46 | 47 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 48 | 49 | 50 | 51 | 52 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 53 | 54 | 55 | 56 | 57 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 58 | 59 | 60 | 61 | 62 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 63 | 64 | 65 | 66 | 67 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 68 | 69 | 70 | 71 | 72 | A list of unmanaged 32 bit assembly names to include, delimited with |. 73 | 74 | 75 | 76 | 77 | A list of unmanaged 64 bit assembly names to include, delimited with |. 78 | 79 | 80 | 81 | 82 | The order of preloaded assemblies, delimited with |. 83 | 84 | 85 | -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/.signature.p7s: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/.signature.p7s -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/Fody.3.3.5.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/Fody.3.3.5.nupkg -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/build/Fody.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(ProjectDir)FodyWeavers.xml 5 | $(MSBuildThisFileDirectory)..\ 6 | $(FodyPath)netstandardtask 7 | $(FodyPath)netclassictask 8 | $(FodyAssemblyDirectory)\Fody.dll 9 | $(MSBuildProjectFile).Fody.CopyLocal.cache 10 | $(DefaultItemExcludes);FodyWeavers.xsd 11 | true 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 52 | 53 | 56 | 57 | 58 | 59 | 60 | 61 | 65 | 66 | 70 | 71 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Fody.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Fody.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/FodyCommon.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/FodyCommon.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/FodyHelpers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/FodyHelpers.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/FodyIsolated.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/FodyIsolated.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Mdb.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Mdb.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Pdb.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Pdb.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Rocks.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.Rocks.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netclassictask/Mono.Cecil.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Fody.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Fody.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/FodyCommon.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/FodyCommon.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/FodyHelpers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/FodyHelpers.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/FodyIsolated.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/FodyIsolated.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Mdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Mdb.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Mdb.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Mdb.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Pdb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Pdb.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Pdb.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Pdb.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Rocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Rocks.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Rocks.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.Rocks.pdb -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.dll -------------------------------------------------------------------------------- /LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JariKCoding/T7-8-LuaDissassembler/5215235ceb2955742fc2985f923071d17d12f49e/LuaDecompiler/packages/Fody.3.3.5/netstandardtask/Mono.Cecil.pdb -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoD Bo3/4 Lua Disassembler 2 | ![Downloads](https://img.shields.io/github/downloads/JariKCoding/CoD-Bo3-4-Lua-Disassembler/total.svg) 3 | 4 | This is a tool that allows you to disassemble compiled lua files from CoD: Black ops 3 and 4. 5 | 6 | Im not providing a tool to extract these files from the game to prevent leaks. 7 | 8 | To use the program just drag the compiled lua file onto the .exe file 9 | 10 | ## Credits 11 | 12 | - DTZxPorter - Original lua disassembler to find the basics 13 | - Scobalula - Utilities 14 | 15 | ## License 16 | 17 | CoD Bo3/4 Lua Disassembler is licensed under the MIT license and its source code is free to use and modify. CoD Bo3/4 Lua Disassembler comes with NO warranty, any damages caused are solely the responsibility of the user. See the LICENSE file for more information. --------------------------------------------------------------------------------