├── .gitignore ├── CoDLUIDecompiler.sln ├── CoDLUIDecompiler ├── App.config ├── CoDLUIDecompiler.csproj ├── Games │ ├── BlackOps2.cs │ ├── BlackOps3.cs │ ├── Ghosts.cs │ └── WorldWar2.cs ├── Lua │ ├── Datatype.cs │ ├── LuaCondition.cs │ ├── LuaConstant.cs │ ├── LuaFile.cs │ ├── LuaFunction.cs │ ├── LuaInstruction.cs │ ├── LuaOpCode.cs │ └── LuaRegister.cs ├── LuaRipper │ ├── Games │ │ ├── AdvancedWarfare.cs │ │ ├── BlackOps2.cs │ │ ├── BlackOps3.cs │ │ ├── BlackOps4.cs │ │ ├── Ghosts.cs │ │ ├── InfiniteWarfare.cs │ │ ├── ModernWarfareRM.cs │ │ └── WorldWarII.cs │ └── MemoryLoading.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── Util │ └── PhilLibX │ ├── ByteUtil.cs │ ├── IO │ ├── IOExtensions.cs │ ├── MemoryUtil.cs │ └── ProcessReader.cs │ ├── MathUtilities.cs │ ├── NativeMethods.cs │ └── Printer.cs ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | 33 | # Visual Studio 2015/2017 cache/options directory 34 | .vs/ 35 | # Uncomment if you have tasks that create the project's static files in wwwroot 36 | #wwwroot/ 37 | 38 | # Visual Studio 2017 auto generated files 39 | Generated\ Files/ 40 | 41 | # MSTest test Results 42 | [Tt]est[Rr]esult*/ 43 | [Bb]uild[Ll]og.* 44 | 45 | # NUnit 46 | *.VisualState.xml 47 | TestResult.xml 48 | nunit-*.xml 49 | 50 | # Build Results of an ATL Project 51 | [Dd]ebugPS/ 52 | [Rr]eleasePS/ 53 | dlldata.c 54 | 55 | # Benchmark Results 56 | BenchmarkDotNet.Artifacts/ 57 | 58 | # .NET Core 59 | project.lock.json 60 | project.fragment.lock.json 61 | artifacts/ 62 | 63 | # StyleCop 64 | StyleCopReport.xml 65 | 66 | # Files built by Visual Studio 67 | *_i.c 68 | *_p.c 69 | *_h.h 70 | *.ilk 71 | *.meta 72 | *.obj 73 | *.iobj 74 | *.pch 75 | *.pdb 76 | *.ipdb 77 | *.pgc 78 | *.pgd 79 | *.rsp 80 | *.sbr 81 | *.tlb 82 | *.tli 83 | *.tlh 84 | *.tmp 85 | *.tmp_proj 86 | *_wpftmp.csproj 87 | *.log 88 | *.vspscc 89 | *.vssscc 90 | .builds 91 | *.pidb 92 | *.svclog 93 | *.scc 94 | 95 | # Chutzpah Test files 96 | _Chutzpah* 97 | 98 | # Visual C++ cache files 99 | ipch/ 100 | *.aps 101 | *.ncb 102 | *.opendb 103 | *.opensdf 104 | *.sdf 105 | *.cachefile 106 | *.VC.db 107 | *.VC.VC.opendb 108 | 109 | # Visual Studio profiler 110 | *.psess 111 | *.vsp 112 | *.vspx 113 | *.sap 114 | 115 | # Visual Studio Trace Files 116 | *.e2e 117 | 118 | # TFS 2012 Local Workspace 119 | $tf/ 120 | 121 | # Guidance Automation Toolkit 122 | *.gpState 123 | 124 | # ReSharper is a .NET coding add-in 125 | _ReSharper*/ 126 | *.[Rr]e[Ss]harper 127 | *.DotSettings.user 128 | 129 | # JustCode is a .NET coding add-in 130 | .JustCode 131 | 132 | # TeamCity is a build add-in 133 | _TeamCity* 134 | 135 | # DotCover is a Code Coverage Tool 136 | *.dotCover 137 | 138 | # AxoCover is a Code Coverage Tool 139 | .axoCover/* 140 | !.axoCover/settings.json 141 | 142 | # Visual Studio code coverage results 143 | *.coverage 144 | *.coveragexml 145 | 146 | # NCrunch 147 | _NCrunch_* 148 | .*crunch*.local.xml 149 | nCrunchTemp_* 150 | 151 | # MightyMoose 152 | *.mm.* 153 | AutoTest.Net/ 154 | 155 | # Web workbench (sass) 156 | .sass-cache/ 157 | 158 | # Installshield output folder 159 | [Ee]xpress/ 160 | 161 | # DocProject is a documentation generator add-in 162 | DocProject/buildhelp/ 163 | DocProject/Help/*.HxT 164 | DocProject/Help/*.HxC 165 | DocProject/Help/*.hhc 166 | DocProject/Help/*.hhk 167 | DocProject/Help/*.hhp 168 | DocProject/Help/Html2 169 | DocProject/Help/html 170 | 171 | # Click-Once directory 172 | publish/ 173 | 174 | # Publish Web Output 175 | *.[Pp]ublish.xml 176 | *.azurePubxml 177 | # Note: Comment the next line if you want to checkin your web deploy settings, 178 | # but database connection strings (with potential passwords) will be unencrypted 179 | *.pubxml 180 | *.publishproj 181 | 182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 183 | # checkin your Azure Web App publish settings, but sensitive information contained 184 | # in these scripts will be unencrypted 185 | PublishScripts/ 186 | 187 | # NuGet Packages 188 | *.nupkg 189 | # NuGet Symbol Packages 190 | *.snupkg 191 | # The packages folder can be ignored because of Package Restore 192 | **/[Pp]ackages/* 193 | # except build/, which is used as an MSBuild target. 194 | !**/[Pp]ackages/build/ 195 | # Uncomment if necessary however generally it will be regenerated when needed 196 | #!**/[Pp]ackages/repositories.config 197 | # NuGet v3's project.json files produces more ignorable files 198 | *.nuget.props 199 | *.nuget.targets 200 | 201 | # Microsoft Azure Build Output 202 | csx/ 203 | *.build.csdef 204 | 205 | # Microsoft Azure Emulator 206 | ecf/ 207 | rcf/ 208 | 209 | # Windows Store app package directories and files 210 | AppPackages/ 211 | BundleArtifacts/ 212 | Package.StoreAssociation.xml 213 | _pkginfo.txt 214 | *.appx 215 | *.appxbundle 216 | *.appxupload 217 | 218 | # Visual Studio cache files 219 | # files ending in .cache can be ignored 220 | *.[Cc]ache 221 | # but keep track of directories ending in .cache 222 | !?*.[Cc]ache/ 223 | 224 | # Others 225 | ClientBin/ 226 | ~$* 227 | *~ 228 | *.dbmdl 229 | *.dbproj.schemaview 230 | *.jfm 231 | *.pfx 232 | *.publishsettings 233 | orleans.codegen.cs 234 | 235 | # Including strong name files can present a security risk 236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 237 | #*.snk 238 | 239 | # Since there are multiple workflows, uncomment next line to ignore bower_components 240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 241 | #bower_components/ 242 | 243 | # RIA/Silverlight projects 244 | Generated_Code/ 245 | 246 | # Backup & report files from converting an old project file 247 | # to a newer Visual Studio version. Backup files are not needed, 248 | # because we have git ;-) 249 | _UpgradeReport_Files/ 250 | Backup*/ 251 | UpgradeLog*.XML 252 | UpgradeLog*.htm 253 | ServiceFabricBackup/ 254 | *.rptproj.bak 255 | 256 | # SQL Server files 257 | *.mdf 258 | *.ldf 259 | *.ndf 260 | 261 | # Business Intelligence projects 262 | *.rdl.data 263 | *.bim.layout 264 | *.bim_*.settings 265 | *.rptproj.rsuser 266 | *- [Bb]ackup.rdl 267 | *- [Bb]ackup ([0-9]).rdl 268 | *- [Bb]ackup ([0-9][0-9]).rdl 269 | 270 | # Microsoft Fakes 271 | FakesAssemblies/ 272 | 273 | # GhostDoc plugin setting file 274 | *.GhostDoc.xml 275 | 276 | # Node.js Tools for Visual Studio 277 | .ntvs_analysis.dat 278 | node_modules/ 279 | 280 | # Visual Studio 6 build log 281 | *.plg 282 | 283 | # Visual Studio 6 workspace options file 284 | *.opt 285 | 286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 287 | *.vbw 288 | 289 | # Visual Studio LightSwitch build output 290 | **/*.HTMLClient/GeneratedArtifacts 291 | **/*.DesktopClient/GeneratedArtifacts 292 | **/*.DesktopClient/ModelManifest.xml 293 | **/*.Server/GeneratedArtifacts 294 | **/*.Server/ModelManifest.xml 295 | _Pvt_Extensions 296 | 297 | # Paket dependency manager 298 | .paket/paket.exe 299 | paket-files/ 300 | 301 | # FAKE - F# Make 302 | .fake/ 303 | 304 | # CodeRush personal settings 305 | .cr/personal 306 | 307 | # Python Tools for Visual Studio (PTVS) 308 | __pycache__/ 309 | *.pyc 310 | 311 | # Cake - Uncomment if you are using it 312 | # tools/** 313 | # !tools/packages.config 314 | 315 | # Tabs Studio 316 | *.tss 317 | 318 | # Telerik's JustMock configuration file 319 | *.jmconfig 320 | 321 | # BizTalk build output 322 | *.btp.cs 323 | *.btm.cs 324 | *.odx.cs 325 | *.xsd.cs 326 | 327 | # OpenCover UI analysis results 328 | OpenCover/ 329 | 330 | # Azure Stream Analytics local run output 331 | ASALocalRun/ 332 | 333 | # MSBuild Binary and Structured Log 334 | *.binlog 335 | 336 | # NVidia Nsight GPU debugger configuration file 337 | *.nvuser 338 | 339 | # MFractors (Xamarin productivity tool) working folder 340 | .mfractor/ 341 | 342 | # Local History for Visual Studio 343 | .localhistory/ 344 | 345 | # BeatPulse healthcheck temp database 346 | healthchecksdb 347 | 348 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 349 | MigrationBackup/ 350 | 351 | # Ionide (cross platform F# VS Code tools) working folder 352 | .ionide/ 353 | 354 | .idea -------------------------------------------------------------------------------- /CoDLUIDecompiler.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.329 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoDLUIDecompiler", "CoDLUIDecompiler\CoDLUIDecompiler.csproj", "{086385A5-BA10-468D-87FA-5C00FFC55EC3}" 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 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {086385A5-BA10-468D-87FA-5C00FFC55EC3}.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 = {8493A899-A6CA-4ED8-A330-B59EBF5002BD} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/CoDLUIDecompiler.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {086385A5-BA10-468D-87FA-5C00FFC55EC3} 8 | Exe 9 | CoDLUIDecompiler 10 | CoDLUIDecompiler 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | false 27 | 28 | 29 | x64 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 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 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Games/BlackOps2.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 CoDLUIDecompiler 8 | { 9 | class BlackOps2 10 | { 11 | public static Dictionary OPCodeTable = new Dictionary() 12 | { 13 | // Same opcode table as bo3, they just dont have the shift left, right and bitwise operators 14 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD }, 15 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST }, 16 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I }, 17 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C }, 18 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ }, 19 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK }, 20 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL }, 21 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE }, 22 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF }, 23 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN }, 24 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S }, 25 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N }, 26 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE }, 27 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL }, 28 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP }, 29 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD }, 30 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S }, 31 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK }, 32 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N }, 33 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK }, 34 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE }, 35 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK }, 36 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I }, 37 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C }, 38 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M }, 39 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK }, 40 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL }, 41 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL }, 42 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP }, 43 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M }, 44 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL }, 45 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX }, 46 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX }, 47 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF }, 48 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL }, 49 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL }, 50 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL }, 51 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL }, 52 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL }, 53 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL }, 54 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD }, 55 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK }, 56 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB }, 57 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK }, 58 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL }, 59 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK }, 60 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV }, 61 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK }, 62 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD }, 63 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK }, 64 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW }, 65 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK }, 66 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE }, 67 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM }, 68 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT }, 69 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN }, 70 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT }, 71 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK }, 72 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE }, 73 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK }, 74 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT }, 75 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET }, 76 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP }, 77 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP }, 78 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST }, 79 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE }, 80 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE }, 81 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_VARARG }, 82 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 }, 83 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 }, 84 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 }, 85 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 }, 86 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 }, 87 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 }, 88 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 }, 89 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT }, 90 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_DATA }, 91 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN }, 92 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI }, 93 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT }, 94 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS }, 95 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT }, 96 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE }, 97 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES }, 98 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT }, 99 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT }, 100 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT }, 101 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT }, 102 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM }, 103 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D }, 104 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D }, 105 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM }, 106 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_MAX }, 107 | }; 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Games/BlackOps3.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 CoDLUIDecompiler 8 | { 9 | class BlackOps3 10 | { 11 | public static Dictionary OPCodeTable = new Dictionary() 12 | { 13 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD }, 14 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST }, 15 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I }, 16 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C }, 17 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ }, 18 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK }, 19 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL }, 20 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE }, 21 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF }, 22 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN }, 23 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S }, 24 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N }, 25 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE }, 26 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL }, 27 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP }, 28 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD }, 29 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S }, 30 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK }, 31 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N }, 32 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK }, 33 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE }, 34 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK }, 35 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I }, 36 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C }, 37 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M }, 38 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK }, 39 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL }, 40 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL }, 41 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP }, 42 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M }, 43 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL }, 44 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX }, 45 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX }, 46 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF }, 47 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL }, 48 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL }, 49 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL }, 50 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL }, 51 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL }, 52 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL }, 53 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD }, 54 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK }, 55 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB }, 56 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK }, 57 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL }, 58 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK }, 59 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV }, 60 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK }, 61 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD }, 62 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK }, 63 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW }, 64 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK }, 65 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE }, 66 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM }, 67 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT }, 68 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN }, 69 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT }, 70 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK }, 71 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE }, 72 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK }, 73 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT }, 74 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT_BK }, 75 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT }, 76 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT_BK }, 77 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND }, 78 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND_BK }, 79 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR }, 80 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR_BK }, 81 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT }, 82 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET }, 83 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP }, 84 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP }, 85 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST }, 86 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE }, 87 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE }, 88 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_VARARG }, 89 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 }, 90 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 }, 91 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 }, 92 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 }, 93 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 }, 94 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 }, 95 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 }, 96 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT }, 97 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_DATA }, 98 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN }, 99 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI }, 100 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT }, 101 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS }, 102 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT }, 103 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE }, 104 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES }, 105 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT }, 106 | { 93, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT }, 107 | { 94, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT }, 108 | { 95, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT }, 109 | { 96, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM }, 110 | { 97, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D }, 111 | { 98, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D }, 112 | { 99, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM }, 113 | { 100, LuaOpCode.OpCodes.HKS_OPCODE_MAX }, 114 | }; 115 | 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Games/Ghosts.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 CoDLUIDecompiler 8 | { 9 | class Ghosts 10 | { 11 | public static Dictionary OPCodeTable = new Dictionary() 12 | { 13 | // https://pastebin.com/4PhxeMjm 14 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD }, 15 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST }, 16 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I }, 17 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C }, 18 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ }, 19 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK }, 20 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL }, 21 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE }, 22 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF }, 23 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN }, 24 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S }, 25 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N }, 26 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE }, 27 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL }, 28 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP }, 29 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD }, 30 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S }, 31 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK }, 32 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N }, 33 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK }, 34 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE }, 35 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK }, 36 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I }, 37 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C }, 38 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M }, 39 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK }, 40 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL }, 41 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL }, 42 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP }, 43 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M }, 44 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL }, 45 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX }, 46 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX }, 47 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF }, 48 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL }, 49 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL }, 50 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL }, 51 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL }, 52 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL }, 53 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL }, 54 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD }, 55 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK }, 56 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB }, 57 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK }, 58 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL }, 59 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK }, 60 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV }, 61 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK }, 62 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD }, 63 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK }, 64 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW }, 65 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK }, 66 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE }, 67 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM }, 68 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT }, 69 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN }, 70 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT }, 71 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK }, 72 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE }, 73 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK }, 74 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT }, 75 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET }, 76 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP }, 77 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP }, 78 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST }, 79 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE }, 80 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE }, 81 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_VARARG }, 82 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 }, 83 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 }, 84 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 }, 85 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 }, 86 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 }, 87 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 }, 88 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 }, 89 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT }, 90 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_DATA }, 91 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN }, 92 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI }, 93 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT }, 94 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS }, 95 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT }, 96 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE }, 97 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES }, 98 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT }, 99 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT }, 100 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT }, 101 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT }, 102 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM }, 103 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D }, 104 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D }, 105 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM }, 106 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_DELETE }, 107 | { 93, LuaOpCode.OpCodes.HKS_OPCODE_DELETE_BK }, 108 | { 94, LuaOpCode.OpCodes.HKS_OPCODE_MAX }, 109 | }; 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Games/WorldWar2.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 CoDLUIDecompiler 8 | { 9 | class WorldWar2 10 | { 11 | public static Dictionary OPCodeTable = new Dictionary() 12 | { 13 | // Same opcode table as bo3, they just dont have the shift left, right and bitwise operators 14 | { 0, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD }, 15 | { 1, LuaOpCode.OpCodes.HKS_OPCODE_TEST }, 16 | { 2, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I }, 17 | { 3, LuaOpCode.OpCodes.HKS_OPCODE_CALL_C }, 18 | { 4, LuaOpCode.OpCodes.HKS_OPCODE_EQ }, 19 | { 5, LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK }, 20 | { 6, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL }, 21 | { 7, LuaOpCode.OpCodes.HKS_OPCODE_MOVE }, 22 | { 8, LuaOpCode.OpCodes.HKS_OPCODE_SELF }, 23 | { 9, LuaOpCode.OpCodes.HKS_OPCODE_RETURN }, 24 | { 10, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S }, 25 | { 11, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_N }, 26 | { 12, LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE }, 27 | { 13, LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL }, 28 | { 14, LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP }, 29 | { 15, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD }, 30 | { 16, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S }, 31 | { 17, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK }, 32 | { 18, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N }, 33 | { 19, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_N_BK }, 34 | { 20, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE }, 35 | { 21, LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_BK }, 36 | { 22, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I }, 37 | { 23, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_C }, 38 | { 24, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_M }, 39 | { 25, LuaOpCode.OpCodes.HKS_OPCODE_LOADK }, 40 | { 26, LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL }, 41 | { 27, LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL }, 42 | { 28, LuaOpCode.OpCodes.HKS_OPCODE_JMP }, 43 | { 29, LuaOpCode.OpCodes.HKS_OPCODE_CALL_M }, 44 | { 30, LuaOpCode.OpCodes.HKS_OPCODE_CALL }, 45 | { 31, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX }, 46 | { 32, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX }, 47 | { 33, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF }, 48 | { 34, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_INDEX_LITERAL }, 49 | { 35, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL }, 50 | { 36, LuaOpCode.OpCodes.HKS_OPCODE_INTRINSIC_SELF_LITERAL }, 51 | { 37, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL }, 52 | { 38, LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL }, 53 | { 39, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL }, 54 | { 40, LuaOpCode.OpCodes.HKS_OPCODE_ADD }, 55 | { 41, LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK }, 56 | { 42, LuaOpCode.OpCodes.HKS_OPCODE_SUB }, 57 | { 43, LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK }, 58 | { 44, LuaOpCode.OpCodes.HKS_OPCODE_MUL }, 59 | { 45, LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK }, 60 | { 46, LuaOpCode.OpCodes.HKS_OPCODE_DIV }, 61 | { 47, LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK }, 62 | { 48, LuaOpCode.OpCodes.HKS_OPCODE_MOD }, 63 | { 49, LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK }, 64 | { 50, LuaOpCode.OpCodes.HKS_OPCODE_POW }, 65 | { 51, LuaOpCode.OpCodes.HKS_OPCODE_POW_BK }, 66 | { 52, LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE }, 67 | { 53, LuaOpCode.OpCodes.HKS_OPCODE_UNM }, 68 | { 54, LuaOpCode.OpCodes.HKS_OPCODE_NOT }, 69 | { 55, LuaOpCode.OpCodes.HKS_OPCODE_LEN }, 70 | { 56, LuaOpCode.OpCodes.HKS_OPCODE_LT }, 71 | { 57, LuaOpCode.OpCodes.HKS_OPCODE_LT_BK }, 72 | { 58, LuaOpCode.OpCodes.HKS_OPCODE_LE }, 73 | { 59, LuaOpCode.OpCodes.HKS_OPCODE_LE_BK }, 74 | { 60, LuaOpCode.OpCodes.HKS_OPCODE_CONCAT }, 75 | { 61, LuaOpCode.OpCodes.HKS_OPCODE_TESTSET }, 76 | { 62, LuaOpCode.OpCodes.HKS_OPCODE_FORPREP }, 77 | { 63, LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP }, 78 | { 64, LuaOpCode.OpCodes.HKS_OPCODE_SETLIST }, 79 | { 65, LuaOpCode.OpCodes.HKS_OPCODE_CLOSE }, 80 | { 66, LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE }, 81 | { 67, LuaOpCode.OpCodes.HKS_OPCODE_VARARG }, 82 | { 68, LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1 }, 83 | { 69, LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1 }, 84 | { 70, LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL_R1 }, 85 | { 71, LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1 }, 86 | { 72, LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1 }, 87 | { 73, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1 }, 88 | { 74, LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1 }, 89 | { 75, LuaOpCode.OpCodes.HKS_OPCODE_NEWSTRUCT }, 90 | { 76, LuaOpCode.OpCodes.HKS_OPCODE_DATA }, 91 | { 77, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTN }, 92 | { 78, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTI }, 93 | { 79, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOT }, 94 | { 80, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTS }, 95 | { 81, LuaOpCode.OpCodes.HKS_OPCODE_SETSLOTMT }, 96 | { 82, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE }, 97 | { 83, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPES }, 98 | { 84, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT }, 99 | { 85, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOTMT }, 100 | { 86, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOT }, 101 | { 87, LuaOpCode.OpCodes.HKS_OPCODE_SELFSLOTMT }, 102 | { 88, LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_MM }, 103 | { 89, LuaOpCode.OpCodes.HKS_OPCODE_CHECKTYPE_D }, 104 | { 90, LuaOpCode.OpCodes.HKS_OPCODE_GETSLOT_D }, 105 | { 91, LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM }, 106 | { 92, LuaOpCode.OpCodes.HKS_OPCODE_MAX }, 107 | }; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/Datatype.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 CoDLUIDecompiler 8 | { 9 | class Datatype 10 | { 11 | public string Name; 12 | public int Id; 13 | public int Unk; 14 | 15 | public enum Type 16 | { 17 | Nil, 18 | Boolean, 19 | LightUserData, 20 | Number, 21 | String, 22 | Table, 23 | Function, 24 | UserData, 25 | Thread, 26 | IFunction, 27 | CFunction, 28 | UI64, 29 | Struct, 30 | XHash 31 | } 32 | 33 | public Datatype(int ID, int Unk, string Name) 34 | { 35 | this.Name = Name; 36 | this.Id = ID; 37 | this.Unk = Unk; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaCondition.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 CoDLUIDecompiler 8 | { 9 | class LuaCondition 10 | { 11 | public int line; 12 | 13 | public enum Type 14 | { 15 | If, 16 | For, 17 | Foreach, 18 | While, 19 | DoWhile, 20 | Else, 21 | End, 22 | } 23 | 24 | public enum Prefix 25 | { 26 | none, 27 | and, 28 | or 29 | } 30 | 31 | public Type type; 32 | 33 | public Prefix prefix; 34 | 35 | public LuaCondition master; 36 | 37 | public LuaCondition(int line, Type type, Prefix prefix = Prefix.none, LuaCondition master = null) 38 | { 39 | this.line = line; 40 | this.type = type; 41 | this.prefix = prefix; 42 | this.master = master; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaConstant.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 CoDLUIDecompiler 8 | { 9 | class LuaConstant 10 | { 11 | public Datatype.Type type; 12 | public string value; 13 | 14 | 15 | public string getString() 16 | { 17 | if (this.type == Datatype.Type.String && this.value != "nil") 18 | return "\"" + this.value + "\""; 19 | else 20 | return this.value; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Reflection; 6 | using PhilLibX.IO; 7 | 8 | namespace CoDLUIDecompiler 9 | { 10 | class LuaFile 11 | { 12 | public BinaryReader inputReader; 13 | public StreamWriter outputWriter; 14 | 15 | private byte luaVersion; 16 | private byte compilerVersion; 17 | private byte endianness; 18 | private byte sizeOfInt; 19 | private byte sizeOfSizeT; 20 | private byte sizeOfIntruction; 21 | private byte sizeOfLuaNumber; 22 | private byte integralFlag; 23 | private byte gameByte; 24 | private int dataTypeCount; 25 | 26 | public Dictionary OPCodeTable; 27 | 28 | private Datatype[] Datatypes; 29 | 30 | public SupportedGames Game; 31 | 32 | public enum SupportedGames 33 | { 34 | BlackOps2, 35 | BlackOps3, 36 | WorldWar2, 37 | } 38 | 39 | public LuaFile(string filePath) 40 | { 41 | this.inputReader = new BinaryReader(new FileStream(filePath, FileMode.Open)); 42 | // Make sure its a valid lua file by reading the header 43 | if (!this.readHeader()) 44 | { 45 | this.inputReader.Close(); 46 | return; 47 | } 48 | this.outputWriter = new StreamWriter(filePath + "dec"); 49 | this.outputWriter.WriteLine("-- Decompiled with CoDLUIDecompiler by JariK\n"); 50 | this.LoadGame(); 51 | this.readInitFunction(); 52 | this.outputWriter.Close(); 53 | } 54 | 55 | public bool readHeader() 56 | { 57 | if (this.inputReader.BaseStream.Length < 5 || this.inputReader.ReadBytes(4).Equals(new byte[] { 0x1B, 0x4C, 0x75, 0x61 })) 58 | { 59 | Console.WriteLine("Lua file invalid"); 60 | return false; 61 | } 62 | // Jump 9 bytes 63 | this.luaVersion = this.inputReader.ReadByte(); 64 | this.compilerVersion = this.inputReader.ReadByte(); 65 | this.endianness = this.inputReader.ReadByte(); 66 | this.sizeOfInt = this.inputReader.ReadByte(); 67 | this.sizeOfSizeT = this.inputReader.ReadByte(); 68 | this.sizeOfIntruction = this.inputReader.ReadByte(); 69 | this.sizeOfLuaNumber = this.inputReader.ReadByte(); 70 | this.integralFlag = this.inputReader.ReadByte(); 71 | this.gameByte = this.inputReader.ReadByte(); 72 | 73 | byte Unk = this.inputReader.ReadByte(); 74 | // Get the datatypes count 75 | this.dataTypeCount = this.inputReader.ReadInt32(); 76 | this.Datatypes = new Datatype[this.dataTypeCount]; 77 | // Read all the datatypes 78 | for (int i = 0; i < this.dataTypeCount; i++) 79 | { 80 | this.Datatypes[i] = new Datatype( 81 | this.inputReader.ReadInt32(), 82 | this.inputReader.ReadInt32(), 83 | this.inputReader.ReadNullTerminatedString() 84 | ); 85 | } 86 | return true; 87 | } 88 | 89 | public void LoadGame() 90 | { 91 | this.OPCodeTable = BlackOps3.OPCodeTable; 92 | this.Game = SupportedGames.BlackOps3; 93 | if (this.compilerVersion == 0xD) 94 | { 95 | this.OPCodeTable = BlackOps2.OPCodeTable; 96 | this.Game = SupportedGames.BlackOps2; 97 | } 98 | else if (this.gameByte == 3) 99 | { 100 | // OPCode table is the same for IW but 101 | // Same opcodetable as bo2 but has some structure differences 102 | this.OPCodeTable = WorldWar2.OPCodeTable; 103 | this.Game = SupportedGames.WorldWar2; 104 | } 105 | if (this.compilerVersion == 0xD && this.gameByte == 3) 106 | { 107 | this.OPCodeTable = WorldWar2.OPCodeTable; 108 | this.Game = SupportedGames.WorldWar2; 109 | } 110 | } 111 | 112 | public void readInitFunction() 113 | { 114 | new LuaFunction(this, 0, true).decompile(); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaFunction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using PhilLibX.IO; 7 | 8 | namespace CoDLUIDecompiler 9 | { 10 | class LuaFunction 11 | { 12 | public int upValsCount; 13 | public int parameterCount; 14 | public int registerCount; 15 | public int instructionCount; 16 | public int constantCount; 17 | public int subFunctionCount; 18 | 19 | public bool usesVarArg; 20 | 21 | private LuaFile luaFile; 22 | 23 | public LuaInstruction[] Instructions; 24 | public List Upvalues; 25 | public LuaConstant[] Constants; 26 | public LuaRegister[] Registers; 27 | public LuaFunction[] SubFunctions; 28 | 29 | public List tablePositions; 30 | 31 | public List endPositions; 32 | public List elsePositions; 33 | public string orCondition; 34 | 35 | public List conditions; 36 | 37 | public bool isInitFunction; 38 | public LuaFunction superFunction; 39 | public int tabLevel; 40 | public int instructionPtr; 41 | public LuaInstruction currentInstruction; 42 | 43 | public string newName; 44 | 45 | public long startPosition; 46 | public long endPosition; 47 | public BinaryReader inputReader; 48 | public StreamWriter outputWriter; 49 | 50 | public LuaFunction(LuaFile luaFile, int tabLevel = 0, bool IsInitFunction = false, LuaFunction SuperFunction = null) 51 | { 52 | this.inputReader = luaFile.inputReader; 53 | this.outputWriter = luaFile.outputWriter; 54 | this.luaFile = luaFile; 55 | this.tabLevel = tabLevel; 56 | this.isInitFunction = IsInitFunction; 57 | this.superFunction = SuperFunction; 58 | this.startPosition = this.inputReader.BaseStream.Position; 59 | // Read the header 60 | this.readHeader(); 61 | // Read all instructions 62 | this.readInstructions(); 63 | // Read all constants 64 | this.readConstants(); 65 | // read the footer 66 | this.readFooter(); 67 | // read the sub functions 68 | this.readSubFunctions(); 69 | } 70 | 71 | private void readHeader() 72 | { 73 | this.upValsCount = this.inputReader.ReadInt32(); 74 | this.Upvalues = new List(); 75 | this.parameterCount = this.inputReader.ReadInt32(); 76 | int flags = inputReader.ReadByte(); 77 | if (flags != 0) 78 | { 79 | this.usesVarArg = true; 80 | } 81 | this.registerCount = this.inputReader.ReadInt32(); 82 | this.instructionCount = this.inputReader.ReadInt32(); 83 | 84 | // Some unknown bytes (BO3 and BO4) almost 0 85 | if(this.luaFile.Game != LuaFile.SupportedGames.BlackOps2) 86 | { 87 | int weirdint = this.inputReader.ReadInt32(); 88 | } 89 | 90 | // Add extra bytes to make it line up 91 | int extra = 4 - ((int)this.inputReader.BaseStream.Position % 4); 92 | if (extra > 0 && extra < 4) 93 | this.inputReader.ReadBytes(extra); 94 | 95 | this.conditions = new List(); 96 | this.tablePositions = new List(); 97 | this.endPositions = new List(); 98 | this.elsePositions = new List(); 99 | this.orCondition = ""; 100 | } 101 | 102 | private void readFooter() 103 | { 104 | int unkInt = this.inputReader.ReadInt32(); 105 | if (luaFile.Game != LuaFile.SupportedGames.WorldWar2) 106 | { 107 | float unkFloat = this.inputReader.ReadSingle(); 108 | } 109 | 110 | this.subFunctionCount = this.inputReader.ReadInt32(); 111 | this.endPosition = this.inputReader.BaseStream.Position; 112 | } 113 | 114 | private void readInstructions() 115 | { 116 | // Create array for instructions 117 | this.Instructions = new LuaInstruction[this.instructionCount]; 118 | // Go through all instructions 119 | for (int i = 0; i < this.instructionCount; i++) 120 | { 121 | // Making a new instruction 122 | LuaInstruction instruction = new LuaInstruction(this); 123 | // Reading the values attached to the instruction 124 | // A = 8 bits 125 | // B = 9 bits 126 | // C = 8 bits 127 | // OpCode = 7 bits 128 | instruction.A = this.inputReader.ReadByte(); 129 | 130 | int cValue = this.inputReader.ReadByte(); 131 | byte bValue = this.inputReader.ReadByte(); 132 | if (GetBit(bValue, 0) == 1) 133 | cValue += 256; 134 | instruction.C = cValue; 135 | 136 | instruction.B = bValue >> 1; 137 | byte flagsB = this.inputReader.ReadByte(); 138 | if (GetBit(flagsB, 0) == 1) 139 | instruction.B += 128; 140 | 141 | instruction.Bx = (instruction.B * 512) + instruction.C; 142 | instruction.sBx = instruction.Bx - 65536 + 1; 143 | 144 | if(this.luaFile.OPCodeTable.TryGetValue(flagsB >> 1, out LuaOpCode.OpCodes opcode)) 145 | { 146 | instruction.OpCode = opcode; 147 | } 148 | else 149 | { 150 | instruction.OpCode = LuaOpCode.OpCodes.HKS_OPCODE_UNK; 151 | } 152 | 153 | // Add to array 154 | this.Instructions[i] = instruction; 155 | } 156 | } 157 | 158 | private void readConstants() 159 | { 160 | this.constantCount = this.inputReader.ReadInt32(); 161 | // Create array for constants 162 | this.Constants = new LuaConstant[this.constantCount]; 163 | // Go through all constants 164 | for (int i = 0; i < this.constantCount; i++) 165 | { 166 | // Make a new constant object 167 | LuaConstant constant = new LuaConstant(); 168 | // Read the type of constant 169 | constant.type = (Datatype.Type)this.inputReader.ReadByte(); 170 | // Check if its a constant we can read 171 | switch (constant.type) 172 | { 173 | case Datatype.Type.Nil: 174 | constant.value = "nil"; 175 | break; 176 | case Datatype.Type.Boolean: 177 | constant.value = (this.inputReader.ReadByte() == 1) ? "true" : "false"; 178 | break; 179 | case Datatype.Type.Number: 180 | constant.value = this.inputReader.ReadSingle().ToString("0.000000"); 181 | break; 182 | case Datatype.Type.String: 183 | int stringLength = this.inputReader.ReadInt32(); 184 | if(this.luaFile.Game != LuaFile.SupportedGames.BlackOps2) 185 | { 186 | int unkInt = this.inputReader.ReadInt32(); 187 | } 188 | constant.value = this.inputReader.ReadNullTerminatedString(); 189 | break; 190 | case Datatype.Type.XHash: 191 | // TODO : Add support for switch to string 192 | constant.value = String.Format("0x{0:X}", this.inputReader.ReadUInt64() & 0xFFFFFFFFFFFFFFF); 193 | break; 194 | default: 195 | constant.value = "Unknown constant type"; 196 | break; 197 | } 198 | // Add it to the array 199 | this.Constants[i] = constant; 200 | } 201 | } 202 | 203 | private void readSubFunctions() 204 | { 205 | this.SubFunctions = new LuaFunction[this.subFunctionCount]; 206 | for (int i = 0; i < this.subFunctionCount; i++) 207 | { 208 | SubFunctions[i] = new LuaFunction(this.luaFile, this.tabLevel + 1, false, this); 209 | } 210 | } 211 | 212 | public void decompile(int tabLevel = 0, bool inline = false) 213 | { 214 | #if DEBUG 215 | this.writeLine(String.Format("-- OP Count: 0x{0:X}", this.instructionCount)); 216 | this.writeLine(String.Format("-- Constant Count: 0x{0:X}", this.constantCount)); 217 | this.writeLine(String.Format("-- Registers Count: 0x{0:X}", this.registerCount)); 218 | this.writeLine(String.Format("-- UpValue Count: 0x{0:X}", this.upValsCount)); 219 | this.writeLine(String.Format("-- SubFuncs Count: 0x{0:X}", this.subFunctionCount)); 220 | #endif 221 | 222 | FindWhileLoops(); 223 | FindDoWhileLoops(); 224 | FindIfStatements(); 225 | FindForEachLoops(); 226 | 227 | for (int i = 0; i < this.instructionCount; i++) 228 | { 229 | this.Instructions[i].visited = false; 230 | } 231 | 232 | this.tabLevel = tabLevel; 233 | this.Registers = new LuaRegister[this.registerCount]; 234 | for (int i = 0; i < this.registerCount; i++) 235 | { 236 | this.Registers[i] = new LuaRegister(i); 237 | } 238 | 239 | // Write the function header if it isnt the init function 240 | if (!this.isInitFunction) 241 | { 242 | // Look if we have a inline function 243 | if (inline) 244 | { 245 | outputWriter.Write("function ("); 246 | } 247 | else if (this.newName == null) 248 | { 249 | write("local function " + String.Format("__FUNC_{0:X}_", this.startPosition) + "(", -1); 250 | } 251 | else 252 | { 253 | write("function " + this.newName + "(", -1); 254 | } 255 | int argIndex = 0, fixedIndex = 0; 256 | while (argIndex < this.parameterCount) 257 | { 258 | if (this.Upvalues.Contains("arg" + fixedIndex)) 259 | { 260 | fixedIndex++; 261 | continue; 262 | } 263 | this.Registers[argIndex].initialze("arg" + fixedIndex); 264 | outputWriter.Write(((argIndex > 0) ? ", " : "") + "arg" + fixedIndex++); 265 | argIndex++; 266 | } 267 | if (this.usesVarArg) 268 | { 269 | if (this.parameterCount > 0) 270 | outputWriter.Write(", "); 271 | outputWriter.Write("..."); 272 | } 273 | outputWriter.Write(")\n"); 274 | } 275 | 276 | this.instructionPtr = 0; 277 | while (this.instructionPtr < this.instructionCount) 278 | { 279 | try 280 | { 281 | currentInstruction = this.Instructions[instructionPtr]; 282 | 283 | if(HasCondition() || currentInstruction.visited == true) 284 | { 285 | nextInstruction(); 286 | continue; 287 | } 288 | if(LuaOpCode.OPCodeFunctions.TryGetValue(currentInstruction.OpCode, out Func func)) 289 | { 290 | func(this); 291 | } 292 | else 293 | { 294 | this.writeLine(String.Format("Unhandled OpCode: {0} ({1}, {2}, {3}, 0x{4:X})", 295 | currentInstruction.OpCode, 296 | currentInstruction.A, 297 | currentInstruction.B, 298 | currentInstruction.C, 299 | (int)currentInstruction.OpCode)); 300 | } 301 | foreach (LuaCondition condition in this.conditions) 302 | { 303 | if (condition.line == this.instructionPtr) 304 | { 305 | if (condition.type == LuaCondition.Type.End) 306 | { 307 | this.tabLevel--; 308 | this.writeLine("end"); 309 | } 310 | else if (condition.type == LuaCondition.Type.Else) 311 | { 312 | this.writeLine("else", -1); 313 | } 314 | } 315 | } 316 | } 317 | catch(Exception e) 318 | { 319 | Console.WriteLine("Error @ " + this.instructionPtr + ": " + e.Message + " & " + this.Instructions[instructionPtr].OpCode); 320 | } 321 | nextInstruction(); 322 | } 323 | 324 | // Add an ending to the function 325 | if (!this.isInitFunction) 326 | { 327 | writeLine("end", -1); 328 | this.outputWriter.WriteLine(); 329 | } 330 | } 331 | 332 | public bool HasCondition() 333 | { 334 | foreach(LuaCondition condition in this.conditions) 335 | { 336 | if(condition.line == this.instructionPtr && condition.prefix == LuaCondition.Prefix.none) 337 | { 338 | if(condition.type == LuaCondition.Type.Else || condition.type == LuaCondition.Type.End) 339 | { 340 | continue; 341 | } 342 | 343 | if (condition.type == LuaCondition.Type.Foreach) 344 | { 345 | int baseVal = this.Instructions[this.instructionPtr + this.currentInstruction.C + 2].A + 3; 346 | this.Registers[baseVal].value = "index" + baseVal; 347 | this.Registers[baseVal + 1].value = "value" + (baseVal + 1); 348 | this.writeLine(String.Format("for {0},{1} in {2}, {3}, {4} do", 349 | this.Registers[baseVal].value, 350 | this.Registers[baseVal + 1].value, 351 | this.Registers[baseVal - 3].value, 352 | this.Registers[baseVal - 2].value, 353 | this.Registers[baseVal - 1].value)); 354 | this.tabLevel++; 355 | continue; 356 | } 357 | 358 | string expression = BuildExpression(condition); 359 | if(condition.type == LuaCondition.Type.If) 360 | { 361 | this.writeLine(String.Format("if {0} then", expression)); 362 | this.tabLevel++; 363 | } 364 | else if(condition.type == LuaCondition.Type.DoWhile) 365 | { 366 | this.writeLine(String.Format("until {0}", expression)); 367 | } 368 | return true; 369 | } 370 | } 371 | return false; 372 | } 373 | 374 | public string BuildExpression(LuaCondition masterCondition) 375 | { 376 | string Expression = ProcessInstructionReturnString(); 377 | nextInstruction(); 378 | int ChildExpressions = 0; 379 | foreach (LuaCondition condition in this.conditions) 380 | { 381 | if(condition.master == masterCondition) 382 | { 383 | ChildExpressions++; 384 | } 385 | } 386 | while(ChildExpressions > 0 && this.instructionPtr < this.instructionCount) 387 | { 388 | bool done = false; 389 | currentInstruction = this.Instructions[instructionPtr]; 390 | foreach (LuaCondition condition in this.conditions) 391 | { 392 | if (condition.master == masterCondition && condition.line == this.instructionPtr) 393 | { 394 | Expression += String.Format(" {0} ", condition.prefix); 395 | Expression += ProcessInstructionReturnString(); 396 | ChildExpressions--; 397 | done = true; 398 | } 399 | } 400 | if (!done) 401 | { 402 | ProcessInstructionReturnString(); 403 | } 404 | nextInstruction(); 405 | 406 | } 407 | return Expression; 408 | } 409 | 410 | public string ProcessInstructionReturnString() 411 | { 412 | if (LuaOpCode.OPCodeFunctions.TryGetValue(currentInstruction.OpCode, out Func func)) 413 | { 414 | return func(this); 415 | } 416 | else 417 | { 418 | return (String.Format("Unhandled OpCode: {0} ({1}, {2}, {3}, 0x{4:X})", 419 | currentInstruction.OpCode, 420 | currentInstruction.A, 421 | currentInstruction.B, 422 | currentInstruction.C, 423 | (int)currentInstruction.OpCode)); 424 | } 425 | } 426 | 427 | public void FindWhileLoops() 428 | { 429 | for(int i = 0; i < this.instructionCount; i++) 430 | { 431 | if(this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP) 432 | { 433 | if(this.Instructions[i].sBx < 0 && i + this.Instructions[i].sBx >= 0) 434 | { 435 | if(LuaOpCode.isConditionOPCode(this, i + this.Instructions[i].sBx + 1)) 436 | { 437 | this.Instructions[i].visited = true; 438 | } 439 | } 440 | } 441 | } 442 | } 443 | 444 | public void FindDoWhileLoops() 445 | { 446 | for (int i = 0; i < this.instructionCount; i++) 447 | { 448 | if (this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i].visited == false) 449 | { 450 | if (this.Instructions[i].sBx < 0 && i + this.Instructions[i].sBx >= 0) 451 | { 452 | if (LuaOpCode.isConditionOPCode(this, i - 1)) 453 | { 454 | this.Instructions[i].visited = true; 455 | } 456 | } 457 | } 458 | } 459 | } 460 | 461 | public void FindIfStatements() 462 | { 463 | int lines = -1; 464 | LuaCondition master = null; 465 | for (int i = 0; i < this.instructionCount; i++) 466 | { 467 | if (this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i].visited == false) 468 | { 469 | // Make sure the skip goes forward 470 | if (this.Instructions[i].sBx >= 0) 471 | { 472 | if (LuaOpCode.isConditionOPCode(this, i - 1)) 473 | { 474 | // Skip the while loops 475 | if (this.Instructions[i + this.Instructions[i].sBx].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i + this.Instructions[i].sBx].sBx < 0) 476 | { 477 | continue; 478 | } 479 | // OR statement 480 | if(lines == 0) 481 | { 482 | this.conditions.Add(new LuaCondition(i - 1, LuaCondition.Type.If, LuaCondition.Prefix.or, master)); 483 | this.Instructions[i].visited = true; 484 | lines--; 485 | continue; 486 | } 487 | // and statement 488 | if(lines == this.Instructions[i].sBx) 489 | { 490 | this.conditions.Add(new LuaCondition(i - 1, LuaCondition.Type.If, LuaCondition.Prefix.and, master)); 491 | this.Instructions[i].visited = true; 492 | lines--; 493 | continue; 494 | } 495 | master = new LuaCondition(i - 1, LuaCondition.Type.If, LuaCondition.Prefix.none); 496 | this.conditions.Add(master); 497 | lines = this.Instructions[i].sBx; 498 | this.Instructions[i].visited = true; 499 | } 500 | } 501 | } 502 | lines--; 503 | } 504 | List newConditions = new List(); 505 | foreach (LuaCondition condition in this.conditions) 506 | { 507 | if(condition.master == null) 508 | { 509 | LuaCondition lastSon = condition; 510 | foreach (LuaCondition conditionSon in this.conditions) 511 | { 512 | if(conditionSon.master == condition) 513 | { 514 | if(conditionSon.prefix == LuaCondition.Prefix.or) 515 | { 516 | if (this.Instructions[lastSon.line].A == 1) 517 | this.Instructions[lastSon.line].A = 0; 518 | else 519 | this.Instructions[lastSon.line].A = 1; 520 | } 521 | lastSon = conditionSon; 522 | } 523 | } 524 | int skipLines = this.Instructions[lastSon.line + 1].sBx; 525 | if(this.Instructions[lastSon.line + 1 + skipLines].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP) 526 | { 527 | newConditions.Add(new LuaCondition(lastSon.line + 1 + skipLines, LuaCondition.Type.Else)); 528 | int skipElseLines = this.Instructions[lastSon.line + 1 + skipLines].sBx; 529 | newConditions.Add(new LuaCondition(lastSon.line + 1 + skipLines + skipElseLines, LuaCondition.Type.End)); 530 | } 531 | else 532 | { 533 | newConditions.Add(new LuaCondition(lastSon.line + 1 + skipLines, LuaCondition.Type.End)); 534 | } 535 | } 536 | } 537 | foreach (LuaCondition condition in newConditions) 538 | { 539 | this.conditions.Add(condition); 540 | } 541 | } 542 | 543 | public void FindForEachLoops() 544 | { 545 | for (int i = 0; i < this.instructionCount; i++) 546 | { 547 | if (this.Instructions[i].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_JMP && this.Instructions[i].visited == false) 548 | { 549 | if (this.Instructions[i].sBx < 0) 550 | { 551 | if(this.Instructions[i - 1].OpCode == LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP) 552 | { 553 | this.Instructions[i].visited = true; 554 | 555 | this.conditions.Add(new LuaCondition(i + this.Instructions[i].sBx, LuaCondition.Type.Foreach)); 556 | this.conditions.Add(new LuaCondition(i, LuaCondition.Type.End)); 557 | } 558 | } 559 | } 560 | } 561 | } 562 | 563 | public void nextInstruction() 564 | { 565 | this.instructionPtr++; 566 | } 567 | 568 | public void writeLine(string text, int extra = 0) 569 | { 570 | for (int i = 0; i < this.tabLevel + extra + this.endPositions.Count + this.tablePositions.Count; i++) 571 | { 572 | this.outputWriter.Write("\t"); 573 | } 574 | this.outputWriter.Write(text + "\n"); 575 | } 576 | 577 | public void write(string text, int extra = 0) 578 | { 579 | for (int i = 0; i < this.tabLevel + extra + this.endPositions.Count + this.tablePositions.Count; i++) 580 | { 581 | this.outputWriter.Write("\t"); 582 | } 583 | this.outputWriter.Write(text); 584 | } 585 | 586 | private static byte GetBit(long input, int bit) 587 | { 588 | return (byte)((input >> bit) & 1); 589 | } 590 | } 591 | } 592 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaInstruction.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 CoDLUIDecompiler 8 | { 9 | class LuaInstruction 10 | { 11 | public byte A; 12 | public int B; 13 | public int C; 14 | public LuaOpCode.OpCodes OpCode; 15 | public int Bx; 16 | public int sBx; 17 | public bool visited = false; 18 | 19 | private LuaFunction function; 20 | 21 | public LuaInstruction(LuaFunction function) 22 | { 23 | this.function = function; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaOpCode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using PhilLibX.IO; 7 | 8 | namespace CoDLUIDecompiler 9 | { 10 | class LuaOpCode 11 | { 12 | public enum OpCodes : byte 13 | { 14 | HKS_OPCODE_GETFIELD, 15 | HKS_OPCODE_TEST, 16 | HKS_OPCODE_CALL_I, 17 | HKS_OPCODE_CALL_C, 18 | HKS_OPCODE_EQ, 19 | HKS_OPCODE_EQ_BK, 20 | HKS_OPCODE_GETGLOBAL, 21 | HKS_OPCODE_MOVE, 22 | HKS_OPCODE_SELF, 23 | HKS_OPCODE_RETURN, 24 | HKS_OPCODE_GETTABLE_S, 25 | HKS_OPCODE_GETTABLE_N, 26 | HKS_OPCODE_GETTABLE, 27 | HKS_OPCODE_LOADBOOL, 28 | HKS_OPCODE_TFORLOOP, 29 | HKS_OPCODE_SETFIELD, 30 | HKS_OPCODE_SETTABLE_S, 31 | HKS_OPCODE_SETTABLE_S_BK, 32 | HKS_OPCODE_SETTABLE_N, 33 | HKS_OPCODE_SETTABLE_N_BK, 34 | HKS_OPCODE_SETTABLE, 35 | HKS_OPCODE_SETTABLE_BK, 36 | HKS_OPCODE_TAILCALL_I, 37 | HKS_OPCODE_TAILCALL_C, 38 | HKS_OPCODE_TAILCALL_M, 39 | HKS_OPCODE_LOADK, 40 | HKS_OPCODE_LOADNIL, 41 | HKS_OPCODE_SETGLOBAL, 42 | HKS_OPCODE_JMP, 43 | HKS_OPCODE_CALL_M, 44 | HKS_OPCODE_CALL, 45 | HKS_OPCODE_INTRINSIC_INDEX, 46 | HKS_OPCODE_INTRINSIC_NEWINDEX, 47 | HKS_OPCODE_INTRINSIC_SELF, 48 | HKS_OPCODE_INTRINSIC_INDEX_LITERAL, 49 | HKS_OPCODE_INTRINSIC_NEWINDEX_LITERAL, 50 | HKS_OPCODE_INTRINSIC_SELF_LITERAL, 51 | HKS_OPCODE_TAILCALL, 52 | HKS_OPCODE_GETUPVAL, 53 | HKS_OPCODE_SETUPVAL, 54 | HKS_OPCODE_ADD, 55 | HKS_OPCODE_ADD_BK, 56 | HKS_OPCODE_SUB, 57 | HKS_OPCODE_SUB_BK, 58 | HKS_OPCODE_MUL, 59 | HKS_OPCODE_MUL_BK, 60 | HKS_OPCODE_DIV, 61 | HKS_OPCODE_DIV_BK, 62 | HKS_OPCODE_MOD, 63 | HKS_OPCODE_MOD_BK, 64 | HKS_OPCODE_POW, 65 | HKS_OPCODE_POW_BK, 66 | HKS_OPCODE_NEWTABLE, 67 | HKS_OPCODE_UNM, 68 | HKS_OPCODE_NOT, 69 | HKS_OPCODE_LEN, 70 | HKS_OPCODE_LT, 71 | HKS_OPCODE_LT_BK, 72 | HKS_OPCODE_LE, 73 | HKS_OPCODE_LE_BK, 74 | HKS_OPCODE_SHIFT_LEFT, 75 | HKS_OPCODE_SHIFT_LEFT_BK, 76 | HKS_OPCODE_SHIFT_RIGHT, 77 | HKS_OPCODE_SHIFT_RIGHT_BK, 78 | HKS_OPCODE_BITWISE_AND, 79 | HKS_OPCODE_BITWISE_AND_BK, 80 | HKS_OPCODE_BITWISE_OR, 81 | HKS_OPCODE_BITWISE_OR_BK, 82 | HKS_OPCODE_CONCAT, 83 | HKS_OPCODE_TESTSET, 84 | HKS_OPCODE_FORPREP, 85 | HKS_OPCODE_FORLOOP, 86 | HKS_OPCODE_SETLIST, 87 | HKS_OPCODE_CLOSE, 88 | HKS_OPCODE_CLOSURE, 89 | HKS_OPCODE_VARARG, 90 | HKS_OPCODE_TAILCALL_I_R1, 91 | HKS_OPCODE_CALL_I_R1, 92 | HKS_OPCODE_SETUPVAL_R1, 93 | HKS_OPCODE_TEST_R1, 94 | HKS_OPCODE_NOT_R1, 95 | HKS_OPCODE_GETFIELD_R1, 96 | HKS_OPCODE_SETFIELD_R1, 97 | HKS_OPCODE_NEWSTRUCT, 98 | HKS_OPCODE_DATA, 99 | HKS_OPCODE_SETSLOTN, 100 | HKS_OPCODE_SETSLOTI, 101 | HKS_OPCODE_SETSLOT, 102 | HKS_OPCODE_SETSLOTS, 103 | HKS_OPCODE_SETSLOTMT, 104 | HKS_OPCODE_CHECKTYPE, 105 | HKS_OPCODE_CHECKTYPES, 106 | HKS_OPCODE_GETSLOT, 107 | HKS_OPCODE_GETSLOTMT, 108 | HKS_OPCODE_SELFSLOT, 109 | HKS_OPCODE_SELFSLOTMT, 110 | HKS_OPCODE_GETFIELD_MM, 111 | HKS_OPCODE_CHECKTYPE_D, 112 | HKS_OPCODE_GETSLOT_D, 113 | HKS_OPCODE_GETGLOBAL_MEM, 114 | HKS_OPCODE_MAX, 115 | HKS_OPCODE_DELETE, 116 | HKS_OPCODE_DELETE_BK, 117 | HKS_OPCODE_UNK, 118 | } 119 | 120 | 121 | public static Dictionary> OPCodeFunctions = 122 | new Dictionary>() 123 | { 124 | {LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD, OP_GetField}, 125 | {LuaOpCode.OpCodes.HKS_OPCODE_TEST, OP_Test}, 126 | {LuaOpCode.OpCodes.HKS_OPCODE_CALL_I, OP_Call_I}, 127 | {LuaOpCode.OpCodes.HKS_OPCODE_EQ, OP_Eq}, 128 | {LuaOpCode.OpCodes.HKS_OPCODE_EQ_BK, OP_EqBk}, 129 | {LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL, OP_GetGlobal}, 130 | {LuaOpCode.OpCodes.HKS_OPCODE_MOVE, OP_Move}, 131 | {LuaOpCode.OpCodes.HKS_OPCODE_SELF, OP_Self}, 132 | {LuaOpCode.OpCodes.HKS_OPCODE_RETURN, OP_Return}, 133 | {LuaOpCode.OpCodes.HKS_OPCODE_GETTABLE_S, OP_GetTableS}, 134 | {LuaOpCode.OpCodes.HKS_OPCODE_LOADBOOL, OP_LoadBool}, 135 | {LuaOpCode.OpCodes.HKS_OPCODE_TFORLOOP, OP_TForLoop}, 136 | {LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD, OP_SetField}, 137 | {LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S, OP_SetTableS}, 138 | {LuaOpCode.OpCodes.HKS_OPCODE_SETTABLE_S_BK, OP_SetTableSBk}, 139 | {LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I, OP_TailCallI}, 140 | {LuaOpCode.OpCodes.HKS_OPCODE_LOADK, OP_LoadK}, 141 | {LuaOpCode.OpCodes.HKS_OPCODE_LOADNIL, OP_LoadNil}, 142 | {LuaOpCode.OpCodes.HKS_OPCODE_SETGLOBAL, OP_SetGlobal}, 143 | {LuaOpCode.OpCodes.HKS_OPCODE_JMP, OP_Jmp}, 144 | {LuaOpCode.OpCodes.HKS_OPCODE_GETUPVAL, OP_GetUpVal}, 145 | {LuaOpCode.OpCodes.HKS_OPCODE_SETUPVAL, OP_SetUpVal}, 146 | {LuaOpCode.OpCodes.HKS_OPCODE_ADD, OP_Add}, 147 | {LuaOpCode.OpCodes.HKS_OPCODE_ADD_BK, OP_AddBk}, 148 | {LuaOpCode.OpCodes.HKS_OPCODE_SUB, OP_Sub}, 149 | {LuaOpCode.OpCodes.HKS_OPCODE_SUB_BK, OP_SubBk}, 150 | {LuaOpCode.OpCodes.HKS_OPCODE_MUL, OP_Mul}, 151 | {LuaOpCode.OpCodes.HKS_OPCODE_MUL_BK, OP_MulBk}, 152 | {LuaOpCode.OpCodes.HKS_OPCODE_DIV, OP_Div}, 153 | {LuaOpCode.OpCodes.HKS_OPCODE_DIV_BK, OP_DivBk}, 154 | {LuaOpCode.OpCodes.HKS_OPCODE_MOD, OP_Mod}, 155 | {LuaOpCode.OpCodes.HKS_OPCODE_MOD_BK, OP_ModBk}, 156 | {LuaOpCode.OpCodes.HKS_OPCODE_POW, OP_Pow}, 157 | {LuaOpCode.OpCodes.HKS_OPCODE_POW_BK, OP_PowBk}, 158 | {LuaOpCode.OpCodes.HKS_OPCODE_NEWTABLE, OP_NewTable}, 159 | {LuaOpCode.OpCodes.HKS_OPCODE_UNM, OP_Unm}, 160 | {LuaOpCode.OpCodes.HKS_OPCODE_NOT, OP_Not}, 161 | {LuaOpCode.OpCodes.HKS_OPCODE_LEN, OP_Len}, 162 | {LuaOpCode.OpCodes.HKS_OPCODE_LT, OP_Lt}, 163 | {LuaOpCode.OpCodes.HKS_OPCODE_LT_BK, OP_LtBk}, 164 | {LuaOpCode.OpCodes.HKS_OPCODE_LE, OP_Le}, 165 | {LuaOpCode.OpCodes.HKS_OPCODE_LE_BK, OP_LeBk}, 166 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT, OP_ShiftLeft}, 167 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_LEFT_BK, OP_ShiftLeftBk}, 168 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT, OP_ShiftRight}, 169 | {LuaOpCode.OpCodes.HKS_OPCODE_SHIFT_RIGHT_BK, OP_ShiftRightBk}, 170 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND, OP_BitWiseAnd}, 171 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_AND_BK, OP_BitWiseAndBk}, 172 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR, OP_BitWiseOr}, 173 | {LuaOpCode.OpCodes.HKS_OPCODE_BITWISE_OR_BK, OP_BitWiseOrBk}, 174 | {LuaOpCode.OpCodes.HKS_OPCODE_CONCAT, OP_ConCat}, 175 | { LuaOpCode.OpCodes.HKS_OPCODE_TESTSET, OP_TestSet}, 176 | {LuaOpCode.OpCodes.HKS_OPCODE_FORPREP, OP_ForPrep}, 177 | {LuaOpCode.OpCodes.HKS_OPCODE_FORLOOP, OP_ForLoop}, 178 | {LuaOpCode.OpCodes.HKS_OPCODE_SETLIST, OP_SetList}, 179 | {LuaOpCode.OpCodes.HKS_OPCODE_CLOSE, OP_Close}, 180 | {LuaOpCode.OpCodes.HKS_OPCODE_CLOSURE, OP_Closure}, 181 | {LuaOpCode.OpCodes.HKS_OPCODE_VARARG, OP_VarArg}, 182 | {LuaOpCode.OpCodes.HKS_OPCODE_TAILCALL_I_R1, OP_TailCallI}, 183 | {LuaOpCode.OpCodes.HKS_OPCODE_CALL_I_R1, OP_Call_I}, 184 | {LuaOpCode.OpCodes.HKS_OPCODE_TEST_R1, OP_Test}, 185 | {LuaOpCode.OpCodes.HKS_OPCODE_NOT_R1, OP_Not}, 186 | {LuaOpCode.OpCodes.HKS_OPCODE_GETFIELD_R1, OP_GetField}, 187 | {LuaOpCode.OpCodes.HKS_OPCODE_SETFIELD_R1, OP_SetField}, 188 | {LuaOpCode.OpCodes.HKS_OPCODE_DATA, OP_Data}, 189 | {LuaOpCode.OpCodes.HKS_OPCODE_GETGLOBAL_MEM, OP_GetGlobal}, 190 | }; 191 | 192 | public static string OP_GetField(LuaFunction function) 193 | { 194 | function.Registers[function.currentInstruction.A].value = 195 | function.Registers[function.currentInstruction.B].value + "." + 196 | function.Constants[function.currentInstruction.C].value; 197 | #if DEBUG 198 | function.writeLine(String.Format("-- r({0}) = r({1}).field({2}) // {3}", 199 | function.currentInstruction.A, 200 | function.currentInstruction.B, 201 | function.currentInstruction.C, 202 | function.Registers[function.currentInstruction.A].value)); 203 | #endif 204 | return ""; 205 | } 206 | 207 | public static string OP_Test(LuaFunction function) 208 | { 209 | return String.Format("{0}{1}", 210 | (function.currentInstruction.C == 1) ? "not " : "", 211 | function.Registers[function.currentInstruction.A].value); 212 | } 213 | 214 | public static string OP_Call_I(LuaFunction function) 215 | { 216 | string funcName = function.Registers[function.currentInstruction.A].value; 217 | 218 | int parameterCount = function.currentInstruction.B - 1; 219 | int returnValueCount = function.currentInstruction.C - 1; 220 | string parametersString = ""; 221 | 222 | // Setting up the parameter string 223 | // Check if b >= 1 224 | // if it is, there are b - 1 parameters 225 | if (parameterCount > 0) 226 | { 227 | byte startIndex = 1; 228 | // If the functions gets called on something, we want to use 1 parameter less 229 | if (!(funcName.Contains(":") && parameterCount == 1)) 230 | { 231 | if (funcName.Contains(":")) 232 | { 233 | startIndex = 2; 234 | } 235 | 236 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value; 237 | for (int j = function.currentInstruction.A + startIndex + 1; 238 | j <= function.currentInstruction.A + parameterCount; 239 | j++) 240 | { 241 | parametersString += ", " + function.Registers[j].value; 242 | } 243 | } 244 | } 245 | // If b is 0 246 | // parameters range from a + 1 to the top of the stack 247 | else if (parameterCount < 0) 248 | { 249 | byte startIndex = 1; 250 | if (funcName.Contains(":")) 251 | { 252 | startIndex = 2; 253 | } 254 | 255 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value; 256 | for (int j = function.currentInstruction.A + startIndex + 1; 257 | j <= function.Instructions[function.instructionPtr - 1].A; 258 | j++) 259 | { 260 | parametersString += ", " + function.Registers[j].value; 261 | } 262 | } 263 | 264 | // Setting up the return values 265 | // Check if c >= 1 266 | // if it is, there are c - 1 return values 267 | if (returnValueCount > 0) 268 | { 269 | string returnVars = function.Registers[function.currentInstruction.A].makeLocalVariable(); 270 | for (int i = function.currentInstruction.A + 1; 271 | i < function.currentInstruction.A + returnValueCount; 272 | i++) 273 | { 274 | returnVars += ", " + function.Registers[i].makeLocalVariable(); 275 | function.Registers[i].isInitialized = true; 276 | } 277 | 278 | function.writeLine(String.Format("{0}{1} = {2}({3})", 279 | (!function.Registers[function.currentInstruction.A].isInitialized) ? "local " : "", 280 | returnVars, 281 | funcName, 282 | parametersString)); 283 | function.Registers[function.currentInstruction.A].isInitialized = true; 284 | for (int i = function.currentInstruction.A + 1; 285 | i < function.currentInstruction.A + returnValueCount; 286 | i++) 287 | { 288 | function.Registers[i].isInitialized = true; 289 | } 290 | } 291 | // We dont have return values 292 | else 293 | { 294 | if (function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_CALL_I || 295 | function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_CALL_I_R1) 296 | { 297 | function.Registers[function.currentInstruction.A].value = funcName + "(" + parametersString + ")"; 298 | return ""; 299 | } 300 | 301 | function.writeLine(String.Format("{1}({2})", 302 | (returnValueCount == -1) ? "return " : "", // if c = 0 it returns the value straight away 303 | funcName, 304 | parametersString)); 305 | } 306 | 307 | return ""; 308 | } 309 | 310 | public static string OP_Eq(LuaFunction function) 311 | { 312 | return DoCondition(function, "==", "~="); 313 | } 314 | 315 | public static string OP_EqBk(LuaFunction function) 316 | { 317 | return DoConditionBk(function, "==", "~="); 318 | } 319 | 320 | public static string OP_GetGlobal(LuaFunction function) 321 | { 322 | function.Registers[function.currentInstruction.A] 323 | .changeTo(function.Constants[function.currentInstruction.Bx], true); 324 | function.Registers[function.currentInstruction.A].globalValue = true; 325 | #if DEBUG 326 | function.writeLine(String.Format("-- r({0}) = g[{1}] // {2}", 327 | function.currentInstruction.A, 328 | function.currentInstruction.Bx, 329 | function.Constants[function.currentInstruction.Bx].value)); 330 | #endif 331 | return ""; 332 | } 333 | 334 | public static string OP_Move(LuaFunction function) 335 | { 336 | function.Registers[function.currentInstruction.A].value = 337 | function.Registers[function.currentInstruction.B].value; 338 | #if DEBUG 339 | function.writeLine(String.Format("-- r({0}) = r({1}) // {2}", 340 | function.currentInstruction.A, 341 | function.currentInstruction.B, 342 | function.Registers[function.currentInstruction.A].value)); 343 | #endif 344 | return ""; 345 | } 346 | 347 | public static string OP_Self(LuaFunction function) 348 | { 349 | string cValue; 350 | if (function.currentInstruction.C > 255) 351 | { 352 | function.Registers[function.currentInstruction.A].value = 353 | function.Registers[function.currentInstruction.B].value + ":" + 354 | function.Constants[function.currentInstruction.C - 256].value; 355 | #if DEBUG 356 | function.writeLine(String.Format("-- r({0}) = r({1}):c[{2}] // {3}", 357 | function.currentInstruction.A, 358 | function.currentInstruction.B, 359 | function.currentInstruction.C - 256, 360 | function.Registers[function.currentInstruction.A].value)); 361 | #endif 362 | } 363 | else 364 | { 365 | function.Registers[function.currentInstruction.A].value = 366 | function.Registers[function.currentInstruction.B].value + ":" + 367 | function.Registers[function.currentInstruction.C].value; 368 | #if DEBUG 369 | function.writeLine(String.Format("-- r({0}) = r({1}):r({2}) // {3}", 370 | function.currentInstruction.A, 371 | function.currentInstruction.B, 372 | function.currentInstruction.C, 373 | function.Registers[function.currentInstruction.A].value)); 374 | #endif 375 | } 376 | 377 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Function; 378 | return ""; 379 | } 380 | 381 | public static string OP_Return(LuaFunction function) 382 | { 383 | // we dont want to write return at the end of every function, only if it actually does something 384 | // Also skip it if the previous opcode was a tailcall 385 | if (function.instructionPtr == function.instructionCount - 1 || (function.instructionPtr >= 1) && 386 | (function.Instructions[function.instructionPtr - 1].OpCode == OpCodes.HKS_OPCODE_TAILCALL_I || function.Instructions[function.instructionPtr - 1].OpCode == OpCodes.HKS_OPCODE_TAILCALL_I_R1)) 387 | { 388 | #if DEBUG 389 | function.writeLine("-- return"); 390 | #endif 391 | return ""; 392 | } 393 | 394 | string returns = ""; 395 | if (function.currentInstruction.B > 1) 396 | { 397 | returns += function.Registers[function.currentInstruction.A].value; 398 | for (int i = function.currentInstruction.A + 1; 399 | i <= function.currentInstruction.A + function.currentInstruction.B - 2; 400 | i++) 401 | { 402 | returns += ", " + function.Registers[i]; 403 | } 404 | } 405 | 406 | function.writeLine("return " + returns); 407 | return ""; 408 | } 409 | 410 | public static string OP_GetTableS(LuaFunction function) 411 | { 412 | string cValue = getCValue(function); 413 | function.Registers[function.currentInstruction.A].value = 414 | function.Registers[function.currentInstruction.B].value + "[" + cValue + "]"; 415 | #if DEBUG 416 | function.writeLine(String.Format("-- r({0}) = r({1})[{2}] // {3}", 417 | function.currentInstruction.A, 418 | function.currentInstruction.B, 419 | (function.currentInstruction.C > 255) ? String.Format("c[{0}]", function.currentInstruction.C - 256) : String.Format("r({0})", function.currentInstruction.C), 420 | function.Registers[function.currentInstruction.A].value)); 421 | #endif 422 | return ""; 423 | } 424 | 425 | public static string OP_LoadBool(LuaFunction function) 426 | { 427 | if (function.currentInstruction.B == 0) 428 | function.Registers[function.currentInstruction.A].value = "false"; 429 | else 430 | function.Registers[function.currentInstruction.A].value = "true"; 431 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Boolean; 432 | #if DEBUG 433 | function.writeLine(String.Format("-- r({0}) = {1}{2}", 434 | function.currentInstruction.A, 435 | function.Registers[function.currentInstruction.A].value, 436 | (function.currentInstruction.C == 1) ? " // skip next opcode" : "")); 437 | #endif 438 | return ""; 439 | } 440 | 441 | public static string OP_TForLoop(LuaFunction function) 442 | { 443 | return ""; 444 | } 445 | 446 | public static string OP_SetField(LuaFunction function) 447 | { 448 | string cValue = getCValue(function); 449 | function.writeLine(String.Format("{0}.{1} = {2}", 450 | function.Registers[function.currentInstruction.A].value, 451 | function.Constants[function.currentInstruction.B].value, 452 | cValue 453 | )); 454 | return ""; 455 | } 456 | 457 | public static string OP_SetTableS(LuaFunction function) 458 | { 459 | string cValue = getCValue(function); 460 | function.writeLine(String.Format("{0}[{1}] = {2}", 461 | function.Registers[function.currentInstruction.A].value, 462 | function.Registers[function.currentInstruction.B].value, 463 | cValue 464 | )); 465 | return ""; 466 | } 467 | 468 | public static string OP_SetTableSBk(LuaFunction function) 469 | { 470 | string cValue = getCValue(function); 471 | function.writeLine(String.Format("{0}[{1}] = {2}", 472 | function.Registers[function.currentInstruction.A].value, 473 | function.Constants[function.currentInstruction.B].getString(), 474 | cValue 475 | )); 476 | return ""; 477 | } 478 | 479 | public static string OP_TailCallI(LuaFunction function) 480 | { 481 | string funcName = function.Registers[function.currentInstruction.A].value; 482 | 483 | int parameterCount = function.currentInstruction.B - 1; 484 | string parametersString = ""; 485 | 486 | 487 | // Setting up the parameter string 488 | // Check if b >= 1 489 | // if it is, there are b - 1 parameters 490 | if (parameterCount > 0) 491 | { 492 | 493 | byte startIndex = 1; 494 | // If the functions gets called on something, we want to use 1 parameter less 495 | if (!(funcName.Contains(":") && parameterCount == 1)) 496 | { 497 | if (funcName.Contains(":")) 498 | { 499 | startIndex = 2; 500 | } 501 | 502 | 503 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value; 504 | for (int j = function.currentInstruction.A + startIndex + 1; 505 | j <= function.currentInstruction.A + parameterCount; 506 | j++) 507 | { 508 | parametersString += ", " + function.Registers[j].value; 509 | } 510 | } 511 | } 512 | // If b is 0 513 | // parameters range from a + 1 to the top of the stack 514 | else if (parameterCount < 0) 515 | { 516 | byte startIndex = 1; 517 | if (funcName.Contains(":")) 518 | { 519 | startIndex = 2; 520 | } 521 | 522 | parametersString += function.Registers[function.currentInstruction.A + startIndex].value; 523 | for (int j = function.currentInstruction.A + startIndex + 1; 524 | j <= function.Instructions[function.instructionPtr - 1].A; 525 | j++) 526 | { 527 | parametersString += ", " + function.Registers[j].value; 528 | } 529 | } 530 | function.writeLine(String.Format("return {0}({1})", 531 | funcName, 532 | parametersString)); 533 | 534 | return ""; 535 | } 536 | 537 | public static string OP_LoadK(LuaFunction function) 538 | { 539 | function.Registers[function.currentInstruction.A] 540 | .changeTo(function.Constants[function.currentInstruction.Bx].getString()); 541 | #if DEBUG 542 | function.writeLine(String.Format("-- r({0}) = c[{1}] // {2}", 543 | function.currentInstruction.A, 544 | function.currentInstruction.Bx, 545 | function.Registers[function.currentInstruction.A].value)); 546 | #endif 547 | return ""; 548 | } 549 | 550 | public static string OP_LoadNil(LuaFunction function) 551 | { 552 | for (int i = function.currentInstruction.A; i <= (function.currentInstruction.B); i++) 553 | { 554 | function.Registers[i].value = "nil"; 555 | function.Registers[i].type = Datatype.Type.Nil; 556 | } 557 | #if DEBUG 558 | if (function.currentInstruction.B > function.currentInstruction.A) 559 | function.writeLine(String.Format("-- r({0} to {1}) inclusive = nil", function.currentInstruction.A, function.currentInstruction.B)); 560 | else 561 | function.writeLine(String.Format("-- r({0}) = nil", function.currentInstruction.A)); 562 | #endif 563 | return ""; 564 | } 565 | 566 | public static string OP_SetGlobal(LuaFunction function) 567 | { 568 | function.writeLine(String.Format("{0} = {1}", 569 | function.Constants[function.currentInstruction.Bx].value, 570 | function.Registers[function.currentInstruction.A].value 571 | )); 572 | return ""; 573 | } 574 | 575 | public static string OP_Jmp(LuaFunction function) 576 | { 577 | #if DEBUG 578 | function.writeLine(String.Format("-- skip the next [{0}] opcodes // advance {0} lines", 579 | function.currentInstruction.sBx)); 580 | #endif 581 | return ""; 582 | } 583 | 584 | public static string OP_GetUpVal(LuaFunction function) 585 | { 586 | #if DEBUG 587 | function.writeLine(String.Format("-- r({0}) = upval({1}) // {2}", 588 | function.currentInstruction.A, 589 | function.currentInstruction.B, 590 | function.Upvalues[function.currentInstruction.B])); 591 | #endif 592 | function.Registers[function.currentInstruction.A].value = function.Upvalues[function.currentInstruction.B]; 593 | return ""; 594 | } 595 | 596 | public static string OP_SetUpVal(LuaFunction function) 597 | { 598 | #if DEBUG 599 | function.writeLine(String.Format("-- upval({0}) = r({1}) // {2}", 600 | function.currentInstruction.B, 601 | function.currentInstruction.A, 602 | function.Registers[function.currentInstruction.A].value)); 603 | #endif 604 | function.Upvalues[function.currentInstruction.B] = function.Registers[function.currentInstruction.A].value; 605 | return ""; 606 | } 607 | 608 | public static string OP_Add(LuaFunction function) 609 | { 610 | return DoOperator(function, "+"); 611 | } 612 | 613 | public static string OP_AddBk(LuaFunction function) 614 | { 615 | return DoOperatorBK(function, "+"); 616 | } 617 | 618 | public static string OP_Sub(LuaFunction function) 619 | { 620 | return DoOperator(function, "-"); 621 | } 622 | 623 | public static string OP_SubBk(LuaFunction function) 624 | { 625 | return DoOperatorBK(function, "-"); 626 | } 627 | 628 | public static string OP_Mul(LuaFunction function) 629 | { 630 | return DoOperator(function, "*"); 631 | } 632 | 633 | public static string OP_MulBk(LuaFunction function) 634 | { 635 | return DoOperatorBK(function, "*"); 636 | } 637 | 638 | public static string OP_Div(LuaFunction function) 639 | { 640 | return DoOperator(function, "/"); 641 | } 642 | 643 | public static string OP_DivBk(LuaFunction function) 644 | { 645 | return DoOperatorBK(function, "/"); 646 | } 647 | 648 | public static string OP_Mod(LuaFunction function) 649 | { 650 | return DoOperator(function, "%"); 651 | } 652 | 653 | public static string OP_ModBk(LuaFunction function) 654 | { 655 | return DoOperatorBK(function, "%"); 656 | } 657 | 658 | public static string OP_Pow(LuaFunction function) 659 | { 660 | return DoOperator(function, "^"); 661 | } 662 | 663 | public static string OP_PowBk(LuaFunction function) 664 | { 665 | return DoOperatorBK(function, "^"); 666 | } 667 | 668 | public static string OP_NewTable(LuaFunction function) 669 | { 670 | if (function.currentInstruction.B == 0 && function.currentInstruction.C == 0) 671 | { 672 | function.Registers[function.currentInstruction.A].value = "{}"; 673 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Table; 674 | return ""; 675 | } 676 | 677 | function.Registers[function.currentInstruction.A].makeLocalVariable(); 678 | function.writeLine(String.Format("{0}{1} = {2}", 679 | (!function.Registers[function.currentInstruction.A].isInitialized) ? "local " : "", 680 | function.Registers[function.currentInstruction.A].value, "{}" 681 | )); 682 | function.Registers[function.currentInstruction.A].isInitialized = true; 683 | function.Registers[function.currentInstruction.A].globalValue = false; 684 | return ""; 685 | } 686 | 687 | public static string OP_Unm(LuaFunction function) 688 | { 689 | function.Registers[function.currentInstruction.A].value = 690 | "-" + function.Registers[function.currentInstruction.B].value; 691 | return ""; 692 | } 693 | 694 | public static string OP_Not(LuaFunction function) 695 | { 696 | function.Registers[function.currentInstruction.A].value = 697 | "(not " + function.Registers[function.currentInstruction.A].value + ")"; 698 | return ""; 699 | } 700 | 701 | public static string OP_Len(LuaFunction function) 702 | { 703 | function.Registers[function.currentInstruction.A].value = 704 | "#" + function.Registers[function.currentInstruction.A].value; 705 | return ""; 706 | } 707 | 708 | public static string OP_Lt(LuaFunction function) 709 | { 710 | return DoCondition(function, "<", ">="); 711 | } 712 | 713 | public static string OP_LtBk(LuaFunction function) 714 | { 715 | return DoConditionBk(function, "<", ">="); 716 | } 717 | 718 | public static string OP_Le(LuaFunction function) 719 | { 720 | return DoCondition(function, "<=", ">"); 721 | } 722 | 723 | public static string OP_LeBk(LuaFunction function) 724 | { 725 | return DoConditionBk(function, "<=", ">"); 726 | } 727 | 728 | public static string OP_ShiftLeft(LuaFunction function) 729 | { 730 | return DoOperator(function, "<<"); 731 | } 732 | 733 | public static string OP_ShiftLeftBk(LuaFunction function) 734 | { 735 | return DoOperatorBK(function, "<<"); 736 | } 737 | 738 | public static string OP_ShiftRight(LuaFunction function) 739 | { 740 | return DoOperator(function, ">>"); 741 | } 742 | 743 | public static string OP_ShiftRightBk(LuaFunction function) 744 | { 745 | return DoOperatorBK(function, ">>"); 746 | } 747 | 748 | public static string OP_BitWiseAnd(LuaFunction function) 749 | { 750 | return DoOperator(function, "&"); 751 | } 752 | 753 | public static string OP_BitWiseAndBk(LuaFunction function) 754 | { 755 | return DoOperatorBK(function, "&"); 756 | } 757 | 758 | public static string OP_BitWiseOr(LuaFunction function) 759 | { 760 | return DoOperator(function, "|"); 761 | } 762 | 763 | public static string OP_BitWiseOrBk(LuaFunction function) 764 | { 765 | return DoOperatorBK(function, "|"); 766 | } 767 | 768 | public static string OP_ConCat(LuaFunction function) 769 | { 770 | string output = "(" + function.Registers[function.currentInstruction.B].value; 771 | string registers = "r(" + function.currentInstruction.B + ")"; 772 | for (int i = function.currentInstruction.B + 1; i <= function.currentInstruction.C; i++) 773 | { 774 | output += " .. " + function.Registers[i].value; 775 | registers += "..r(" + i + ")"; 776 | } 777 | output += ")"; 778 | function.Registers[function.currentInstruction.A].value = output; 779 | #if DEBUG 780 | function.writeLine(String.Format("-- r({0}) = {1} // {2}", 781 | function.currentInstruction.A, 782 | registers, 783 | function.Registers[function.currentInstruction.A].value)); 784 | #endif 785 | return ""; 786 | } 787 | 788 | public static string OP_TestSet(LuaFunction function) 789 | { 790 | // TODO: Check this cuz idk if this is right for the second value 791 | function.Registers[function.currentInstruction.A].value = String.Format("({0} {1} {2})", 792 | function.Registers[function.currentInstruction.B].value, 793 | function.currentInstruction.B == 0 ? "and" : "or", 794 | function.Registers[function.currentInstruction.B + 1].value); 795 | #if DEBUG 796 | function.writeLine(String.Format("-- r({0}) = {1}", 797 | function.currentInstruction.A, 798 | function.Registers[function.currentInstruction.A].value)); 799 | #endif 800 | return ""; 801 | } 802 | 803 | public static string OP_ForPrep(LuaFunction function) 804 | { 805 | function.Registers[function.currentInstruction.A + 3].value = "index" + function.currentInstruction.A; 806 | function.writeLine(String.Format("for {0}={1}, {2}, {3} do", 807 | function.Registers[function.currentInstruction.A + 3].value, 808 | function.Registers[function.currentInstruction.A].value, 809 | function.Registers[function.currentInstruction.A + 1].value, 810 | function.Registers[function.currentInstruction.A + 2].value)); 811 | function.tabLevel++; 812 | return ""; 813 | } 814 | 815 | public static string OP_ForLoop(LuaFunction function) 816 | { 817 | function.tabLevel--; 818 | function.writeLine("end"); 819 | return ""; 820 | } 821 | 822 | public static string OP_SetList(LuaFunction function) 823 | { 824 | string tableString = "{"; 825 | if (function.currentInstruction.B > 0) 826 | { 827 | tableString += function.Registers[function.currentInstruction.A + 1].value; 828 | if (function.currentInstruction.B > 1) 829 | { 830 | for (int j = function.currentInstruction.A + 2; j <= function.currentInstruction.A + function.currentInstruction.B; j++) 831 | { 832 | tableString += ", " + function.Registers[j].value; 833 | } 834 | } 835 | } 836 | tableString += "}"; 837 | 838 | function.writeLine(String.Format("{0} = {1}", 839 | function.Registers[function.currentInstruction.A].value, 840 | tableString 841 | )); 842 | return ""; 843 | } 844 | 845 | public static string OP_Close(LuaFunction function) 846 | { 847 | function.Registers[function.currentInstruction.A].value = ""; 848 | return ""; 849 | } 850 | 851 | public static string OP_Closure(LuaFunction function) 852 | { 853 | // Setting up all the upvalues 854 | int i = function.instructionPtr + 1; 855 | while(i < function.instructionCount && function.Instructions[i].OpCode == OpCodes.HKS_OPCODE_DATA) 856 | { 857 | if (function.Instructions[i].A == 1) 858 | { 859 | function.SubFunctions[function.currentInstruction.Bx].Upvalues.Add(function.Registers[function.Instructions[i].C].value); 860 | } 861 | else if (function.Instructions[i].A == 2) 862 | { 863 | function.SubFunctions[function.currentInstruction.Bx].Upvalues.Add(function.Upvalues[function.Instructions[i].C]); 864 | } 865 | else 866 | { 867 | Console.WriteLine("Closuse extra arg error: " + function.Instructions[i].A); 868 | } 869 | i++; 870 | } 871 | // Put the name in the register 872 | function.Registers[function.currentInstruction.A].value = String.Format("__FUNC_{0:X}_", function.SubFunctions[function.currentInstruction.Bx].startPosition); 873 | function.Registers[function.currentInstruction.A].type = Datatype.Type.Function; 874 | 875 | if ((function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_SETFIELD || function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_SETFIELD_R1) && function.Registers[function.Instructions[function.instructionPtr + 1].A].globalValue) 876 | { 877 | function.SubFunctions[function.currentInstruction.Bx].newName = String.Format("{0}.{1}", 878 | function.Registers[function.Instructions[function.instructionPtr + 1].A].value, 879 | function.Constants[function.Instructions[function.instructionPtr + 1].B].value 880 | ); 881 | function.nextInstruction(); 882 | } 883 | else if (function.Instructions[function.instructionPtr + 1].OpCode == OpCodes.HKS_OPCODE_SETGLOBAL) 884 | { 885 | function.SubFunctions[function.currentInstruction.Bx].newName = function.Constants[function.Instructions[function.instructionPtr + 1].Bx].value; 886 | function.nextInstruction(); 887 | } 888 | // Move to the new functions 889 | long oldPos = function.inputReader.BaseStream.Position; 890 | function.inputReader.Seek(function.SubFunctions[function.currentInstruction.Bx].startPosition, SeekOrigin.Begin); 891 | // Start the function 892 | function.SubFunctions[function.currentInstruction.Bx].decompile(function.tabLevel + function.endPositions.Count + function.tablePositions.Count + 1); 893 | // move back 894 | function.inputReader.Seek(oldPos, SeekOrigin.Begin); 895 | return ""; 896 | } 897 | 898 | public static string OP_VarArg(LuaFunction function) 899 | { 900 | function.Registers[function.currentInstruction.A].value = "..."; 901 | return ""; 902 | } 903 | 904 | public static string OP_Data(LuaFunction function) 905 | { 906 | return ""; 907 | } 908 | 909 | public static string getCValue(LuaFunction function) 910 | { 911 | if (function.currentInstruction.C > 255) 912 | { 913 | return function.Constants[function.currentInstruction.C - 256].getString(); 914 | } 915 | else 916 | { 917 | return function.Registers[function.currentInstruction.C].value; 918 | } 919 | } 920 | 921 | public static string DoOperator(LuaFunction function, string oper) 922 | { 923 | string cValue = getCValue(function); 924 | function.Registers[function.currentInstruction.A].value = String.Format("({0} {1} {2})", 925 | function.Registers[function.currentInstruction.B].value, 926 | oper, 927 | cValue); 928 | return ""; 929 | } 930 | 931 | public static string DoOperatorBK(LuaFunction function, string oper) 932 | { 933 | function.Registers[function.currentInstruction.A].value = String.Format("({0} {1} {2})", 934 | function.Constants[function.currentInstruction.B].value, 935 | oper, 936 | function.Registers[function.currentInstruction.C].value); 937 | return ""; 938 | } 939 | 940 | private static string DoCondition(LuaFunction function, string oper, string operFalse) 941 | { 942 | string cValue = getCValue(function); 943 | return String.Format("{0} {1} {2}", 944 | function.Registers[function.currentInstruction.B].value, 945 | (function.currentInstruction.A == 0) ? oper : operFalse, 946 | cValue); 947 | } 948 | 949 | private static string DoConditionBk(LuaFunction function, string oper, string operFalse) 950 | { 951 | return String.Format("{0} {1} {2}", 952 | function.Constants[function.currentInstruction.B].value, 953 | (function.currentInstruction.A == 0) ? oper : operFalse, 954 | function.Registers[function.currentInstruction.C].value); 955 | } 956 | 957 | public static bool isConditionOPCode(LuaFunction function, int ptr) 958 | { 959 | OpCodes OpCode = function.Instructions[ptr].OpCode; 960 | if (OpCode == OpCodes.HKS_OPCODE_EQ || OpCode == OpCodes.HKS_OPCODE_EQ_BK || OpCode == OpCodes.HKS_OPCODE_LE || OpCode == OpCodes.HKS_OPCODE_LE_BK || 961 | OpCode == OpCodes.HKS_OPCODE_LT || OpCode == OpCodes.HKS_OPCODE_LT_BK || OpCode == OpCodes.HKS_OPCODE_TEST || OpCode == OpCodes.HKS_OPCODE_TEST_R1) 962 | return true; 963 | return false; 964 | } 965 | } 966 | } 967 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Lua/LuaRegister.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 CoDLUIDecompiler 8 | { 9 | class LuaRegister 10 | { 11 | public string value = ""; 12 | public int index; 13 | public Datatype.Type type; 14 | public bool globalValue = false; 15 | public bool isInitialized = false; 16 | 17 | public LuaRegister(int index) 18 | { 19 | this.isInitialized = false; 20 | this.index = index; 21 | this.globalValue = false; 22 | } 23 | 24 | public void changeTo(LuaConstant constant, bool isGlobal = false) 25 | { 26 | this.globalValue = isGlobal; 27 | this.value = constant.value; 28 | 29 | this.type = constant.type; 30 | } 31 | 32 | public void changeTo(string value) 33 | { 34 | this.value = value; 35 | } 36 | 37 | public string makeLocalVariable() 38 | { 39 | this.value = "registerVal" + this.index; 40 | return this.value; 41 | } 42 | 43 | public void initialze(string value) 44 | { 45 | this.value = value; 46 | this.isInitialized = true; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/AdvancedWarfare.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class AdvancedWarfare 12 | { 13 | public struct LuaFile 14 | { 15 | /// 16 | /// Asset Name Hash 17 | /// 18 | public long NamePtr { get; set; } 19 | 20 | /// 21 | /// Data Size 22 | /// 23 | public Int32 DataSize { get; set; } 24 | public Int32 DataSize2 { get; set; } 25 | 26 | /// 27 | /// Asset Hash 28 | /// 29 | public long startLocation { get; set; } 30 | } 31 | 32 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 33 | { 34 | // Found the game 35 | Console.WriteLine("Found supported game: Call of Duty: Advanced Warfare"); 36 | 37 | // Validate by XModel Name 38 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(assetPoolsAddress + 0x38) + 8)) == "fx") 39 | { 40 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (8 * 59)); 41 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 59)); 42 | 43 | Directory.CreateDirectory("s1_luafiles"); 44 | 45 | int filesExported = 0; 46 | 47 | for (int i = 0; i < poolSize; i++) 48 | { 49 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24)); 50 | 51 | if (!(data.DataSize != 0 && data.DataSize2 == 2)) 52 | continue; 53 | 54 | filesExported++; 55 | 56 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize); 57 | 58 | string exportName = Path.Combine("s1_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 59 | 60 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize) 61 | continue; 62 | 63 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 64 | 65 | File.WriteAllBytes(exportName, RawData); 66 | } 67 | 68 | Console.WriteLine("Exported {0} files", filesExported); 69 | } 70 | else 71 | { 72 | Console.WriteLine("Unsupported version of game found"); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/BlackOps2.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class BlackOps2 12 | { 13 | /// 14 | /// LuaFile Asset 15 | /// 16 | public struct LuaFile 17 | { 18 | /// 19 | /// Asset Name Hash 20 | /// 21 | public UInt32 NamePtr { get; set; } 22 | 23 | /// 24 | /// Data Size 25 | /// 26 | public Int32 AssetSize { get; set; } 27 | 28 | /// 29 | /// Raw Data Pointer 30 | /// 31 | public Int32 RawDataPtr { get; set; } 32 | } 33 | 34 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 35 | { 36 | // Found the game 37 | Console.WriteLine("Found supported game: Call of Duty: Black Ops 2"); 38 | 39 | // Validate by XModel Name 40 | if (reader.ReadNullTerminatedString(reader.ReadInt32(reader.ReadInt32(assetPoolsAddress + 0x14) + 4)) == "defaultvehicle") 41 | { 42 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (4 * 41)) + 4; 43 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 41)); 44 | 45 | Directory.CreateDirectory("t6_luafiles"); 46 | 47 | int filesExported = 0; 48 | 49 | for (int i = 0; i < poolSize; i++) 50 | { 51 | var data = reader.ReadStruct(AssetPoolOffset + (i * 12)); 52 | 53 | if (!(data.AssetSize != 0)) 54 | continue; 55 | 56 | filesExported++; 57 | var RawData = reader.ReadBytes(data.RawDataPtr, data.AssetSize); 58 | 59 | string exportName = Path.Combine("t6_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 60 | 61 | if (Path.GetExtension(exportName) != ".lua" || File.Exists(exportName) && new FileInfo(exportName).Length == data.AssetSize) 62 | continue; 63 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 64 | 65 | File.WriteAllBytes(exportName, RawData); 66 | } 67 | 68 | Console.WriteLine("Exported {0} files", filesExported); 69 | } 70 | else 71 | { 72 | Console.WriteLine("Unsupported version of game found"); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/BlackOps3.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class BlackOps3 12 | { 13 | public struct AssetPool 14 | { 15 | /// 16 | /// A pointer to the asset pool 17 | /// 18 | public long PoolPointer { get; set; } 19 | 20 | /// 21 | /// Entry Size 22 | /// 23 | public int AssetSize { get; set; } 24 | 25 | /// 26 | /// Max Asset Count/Pool Size 27 | /// 28 | public int PoolSize { get; set; } 29 | 30 | /// 31 | /// Null Padding 32 | /// 33 | public int Padding { get; set; } 34 | 35 | /// 36 | /// Numbers of Assets in this Pool 37 | /// 38 | public int AssetCount { get; set; } 39 | 40 | /// 41 | /// Next Free Header/Slot 42 | /// 43 | public long NextSlot { get; set; } 44 | } 45 | 46 | /// 47 | /// LuaFile Asset 48 | /// 49 | public struct LuaFile 50 | { 51 | /// 52 | /// Asset Name Hash 53 | /// 54 | public long NamePtr { get; set; } 55 | 56 | /// 57 | /// Data Size 58 | /// 59 | public Int32 AssetSize { get; set; } 60 | 61 | /// 62 | /// Raw Data Pointer 63 | /// 64 | public long RawDataPtr { get; set; } 65 | } 66 | 67 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 68 | { 69 | // Found the game 70 | Console.WriteLine("Found supported game: Call of Duty: Black Ops 3"); 71 | 72 | // Get Base Address for ASLR and Scans 73 | long baseAddress = reader.GetBaseAddress(); 74 | 75 | // Validate by XModel Name 76 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(baseAddress + assetPoolsAddress + 0x80))) == "void") 77 | { 78 | AssetPool LuaPoolData = reader.ReadStruct(baseAddress + assetPoolsAddress + 0x20 * 47); 79 | 80 | long address = LuaPoolData.PoolPointer; 81 | long endAddress = LuaPoolData.PoolSize * LuaPoolData.AssetSize + address; 82 | 83 | Directory.CreateDirectory("t7_luafiles"); 84 | int filesExported = 0; 85 | 86 | for (int i = 0; i < LuaPoolData.PoolSize; i++) 87 | { 88 | var data = reader.ReadStruct(address + (i * LuaPoolData.AssetSize)); 89 | 90 | if (!(data.AssetSize != 0)) 91 | continue; 92 | 93 | filesExported++; 94 | var RawData = reader.ReadBytes(data.RawDataPtr, data.AssetSize); 95 | 96 | string exportName = Path.Combine("t7_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 97 | 98 | if (Path.GetExtension(exportName) != ".lua" || File.Exists(exportName) && new FileInfo(exportName).Length == data.AssetSize) 99 | continue; 100 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 101 | 102 | File.WriteAllBytes(exportName, RawData); 103 | } 104 | 105 | Console.WriteLine("Exported {0} files", filesExported); 106 | } 107 | else 108 | { 109 | Console.WriteLine("Unsupported version of game found"); 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/BlackOps4.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class BlackOps4 12 | { 13 | /// 14 | /// Asset Pool Data 15 | /// 16 | public struct AssetPool 17 | { 18 | /// 19 | /// A pointer to the asset pool 20 | /// 21 | public long PoolPointer { get; set; } 22 | 23 | /// 24 | /// Entry Size 25 | /// 26 | public int AssetSize { get; set; } 27 | 28 | /// 29 | /// Max Asset Count/Pool Size 30 | /// 31 | public int PoolSize { get; set; } 32 | 33 | /// 34 | /// Null Padding 35 | /// 36 | public int Padding { get; set; } 37 | 38 | /// 39 | /// Numbers of Assets in this Pool 40 | /// 41 | public int AssetCount { get; set; } 42 | 43 | /// 44 | /// Next Free Header/Slot 45 | /// 46 | public long NextSlot { get; set; } 47 | } 48 | 49 | /// 50 | /// LuaFile Asset 51 | /// 52 | public struct LuaFile 53 | { 54 | /// 55 | /// Asset Name Hash 56 | /// 57 | public long Hash { get; set; } 58 | 59 | /// 60 | /// Asset Hash 61 | /// 62 | public ulong NullPointer { get; set; } 63 | 64 | /// 65 | /// Data Size 66 | /// 67 | public Int32 DataSize { get; set; } 68 | 69 | /// 70 | /// Asset Hash 71 | /// 72 | public Int32 UnknownHash1 { get; set; } 73 | 74 | /// 75 | /// Data startLocation 76 | /// 77 | public long startLocation { get; set; } 78 | } 79 | 80 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 81 | { 82 | // Found the game 83 | Console.WriteLine("Found supported game: Call of Duty: Black Ops 4"); 84 | 85 | // Get Base Address for ASLR and Scans 86 | long baseAddress = reader.GetBaseAddress(); 87 | 88 | // Validate by XModel Name 89 | if (reader.ReadUInt64(reader.ReadStruct(baseAddress + assetPoolsAddress + 0x20 * 0x4).PoolPointer) == 0x04647533e968c910) 90 | { 91 | AssetPool LuaPoolData = reader.ReadStruct(baseAddress + assetPoolsAddress + 0x20 * 0x67); 92 | 93 | long address = LuaPoolData.PoolPointer; 94 | long endAddress = LuaPoolData.PoolSize * LuaPoolData.AssetSize + address; 95 | 96 | Directory.CreateDirectory("t8_luafiles"); 97 | int filesExported = 0; 98 | for (int i = 0; i < LuaPoolData.PoolSize; i++) 99 | { 100 | var data = reader.ReadStruct(address + (i * LuaPoolData.AssetSize)); 101 | 102 | if (data.NullPointer != 0 || data.Hash == 0) 103 | continue; 104 | if (data.Hash >= address && data.Hash <= endAddress) 105 | continue; 106 | 107 | filesExported++; 108 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize); 109 | ulong assetHash = (ulong)data.Hash & 0xFFFFFFFFFFFFFFF; 110 | string HashString, fileName; 111 | //if (!Program.AssetNameCache.Entries.TryGetValue(assetHash, out HashString)) 112 | fileName = String.Format("t8_luafiles\\LuaFile_{0:x}.lua", assetHash); 113 | //else 114 | //fileName = String.Format("t8_luafiles\\{0}.lua", HashString); 115 | if (File.Exists(fileName) && new FileInfo(fileName).Length == data.DataSize) 116 | continue; 117 | File.WriteAllBytes(fileName, RawData); 118 | } 119 | 120 | Console.WriteLine("Exported {0} files", filesExported); 121 | } 122 | else 123 | { 124 | Console.WriteLine("Unsupported version of game found"); 125 | } 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/Ghosts.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class Ghosts 12 | { 13 | public struct LuaFile 14 | { 15 | /// 16 | /// Asset Name Hash 17 | /// 18 | public long NamePtr { get; set; } 19 | 20 | /// 21 | /// Data Size 22 | /// 23 | public Int32 DataSize { get; set; } 24 | public Int32 DataSize2 { get; set; } 25 | 26 | /// 27 | /// Asset Hash 28 | /// 29 | public long startLocation { get; set; } 30 | } 31 | 32 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 33 | { 34 | // Found the game 35 | Console.WriteLine("Found supported game: Call of Duty: Ghosts"); 36 | 37 | // Validate by XModel Name 38 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(assetPoolsAddress + 0x20) + 8)) == "void") 39 | { 40 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (8 * 54)); 41 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 54)); 42 | 43 | Directory.CreateDirectory("iw6_luafiles"); 44 | 45 | int filesExported = 0; 46 | 47 | for (int i = 0; i < poolSize; i++) 48 | { 49 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24)); 50 | 51 | if (!(data.DataSize != 0 && data.DataSize2 == 2)) 52 | continue; 53 | 54 | filesExported++; 55 | 56 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize); 57 | 58 | string exportName = Path.Combine("iw6_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 59 | 60 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize) 61 | continue; 62 | 63 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 64 | 65 | File.WriteAllBytes(exportName, RawData); 66 | } 67 | 68 | Console.WriteLine("Exported {0} files", filesExported); 69 | } 70 | else 71 | { 72 | Console.WriteLine("Unsupported version of game found"); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/InfiniteWarfare.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class InfiniteWarfare 12 | { 13 | /// 14 | /// LuaFile Asset 15 | /// 16 | public struct LuaFile 17 | { 18 | /// 19 | /// Asset Name Hash 20 | /// 21 | public long NamePtr { get; set; } 22 | 23 | /// 24 | /// Data Size 25 | /// 26 | public Int32 DataSize { get; set; } 27 | public Int32 DataSize2 { get; set; } 28 | 29 | /// 30 | /// Asset Hash 31 | /// 32 | public long startLocation { get; set; } 33 | } 34 | 35 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 36 | { 37 | // Found the game 38 | Console.WriteLine("Found supported game: Call of Duty: Infinite Warfare"); 39 | 40 | // Validate by XModel Name 41 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(assetPoolsAddress + 0x40) + 8)) == "viewmodel_default") 42 | { 43 | var AssetPoolOffset = reader.ReadStruct(assetPoolsAddress + (8 * 59)); 44 | var poolSize = reader.ReadStruct(assetSizesAddress + (4 * 59)); 45 | 46 | Directory.CreateDirectory("iw7_luafiles"); 47 | 48 | int filesExported = 0; 49 | 50 | for (int i = 0; i < poolSize; i++) 51 | { 52 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24)); 53 | 54 | if (!(data.DataSize != 0 && data.DataSize2 == 2)) 55 | continue; 56 | 57 | filesExported++; 58 | 59 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize); 60 | 61 | string exportName = Path.Combine("iw7_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 62 | 63 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize) 64 | continue; 65 | 66 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 67 | 68 | File.WriteAllBytes(exportName, RawData); 69 | } 70 | 71 | Console.WriteLine("Exported {0} files", filesExported); 72 | } 73 | else 74 | { 75 | Console.WriteLine("Unsupported version of game found"); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/ModernWarfareRM.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class ModernWarfareRM 12 | { 13 | public struct LuaFile 14 | { 15 | /// 16 | /// Asset Name Hash 17 | /// 18 | public long NamePtr { get; set; } 19 | 20 | /// 21 | /// Data Size 22 | /// 23 | public Int32 DataSize { get; set; } 24 | public Int32 DataSize2 { get; set; } 25 | 26 | /// 27 | /// Asset Hash 28 | /// 29 | public long startLocation { get; set; } 30 | } 31 | 32 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 33 | { 34 | // Found the game 35 | Console.WriteLine("Found supported game: Call of Duty: Modern Warfare Remastered"); 36 | 37 | // Get Base Address for ASLR and Scans 38 | long baseAddress = reader.GetBaseAddress(); 39 | 40 | // Validate by XModel Name 41 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(baseAddress + assetPoolsAddress + 0x38) + 8)) == "fx") 42 | { 43 | var AssetPoolOffset = reader.ReadStruct(baseAddress + assetPoolsAddress + (8 * 61)); 44 | var poolSize = reader.ReadStruct(baseAddress + assetSizesAddress + (4 * 61)); 45 | 46 | Directory.CreateDirectory("h1_luafiles"); 47 | 48 | int filesExported = 0; 49 | for (int i = 0; i < poolSize; i++) 50 | { 51 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24)); 52 | 53 | if (!(data.DataSize != 0 && data.DataSize2 == 2)) 54 | continue; 55 | 56 | filesExported++; 57 | 58 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize); 59 | 60 | string exportName = Path.Combine("h1_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 61 | 62 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize) 63 | continue; 64 | 65 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 66 | 67 | File.WriteAllBytes(exportName, RawData); 68 | } 69 | 70 | Console.WriteLine("Exported {0} files", filesExported); 71 | } 72 | else 73 | { 74 | Console.WriteLine("Unsupported version of game found"); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/Games/WorldWarII.cs: -------------------------------------------------------------------------------- 1 | using PhilLibX; 2 | using PhilLibX.IO; 3 | using System; 4 | using System.IO; 5 | using System.Diagnostics; 6 | using System.Collections.Generic; 7 | using System.Runtime.InteropServices; 8 | 9 | namespace CoDLUIDecompiler.LuaRipper 10 | { 11 | class WorldWarII 12 | { 13 | /// 14 | /// LuaFile Asset 15 | /// 16 | public struct LuaFile 17 | { 18 | /// 19 | /// Asset Name Hash 20 | /// 21 | public long NamePtr { get; set; } 22 | 23 | /// 24 | /// Data Size 25 | /// 26 | public Int32 DataSize { get; set; } 27 | public Int32 DataSize2 { get; set; } 28 | 29 | /// 30 | /// Asset Hash 31 | /// 32 | public long startLocation { get; set; } 33 | } 34 | 35 | public static void ExportLuaFIles(ProcessReader reader, long assetPoolsAddress, long assetSizesAddress, string gameType) 36 | { 37 | // Found the game 38 | Console.WriteLine("Found supported game: Call of Duty: World War II"); 39 | 40 | // Validate by XModel Name 41 | if (reader.ReadNullTerminatedString(reader.ReadInt64(reader.ReadInt64(reader.GetBaseAddress() + assetPoolsAddress + 0x50) + 8)) == "empty_model") 42 | { 43 | // Get Base Address for ASLR and Scans 44 | long baseAddress = reader.GetBaseAddress(); 45 | 46 | var AssetPoolOffset = reader.ReadStruct(baseAddress + assetPoolsAddress + (8 * 69)); 47 | var poolSize = reader.ReadStruct(AssetPoolOffset + 4 * 69); 48 | 49 | Directory.CreateDirectory("s2_luafiles"); 50 | 51 | int filesExported = 0; 52 | 53 | for (int i = 0; i < poolSize; i++) 54 | { 55 | var data = reader.ReadStruct(AssetPoolOffset + 8 + (i * 24)); 56 | 57 | if (!(data.DataSize != 0 && data.DataSize2 == 2)) 58 | continue; 59 | 60 | filesExported++; 61 | var RawData = reader.ReadBytes(data.startLocation, data.DataSize); 62 | 63 | string exportName = Path.Combine("s2_luafiles", reader.ReadNullTerminatedString(data.NamePtr)); 64 | 65 | if (File.Exists(exportName) && new FileInfo(exportName).Length == data.DataSize) 66 | continue; 67 | Directory.CreateDirectory(Path.GetDirectoryName(exportName)); 68 | 69 | File.WriteAllBytes(exportName, RawData); 70 | } 71 | 72 | Console.WriteLine("Exported {0} files", filesExported); 73 | } 74 | else 75 | { 76 | Console.WriteLine("Unsupported version of game found"); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/LuaRipper/MemoryLoading.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Reflection; 6 | using PhilLibX; 7 | using PhilLibX.IO; 8 | 9 | namespace CoDLUIDecompiler 10 | { 11 | /// 12 | /// Game Definition (AssetDB Address, Sizes Address, Game Type ID (MP, SP, ZM, etc.), Export Method 13 | /// 14 | using GameDefinition = Tuple>; 15 | 16 | class MemoryLoading 17 | { 18 | static readonly Dictionary Games = new Dictionary() 19 | { 20 | // Call of Duty: Black Ops 2 21 | { "t6zm", new GameDefinition(0xD41240, 0xD40E80, "zm", LuaRipper.BlackOps2.ExportLuaFIles) }, 22 | { "t6mp", new GameDefinition(0xD4B340, 0xD4AF80, "mp", LuaRipper.BlackOps2.ExportLuaFIles) }, 23 | { "t6sp", new GameDefinition(0xBD46B8, 0xBD42F8, "sp", LuaRipper.BlackOps2.ExportLuaFIles) }, 24 | // Call of Duty: Ghosts 25 | { "iw6mp64_ship", new GameDefinition(0x1409E4F20, 0x1409E4E20, "mp", LuaRipper.Ghosts.ExportLuaFIles) }, 26 | { "iw6sp64_ship", new GameDefinition(0x14086DCB0, 0x14086DBB0, "sp", LuaRipper.Ghosts.ExportLuaFIles) }, 27 | // Call of Duty: Advanced Warfare 28 | { "s1_mp64_ship", new GameDefinition(0x1409B40D0, 0x1409B4B90, "mp", LuaRipper.AdvancedWarfare.ExportLuaFIles) }, 29 | { "s1_sp64_ship", new GameDefinition(0x140804690, 0x140804140, "sp", LuaRipper.AdvancedWarfare.ExportLuaFIles) }, 30 | // Call of Duty: Black Ops 3 31 | { "BlackOps3", new GameDefinition(0x93FA290, 0x4D4F100, "core", LuaRipper.BlackOps3.ExportLuaFIles) }, 32 | // Call of Duty: Infinite Warfare 33 | { "iw7_ship", new GameDefinition(0x1414663D0, 0x141466290, "core", LuaRipper.InfiniteWarfare.ExportLuaFIles) }, 34 | // Call of Duty: Modern Warfare Remastered 35 | { "h1_mp64_ship", new GameDefinition(0x10B4460, 0x10B3C80, "mp", LuaRipper.ModernWarfareRM.ExportLuaFIles) }, 36 | { "h1_sp64_ship", new GameDefinition(0xEC9FB0, 0xEC97D0, "sp", LuaRipper.ModernWarfareRM.ExportLuaFIles) }, 37 | // Call of Duty: World War II 38 | { "s2_mp64_ship", new GameDefinition(0xC05370, 0xC05370, "mp", LuaRipper.WorldWarII.ExportLuaFIles) }, 39 | { "s2_sp64_ship", new GameDefinition(0x9483F0, 0xBCC5E0, "sp", LuaRipper.WorldWarII.ExportLuaFIles) }, 40 | // Call of Duty: Black Ops 4 41 | { "BlackOps4", new GameDefinition(0x88788D0, 0x74FDED0, "core", LuaRipper.BlackOps4.ExportLuaFIles) }, 42 | }; 43 | 44 | /// 45 | /// Looks for matching game and loads BSP from it 46 | /// 47 | public static void LoadGame() 48 | { 49 | try 50 | { 51 | // Get all processes 52 | var processes = Process.GetProcesses(); 53 | 54 | // Loop through them, find match 55 | foreach (var process in processes) 56 | { 57 | // Check for it in dictionary 58 | if (Games.TryGetValue(process.ProcessName, out var game)) 59 | { 60 | // Export it 61 | game.Item4(new ProcessReader(process), game.Item1, game.Item2, game.Item3); 62 | 63 | // Done 64 | return; 65 | } 66 | } 67 | 68 | // Failed 69 | Console.WriteLine("Failed to find a supported game, please ensure one of them is running."); 70 | } 71 | catch (Exception e) 72 | { 73 | Console.WriteLine("An unhandled exception has occured:"); 74 | Console.WriteLine(e); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Program.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 CoDLUIDecompiler 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | Console.WriteLine("CoD LUI Decompiler by JariK"); 14 | string[] files = new string[1]; 15 | if (args.Length == 0) 16 | { 17 | MemoryLoading.LoadGame(); 18 | Console.WriteLine("Give the folder that you want to decompile: "); 19 | string folder = Console.ReadLine(); 20 | //folder = @"../Debug"; 21 | if (Directory.Exists(folder)) 22 | { 23 | files = Directory.GetFiles(folder, "*.lua*", SearchOption.AllDirectories); 24 | } 25 | } 26 | else 27 | { 28 | files = args.Where(x => (Path.GetExtension(x) == ".lua" || Path.GetExtension(x) == ".luac") && File.Exists(x)).ToArray(); 29 | } 30 | foreach (string fileName in files) 31 | { 32 | if (Path.GetExtension(fileName) != ".lua" && Path.GetExtension(fileName) != ".luac") 33 | { 34 | continue; 35 | } 36 | Console.WriteLine("Decompiling file: " + Path.GetFileName(fileName)); 37 | new LuaFile(fileName); 38 | 39 | } 40 | Console.ReadLine(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/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("CoDLUIDecompiler")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CoDLUIDecompiler")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 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("086385a5-ba10-468d-87fa-5c00ffc55ec3")] 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 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/ByteUtil.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: ByteUtil.cs 24 | // Author: Philip/Scobalula 25 | // Description: Utilities for working with Bytes and Bits 26 | using System.Collections.Generic; 27 | using System.Text; 28 | 29 | namespace PhilLibX 30 | { 31 | /// 32 | /// Utilities for working with Bytes and Bits 33 | /// 34 | public class ByteUtil 35 | { 36 | /// 37 | /// Reads a null terminated string from a byte array 38 | /// 39 | /// Byte Array input 40 | /// Start Index 41 | /// Resulting string 42 | public static string ReadNullTerminatedString(byte[] input, int startIndex) 43 | { 44 | List result = new List(); 45 | 46 | for (int i = startIndex; i < input.Length && input[i] != 0; i++) 47 | result.Add(input[i]); 48 | 49 | return Encoding.ASCII.GetString(result.ToArray()); 50 | } 51 | 52 | /// 53 | /// Returns the value of the bit in the given integer 54 | /// 55 | /// Integer Input 56 | /// Position 57 | /// Result 58 | public static byte GetBit(long input, int bit) 59 | { 60 | return (byte)((input >> bit) & 1); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/IO/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 PhilLibX.IO 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 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/IO/MemoryUtil.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/MemoryUtil.cs 24 | // Author: Philip/Scobalula 25 | // Description: Utilities for Reading Process Memory 26 | using System; 27 | using System.Collections.Generic; 28 | using System.Runtime.InteropServices; 29 | using System.Text; 30 | 31 | namespace PhilLibX.IO 32 | { 33 | /// 34 | /// Utilities for Reading Process Memory 35 | /// 36 | public class MemoryUtil 37 | { 38 | /// 39 | /// Required to read memory in a process using ReadProcessMemory. 40 | /// 41 | public const int ProcessVMRead = 0x0010; 42 | 43 | /// 44 | /// Required to write to memory in a process using WriteProcessMemory. 45 | /// 46 | public const int ProcessVMWrite = 0x0020; 47 | 48 | /// 49 | /// Reads bytes from a Processes Memory and returns a byte array of read data. 50 | /// 51 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 52 | /// The address of the data to be read. 53 | /// The number of bytes to be read from the specified process. 54 | /// Bytes read 55 | public static byte[] ReadBytes(IntPtr processHandle, long address, int numBytes) 56 | { 57 | // Resulting buffer 58 | byte[] buffer = new byte[numBytes]; 59 | // Request ReadProcessMemory 60 | NativeMethods.ReadProcessMemory((int)processHandle, address, buffer, buffer.Length, out int bytesRead); 61 | // Return result 62 | return buffer; 63 | } 64 | 65 | /// 66 | /// Reads a 64Bit Integer from a Processes Memory 67 | /// 68 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 69 | /// The address of the data to be read. 70 | /// Resulting Data 71 | public static long ReadInt64(IntPtr processHandle, long address) 72 | { 73 | return BitConverter.ToInt64(ReadBytes(processHandle, address, 8), 0); 74 | } 75 | 76 | /// 77 | /// Reads an unsigned 64Bit Integer from a Processes Memory 78 | /// 79 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 80 | /// The address of the data to be read. 81 | /// Resulting Data 82 | public static ulong ReadUInt64(IntPtr processHandle, long address) 83 | { 84 | return BitConverter.ToUInt64(ReadBytes(processHandle, address, 8), 0); 85 | } 86 | 87 | /// 88 | /// Reads a 32Bit Integer from a Processes Memory 89 | /// 90 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 91 | /// The address of the data to be read. 92 | /// Resulting Data 93 | public static int ReadInt32(IntPtr processHandle, long address) 94 | { 95 | return BitConverter.ToInt32(ReadBytes(processHandle, address, 4), 0); 96 | } 97 | 98 | /// 99 | /// Reads an unsigned 32Bit Integer from a Processes Memory 100 | /// 101 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 102 | /// The address of the data to be read. 103 | /// Resulting Data 104 | public static uint ReadUInt32(IntPtr processHandle, long address) 105 | { 106 | return BitConverter.ToUInt32(ReadBytes(processHandle, address, 4), 0); 107 | } 108 | 109 | /// 110 | /// Reads a 16Bit Integer from a Processes Memory 111 | /// 112 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 113 | /// The address of the data to be read. 114 | /// Resulting Data 115 | public static short ReadInt16(IntPtr processHandle, long address) 116 | { 117 | return BitConverter.ToInt16(ReadBytes(processHandle, address, 4), 0); 118 | } 119 | 120 | /// 121 | /// Reads an unsigned 16Bit Integer from a Processes Memory 122 | /// 123 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 124 | /// The address of the data to be read. 125 | /// Resulting Data 126 | public static ushort ReadUInt16(IntPtr processHandle, long address) 127 | { 128 | return BitConverter.ToUInt16(ReadBytes(processHandle, address, 2), 0); 129 | } 130 | 131 | /// 132 | /// Reads a 4 byte single precision floating point number from a Processes Memory 133 | /// 134 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 135 | /// The address of the data to be read. 136 | /// Resulting Data 137 | public static float ReadSingle(IntPtr processHandle, long address) 138 | { 139 | return BitConverter.ToSingle(ReadBytes(processHandle, address, 2), 0); 140 | } 141 | 142 | /// 143 | /// Reads an 8 byte double precision floating point number from a Processes Memory 144 | /// 145 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 146 | /// The address of the data to be read. 147 | /// Resulting Data 148 | public static double ReadDouble(IntPtr processHandle, long address) 149 | { 150 | return BitConverter.ToDouble(ReadBytes(processHandle, address, 8), 0); 151 | } 152 | 153 | /// 154 | /// Reads a string from a processes' memory terminated by a null byte. 155 | /// 156 | /// Process Handle Pointer 157 | /// Memory Address 158 | /// Buffer Read Size 159 | /// Resulting String 160 | public static string ReadNullTerminatedString(IntPtr processHandle, long address, int bufferSize = 0xFF) 161 | { 162 | List result = new List(); 163 | 164 | byte[] buffer = ReadBytes(processHandle, address, bufferSize); 165 | 166 | while (true) 167 | { 168 | for (int i = 0; i < buffer.Length; i++) 169 | { 170 | if (buffer[i] == 0x0) 171 | return Encoding.ASCII.GetString(result.ToArray()); 172 | 173 | result.Add(buffer[i]); 174 | } 175 | 176 | buffer = ReadBytes(processHandle, address += bufferSize, bufferSize); 177 | } 178 | } 179 | 180 | /// 181 | /// Reads a struct from a Processes Memory 182 | /// 183 | /// Struct Type 184 | /// Process Handle Pointer 185 | /// Memory Address 186 | /// Resulting Struct 187 | public static T ReadStruct(IntPtr processHandle, long address) 188 | { 189 | byte[] data = ReadBytes(processHandle, address, Marshal.SizeOf()); 190 | GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); 191 | T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T)); 192 | handle.Free(); 193 | return theStructure; 194 | } 195 | 196 | /// 197 | /// Searches for bytes in a processes memory. 198 | /// 199 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 200 | /// Byte Sequence to scan for. 201 | /// Address to start the search at. 202 | /// Address to end the search at. 203 | /// Byte Buffer Size 204 | /// If we should stop the search at the first result. 205 | /// 206 | public static long[] FindBytes(IntPtr processHandle, byte?[] needle, long startAddress, long endAddress, bool firstMatch = false, int bufferSize = 0xFFFF) 207 | { 208 | List results = new List(); 209 | long searchAddress = startAddress; 210 | 211 | int needleIndex = 0; 212 | int bufferIndex = 0; 213 | 214 | while (true) 215 | { 216 | try 217 | { 218 | byte[] buffer = ReadBytes(processHandle, searchAddress, bufferSize); 219 | 220 | for (bufferIndex = 0; bufferIndex < buffer.Length; bufferIndex++) 221 | { 222 | if (needle[needleIndex] == null) 223 | { 224 | needleIndex++; 225 | continue; 226 | } 227 | 228 | if (needle[needleIndex] == buffer[bufferIndex]) 229 | { 230 | needleIndex++; 231 | 232 | if (needleIndex == needle.Length) 233 | { 234 | results.Add(searchAddress + bufferIndex - needle.Length + 1); 235 | 236 | if (firstMatch) 237 | return results.ToArray(); 238 | 239 | needleIndex = 0; 240 | } 241 | } 242 | else 243 | { 244 | needleIndex = 0; 245 | } 246 | } 247 | } 248 | catch 249 | { 250 | break; 251 | } 252 | 253 | searchAddress += bufferSize; 254 | 255 | if (searchAddress > endAddress) 256 | break; 257 | } 258 | 259 | return results.ToArray(); 260 | } 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/IO/ProcessReader.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/ProcessReader.cs 24 | // Author: Philip/Scobalula 25 | // Description: A class to help with reading the memory of other processes. 26 | using System; 27 | using System.Diagnostics; 28 | 29 | namespace PhilLibX.IO 30 | { 31 | /// 32 | /// A class to help with reading the memory of other processes. 33 | /// 34 | public class ProcessReader 35 | { 36 | /// 37 | /// Internal Process Property 38 | /// 39 | private Process _Process { get; set; } 40 | 41 | /// 42 | /// Internal Handle Property 43 | /// 44 | private IntPtr _Handle { get; set; } 45 | 46 | /// 47 | /// Active Process 48 | /// 49 | public Process ActiveProcess 50 | { 51 | get { return _Process; } 52 | set 53 | { 54 | _Process = value; 55 | _Handle = NativeMethods.OpenProcess(MemoryUtil.ProcessVMRead, false, _Process.Id); 56 | } 57 | } 58 | 59 | /// 60 | /// Active Process Handle 61 | /// 62 | public IntPtr Handle { get { return _Handle; } } 63 | 64 | /// 65 | /// Initalizes a Process Reader with a Process 66 | /// 67 | public ProcessReader(Process process) 68 | { 69 | ActiveProcess = process; 70 | } 71 | 72 | /// 73 | /// Reads bytes from the Processes Memory 74 | /// 75 | /// The address of the data to be read. 76 | /// The number of bytes to be read. 77 | /// Bytes read 78 | public byte[] ReadBytes(long address, int numBytes) 79 | { 80 | return MemoryUtil.ReadBytes(Handle, address, numBytes); 81 | } 82 | 83 | /// 84 | /// Reads 64Bit Integer from the Processes Memory 85 | /// 86 | /// The address of the data to be read. 87 | /// Resulting Data 88 | public long ReadInt64(long address) 89 | { 90 | return MemoryUtil.ReadInt64(Handle, address); 91 | } 92 | 93 | /// 94 | /// Reads an unsigned 64Bit Integer from the Processes Memory 95 | /// 96 | /// The address of the data to be read. 97 | /// Resulting Data 98 | public ulong ReadUInt64(long address) 99 | { 100 | return MemoryUtil.ReadUInt64(Handle, address); 101 | } 102 | 103 | /// 104 | /// Reads 32Bit Integer from the Processes Memory 105 | /// 106 | /// The address of the data to be read. 107 | /// Resulting Data 108 | public int ReadInt32(long address) 109 | { 110 | return MemoryUtil.ReadInt32(Handle, address); 111 | } 112 | 113 | /// 114 | /// Reads 32Bit Integer from the Processes Memory 115 | /// 116 | /// The address of the data to be read. 117 | /// Resulting Data 118 | public uint ReadUInt32(long address) 119 | { 120 | return MemoryUtil.ReadUInt32(Handle, address); 121 | } 122 | 123 | /// 124 | /// Reads a 16Bit Integer from the Processes Memory 125 | /// 126 | /// The address of the data to be read. 127 | /// Resulting Data 128 | public short ReadInt16(long address) 129 | { 130 | return MemoryUtil.ReadInt16(Handle, address); 131 | } 132 | 133 | /// 134 | /// Reads an unsigned 16Bit Integer from the Processes Memory 135 | /// 136 | /// The address of the data to be read. 137 | /// Resulting Data 138 | public ushort ReadUInt16(long address) 139 | { 140 | return MemoryUtil.ReadUInt16(Handle, address); 141 | } 142 | 143 | /// 144 | /// Reads a 4 byte single precision floating point number from the Processes Memory 145 | /// 146 | /// The address of the data to be read. 147 | /// Resulting Data 148 | public float ReadSingle(long address) 149 | { 150 | return MemoryUtil.ReadSingle(Handle, address); 151 | } 152 | 153 | /// 154 | /// Reads an 8 byte double precision floating point number from the Processes Memory 155 | /// 156 | /// The address of the data to be read. 157 | /// Resulting Data 158 | public double ReadDouble(long address) 159 | { 160 | return MemoryUtil.ReadDouble(Handle, address); 161 | } 162 | 163 | /// 164 | /// Reads a string from the processes' memory terminated by a null byte. 165 | /// 166 | /// Memory Address 167 | /// Buffer Read Size 168 | /// Resulting String 169 | public string ReadNullTerminatedString(long address, int bufferSize = 0xFF) 170 | { 171 | return MemoryUtil.ReadNullTerminatedString(Handle, address, bufferSize); 172 | } 173 | 174 | /// 175 | /// Reads a struct from the Processes Memory 176 | /// 177 | /// Struct Type 178 | /// Memory Address 179 | /// Resulting Struct 180 | public T ReadStruct(long address) 181 | { 182 | return MemoryUtil.ReadStruct(Handle, address); 183 | } 184 | 185 | /// 186 | /// Searches for bytes in the Processes Memory 187 | /// 188 | /// Byte Sequence to scan for. 189 | /// Address to start the search at. 190 | /// Address to end the search at. 191 | /// If we should stop the search at the first result. 192 | /// Byte Buffer Size 193 | /// Results 194 | public long[] FindBytes(byte?[] needle, long startAddress, long endAddress, bool firstMatch = false, int bufferSize = 0xFFFF) 195 | { 196 | return MemoryUtil.FindBytes(Handle, needle, startAddress, endAddress, firstMatch, bufferSize); 197 | } 198 | 199 | /// 200 | /// Gets the Active Processes' Base Address 201 | /// 202 | /// Base Address of the Active Process 203 | public long GetBaseAddress() 204 | { 205 | return (long)ActiveProcess?.MainModule.BaseAddress; 206 | } 207 | 208 | /// 209 | /// Gets the size of the Main Module Size 210 | /// 211 | /// Main Module Size 212 | public long GetModuleMemorySize() 213 | { 214 | return (long)ActiveProcess?.MainModule.ModuleMemorySize; 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/MathUtilities.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: MathUtilities.cs 24 | // Author: Philip/Scobalula 25 | // Description: Mathematic Utilities 26 | using System; 27 | 28 | namespace PhilLibX 29 | { 30 | /// 31 | /// Mathematic Utilities 32 | /// 33 | public class MathUtilities 34 | { 35 | /// 36 | /// Clamps Value to a range. 37 | /// 38 | /// Value to Clamp 39 | /// Max value 40 | /// Min value 41 | /// Clamped Value 42 | public static T Clamp(T value, T max, T min) where T : IComparable 43 | { 44 | return value.CompareTo(min) < 0 ? min : value.CompareTo(max) > 0 ? max : value; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/NativeMethods.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: NativeMethods.cs 24 | // Author: Philip/Scobalula 25 | // Description: Native/Unmanaged Methods (DLLs required for certain components) 26 | using System; 27 | using System.Runtime.InteropServices; 28 | 29 | namespace PhilLibX 30 | { 31 | /// 32 | /// Description: Native/Unmanaged Methods (DLLs required for certain components) 33 | /// 34 | internal class NativeMethods 35 | { 36 | /// 37 | /// Oodle Library Path 38 | /// 39 | private const string OodleLibraryPath = "oo2core_6_win64"; 40 | 41 | 42 | /// 43 | /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails. 44 | /// 45 | /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. 46 | /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails. 47 | /// A pointer to a buffer that receives the contents from the address space of the specified process. 48 | /// The number of bytes to be read from the specified process. 49 | /// A pointer to a variable that receives the number of bytes transferred into the specified buffer. 50 | /// 51 | [DllImport("kernel32.dll", SetLastError = true)] 52 | public static extern bool ReadProcessMemory 53 | ( 54 | int hProcess, 55 | long lpBaseAddress, 56 | byte[] lpBuffer, 57 | int nSize, 58 | out int lpNumberOfBytesRead 59 | ); 60 | 61 | /// 62 | /// Opens an existing local process object. 63 | /// 64 | /// The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights. If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor. 65 | /// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle. 66 | /// The identifier of the local process to be opened. 67 | /// 68 | [DllImport("kernel32.dll")] 69 | public static extern IntPtr OpenProcess 70 | ( 71 | int dwDesiredAccess, 72 | bool bInheritHandle, 73 | int dwProcessId 74 | ); 75 | 76 | /// 77 | /// Oodle64 Decompression Method 78 | /// 79 | [DllImport(OodleLibraryPath, CallingConvention = CallingConvention.Cdecl)] 80 | public static extern long OodleLZ_Decompress(byte[] buffer, long bufferSize, byte[] result, long outputBufferSize, int a, int b, int c, long d, long e, long f, long g, long h, long i, int ThreadModule); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /CoDLUIDecompiler/Util/PhilLibX/Printer.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: Printer.cs 24 | // Author: Philip/Scobalula 25 | // Description: Class to Print stuff to the Console with more swag 🖨️ 26 | using System; 27 | 28 | namespace PhilLibX 29 | { 30 | /// 31 | /// Class to Print stuff to the Console with more swag 🖨️ 32 | /// 33 | public class Printer 34 | { 35 | /// 36 | /// Prefix Padding 37 | /// 38 | private static int PrefixPadding = 12; 39 | 40 | /// 41 | /// Prefix Color 42 | /// 43 | private static ConsoleColor PrefixColor = ConsoleColor.Blue; 44 | 45 | /// 46 | /// Sets Prefix Padding 47 | /// 48 | /// Padding Size 49 | public static void SetPrefixPadding(int padding) 50 | { 51 | PrefixPadding = padding; 52 | } 53 | 54 | /// 55 | /// Sets the Console Prefix Color 56 | /// 57 | /// Background Color for Prefix 58 | public static void SetPrefixBackgroundColor(ConsoleColor color) 59 | { 60 | PrefixColor = color; 61 | } 62 | 63 | /// 64 | /// Writes a line to the console with optional BackGround 65 | /// 66 | /// Value to print 67 | /// Value to prefix 68 | /// Prefix Padding 69 | /// Background Color 70 | /// Prefix Background Color 71 | public static void WriteLine(object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.Black) 72 | { 73 | // Check if we even have a prefix, if not just do a normal print 74 | if(prefix != null) 75 | { 76 | Console.BackgroundColor = PrefixColor; 77 | Console.Write(" {0}", prefix.ToString().PadRight(PrefixPadding)); 78 | Console.ResetColor(); 79 | Console.Write("│ "); 80 | } 81 | Console.BackgroundColor = backgroundColor; 82 | Console.WriteLine("{0}", value); 83 | Console.ResetColor(); 84 | } 85 | 86 | /// 87 | /// Writes to the console with optional BackGround 88 | /// 89 | /// Value to print 90 | /// Value to prefix 91 | /// Prefix Padding 92 | /// Background Color 93 | /// Prefix Background Color 94 | public static void Write(object prefix = null, object value = null, ConsoleColor backgroundColor = ConsoleColor.Black) 95 | { 96 | // Check if we even have a prefix, if not just do a normal print 97 | if (prefix != null) 98 | { 99 | Console.BackgroundColor = ConsoleColor.DarkBlue; 100 | Console.Write(" {0}", prefix.ToString().PadRight(PrefixPadding)); 101 | Console.ResetColor(); 102 | Console.Write("│ "); 103 | } 104 | Console.BackgroundColor = backgroundColor; 105 | Console.Write("{0}", value); 106 | Console.ResetColor(); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 JariK 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | [![Releases](https://img.shields.io/github/downloads/JariKCoding/CoDLUIDecompiler/total.svg)](https://github.com/JariKCoding/CoDLUIDecompiler/) [![Discord](https://img.shields.io/badge/chat-Discord-blue.svg)](https://discord.gg/yU2Pje6) 3 | 4 | **CoDLUIDecompiler** is a lua decompiler for Havok Scripts from various Call Of Duty games. It's main purpose is to provide access to scripts that Treyarch did not provide in the Call of Duty: Black Ops III Mod Tools and to give greater insight into how Treyarch and the other studios achieved certain things, rebuild menus from the game, etc. 5 | 6 | Supports following games out of the box: **BlackOps2**, **BlackOps3**, **BlackOps4**, **Ghosts**, **AdvancedWarfare**, **InfiniteWarfare**, **ModernWarfareRemastered** and **WorldWar2** 7 | 8 | ### What is it GOOD for? 9 | 10 | - Rebuild widgets and menus from games 11 | - Learn the LUI framework 12 | 13 | ### What is it BAD for? 14 | 15 | - Decompiling big blocks of code that is used for functionality 16 | 17 | ### What can be improved 18 | 19 | - Condition/Loop detection 20 | 21 | ### How to Use 22 | 23 | - To decompile a couple/a single file(s) just drop it on the .exe 24 | - To decompile whole folders open the program and give it the path 25 | 26 | ### How to get the lua files 27 | 28 | - Run the game you want to rip the files from 29 | - Open the program and it will export all files 30 | 31 | ## Download 32 | 33 | The latest version can be found on the [Releases Page](https://github.com/JariKCoding/CoDLUIDecompiler/releases). 34 | 35 | ## Requirements 36 | 37 | * Windows 7 x86 and above 38 | * .NET Framework 4.7.2 39 | 40 | ## Credits 41 | 42 | - DTZxPorter - Original lua disassembler to find the basics 43 | - Scobalula - Utilities and general help 44 | 45 | ## License 46 | 47 | CoDLUIDecompiler is licensed under the MIT license and its source code is free to use and modify. CoDLUIDecompiler comes with NO warranty, any damages caused are solely the responsibility of the user. See the LICENSE file for more information. 48 | --------------------------------------------------------------------------------