├── .gitattributes ├── .gitignore ├── .vs └── ConfuserEx Dynamic Unpacker │ └── v15 │ └── .suo ├── ConfuserEx Dynamic Unpacker.sln ├── ConfuserEx Dynamic Unpacker ├── App.config ├── ConfuserEx Dynamic Unpacker.csproj ├── ConfuserEx Dynamic Unpacker.csproj.user ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── Protections │ ├── AntiTamper.cs │ ├── Constants.cs │ ├── ControlFlow.cs │ ├── ControlFlowRun.cs │ ├── Lzma.cs │ ├── Packer.cs │ ├── ReferenceProxy.cs │ ├── StaticPacker.cs │ └── StaticStrings.cs └── obj │ └── Debug │ └── ConfuserEx Dynamic Unpacker.csproj.FileListAbsolute.txt ├── DLLS ├── de4dot.blocks.dll ├── de4dot.blocks.pdb ├── dnlib.dll └── dnlib.pdb └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | 3 | ConfuserEx Dynamic Unpacker/bin/Debug/dnlib.xml 4 | *.cache 5 | ConfuserEx Dynamic Unpacker/bin/Debug/dnlib.pdb 6 | ConfuserEx Dynamic Unpacker/obj/Debug/ConfuserEx Dynamic Unpacker.pdb 7 | ConfuserEx Dynamic Unpacker/bin/Debug/dnlib.dll 8 | ConfuserEx Dynamic Unpacker/bin/Debug/de4dot.blocks.pdb 9 | ConfuserEx Dynamic Unpacker/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs 10 | ConfuserEx Dynamic Unpacker/bin/Debug/ConfuserEx Dynamic Unpacker.pdb 11 | ConfuserEx Dynamic Unpacker/bin/Debug/de4dot.blocks.dll 12 | -------------------------------------------------------------------------------- /.vs/ConfuserEx Dynamic Unpacker/v15/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uvbs/ConfuserEx-Unpacker/18938d8b51d640a96c58fd8aba8fa6f3b2999730/.vs/ConfuserEx Dynamic Unpacker/v15/.suo -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.12 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfuserEx Dynamic Unpacker", "ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker.csproj", "{21E98071-183F-4FD1-AE99-734404274BA6}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "de4dot.blocks", "..\..\..\GitHub\de4dot\de4dot.blocks\de4dot.blocks.csproj", "{045B96F2-AF80-4C4C-8D27-E38635AC705E}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dnlib", "..\..\..\GitHub\dnlib\src\dnlib.csproj", "{FDFC1237-143F-4919-8318-4926901F4639}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {21E98071-183F-4FD1-AE99-734404274BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {21E98071-183F-4FD1-AE99-734404274BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {21E98071-183F-4FD1-AE99-734404274BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {21E98071-183F-4FD1-AE99-734404274BA6}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {045B96F2-AF80-4C4C-8D27-E38635AC705E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {045B96F2-AF80-4C4C-8D27-E38635AC705E}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {045B96F2-AF80-4C4C-8D27-E38635AC705E}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {045B96F2-AF80-4C4C-8D27-E38635AC705E}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {FDFC1237-143F-4919-8318-4926901F4639}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {FDFC1237-143F-4919-8318-4926901F4639}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/ConfuserEx Dynamic Unpacker.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {21E98071-183F-4FD1-AE99-734404274BA6} 8 | Exe 9 | ConfuserEx_Dynamic_Unpacker 10 | ConfuserEx Dynamic Unpacker 11 | v4.5.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 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 | {045b96f2-af80-4c4c-8d27-e38635ac705e} 63 | de4dot.blocks 64 | 65 | 66 | {fdfc1237-143f-4919-8318-4926901f4639} 67 | dnlib 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/ConfuserEx Dynamic Unpacker.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\Users\owner\Desktop\filke\a.exe -d 5 | 6 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Program.cs: -------------------------------------------------------------------------------- 1 |  2 | using dnlib.DotNet; 3 | using dnlib.DotNet.Writer; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ConfuserEx_Dynamic_Unpacker 12 | { 13 | class Program 14 | { 15 | public static ModuleDefMD module; 16 | public static Assembly asm; 17 | 18 | public static bool veryVerbose =false; 19 | private static string path = null; 20 | private static string mode; 21 | 22 | static void Main(string[] args) 23 | { 24 | Console.ForegroundColor = ConsoleColor.Green; 25 | optionParser(args); 26 | Console.WriteLine("Yeah confuserex unpacker so what"); 27 | 28 | if (path == null||mode == null) 29 | { 30 | Console.WriteLine("Check args make sure path and either -d or -s is included (Dynamic or static)"); Console.ReadLine(); return; 31 | } 32 | 33 | module = ModuleDefMD.Load(path); 34 | 35 | 36 | 37 | if(mode.ToLower() == "static") 38 | { 39 | staticRoute(); 40 | 41 | } 42 | else if(mode.ToLower() == "dynamic") 43 | { 44 | asm = Assembly.LoadFrom(path); 45 | dynamicRoute(); 46 | 47 | } 48 | else 49 | { 50 | Console.Write("Yeah erm you might be a bit of an idiot follow the instructions"); 51 | Console.ReadLine(); 52 | return; 53 | } 54 | 55 | 56 | ModuleWriterOptions writerOptions = new ModuleWriterOptions(module); 57 | writerOptions.MetaDataOptions.Flags |= MetaDataFlags.PreserveAll; 58 | writerOptions.Logger = DummyLogger.NoThrowInstance; 59 | 60 | module.Write(path + "Cleaned.exe",writerOptions); 61 | Console.ReadLine(); 62 | } 63 | static void staticRoute() 64 | { 65 | 66 | antitamper(); 67 | Protections.ControlFlowRun.cleaner(module); 68 | Staticpacker(); 69 | try 70 | { 71 | Console.WriteLine("[!] Cleaning Proxy Calls"); 72 | int amountProxy = Protections.ReferenceProxy.ProxyFixer(module); 73 | Console.WriteLine("[!] Amount Of Proxy Calls Fixed: "+amountProxy); 74 | Protections.ControlFlowRun.cleaner(module); 75 | Console.WriteLine("[!] Decrytping Strings"); 76 | int strings = Protections.StaticStrings.Run(module); 77 | Console.WriteLine("[!] Amount Of Strings Decrypted: " + strings); 78 | 79 | } 80 | catch 81 | { 82 | Console.WriteLine("error happened somewhere apart from tamper and packer im too lazy to implement proper error handling"); 83 | } 84 | } 85 | static void dynamicRoute() 86 | { 87 | 88 | antitamper(); 89 | Protections.ControlFlowRun.cleaner(module); 90 | packer(); 91 | try 92 | { 93 | Console.WriteLine("[!] Cleaning Proxy Calls"); 94 | int amountProxy = Protections.ReferenceProxy.ProxyFixer(module); 95 | Console.WriteLine("[!] Amount Of Proxy Calls Fixed: " + amountProxy); 96 | Protections.ControlFlowRun.cleaner(module); 97 | Console.WriteLine("[!] Decrytping Strings"); 98 | int strings = Protections.Constants.constants(); 99 | Console.WriteLine("[!] Amount Of Strings Decrypted: " + strings); 100 | 101 | } 102 | catch 103 | { 104 | Console.WriteLine("error happened somewhere apart from tamper and packer im too lazy to implement proper error handling"); 105 | } 106 | } 107 | static void optionParser(string[] str) 108 | { 109 | foreach(string arg in str) 110 | { 111 | switch (arg) 112 | { 113 | 114 | case "-vv": 115 | veryVerbose = true; 116 | 117 | break; 118 | case "-d": 119 | mode = "dynamic"; 120 | break; 121 | case "-s": 122 | mode = "static"; 123 | break; 124 | default: 125 | path = arg; 126 | break; 127 | } 128 | } 129 | } 130 | static void packer() 131 | { 132 | try 133 | { 134 | if (Protections.Packer.IsPacked(module)) 135 | { 136 | Console.WriteLine("[!] Compressor Detected"); 137 | try 138 | { 139 | Protections.Packer.findLocal(); 140 | Console.WriteLine("[!] Compressor Removed Successfully"); 141 | Console.WriteLine("[!] Now Cleaning The koi Module"); 142 | } 143 | catch 144 | { 145 | Console.WriteLine("[!] Compressor Failed To Remove"); 146 | } 147 | 148 | antitamper(); 149 | module.EntryPoint = module.ResolveToken(Protections.StaticPacker.epToken) as MethodDef; 150 | 151 | } 152 | } 153 | catch 154 | { 155 | Console.WriteLine("An error in dynamic packer remover happened"); 156 | } 157 | 158 | } 159 | static void Staticpacker() 160 | { 161 | try 162 | { 163 | if (Protections.Packer.IsPacked(module)) 164 | { 165 | Console.WriteLine("[!] Compressor Detected"); 166 | try 167 | { 168 | Protections.StaticPacker.Run(module); 169 | Console.WriteLine("[!] Compressor Removed Successfully"); 170 | Console.WriteLine("[!] Now Cleaning The koi Module"); 171 | } 172 | catch 173 | { 174 | Console.WriteLine("[!] Compressor Failed To Remove"); 175 | } 176 | 177 | antitamper(); 178 | module.EntryPoint = module.ResolveToken(Protections.StaticPacker.epToken) as MethodDef; 179 | 180 | } 181 | } 182 | catch 183 | { 184 | Console.WriteLine("An error in static packer remover happened"); 185 | } 186 | 187 | } 188 | static void antitamper() 189 | { 190 | try 191 | { 192 | if (Protections.AntiTamper.IsTampered(module) == true) 193 | { 194 | Console.WriteLine("[!] Anti Tamper Detected"); 195 | 196 | byte[] rawbytes = null; 197 | 198 | var htdgfd = (module).MetaData.PEImage.CreateFullStream(); 199 | 200 | rawbytes = htdgfd.ReadBytes((int)htdgfd.Length); 201 | try 202 | { 203 | module = Protections.AntiTamper.UnAntiTamper(module, rawbytes); 204 | Console.WriteLine("[!] Anti Tamper Removed Successfully"); 205 | } 206 | catch 207 | { 208 | Console.WriteLine("[!] Anti Tamper Failed To Remove"); 209 | } 210 | 211 | } 212 | 213 | } 214 | catch 215 | { 216 | Console.WriteLine("An error in anti tamper remover happened"); 217 | } 218 | 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/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("ConfuserEx Dynamic Unpacker")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConfuserEx Dynamic Unpacker")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 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("21e98071-183f-4fd1-ae99-734404274ba6")] 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 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/AntiTamper.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using dnlib.PE; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ConfuserEx_Dynamic_Unpacker.Protections 12 | { 13 | class AntiTamper 14 | { 15 | public string DirectoryName = ""; 16 | 17 | private static MethodDef antitamp; 18 | private static uint[] arrayKeys; 19 | private static byte[] byteResult; 20 | private static MethodDef cctor; 21 | private static List dynInstr; 22 | private static uint[] initialKeys; 23 | 24 | private static BinaryReader reader; 25 | private static MemoryStream input; 26 | public static ModuleDefMD UnAntiTamper(ModuleDefMD module, byte[] rawbytes) 27 | { 28 | dynInstr = new List(); 29 | initialKeys = new uint[4]; 30 | cctor = module.GlobalType.FindStaticConstructor(); 31 | antitamp = cctor.Body.Instructions[0].Operand as MethodDef; 32 | if (antitamp == null) return null; 33 | IList imageSectionHeaders = module.MetaData.PEImage.ImageSectionHeaders; 34 | ImageSectionHeader confSec = imageSectionHeaders[0]; 35 | FindInitialKeys(antitamp); 36 | if (initialKeys == null) return null; 37 | input = new MemoryStream(rawbytes); 38 | reader = new BinaryReader(input); 39 | Hash1(input, reader, imageSectionHeaders, confSec); 40 | arrayKeys = GetArrayKeys(); 41 | DecryptMethods(reader, confSec, input); 42 | ModuleDefMD fmd2 = ModuleDefMD.Load(input); 43 | fmd2.GlobalType.FindStaticConstructor().Body.Instructions.RemoveAt(0); 44 | return fmd2; 45 | } 46 | private static void DecryptMethods(BinaryReader reader, ImageSectionHeader confSec, Stream stream) 47 | { 48 | int num = (int)(confSec.SizeOfRawData >> 2); 49 | int pointerToRawData = (int)confSec.PointerToRawData; 50 | stream.Position = pointerToRawData; 51 | uint[] numArray = new uint[num]; 52 | for (uint i = 0; i < num; i++) 53 | { 54 | uint num4 = reader.ReadUInt32(); 55 | numArray[i] = num4 ^ arrayKeys[(int)((IntPtr)(i & 15))]; 56 | arrayKeys[(int)((IntPtr)(i & 15))] = num4 + 0x3dbb2819; 57 | } 58 | byteResult = new byte[num << 2]; 59 | byteResult = Enumerable.SelectMany(numArray, new System.Func>(BitConverter.GetBytes)).ToArray(); 60 | byte[] byteArray = ConvertUInt32ArrayToByteArray(numArray); 61 | stream.Position = pointerToRawData; 62 | stream.Write(byteResult, 0, byteResult.Length); 63 | } 64 | public static bool? IsTampered(ModuleDefMD module) 65 | { 66 | var sections = module.MetaData.PEImage.ImageSectionHeaders; 67 | 68 | if (sections.Count == 3) 69 | { 70 | 71 | return false; 72 | } 73 | 74 | foreach (var section in sections) 75 | { 76 | switch (section.DisplayName) 77 | { 78 | case ".text": 79 | case ".rsrc": 80 | case ".reloc": 81 | continue; 82 | default: 83 | 84 | return true; 85 | } 86 | } 87 | return null; 88 | } 89 | private static byte[] ConvertUInt32ArrayToByteArray(uint[] value) 90 | { 91 | const int bytesPerUInt32 = 4; 92 | byte[] result = new byte[value.Length * bytesPerUInt32]; 93 | for (int index = 0; index < value.Length; index++) 94 | { 95 | byte[] partialResult = System.BitConverter.GetBytes(value[index]); 96 | for (int indexTwo = 0; indexTwo < partialResult.Length; indexTwo++) 97 | result[index * bytesPerUInt32 + indexTwo] = partialResult[indexTwo]; 98 | } 99 | return result; 100 | } 101 | private static void FindInitialKeys(MethodDef antitamp) 102 | { 103 | int count = antitamp.Body.Instructions.Count; 104 | int num2 = count - 0x125; 105 | for (int i = 0; i < count; i++) 106 | { 107 | Instruction item = antitamp.Body.Instructions[i]; 108 | if (item.OpCode.Equals(OpCodes.Ldc_I4)) 109 | { 110 | if (antitamp.Body.Instructions[i + 1].OpCode.Equals(OpCodes.Stloc_S)) 111 | { 112 | if (antitamp.Body.Instructions[i + 1].Operand.ToString().Contains("V_10")) 113 | { 114 | initialKeys[0] = (uint)((int)item.Operand); 115 | } 116 | if (antitamp.Body.Instructions[i + 1].Operand.ToString().Contains("V_11")) 117 | { 118 | initialKeys[1] = (uint)((int)item.Operand); 119 | } 120 | if (antitamp.Body.Instructions[i + 1].Operand.ToString().Contains("V_12")) 121 | { 122 | initialKeys[2] = (uint)((int)item.Operand); 123 | } 124 | if (antitamp.Body.Instructions[i + 1].Operand.ToString().Contains("V_13")) 125 | { 126 | initialKeys[3] = (uint)((int)item.Operand); 127 | } 128 | } 129 | } 130 | } 131 | } 132 | 133 | private static uint[] GetArrayKeys() 134 | { 135 | uint[] dst = new uint[0x10]; 136 | uint[] src = new uint[0x10]; 137 | for (int i = 0; i < 0x10; i++) 138 | { 139 | dst[i] = initialKeys[3]; 140 | src[i] = initialKeys[1]; 141 | initialKeys[0] = (initialKeys[1] >> 5) | (initialKeys[1] << 0x1b); 142 | initialKeys[1] = (initialKeys[2] >> 3) | (initialKeys[2] << 0x1d); 143 | initialKeys[2] = (initialKeys[3] >> 7) | (initialKeys[3] << 0x19); 144 | initialKeys[3] = (initialKeys[0] >> 11) | (initialKeys[0] << 0x15); 145 | } 146 | return DeriveKeyAntiTamp(dst, src); 147 | } 148 | public static uint[] DeriveKeyAntiTamp(uint[] dst, uint[] src) 149 | { 150 | uint[] numArray = new uint[0x10]; 151 | for (int i = 0; i < 0x10; i++) 152 | { 153 | switch ((i % 3)) 154 | { 155 | case 0: 156 | numArray[i] = dst[i] ^ src[i]; 157 | break; 158 | 159 | case 1: 160 | numArray[i] = dst[i] * src[i]; 161 | break; 162 | 163 | case 2: 164 | numArray[i] = dst[i] + src[i]; 165 | break; 166 | } 167 | } 168 | return numArray; 169 | } 170 | private static void Hash1(Stream stream, BinaryReader reader, IList sections, ImageSectionHeader confSec) 171 | { 172 | foreach (ImageSectionHeader header in sections) 173 | { 174 | if ((header != confSec) && (header.DisplayName != "")) 175 | { 176 | int num = (int)(header.SizeOfRawData >> 2); 177 | int pointerToRawData = (int)header.PointerToRawData; 178 | stream.Position = pointerToRawData; 179 | for (int i = 0; i < num; i++) 180 | { 181 | uint num4 = reader.ReadUInt32(); 182 | uint num5 = ((initialKeys[0] ^ num4) + initialKeys[1]) + (initialKeys[2] * initialKeys[3]); 183 | initialKeys[0] = initialKeys[1]; 184 | initialKeys[1] = initialKeys[2]; 185 | initialKeys[1] = initialKeys[3]; 186 | initialKeys[3] = num5; 187 | } 188 | } 189 | } 190 | } 191 | 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/Constants.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace ConfuserEx_Dynamic_Unpacker.Protections 10 | { 11 | class Constants 12 | { 13 | public static int constants() 14 | { 15 | int amount = 0; 16 | var manifestModule = Program.asm.ManifestModule; 17 | foreach(TypeDef types in Program.module.GetTypes()) 18 | { 19 | foreach(MethodDef methods in types.Methods) 20 | { 21 | if (!methods.HasBody) continue; 22 | for(int i = 0; i < methods.Body.Instructions.Count; i++) 23 | { 24 | if(methods.Body.Instructions[i].OpCode == OpCodes.Call && methods.Body.Instructions[i].Operand.ToString().Contains("tring>")&&methods.Body.Instructions[i].Operand is MethodSpec) 25 | { 26 | if (methods.Body.Instructions[i - 1].IsLdcI4()) 27 | { 28 | MethodSpec methodSpec = methods.Body.Instructions[i].Operand as MethodSpec; 29 | 30 | uint param1 = (uint)methods.Body.Instructions[i - 1].GetLdcI4Value(); 31 | var value = (string)manifestModule.ResolveMethod(methodSpec.MDToken.ToInt32()).Invoke(null,new object[] {(uint) param1 }); 32 | methods.Body.Instructions[i].OpCode = OpCodes.Nop; 33 | methods.Body.Instructions[i - 1].OpCode = OpCodes.Ldstr; 34 | methods.Body.Instructions[i - 1].Operand = value; 35 | amount++; 36 | if (Program.veryVerbose) 37 | { 38 | Console.ForegroundColor = ConsoleColor.Cyan; 39 | Console.WriteLine(string.Format("Encrypted String Found In Method {0} With Param of {1} the decrypted string is {2}", methods.Name, param1.ToString(), value)); 40 | Console.ForegroundColor = ConsoleColor.Green; 41 | } 42 | } 43 | } 44 | } 45 | } 46 | } 47 | return amount; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/ControlFlow.cs: -------------------------------------------------------------------------------- 1 | using de4dot.blocks; 2 | using de4dot.blocks.cflow; 3 | using dnlib.DotNet; 4 | using dnlib.DotNet.Emit; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ConfuserEx_Dynamic_Unpacker.Protections 12 | { 13 | class ControlFlow : BlockDeobfuscator 14 | { 15 | private Block switchBlock; 16 | private Local localSwitch; 17 | private bool native; 18 | private bool isolder; 19 | public MethodDef currentMethod; 20 | protected override bool Deobfuscate(Block block) 21 | { 22 | 23 | 24 | 25 | 26 | bool modified = false; 27 | if (block.LastInstr.OpCode == OpCodes.Switch) 28 | { 29 | 30 | 31 | allVars = blocks.Method.Body.Variables; 32 | isSwitchBlock(block); 33 | if (switchBlock != null && localSwitch != null) 34 | { 35 | ins.Initialize(blocks.Method); 36 | modified |= Cleaner(); 37 | 38 | 39 | 40 | 41 | } 42 | isExpressionBlock(block); 43 | if (switchBlock != null || localSwitch != null) 44 | { 45 | ins.Initialize(blocks.Method); modified |= Cleaner(); 46 | while (Cleaner()) 47 | { 48 | 49 | modified |= Cleaner(); 50 | } 51 | 52 | 53 | 54 | 55 | } 56 | } 57 | 58 | return modified; 59 | 60 | } 61 | public InstructionEmulator ins = new InstructionEmulator(); 62 | bool Cleaner() 63 | { 64 | bool modified = false; 65 | List allblocks = new List(); 66 | foreach (var block in allBlocks) 67 | { 68 | if (block.FallThrough == switchBlock) 69 | { 70 | allblocks.Add(block); 71 | } 72 | 73 | } 74 | List targetBlocks = new List(); 75 | targetBlocks = switchBlock.Targets; 76 | foreach (Block block in allblocks) 77 | { 78 | if (block.LastInstr.IsLdcI4()) 79 | { 80 | int val1 = block.LastInstr.GetLdcI4Value(); 81 | ins.Push(new Int32Value(val1)); 82 | int nextCase = emulateCase(out int localValue); 83 | if (Program.veryVerbose) 84 | { 85 | Console.ForegroundColor = ConsoleColor.Cyan; 86 | Console.Write(nextCase+","); 87 | Console.ForegroundColor = ConsoleColor.Green; 88 | } 89 | 90 | block.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); 91 | replace(targetBlocks[nextCase], localValue); 92 | 93 | block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); 94 | modified = true; 95 | } 96 | else if (isXor(block)) 97 | { 98 | ins.Emulate(block.Instructions, block.Instructions.Count - 5, block.Instructions.Count); 99 | Int32Value val1 = (Int32Value)ins.Pop(); 100 | ins.Push(val1); 101 | int nextCase = emulateCase(out int localValue); 102 | if (Program.veryVerbose) 103 | { 104 | Console.ForegroundColor = ConsoleColor.Cyan; 105 | Console.Write(nextCase+","); 106 | Console.ForegroundColor = ConsoleColor.Green; 107 | } 108 | block.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); 109 | replace(targetBlocks[nextCase], localValue); 110 | 111 | block.Instructions.Add(new Instr(new Instruction(OpCodes.Pop))); 112 | modified = true; 113 | } 114 | else if (block.Sources.Count == 2 && block.Instructions.Count == 1) 115 | { 116 | var sources = new List(block.Sources); 117 | foreach (Block source in sources) 118 | { 119 | if (source.FirstInstr.IsLdcI4()) 120 | { 121 | int val1 = source.FirstInstr.GetLdcI4Value(); 122 | ins.Push(new Int32Value(val1)); 123 | int nextCase = emulateCase(out int localValue); 124 | if (Program.veryVerbose) 125 | { 126 | Console.ForegroundColor = ConsoleColor.Cyan; 127 | if (source == sources[0]) 128 | { 129 | Console.Write("True: "+nextCase + ","); 130 | 131 | } 132 | else 133 | { 134 | Console.Write("False: " + nextCase + ","); 135 | } 136 | Console.ForegroundColor = ConsoleColor.Green; 137 | } 138 | source.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); 139 | replace(targetBlocks[nextCase], localValue); 140 | 141 | source.Instructions[1] = (new Instr(new Instruction(OpCodes.Pop))); 142 | modified = true; 143 | } 144 | } 145 | } 146 | else if (block.LastInstr.OpCode == OpCodes.Xor) 147 | { 148 | if (block.Instructions[block.Instructions.Count - 2].OpCode == OpCodes.Mul) 149 | { 150 | var instr = block.Instructions; 151 | 152 | int l = instr.Count; 153 | if (!(instr[l - 4].IsLdcI4())) continue; 154 | var sources = new List(block.Sources); 155 | foreach (Block source in sources) 156 | { 157 | if (source.FirstInstr.IsLdcI4()) 158 | { 159 | int val1 = source.FirstInstr.GetLdcI4Value(); 160 | try 161 | { 162 | instr[l - 5] = new Instr(new Instruction(OpCodes.Ldc_I4, val1)); 163 | } 164 | catch 165 | { 166 | instr.Insert(l - 4, new Instr(new Instruction(OpCodes.Ldc_I4, val1))); 167 | l++; 168 | } 169 | 170 | ins.Emulate(instr, l - 5, l); 171 | 172 | int nextCase = emulateCase(out int localValue); 173 | if (Program.veryVerbose) 174 | { 175 | Console.ForegroundColor = ConsoleColor.Cyan; 176 | if (source == sources[0]) 177 | { 178 | Console.Write("True: " + nextCase + ","); 179 | 180 | } 181 | else 182 | { 183 | Console.Write("False: " + nextCase + ","); 184 | } 185 | Console.ForegroundColor = ConsoleColor.Green; 186 | } 187 | source.ReplaceLastNonBranchWithBranch(0, targetBlocks[nextCase]); 188 | replace(targetBlocks[nextCase], localValue); 189 | try 190 | { 191 | source.Instructions[1] = (new Instr(new Instruction(OpCodes.Pop))); 192 | } 193 | catch 194 | { 195 | source.Instructions.Add((new Instr(new Instruction(OpCodes.Pop)))); 196 | } 197 | 198 | modified = true; 199 | } 200 | } 201 | } 202 | } 203 | 204 | } 205 | 206 | return modified; 207 | } 208 | public bool replace(Block test, int locVal) 209 | { 210 | 211 | //we replace the ldloc values with the correct ldc value 212 | if (test.IsConditionalBranch()) 213 | { 214 | //if it happens to be a conditional block then the ldloc wont be in the current block it will be in the fallthrough block 215 | //normally the fallthrough block is the switch block but then fallthrough again you get the correct block you need to replace 216 | //however this bit i dont really understand as much but it works so what ever but sometimes the fallthrough block is the first fallthrough not the second so we just set it to the first 217 | if (test.FallThrough.FallThrough == switchBlock) 218 | { 219 | 220 | test = test.FallThrough; 221 | } 222 | else 223 | { 224 | test = test.FallThrough.FallThrough; 225 | 226 | } 227 | 228 | } 229 | if (test == switchBlock) return false; 230 | 231 | for (int i = 0; i < test.Instructions.Count; i++) 232 | { 233 | if (test.Instructions[i].Instruction.GetLocal(blocks.Method.Body.Variables) == localSwitch) 234 | { 235 | 236 | //check to see if the local is the same as the one from the switch block and replace it 237 | test.Instructions[i] = new Instr(Instruction.CreateLdcI4(locVal)); 238 | return true; 239 | } 240 | } 241 | return false; 242 | } 243 | public int emulateCase(out int localValueasInt) 244 | { 245 | ins.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1); 246 | var localValue = ins.GetLocal(localSwitch) as Int32Value; 247 | localValueasInt = localValue.Value; 248 | return ((Int32Value)ins.Pop()).Value; 249 | } 250 | bool isXor(Block block) 251 | { 252 | //check to confirm it is indeed the correct block 253 | //credits to TheProxy for this method since mine wasnt as efficient 254 | int l = block.Instructions.Count - 1; 255 | var instr = block.Instructions; 256 | if (l < 4) 257 | return false; 258 | if (instr[l].OpCode != OpCodes.Xor) 259 | return false; 260 | if (!instr[l - 1].IsLdcI4()) 261 | return false; 262 | if (instr[l - 2].OpCode != OpCodes.Mul) 263 | return false; 264 | if (!instr[l - 3].IsLdcI4()) 265 | return false; 266 | if (!instr[l - 4].IsLdcI4()) 267 | return false; 268 | 269 | 270 | return true; 271 | } 272 | #region detectSwitches 273 | void isExpressionBlock(Block block) 274 | { 275 | if (block.Instructions.Count < 7) 276 | return; 277 | if (!block.FirstInstr.IsStloc()) 278 | return; 279 | //we check to see if the switch block is confuserex cflow expression 280 | 281 | switchBlock = block; 282 | //set the local to a variable to compare to later 283 | localSwitch = Instr.GetLocalVar(blocks.Method.Body.Variables.Locals, block.Instructions[block.Instructions.Count - 4]); 284 | return; 285 | 286 | 287 | } 288 | void isNative(Block block) 289 | { 290 | 291 | if (block.Instructions.Count <= 5) 292 | return; 293 | if (block.FirstInstr.OpCode != OpCodes.Call) 294 | return; 295 | switchBlock = block; 296 | native = true; 297 | 298 | //set the local to a variable to compare to later 299 | localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]); 300 | return; 301 | } 302 | void isolderCflow(Block block) 303 | { 304 | if (block.Instructions.Count <= 2) 305 | return; 306 | if (!block.FirstInstr.IsLdcI4()) 307 | return; 308 | //check to see if its confuserex switch block 309 | isolder = true; 310 | switchBlock = block; 311 | //set the local to a variable to compare to later 312 | // localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]); 313 | return; 314 | } 315 | void isolderNatCflow(Block block) 316 | { 317 | if (block.Instructions.Count != 2) 318 | return; 319 | if (block.FirstInstr.OpCode != OpCodes.Call) 320 | return; 321 | //check to see if its confuserex switch block 322 | isolder = true; 323 | switchBlock = block; 324 | native = true; 325 | //set the local to a variable to compare to later 326 | // localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]); 327 | return; 328 | } 329 | void isolderExpCflow(Block block) 330 | { 331 | if (block.Instructions.Count <= 2) 332 | return; 333 | if (!block.FirstInstr.IsStloc()) 334 | return; 335 | //check to see if its confuserex switch block 336 | isolder = true; 337 | switchBlock = block; 338 | //set the local to a variable to compare to later 339 | // localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]); 340 | return; 341 | } 342 | private IList allVars; 343 | void isSwitchBlock(Block block) 344 | { 345 | if (block.Instructions.Count <= 6) 346 | return; 347 | if (!block.FirstInstr.IsLdcI4()) 348 | return; 349 | //check to see if its confuserex switch block 350 | 351 | switchBlock = block; 352 | //set the local to a variable to compare to later 353 | localSwitch = Instr.GetLocalVar(allVars, block.Instructions[block.Instructions.Count - 4]); 354 | return; 355 | 356 | 357 | 358 | 359 | } 360 | #endregion; 361 | } 362 | } 363 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/ControlFlowRun.cs: -------------------------------------------------------------------------------- 1 | using de4dot.blocks; 2 | using de4dot.blocks.cflow; 3 | using dnlib.DotNet; 4 | using dnlib.DotNet.Emit; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ConfuserEx_Dynamic_Unpacker.Protections 12 | { 13 | class ControlFlowRun 14 | { 15 | private static BlocksCflowDeobfuscator CfDeob; 16 | 17 | public static void DeobfuscateCflow(MethodDef meth) 18 | { 19 | 20 | for (int i = 0; i < 2; i++) 21 | { 22 | 23 | CfDeob = new BlocksCflowDeobfuscator(); 24 | Blocks blocks = new Blocks(meth); 25 | List test = blocks.MethodBlocks.GetAllBlocks(); 26 | blocks.RemoveDeadBlocks(); 27 | blocks.RepartitionBlocks(); 28 | 29 | blocks.UpdateBlocks(); 30 | blocks.Method.Body.SimplifyBranches(); 31 | blocks.Method.Body.OptimizeBranches(); 32 | CfDeob.Initialize(blocks); 33 | //CfDeob.Deobfuscate(); 34 | CfDeob.Add(new ControlFlow()); 35 | 36 | // CfDeob.Add(new Cflow()); 37 | CfDeob.Deobfuscate(); 38 | blocks.RepartitionBlocks(); 39 | 40 | 41 | IList instructions; 42 | IList exceptionHandlers; 43 | blocks.GetCode(out instructions, out exceptionHandlers); 44 | DotNetUtils.RestoreBody(meth, instructions, exceptionHandlers); 45 | 46 | 47 | 48 | 49 | 50 | } 51 | } 52 | public static bool hasCflow(dnlib.DotNet.MethodDef methods) 53 | { 54 | for (int i = 0; i < methods.Body.Instructions.Count; i++) 55 | { 56 | if (methods.Body.Instructions[i].OpCode == OpCodes.Switch) 57 | { 58 | return true; 59 | } 60 | } 61 | return false; 62 | } 63 | public static void cleaner(ModuleDefMD module) 64 | { 65 | foreach (TypeDef types in module.GetTypes()) 66 | { 67 | foreach (MethodDef methods in types.Methods) 68 | { 69 | if (!methods.HasBody) continue; 70 | 71 | if (hasCflow(methods)) 72 | { 73 | if (Program.veryVerbose) 74 | { 75 | Console.ForegroundColor = ConsoleColor.Cyan; 76 | Console.Write("Cleaning Control Flow for " + methods.FullName + "\nThe case order is: "); 77 | Console.ForegroundColor = ConsoleColor.Green; 78 | } 79 | 80 | 81 | DeobfuscateCflow(methods); 82 | if(Program.veryVerbose) 83 | Console.WriteLine(); 84 | } 85 | 86 | 87 | 88 | } 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/Lzma.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace ConfuserEx_Dynamic_Unpacker.Protections 10 | { 11 | internal static class Lzma 12 | { 13 | private const uint kAlignTableSize = 0x10; 14 | private const uint kEndPosModelIndex = 14; 15 | private const uint kMatchMinLen = 2; 16 | private const int kNumAlignBits = 4; 17 | private const uint kNumFullDistances = 0x80; 18 | private const int kNumHighLenBits = 8; 19 | private const uint kNumLenToPosStates = 4; 20 | private const int kNumLowLenBits = 3; 21 | private const uint kNumLowLenSymbols = 8; 22 | private const int kNumMidLenBits = 3; 23 | private const uint kNumMidLenSymbols = 8; 24 | private const int kNumPosSlotBits = 6; 25 | private const int kNumPosStatesBitsMax = 4; 26 | private const uint kNumPosStatesMax = 0x10; 27 | private const uint kNumStates = 12; 28 | private const uint kStartPosModelIndex = 4; 29 | 30 | public static byte[] Decompress(byte[] data) 31 | { 32 | MemoryStream inStream = new MemoryStream(data); 33 | LzmaDecoder decoder = new LzmaDecoder(); 34 | byte[] buffer = new byte[5]; 35 | inStream.Read(buffer, 0, 5); 36 | decoder.SetDecoderProperties(buffer); 37 | long outSize = 0L; 38 | for (int i = 0; i < 8; i++) 39 | { 40 | int num3 = inStream.ReadByte(); 41 | outSize |= (long)((long)((ulong)((byte)num3)) << 8 * i); 42 | } 43 | byte[] buffer2 = new byte[outSize]; 44 | MemoryStream outStream = new MemoryStream(buffer2, true); 45 | long inSize = inStream.Length - 13L; 46 | decoder.Code(inStream, outStream, inSize, outSize); 47 | return buffer2; 48 | } 49 | 50 | [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] 51 | private struct BitDecoder 52 | { 53 | public const int kNumBitModelTotalBits = 11; 54 | public const uint kBitModelTotal = 0x800; 55 | private const int kNumMoveBits = 5; 56 | private uint Prob; 57 | public void Init() 58 | { 59 | this.Prob = 0x400; 60 | } 61 | 62 | public uint Decode(Lzma.Decoder rangeDecoder) 63 | { 64 | uint num = (rangeDecoder.Range >> 11) * this.Prob; 65 | if (rangeDecoder.Code < num) 66 | { 67 | rangeDecoder.Range = num; 68 | this.Prob += (uint)((0x800 - this.Prob) >> 5); 69 | if (rangeDecoder.Range < 0x1000000) 70 | { 71 | rangeDecoder.Code = (rangeDecoder.Code << 8) | ((byte)rangeDecoder.Stream.ReadByte()); 72 | rangeDecoder.Range = rangeDecoder.Range << 8; 73 | } 74 | return 0; 75 | } 76 | rangeDecoder.Range -= num; 77 | rangeDecoder.Code -= num; 78 | this.Prob -= this.Prob >> 5; 79 | if (rangeDecoder.Range < 0x1000000) 80 | { 81 | rangeDecoder.Code = (rangeDecoder.Code << 8) | ((byte)rangeDecoder.Stream.ReadByte()); 82 | rangeDecoder.Range = rangeDecoder.Range << 8; 83 | } 84 | return 1; 85 | } 86 | } 87 | 88 | [StructLayout(LayoutKind.Sequential)] 89 | private struct BitTreeDecoder 90 | { 91 | private readonly Lzma.BitDecoder[] Models; 92 | private readonly int NumBitLevels; 93 | public BitTreeDecoder(int numBitLevels) 94 | { 95 | this.NumBitLevels = numBitLevels; 96 | this.Models = new Lzma.BitDecoder[((int)1) << numBitLevels]; 97 | } 98 | 99 | public void Init() 100 | { 101 | for (uint i = 1; i < (((int)1) << this.NumBitLevels); i++) 102 | { 103 | this.Models[i].Init(); 104 | } 105 | } 106 | 107 | public uint Decode(Lzma.Decoder rangeDecoder) 108 | { 109 | uint index = 1; 110 | for (int i = this.NumBitLevels; i > 0; i--) 111 | { 112 | index = (index << 1) + this.Models[index].Decode(rangeDecoder); 113 | } 114 | return (index - (((uint)1) << this.NumBitLevels)); 115 | } 116 | 117 | public uint ReverseDecode(Lzma.Decoder rangeDecoder) 118 | { 119 | uint index = 1; 120 | uint num2 = 0; 121 | for (int i = 0; i < this.NumBitLevels; i++) 122 | { 123 | uint num4 = this.Models[index].Decode(rangeDecoder); 124 | index = index << 1; 125 | index += num4; 126 | num2 |= num4 << i; 127 | } 128 | return num2; 129 | } 130 | 131 | public static uint ReverseDecode(Lzma.BitDecoder[] Models, uint startIndex, Lzma.Decoder rangeDecoder, int NumBitLevels) 132 | { 133 | uint num = 1; 134 | uint num2 = 0; 135 | for (int i = 0; i < NumBitLevels; i++) 136 | { 137 | uint num4 = Models[startIndex + num].Decode(rangeDecoder); 138 | num = num << 1; 139 | num += num4; 140 | num2 |= num4 << i; 141 | } 142 | return num2; 143 | } 144 | } 145 | 146 | private class Decoder 147 | { 148 | public uint Code; 149 | public const uint kTopValue = 0x1000000; 150 | public uint Range; 151 | public System.IO.Stream Stream; 152 | 153 | public uint DecodeDirectBits(int numTotalBits) 154 | { 155 | uint range = this.Range; 156 | uint code = this.Code; 157 | uint num3 = 0; 158 | for (int i = numTotalBits; i > 0; i--) 159 | { 160 | range = range >> 1; 161 | uint num5 = (code - range) >> 0x1f; 162 | code -= range & (num5 - 1); 163 | num3 = (num3 << 1) | (1 - num5); 164 | if (range < 0x1000000) 165 | { 166 | code = (code << 8) | ((byte)this.Stream.ReadByte()); 167 | range = range << 8; 168 | } 169 | } 170 | this.Range = range; 171 | this.Code = code; 172 | return num3; 173 | } 174 | 175 | public void Init(System.IO.Stream stream) 176 | { 177 | this.Stream = stream; 178 | this.Code = 0; 179 | this.Range = uint.MaxValue; 180 | for (int i = 0; i < 5; i++) 181 | { 182 | this.Code = (this.Code << 8) | ((byte)this.Stream.ReadByte()); 183 | } 184 | } 185 | 186 | public void Normalize() 187 | { 188 | while (this.Range < 0x1000000) 189 | { 190 | this.Code = (this.Code << 8) | ((byte)this.Stream.ReadByte()); 191 | this.Range = this.Range << 8; 192 | } 193 | } 194 | 195 | public void ReleaseStream() 196 | { 197 | this.Stream = null; 198 | } 199 | } 200 | 201 | private class LzmaDecoder 202 | { 203 | private bool _solid = false; 204 | private uint m_DictionarySize = uint.MaxValue; 205 | private uint m_DictionarySizeCheck; 206 | private readonly Lzma.BitDecoder[] m_IsMatchDecoders = new Lzma.BitDecoder[0xc0]; 207 | private readonly Lzma.BitDecoder[] m_IsRep0LongDecoders = new Lzma.BitDecoder[0xc0]; 208 | private readonly Lzma.BitDecoder[] m_IsRepDecoders = new Lzma.BitDecoder[12]; 209 | private readonly Lzma.BitDecoder[] m_IsRepG0Decoders = new Lzma.BitDecoder[12]; 210 | private readonly Lzma.BitDecoder[] m_IsRepG1Decoders = new Lzma.BitDecoder[12]; 211 | private readonly Lzma.BitDecoder[] m_IsRepG2Decoders = new Lzma.BitDecoder[12]; 212 | private readonly LenDecoder m_LenDecoder = new LenDecoder(); 213 | private readonly LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); 214 | private readonly Lzma.OutWindow m_OutWindow = new Lzma.OutWindow(); 215 | private Lzma.BitTreeDecoder m_PosAlignDecoder = new Lzma.BitTreeDecoder(4); 216 | private readonly Lzma.BitDecoder[] m_PosDecoders = new Lzma.BitDecoder[0x72]; 217 | private readonly Lzma.BitTreeDecoder[] m_PosSlotDecoder = new Lzma.BitTreeDecoder[4]; 218 | private uint m_PosStateMask; 219 | private readonly Lzma.Decoder m_RangeDecoder = new Lzma.Decoder(); 220 | private readonly LenDecoder m_RepLenDecoder = new LenDecoder(); 221 | 222 | public LzmaDecoder() 223 | { 224 | for (int i = 0; i < 4L; i++) 225 | { 226 | this.m_PosSlotDecoder[i] = new Lzma.BitTreeDecoder(6); 227 | } 228 | } 229 | 230 | public void Code(Stream inStream, Stream outStream, long inSize, long outSize) 231 | { 232 | byte num7; 233 | this.Init(inStream, outStream); 234 | Lzma.State state = new Lzma.State(); 235 | state.Init(); 236 | uint distance = 0; 237 | uint num2 = 0; 238 | uint num3 = 0; 239 | uint num4 = 0; 240 | ulong num5 = 0L; 241 | ulong num6 = (ulong)outSize; 242 | if (num5 < num6) 243 | { 244 | this.m_IsMatchDecoders[state.Index << 4].Decode(this.m_RangeDecoder); 245 | state.UpdateChar(); 246 | num7 = this.m_LiteralDecoder.DecodeNormal(this.m_RangeDecoder, 0, 0); 247 | this.m_OutWindow.PutByte(num7); 248 | num5 += (ulong)1L; 249 | } 250 | while (num5 < num6) 251 | { 252 | uint posState = ((uint)num5) & this.m_PosStateMask; 253 | if (this.m_IsMatchDecoders[(state.Index << 4) + posState].Decode(this.m_RangeDecoder) == 0) 254 | { 255 | byte @byte = this.m_OutWindow.GetByte(0); 256 | if (!state.IsCharState()) 257 | { 258 | num7 = this.m_LiteralDecoder.DecodeWithMatchByte(this.m_RangeDecoder, (uint)num5, @byte, this.m_OutWindow.GetByte(distance)); 259 | } 260 | else 261 | { 262 | num7 = this.m_LiteralDecoder.DecodeNormal(this.m_RangeDecoder, (uint)num5, @byte); 263 | } 264 | this.m_OutWindow.PutByte(num7); 265 | state.UpdateChar(); 266 | num5 += (ulong)1L; 267 | } 268 | else 269 | { 270 | uint num10; 271 | if (this.m_IsRepDecoders[state.Index].Decode(this.m_RangeDecoder) == 1) 272 | { 273 | if (this.m_IsRepG0Decoders[state.Index].Decode(this.m_RangeDecoder) == 0) 274 | { 275 | if (this.m_IsRep0LongDecoders[(state.Index << 4) + posState].Decode(this.m_RangeDecoder) == 0) 276 | { 277 | state.UpdateShortRep(); 278 | this.m_OutWindow.PutByte(this.m_OutWindow.GetByte(distance)); 279 | num5 += (ulong)1L; 280 | continue; 281 | } 282 | } 283 | else 284 | { 285 | uint num11; 286 | if (this.m_IsRepG1Decoders[state.Index].Decode(this.m_RangeDecoder) == 0) 287 | { 288 | num11 = num2; 289 | } 290 | else 291 | { 292 | if (this.m_IsRepG2Decoders[state.Index].Decode(this.m_RangeDecoder) == 0) 293 | { 294 | num11 = num3; 295 | } 296 | else 297 | { 298 | num11 = num4; 299 | num4 = num3; 300 | } 301 | num3 = num2; 302 | } 303 | num2 = distance; 304 | distance = num11; 305 | } 306 | num10 = this.m_RepLenDecoder.Decode(this.m_RangeDecoder, posState) + 2; 307 | state.UpdateRep(); 308 | } 309 | else 310 | { 311 | num4 = num3; 312 | num3 = num2; 313 | num2 = distance; 314 | num10 = 2 + this.m_LenDecoder.Decode(this.m_RangeDecoder, posState); 315 | state.UpdateMatch(); 316 | uint num12 = this.m_PosSlotDecoder[GetLenToPosState(num10)].Decode(this.m_RangeDecoder); 317 | if (num12 >= 4) 318 | { 319 | int numBitLevels = ((int)(num12 >> 1)) - 1; 320 | distance = (uint)((2 | (num12 & 1)) << (numBitLevels & 0x1f)); 321 | if (num12 < 14) 322 | { 323 | distance += Lzma.BitTreeDecoder.ReverseDecode(this.m_PosDecoders, (distance - num12) - 1, this.m_RangeDecoder, numBitLevels); 324 | } 325 | else 326 | { 327 | distance += this.m_RangeDecoder.DecodeDirectBits(numBitLevels - 4) << 4; 328 | distance += this.m_PosAlignDecoder.ReverseDecode(this.m_RangeDecoder); 329 | } 330 | } 331 | else 332 | { 333 | distance = num12; 334 | } 335 | } 336 | if (((distance >= num5) || (distance >= this.m_DictionarySizeCheck)) && (distance == uint.MaxValue)) 337 | { 338 | break; 339 | } 340 | this.m_OutWindow.CopyBlock(distance, num10); 341 | num5 += num10; 342 | } 343 | } 344 | this.m_OutWindow.Flush(); 345 | this.m_OutWindow.ReleaseStream(); 346 | this.m_RangeDecoder.ReleaseStream(); 347 | } 348 | 349 | private static uint GetLenToPosState(uint len) 350 | { 351 | len -= 2; 352 | if (len < 4) 353 | { 354 | return len; 355 | } 356 | return 3; 357 | } 358 | 359 | private void Init(Stream inStream, Stream outStream) 360 | { 361 | uint num; 362 | this.m_RangeDecoder.Init(inStream); 363 | this.m_OutWindow.Init(outStream, this._solid); 364 | for (num = 0; num < 12; num++) 365 | { 366 | for (uint i = 0; i <= this.m_PosStateMask; i++) 367 | { 368 | uint index = (num << 4) + i; 369 | this.m_IsMatchDecoders[index].Init(); 370 | this.m_IsRep0LongDecoders[index].Init(); 371 | } 372 | this.m_IsRepDecoders[num].Init(); 373 | this.m_IsRepG0Decoders[num].Init(); 374 | this.m_IsRepG1Decoders[num].Init(); 375 | this.m_IsRepG2Decoders[num].Init(); 376 | } 377 | this.m_LiteralDecoder.Init(); 378 | for (num = 0; num < 4; num++) 379 | { 380 | this.m_PosSlotDecoder[num].Init(); 381 | } 382 | for (num = 0; num < 0x72; num++) 383 | { 384 | this.m_PosDecoders[num].Init(); 385 | } 386 | this.m_LenDecoder.Init(); 387 | this.m_RepLenDecoder.Init(); 388 | this.m_PosAlignDecoder.Init(); 389 | } 390 | 391 | public void SetDecoderProperties(byte[] properties) 392 | { 393 | int lc = properties[0] % 9; 394 | int num2 = properties[0] / 9; 395 | int lp = num2 % 5; 396 | int pb = num2 / 5; 397 | uint dictionarySize = 0; 398 | for (int i = 0; i < 4; i++) 399 | { 400 | dictionarySize += (uint)(properties[1 + i] << (i * 8)); 401 | } 402 | this.SetDictionarySize(dictionarySize); 403 | this.SetLiteralProperties(lp, lc); 404 | this.SetPosBitsProperties(pb); 405 | } 406 | 407 | private void SetDictionarySize(uint dictionarySize) 408 | { 409 | if (this.m_DictionarySize != dictionarySize) 410 | { 411 | this.m_DictionarySize = dictionarySize; 412 | this.m_DictionarySizeCheck = Math.Max(this.m_DictionarySize, 1); 413 | uint windowSize = Math.Max(this.m_DictionarySizeCheck, 0x1000); 414 | this.m_OutWindow.Create(windowSize); 415 | } 416 | } 417 | 418 | private void SetLiteralProperties(int lp, int lc) 419 | { 420 | this.m_LiteralDecoder.Create(lp, lc); 421 | } 422 | 423 | private void SetPosBitsProperties(int pb) 424 | { 425 | uint numPosStates = ((uint)1) << pb; 426 | this.m_LenDecoder.Create(numPosStates); 427 | this.m_RepLenDecoder.Create(numPosStates); 428 | this.m_PosStateMask = numPosStates - 1; 429 | } 430 | 431 | private class LenDecoder 432 | { 433 | private Lzma.BitDecoder m_Choice = new Lzma.BitDecoder(); 434 | private Lzma.BitDecoder m_Choice2 = new Lzma.BitDecoder(); 435 | private Lzma.BitTreeDecoder m_HighCoder = new Lzma.BitTreeDecoder(8); 436 | private readonly Lzma.BitTreeDecoder[] m_LowCoder = new Lzma.BitTreeDecoder[0x10]; 437 | private readonly Lzma.BitTreeDecoder[] m_MidCoder = new Lzma.BitTreeDecoder[0x10]; 438 | private uint m_NumPosStates; 439 | 440 | public void Create(uint numPosStates) 441 | { 442 | for (uint i = this.m_NumPosStates; i < numPosStates; i++) 443 | { 444 | this.m_LowCoder[i] = new Lzma.BitTreeDecoder(3); 445 | this.m_MidCoder[i] = new Lzma.BitTreeDecoder(3); 446 | } 447 | this.m_NumPosStates = numPosStates; 448 | } 449 | 450 | public uint Decode(Lzma.Decoder rangeDecoder, uint posState) 451 | { 452 | if (this.m_Choice.Decode(rangeDecoder) == 0) 453 | { 454 | return this.m_LowCoder[posState].Decode(rangeDecoder); 455 | } 456 | uint num = 8; 457 | if (this.m_Choice2.Decode(rangeDecoder) == 0) 458 | { 459 | num += this.m_MidCoder[posState].Decode(rangeDecoder); 460 | } 461 | else 462 | { 463 | num += 8; 464 | num += this.m_HighCoder.Decode(rangeDecoder); 465 | } 466 | return num; 467 | } 468 | 469 | public void Init() 470 | { 471 | this.m_Choice.Init(); 472 | for (uint i = 0; i < this.m_NumPosStates; i++) 473 | { 474 | this.m_LowCoder[i].Init(); 475 | this.m_MidCoder[i].Init(); 476 | } 477 | this.m_Choice2.Init(); 478 | this.m_HighCoder.Init(); 479 | } 480 | } 481 | 482 | private class LiteralDecoder 483 | { 484 | private Decoder2[] m_Coders; 485 | private int m_NumPosBits; 486 | private int m_NumPrevBits; 487 | private uint m_PosMask; 488 | 489 | public void Create(int numPosBits, int numPrevBits) 490 | { 491 | if (((this.m_Coders == null) || (this.m_NumPrevBits != numPrevBits)) || (this.m_NumPosBits != numPosBits)) 492 | { 493 | this.m_NumPosBits = numPosBits; 494 | this.m_PosMask = (uint)((((int)1) << numPosBits) - 1); 495 | this.m_NumPrevBits = numPrevBits; 496 | uint num = ((uint)1) << (this.m_NumPrevBits + this.m_NumPosBits); 497 | this.m_Coders = new Decoder2[num]; 498 | for (uint i = 0; i < num; i++) 499 | { 500 | this.m_Coders[i].Create(); 501 | } 502 | } 503 | } 504 | 505 | public byte DecodeNormal(Lzma.Decoder rangeDecoder, uint pos, byte prevByte) 506 | { 507 | return this.m_Coders[this.GetState(pos, prevByte)].DecodeNormal(rangeDecoder); 508 | } 509 | 510 | public byte DecodeWithMatchByte(Lzma.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte) 511 | { 512 | return this.m_Coders[this.GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); 513 | } 514 | 515 | private uint GetState(uint pos, byte prevByte) 516 | { 517 | return (((pos & this.m_PosMask) << this.m_NumPrevBits) + ((uint)(prevByte >> (8 - this.m_NumPrevBits)))); 518 | } 519 | 520 | public void Init() 521 | { 522 | uint num = ((uint)1) << (this.m_NumPrevBits + this.m_NumPosBits); 523 | for (uint i = 0; i < num; i++) 524 | { 525 | this.m_Coders[i].Init(); 526 | } 527 | } 528 | 529 | [StructLayout(LayoutKind.Sequential)] 530 | private struct Decoder2 531 | { 532 | private Lzma.BitDecoder[] m_Decoders; 533 | public void Create() 534 | { 535 | this.m_Decoders = new Lzma.BitDecoder[0x300]; 536 | } 537 | 538 | public void Init() 539 | { 540 | for (int i = 0; i < 0x300; i++) 541 | { 542 | this.m_Decoders[i].Init(); 543 | } 544 | } 545 | 546 | public byte DecodeNormal(Lzma.Decoder rangeDecoder) 547 | { 548 | uint index = 1; 549 | do 550 | { 551 | index = (index << 1) | this.m_Decoders[index].Decode(rangeDecoder); 552 | } 553 | while (index < 0x100); 554 | return (byte)index; 555 | } 556 | 557 | public byte DecodeWithMatchByte(Lzma.Decoder rangeDecoder, byte matchByte) 558 | { 559 | uint index = 1; 560 | do 561 | { 562 | uint num2 = (uint)((matchByte >> 7) & 1); 563 | matchByte = (byte)(matchByte << 1); 564 | uint num3 = this.m_Decoders[(int)((IntPtr)(((1 + num2) << 8) + index))].Decode(rangeDecoder); 565 | index = (index << 1) | num3; 566 | if (num2 != num3) 567 | { 568 | while (index < 0x100) 569 | { 570 | index = (index << 1) | this.m_Decoders[index].Decode(rangeDecoder); 571 | } 572 | break; 573 | } 574 | } 575 | while (index < 0x100); 576 | return (byte)index; 577 | } 578 | } 579 | } 580 | } 581 | 582 | private class OutWindow 583 | { 584 | private byte[] _buffer; 585 | private uint _pos; 586 | private Stream _stream; 587 | private uint _streamPos; 588 | private uint _windowSize; 589 | 590 | public void CopyBlock(uint distance, uint len) 591 | { 592 | uint num = (this._pos - distance) - 1; 593 | if (num >= this._windowSize) 594 | { 595 | num += this._windowSize; 596 | } 597 | while (len > 0) 598 | { 599 | if (num >= this._windowSize) 600 | { 601 | num = 0; 602 | } 603 | this._buffer[this._pos++] = this._buffer[num++]; 604 | if (this._pos >= this._windowSize) 605 | { 606 | this.Flush(); 607 | } 608 | len--; 609 | } 610 | } 611 | 612 | public void Create(uint windowSize) 613 | { 614 | if (this._windowSize != windowSize) 615 | { 616 | this._buffer = new byte[windowSize]; 617 | } 618 | this._windowSize = windowSize; 619 | this._pos = 0; 620 | this._streamPos = 0; 621 | } 622 | 623 | public void Flush() 624 | { 625 | uint num = this._pos - this._streamPos; 626 | if (num != 0) 627 | { 628 | this._stream.Write(this._buffer, (int)this._streamPos, (int)num); 629 | if (this._pos >= this._windowSize) 630 | { 631 | this._pos = 0; 632 | } 633 | this._streamPos = this._pos; 634 | } 635 | } 636 | 637 | public byte GetByte(uint distance) 638 | { 639 | uint index = (this._pos - distance) - 1; 640 | if (index >= this._windowSize) 641 | { 642 | index += this._windowSize; 643 | } 644 | return this._buffer[index]; 645 | } 646 | 647 | public void Init(Stream stream, bool solid) 648 | { 649 | this.ReleaseStream(); 650 | this._stream = stream; 651 | if (!solid) 652 | { 653 | this._streamPos = 0; 654 | this._pos = 0; 655 | } 656 | } 657 | 658 | public void PutByte(byte b) 659 | { 660 | this._buffer[this._pos++] = b; 661 | if (this._pos >= this._windowSize) 662 | { 663 | this.Flush(); 664 | } 665 | } 666 | 667 | public void ReleaseStream() 668 | { 669 | this.Flush(); 670 | this._stream = null; 671 | Buffer.BlockCopy(new byte[this._buffer.Length], 0, this._buffer, 0, this._buffer.Length); 672 | } 673 | } 674 | 675 | [StructLayout(LayoutKind.Sequential)] 676 | private struct State 677 | { 678 | public uint Index; 679 | public void Init() 680 | { 681 | this.Index = 0; 682 | } 683 | 684 | public void UpdateChar() 685 | { 686 | if (this.Index < 4) 687 | { 688 | this.Index = 0; 689 | } 690 | else if (this.Index < 10) 691 | { 692 | this.Index -= 3; 693 | } 694 | else 695 | { 696 | this.Index -= 6; 697 | } 698 | } 699 | 700 | public void UpdateMatch() 701 | { 702 | this.Index = ((this.Index < 7u) ? 7u : 10u); 703 | } 704 | 705 | public void UpdateRep() 706 | { 707 | this.Index = ((this.Index < 7u) ? 8u : 11u); 708 | } 709 | 710 | public void UpdateShortRep() 711 | { 712 | this.Index = ((this.Index < 7u) ? 9u : 11u); 713 | } 714 | 715 | public bool IsCharState() 716 | { 717 | return (this.Index < 7); 718 | } 719 | } 720 | } 721 | } 722 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/Packer.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ConfuserEx_Dynamic_Unpacker.Protections 12 | { 13 | class Packer 14 | { 15 | public static bool IsPacked(ModuleDefMD module) 16 | { 17 | 18 | // Thanks to 0xd4d https://github.com/0xd4d/dnlib/issues/72 19 | for (uint rid = 1; rid <= module.MetaData.TablesStream.FileTable.Rows; rid++) 20 | { 21 | var row = module.TablesStream.ReadFileRow(rid); 22 | string name = module.StringsStream.ReadNoNull(row.Name); 23 | if (name!="koi") continue; 24 | 25 | 26 | return true; 27 | } 28 | 29 | return false; 30 | } 31 | private static byte[] initialValue; 32 | public static int epToken; 33 | 34 | private static void arrayFinder(Local loc) 35 | { 36 | MethodDef entryPoint = Program.module.EntryPoint; 37 | for (int i = 0; i < entryPoint.Body.Instructions.Count; i++) 38 | { 39 | if (entryPoint.Body.Instructions[i].IsStloc()) 40 | { 41 | if (entryPoint.Body.Instructions[i].GetLocal(entryPoint.Body.Variables) == loc) 42 | { 43 | if(entryPoint.Body.Instructions[i-1].OpCode == OpCodes.Call&&entryPoint.Body.Instructions[i-2].OpCode == OpCodes.Ldtoken) 44 | { 45 | var tester = entryPoint.Body.Instructions[i - 2].Operand as FieldDef; 46 | initialValue = tester.InitialValue; 47 | break; 48 | } 49 | } 50 | } 51 | } 52 | } 53 | public static void findLocal() 54 | { 55 | var manifestModule = Program.asm.ManifestModule; 56 | MethodDef entryPoint = Program.module.EntryPoint; 57 | var aaa = Program.module.CorLibTypes.GetTypeRef("System.Runtime.InteropServices", "GCHandle"); 58 | var tester = Program.module.EntryPoint.Body.Variables.Where(i=>i.Type.Namespace == "System.Runtime.InteropServices" && i.Type.TypeName == "GCHandle").ToArray(); 59 | if(tester.Length != 0) 60 | { 61 | Local loc = tester[0]; 62 | for(int i = 0; i < entryPoint.Body.Instructions.Count; i++) 63 | { 64 | if (entryPoint.Body.Instructions[i].IsStloc()) 65 | { 66 | if (entryPoint.Body.Instructions[i].GetLocal(entryPoint.Body.Variables) == loc) 67 | { 68 | if(entryPoint.Body.Instructions[i-1].OpCode == OpCodes.Call) 69 | { 70 | if (entryPoint.Body.Instructions[i - 2].IsLdcI4()) 71 | { 72 | if(entryPoint.Body.Instructions[i - 3].IsLdloc()) 73 | { 74 | MethodDef decryptMethod = entryPoint.Body.Instructions[i - 1].Operand as MethodDef; 75 | var dec = manifestModule.ResolveMethod(decryptMethod.MDToken.ToInt32()); 76 | object[] param = new object[2]; 77 | param[1] = (uint)entryPoint.Body.Instructions[i - 2].GetLdcI4Value(); 78 | Local loc2 = entryPoint.Body.Instructions[i - 3].GetLocal(entryPoint.Body.Variables); 79 | arrayFinder(loc2); 80 | uint[] decoded = new uint[initialValue.Length / 4]; 81 | Buffer.BlockCopy(initialValue, 0, decoded, 0, initialValue.Length); 82 | param[0] = decoded; 83 | GCHandle aaaaa = (GCHandle)dec.Invoke(null, param); 84 | Program.module = ModuleDefMD.Load((byte[])aaaaa.Target); 85 | var key = manifestModule.ResolveSignature(0x11000001); 86 | 87 | epToken= ((int)key[0] | (int)key[1] << 8 | (int)key[2] << 16 | (int)key[3] << 24); 88 | Program.module.EntryPoint = Program.module.ResolveToken(epToken) as MethodDef; 89 | Program.asm = Assembly.Load((byte[])aaaaa.Target); 90 | 91 | return; 92 | } 93 | 94 | 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/ReferenceProxy.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace ConfuserEx_Dynamic_Unpacker.Protections 10 | { 11 | class ReferenceProxy 12 | { 13 | private static List junkMethods = new List(); 14 | private static object result; 15 | private static void RemoveJunkMethods(ModuleDefMD module) 16 | { 17 | int num = 0; 18 | foreach (TypeDef current in module.GetTypes()) 19 | { 20 | List list = new List(); 21 | foreach (MethodDef current2 in current.Methods) 22 | { 23 | bool flag = junkMethods.Contains(current2); 24 | if (flag) 25 | { 26 | list.Add(current2); 27 | } 28 | } 29 | int num2; 30 | for (int i = 0; i < list.Count; i = num2 + 1) 31 | { 32 | current.Methods.Remove(list[i]); 33 | num2 = num; 34 | num = num2 + 1; 35 | num2 = i; 36 | } 37 | list.Clear(); 38 | } 39 | junkMethods.Clear(); 40 | bool flag2 = num > 0; 41 | 42 | } 43 | 44 | public static int ProxyFixer(ModuleDefMD module) 45 | { 46 | int amount = 0; 47 | foreach (TypeDef type in module.Types) 48 | { 49 | foreach (MethodDef method in type.Methods) 50 | { 51 | if (!method.HasBody) continue; 52 | for (int i = 0; i < method.Body.Instructions.Count; i++) 53 | { 54 | if (method.Body.Instructions[i].OpCode == OpCodes.Call) 55 | { 56 | try 57 | { 58 | MethodDef methodDef = method.Body.Instructions[i].Operand as MethodDef; 59 | bool flag2 = methodDef == null; 60 | if (!flag2) 61 | { 62 | bool flag3 = !methodDef.IsStatic || !type.Methods.Contains(methodDef); 63 | if (!flag3) 64 | { 65 | OpCode opCode; 66 | object proxyValues = GetProxyValues(methodDef, out opCode); 67 | bool flag4 = opCode == null || proxyValues == null; 68 | if (!flag4) 69 | { 70 | method.Body.Instructions[i].OpCode = opCode; 71 | method.Body.Instructions[i].Operand = proxyValues; 72 | amount++; 73 | 74 | if (!junkMethods.Contains(methodDef)) 75 | { 76 | junkMethods.Add(methodDef); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | catch 83 | { 84 | } 85 | } 86 | } 87 | } 88 | } 89 | RemoveJunkMethods(module); 90 | return amount; 91 | } 92 | private static object GetProxyValues(MethodDef method, out OpCode opCode) 93 | { 94 | result = null; 95 | opCode = null; 96 | for (int i = 0; i < method.Body.Instructions.Count; i++) 97 | { 98 | if (method.Body.Instructions.Count <= 10) 99 | { 100 | if (method.Body.Instructions[i].OpCode == OpCodes.Call) 101 | { 102 | opCode = OpCodes.Call; 103 | result = method.Body.Instructions[i].Operand; 104 | return result; 105 | 106 | } 107 | else if (method.Body.Instructions[i].OpCode == OpCodes.Newobj) 108 | { 109 | opCode = OpCodes.Newobj; 110 | result = method.Body.Instructions[i].Operand; 111 | return result; 112 | 113 | } 114 | else if (method.Body.Instructions[i].OpCode == OpCodes.Callvirt) 115 | { 116 | opCode = OpCodes.Callvirt; 117 | result = method.Body.Instructions[i].Operand; 118 | return result; 119 | } 120 | else 121 | { 122 | opCode = null; 123 | result = null; 124 | 125 | } 126 | } 127 | else 128 | { 129 | return null; 130 | } 131 | } 132 | return result; 133 | 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/StaticPacker.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace ConfuserEx_Dynamic_Unpacker.Protections 12 | { 13 | 14 | 15 | class StaticPacker 16 | { 17 | private static byte[] initialValue; 18 | private static uint[] dst; 19 | private static uint[] src; 20 | private static MethodDef decryptMethod; 21 | public static int epToken; 22 | 23 | public static bool Run(ModuleDefMD module) 24 | { 25 | MethodDef GetFirstMetohd = module.EntryPoint; 26 | 27 | 28 | uint[] val2 = arrayFinder(); 29 | if (val2 == null) 30 | return false; 31 | uint val3 = findLocal(); 32 | if (val3 == 0) 33 | return false; 34 | byte[] val = Decrypt(decryptMethod,val2, val3); 35 | if (val == null) 36 | return false; 37 | int value = epStuff(module.EntryPoint); 38 | if (value == 0) 39 | return false; 40 | byte[] epstuff = module.ReadBlob((uint)value); 41 | if (epstuff == null) 42 | return false; 43 | epToken = ((int)epstuff[0] | (int)epstuff[1] << 8 | (int)epstuff[2] << 16 | (int)epstuff[3] << 24); 44 | Program.module = ModuleDefMD.Load(val); 45 | Program.module.EntryPoint = Program.module.ResolveToken(epToken) as MethodDef; 46 | return true; 47 | } 48 | public static void PopolateArrays(ulong key, out ulong conv) 49 | { 50 | dst = new uint[0x10]; 51 | src = new uint[0x10]; 52 | ulong decryptionKey = key; 53 | for (int i = 0; i < 0x10; i++) 54 | { 55 | decryptionKey = (decryptionKey * decryptionKey) % ((ulong)0x143fc089L); 56 | src[i] = (uint)decryptionKey; 57 | dst[i] = (uint)((decryptionKey * decryptionKey) % ((ulong)0x444d56fbL)); 58 | } 59 | conv = decryptionKey; 60 | } 61 | public static int epStuff(MethodDef method) 62 | { 63 | for (int i = 38; i < method.Body.Instructions.Count; i++) 64 | { 65 | if (method.Body.Instructions[i].IsLdcI4()) 66 | { 67 | //42 0075 callvirt instance uint8[] [mscorlib]System.Reflection.Module::ResolveSignature(int32) 68 | if (method.Body.Instructions[i+1].OpCode == OpCodes.Callvirt&&method.Body.Instructions[i+1].Operand.ToString().Contains("ResolveSignature")) 69 | { 70 | return method.Body.Instructions[i].GetLdcI4Value(); 71 | } 72 | 73 | } 74 | } 75 | return 0; 76 | } 77 | private static byte[] Decrypt(MethodDef meth,uint[] array, uint num) 78 | { 79 | PopolateArrays((ulong)num,out ulong conv); 80 | uint[] uii = DeriveKey(meth,dst, src); 81 | var fgfff = decryptDataArray(array); 82 | byte[] arr = Lzma.Decompress(fgfff); 83 | return decryptDecompData(arr, conv); 84 | } 85 | public static byte[] decryptDecompData(byte[] arr, ulong conv) 86 | { 87 | for (int i = 0; i < arr.Length; i++) 88 | { 89 | byte[] buffer = arr; 90 | buffer[i] = (byte)(buffer[i] ^ ((byte)conv)); 91 | if ((i & 0xff) == 0) 92 | { 93 | conv = (conv * conv) % ((ulong)0x8a5cb7L); 94 | } 95 | } 96 | return arr; 97 | } 98 | public static byte[] decryptDataArray(uint[] DataField) 99 | { 100 | byte[] buffer = new byte[DataField.Length << 2]; 101 | uint index = 0; 102 | for (int i = 0; i < DataField.Length; i++) 103 | { 104 | uint decryption_key = DataField[i] ^ dst[i & 15]; 105 | dst[i & 15] = (dst[i & 15] ^ decryption_key) + 0x3ddb2819; 106 | buffer[index] = (byte)decryption_key; 107 | buffer[((int)index) + 1] = (byte)(decryption_key >> 8); 108 | buffer[((int)index) + 2] = (byte)(decryption_key >> 0x10); 109 | buffer[((int)index) + 3] = (byte)(decryption_key >> 0x18); 110 | index += 4; 111 | } 112 | return buffer; 113 | } 114 | private static uint[] DeriveKey(MethodDef DecryptMethod,uint[] dst, uint[] src) 115 | { 116 | Instruction[] bodyInstr = DecryptMethod.Body.Instructions.ToArray(); 117 | int valCheck; 118 | if (bodyInstr[48].IsLdcI4()) 119 | { 120 | valCheck = 48; 121 | } 122 | else 123 | { 124 | valCheck = 50; 125 | } 126 | int num = 0; 127 | for (int i = valCheck; i < 240; i += 12) 128 | { 129 | uint operand2 = (uint)((int)bodyInstr[i].Operand); 130 | if (bodyInstr[i - 1].OpCode.Equals(OpCodes.Add)) 131 | { 132 | dst[num] += src[num]; 133 | } 134 | if (bodyInstr[i - 1].OpCode.Equals(OpCodes.Mul)) 135 | { 136 | dst[num] *= src[num]; 137 | } 138 | if (bodyInstr[i - 1].OpCode.Equals(OpCodes.Xor)) 139 | { 140 | dst[num] ^= src[num]; 141 | } 142 | if (bodyInstr[i + 1].OpCode.Equals(OpCodes.Add)) 143 | { 144 | dst[num] += operand2; 145 | } 146 | if (bodyInstr[i + 1].OpCode.Equals(OpCodes.Mul)) 147 | { 148 | dst[num] *= operand2; 149 | } 150 | if (bodyInstr[i + 1].OpCode.Equals(OpCodes.Xor)) 151 | { 152 | dst[num] ^= operand2; 153 | } 154 | num++; 155 | } 156 | return dst; 157 | } 158 | 159 | 160 | public static uint findLocal() 161 | { 162 | 163 | MethodDef entryPoint = Program.module.EntryPoint; 164 | var aaa = Program.module.CorLibTypes.GetTypeRef("System.Runtime.InteropServices", "GCHandle"); 165 | var tester = Program.module.EntryPoint.Body.Variables.Where(i => i.Type.Namespace == "System.Runtime.InteropServices" && i.Type.TypeName == "GCHandle").ToArray(); 166 | if (tester.Length != 0) 167 | { 168 | Local loc = tester[0]; 169 | for (int i = 0; i < entryPoint.Body.Instructions.Count; i++) 170 | { 171 | if (entryPoint.Body.Instructions[i].IsStloc()) 172 | { 173 | if (entryPoint.Body.Instructions[i].GetLocal(entryPoint.Body.Variables) == loc) 174 | { 175 | if (entryPoint.Body.Instructions[i - 1].OpCode == OpCodes.Call) 176 | { 177 | if (entryPoint.Body.Instructions[i - 2].IsLdcI4()) 178 | { 179 | if (entryPoint.Body.Instructions[i - 3].IsLdloc()) 180 | { 181 | decryptMethod = entryPoint.Body.Instructions[i - 1].Operand as MethodDef; 182 | 183 | 184 | return (uint)entryPoint.Body.Instructions[i - 2].GetLdcI4Value(); 185 | 186 | } 187 | 188 | 189 | } 190 | } 191 | } 192 | } 193 | } 194 | } 195 | return 0; 196 | } 197 | private static uint[] arrayFinder() 198 | { 199 | MethodDef entryPoint = Program.module.EntryPoint; 200 | for (int i = 0; i < entryPoint.Body.Instructions.Count; i++) 201 | { 202 | if (entryPoint.Body.Instructions[i].OpCode == OpCodes.Stloc_0) 203 | { 204 | 205 | if (entryPoint.Body.Instructions[i - 1].OpCode == OpCodes.Call && entryPoint.Body.Instructions[i - 2].OpCode == OpCodes.Ldtoken) 206 | { 207 | var tester = entryPoint.Body.Instructions[i - 2].Operand as FieldDef; 208 | var aa = tester.InitialValue; 209 | uint[] decoded = new uint[aa.Length / 4]; 210 | Buffer.BlockCopy(aa, 0, decoded, 0, aa.Length); 211 | 212 | return decoded ; 213 | 214 | } 215 | 216 | } 217 | } 218 | return null; 219 | } 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/Protections/StaticStrings.cs: -------------------------------------------------------------------------------- 1 | using dnlib.DotNet; 2 | using dnlib.DotNet.Emit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace ConfuserEx_Dynamic_Unpacker.Protections 11 | { 12 | class StaticStrings 13 | { 14 | public static List C = new List(); 15 | public static int StringsDecrypted = 0; 16 | public static int Run(ModuleDefMD module) 17 | { 18 | MethodDef GetFirstMetohd = firstStep(module); 19 | uint val = getShit(module, GetFirstMetohd); 20 | if (val == 0) 21 | return 0; 22 | string fieldName = getArrayName(module, GetFirstMetohd); 23 | if (fieldName == null) 24 | return 0; 25 | uint[] val2 = getArray(module, fieldName); 26 | if (val2 == null) 27 | return 0; 28 | uint val3 = getFinalShit(module, GetFirstMetohd); 29 | if (val3 == 0) 30 | return 0; 31 | smethod_1(val, val2, val3); 32 | FindString(module); 33 | return StringsDecrypted; 34 | } 35 | public static MethodDef firstStep(ModuleDefMD module) 36 | { 37 | foreach (TypeDef type in module.Types) 38 | { 39 | foreach (MethodDef method in type.Methods) 40 | { 41 | if (!method.HasBody) continue; 42 | if (!method.IsConstructor) continue; 43 | if (!method.FullName.ToLower().Contains("module")) continue; 44 | for (int i = 0; i < method.Body.Instructions.Count; i++) 45 | { 46 | if (method.Body.Instructions[i].OpCode == OpCodes.Call) 47 | { 48 | MethodDef initMethod = (MethodDef)method.Body.Instructions[i].Operand; 49 | if (!initMethod.HasBody) continue; 50 | if (initMethod.Body.Instructions.Count < 300) continue; 51 | for (int y = 0; y < initMethod.Body.Instructions.Count; y++) 52 | { 53 | 54 | if (initMethod.Body.Instructions[y].OpCode == OpCodes.Stloc_0) 55 | { 56 | if (initMethod.Body.Instructions[y - 1].IsLdcI4()) 57 | { 58 | C.Clear(); 59 | var grfds = dthfs(module, initMethod); 60 | if (grfds == false) continue; 61 | else 62 | return initMethod; 63 | 64 | } 65 | } 66 | 67 | } 68 | 69 | } 70 | } 71 | } 72 | } 73 | return null; 74 | 75 | } 76 | public static bool dthfs(ModuleDefMD module, MethodDef method) 77 | { 78 | for (int y = 0; y < method.Body.Instructions.Count; y++) 79 | { 80 | if (method.Body.Instructions[y].OpCode == OpCodes.Call) 81 | { 82 | 83 | C.Add(method.Body.Instructions[y]); 84 | 85 | 86 | 87 | } 88 | 89 | } 90 | return SortList(); 91 | 92 | 93 | 94 | 95 | } 96 | public static bool SortList() 97 | { 98 | var dgrfs = "System.Reflection.Assembly System.Reflection.Assembly::Load(System.Byte[])"; 99 | for (int i = 0; i < C.Count; i++) 100 | { 101 | if (C[i].Operand.ToString().Contains(dgrfs)) 102 | { 103 | return false; 104 | } 105 | } 106 | return true; 107 | } 108 | public static uint getFinalShit(ModuleDefMD module, MethodDef correct) 109 | { 110 | foreach (TypeDef type in module.Types) 111 | { 112 | foreach (MethodDef method in type.Methods) 113 | { 114 | 115 | if (!method.HasBody) continue; 116 | if (!method.IsConstructor) continue; 117 | if (!method.FullName.ToLower().Contains("module")) continue; 118 | for (int i = 0; i < method.Body.Instructions.Count; i++) 119 | { 120 | if (method.Body.Instructions[i].OpCode == OpCodes.Call) 121 | { 122 | MethodDef initMethod = (MethodDef)method.Body.Instructions[i].Operand; 123 | if (!(initMethod == correct)) continue; 124 | for (int y = 0; y < initMethod.Body.Instructions.Count; y++) 125 | { 126 | if (initMethod.Body.Instructions[y].OpCode == OpCodes.Stloc_3) 127 | { 128 | if (initMethod.Body.Instructions[y - 1].IsLdcI4()) 129 | { 130 | if (initMethod.Body.Instructions[y - 1].GetLdcI4Value() == 0) continue; 131 | else 132 | return (uint)initMethod.Body.Instructions[y - 1].GetLdcI4Value(); 133 | 134 | 135 | 136 | } 137 | } 138 | } 139 | 140 | } 141 | } 142 | } 143 | } 144 | return 0; 145 | } 146 | 147 | public static void FindString(ModuleDefMD module) 148 | { 149 | foreach (TypeDef type in module.Types) 150 | { 151 | foreach (MethodDef method in type.Methods) 152 | { 153 | if (!method.HasBody) continue; 154 | 155 | for (int i = 0; i < method.Body.Instructions.Count; i++) 156 | { 157 | if (i < 1) continue; 158 | if (method.Body.Instructions[i].OpCode == OpCodes.Call && method.Body.Instructions[i - 1].IsLdcI4()) 159 | { 160 | try 161 | { 162 | DecryptionMethod = (MethodSpec)method.Body.Instructions[i].Operand; 163 | if (DecryptionMethod.FullName.ToLower().Contains("string")) 164 | { 165 | int param = method.Body.Instructions[i - 1].GetLdcI4Value(); 166 | string DecryptedStringValue = GetParamValues(module, DecryptionMethod, (uint)param); 167 | if (DecryptedStringValue != null) 168 | { 169 | method.Body.Instructions[i].OpCode = OpCodes.Nop; 170 | method.Body.Instructions[i - 1].OpCode = OpCodes.Ldstr; 171 | method.Body.Instructions[i - 1].Operand = DecryptedStringValue; 172 | if (Program.veryVerbose) 173 | { 174 | Console.ForegroundColor = ConsoleColor.Cyan; 175 | Console.WriteLine(string.Format("Encrypted String Found In Method {0} With Param of {1} the decrypted string is {2}", method.Name, param.ToString(), DecryptedStringValue)); 176 | Console.ForegroundColor = ConsoleColor.Green; 177 | } 178 | StringsDecrypted++; 179 | } 180 | } 181 | 182 | } 183 | catch(Exception ex) 184 | { 185 | 186 | } 187 | 188 | 189 | 190 | } 191 | } 192 | 193 | } 194 | } 195 | } 196 | 197 | public static string GetParamValues(ModuleDefMD module, MethodSpec decryption, uint param) 198 | { 199 | foreach (TypeDef type in module.Types) 200 | { 201 | foreach (MethodDef method in type.Methods) 202 | { 203 | if (!method.HasBody) continue; 204 | if (!(method.FullName.Contains(decryption.Name))) continue; 205 | for (int y = 0; y < method.Body.Instructions.Count; y++) 206 | { 207 | if (method.Body.Instructions[y].OpCode == OpCodes.Mul) 208 | { 209 | if (method.Body.Instructions[y - 1].IsLdcI4() && method.Body.Instructions[y + 1].IsLdcI4()) 210 | return smethod_6((uint)param, (uint)method.Body.Instructions[y - 1].GetLdcI4Value(), (uint)method.Body.Instructions[y + 1].GetLdcI4Value()); 211 | 212 | } 213 | } 214 | } 215 | } 216 | return null; 217 | } 218 | 219 | internal static T smethod_6(uint uint_0, uint param1, uint param2) 220 | { 221 | uint_0 = (uint_0 * param1 ^ param2); 222 | uint num = uint_0 >> 30; 223 | T result = default(T); 224 | uint_0 &= 1073741823u; 225 | uint_0 <<= 2; 226 | num = 3; 227 | if ((ulong)num == 3uL) 228 | { 229 | int count = (int)byte_0[(int)((UIntPtr)(uint_0++))] | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 8 | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 16 | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 24; 230 | result = (T)((object)string.Intern(Encoding.UTF8.GetString(byte_0, (int)uint_0, count))); 231 | } 232 | else if ((ulong)num == 2uL) 233 | { 234 | T[] array = new T[1]; 235 | Buffer.BlockCopy(byte_0, (int)uint_0, array, 0, System.Runtime.InteropServices.Marshal.SizeOf(default(T))); 236 | result = array[0]; 237 | } 238 | else if ((ulong)num == 0uL) 239 | { 240 | int num2 = (int)byte_0[(int)((UIntPtr)(uint_0++))] | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 8 | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 16 | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 24; 241 | int length = (int)byte_0[(int)((UIntPtr)(uint_0++))] | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 8 | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 16 | (int)byte_0[(int)((UIntPtr)(uint_0++))] << 24; 242 | Array array2 = Array.CreateInstance(typeof(T).GetElementType(), length); 243 | Buffer.BlockCopy(byte_0, (int)uint_0, array2, 0, num2 - 4); 244 | result = (T)((object)array2); 245 | } 246 | return result; 247 | } 248 | public static uint getShit(ModuleDefMD module, MethodDef correct) 249 | { 250 | foreach (TypeDef type in module.Types) 251 | { 252 | foreach (MethodDef method in type.Methods) 253 | { 254 | 255 | if (!method.HasBody) continue; 256 | if (!method.IsConstructor) continue; 257 | if (!method.FullName.ToLower().Contains("module")) continue; 258 | for (int i = 0; i < method.Body.Instructions.Count; i++) 259 | { 260 | if (method.Body.Instructions[i].OpCode == OpCodes.Call) 261 | { 262 | MethodDef initMethod = (MethodDef)method.Body.Instructions[i].Operand; 263 | if (!(initMethod == correct)) continue; 264 | for (int y = 0; y < initMethod.Body.Instructions.Count; y++) 265 | { 266 | if (initMethod.Body.Instructions[y].OpCode == OpCodes.Stloc_0) 267 | { 268 | if (initMethod.Body.Instructions[y - 1].IsLdcI4()) 269 | { 270 | if (initMethod.Body.Instructions[y - 1].GetLdcI4Value() == 0) 271 | { 272 | 273 | } 274 | else 275 | { 276 | return (uint)initMethod.Body.Instructions[y - 1].GetLdcI4Value(); 277 | } 278 | 279 | 280 | } 281 | } 282 | } 283 | 284 | } 285 | } 286 | } 287 | 288 | } 289 | return 0; 290 | } 291 | public static string getArrayName(ModuleDefMD module, MethodDef correct) 292 | { 293 | foreach (TypeDef type in module.Types) 294 | { 295 | foreach (MethodDef method in type.Methods) 296 | { 297 | 298 | if (!method.HasBody) continue; 299 | if (!method.IsConstructor) continue; 300 | if (!method.FullName.ToLower().Contains("module")) continue; 301 | for (int i = 0; i < method.Body.Instructions.Count; i++) 302 | { 303 | if (method.Body.Instructions[i].OpCode == OpCodes.Call) 304 | { 305 | MethodDef initMethod = (MethodDef)method.Body.Instructions[i].Operand; 306 | if (!(initMethod == correct)) continue; 307 | for (int y = 0; y < initMethod.Body.Instructions.Count; y++) 308 | { 309 | if (initMethod.Body.Instructions[y].OpCode == OpCodes.Stloc_1) 310 | { 311 | if (initMethod.Body.Instructions[y - 2].OpCode == OpCodes.Ldtoken) 312 | { 313 | 314 | return (string)initMethod.Body.Instructions[y - 2].Operand.ToString(); 315 | 316 | 317 | 318 | } 319 | } 320 | } 321 | 322 | } 323 | } 324 | } 325 | 326 | } 327 | return null; 328 | 329 | } 330 | public static uint[] getArray(ModuleDefMD module, string fieldName) 331 | { 332 | foreach (TypeDef type in module.Types) 333 | { 334 | foreach (FieldDef fields in type.Fields) 335 | { 336 | if (!fieldName.ToLower().Contains(fields.Name.ToLower())) continue; 337 | if (!fields.HasFieldRVA) continue; 338 | if (!(fields.InitialValue.Length != 0)) continue; 339 | if (!fields.FullName.ToLower().Contains("module")) continue; 340 | if (!fields.IsStatic) continue; 341 | if (!fields.IsAssembly) continue; 342 | byte[] arrrr = fields.InitialValue; 343 | uint[] decoded = new uint[arrrr.Length / 4]; 344 | Buffer.BlockCopy(arrrr, 0, decoded, 0, arrrr.Length); 345 | return (uint[])decoded; 346 | 347 | } 348 | 349 | } 350 | return null; 351 | 352 | } 353 | 354 | private static byte[] byte_0; 355 | private static MethodSpec DecryptionMethod; 356 | 357 | internal static void smethod_1(uint numis, uint[] arrayy, uint val3) 358 | { 359 | uint num = numis; 360 | uint[] array = arrayy; 361 | uint[] array2 = new uint[16]; 362 | uint num2 = val3; 363 | for (int i = 0; i < 16; i++) 364 | { 365 | num2 ^= num2 >> 12; 366 | num2 ^= num2 << 25; 367 | num2 ^= num2 >> 27; 368 | array2[i] = num2; 369 | } 370 | int num3 = 0; 371 | int num4 = 0; 372 | uint[] array3 = new uint[16]; 373 | byte[] array4 = new byte[num * 4u]; 374 | while ((long)num3 < (long)((ulong)num)) 375 | { 376 | for (int j = 0; j < 16; j++) 377 | { 378 | array3[j] = array[num3 + j]; 379 | } 380 | array3[0] = (array3[0] ^ array2[0]); 381 | array3[1] = (array3[1] ^ array2[1]); 382 | array3[2] = (array3[2] ^ array2[2]); 383 | array3[3] = (array3[3] ^ array2[3]); 384 | array3[4] = (array3[4] ^ array2[4]); 385 | array3[5] = (array3[5] ^ array2[5]); 386 | array3[6] = (array3[6] ^ array2[6]); 387 | array3[7] = (array3[7] ^ array2[7]); 388 | array3[8] = (array3[8] ^ array2[8]); 389 | array3[9] = (array3[9] ^ array2[9]); 390 | array3[10] = (array3[10] ^ array2[10]); 391 | array3[11] = (array3[11] ^ array2[11]); 392 | array3[12] = (array3[12] ^ array2[12]); 393 | array3[13] = (array3[13] ^ array2[13]); 394 | array3[14] = (array3[14] ^ array2[14]); 395 | array3[15] = (array3[15] ^ array2[15]); 396 | for (int k = 0; k < 16; k++) 397 | { 398 | uint num5 = array3[k]; 399 | array4[num4++] = (byte)num5; 400 | array4[num4++] = (byte)(num5 >> 8); 401 | array4[num4++] = (byte)(num5 >> 16); 402 | array4[num4++] = (byte)(num5 >> 24); 403 | array2[k] ^= num5; 404 | } 405 | num3 += 16; 406 | } 407 | 408 | byte_0 = smethod_0(array4); 409 | } 410 | 411 | 412 | internal static byte[] smethod_0(byte[] byte_1) 413 | { 414 | MemoryStream memoryStream = new MemoryStream(byte_1); 415 | 416 | Class1 @class = new Class1(); 417 | byte[] buffer = new byte[5]; 418 | memoryStream.Read(buffer, 0, 5); 419 | @class.method_5(buffer); 420 | long num = 0L; 421 | for (int i = 0; i < 8; i++) 422 | { 423 | int num2 = memoryStream.ReadByte(); 424 | num |= (long)((long)((ulong)((byte)num2)) << 8 * i); 425 | } 426 | byte[] array = new byte[(int)num]; 427 | MemoryStream stream_ = new MemoryStream(array, true); 428 | long long_ = memoryStream.Length - 13L; 429 | @class.method_4(memoryStream, stream_, long_, num); 430 | return array; 431 | } 432 | } 433 | 434 | internal class Class1 435 | { 436 | internal Class1() 437 | { 438 | this.uint_0 = 4294967295u; 439 | int num = 0; 440 | while ((long)num < 4L) 441 | { 442 | this.struct1_0[num] = new Struct1(6); 443 | num++; 444 | } 445 | } 446 | 447 | // Token: 0x06000016 RID: 22 RVA: 0x000031E0 File Offset: 0x000031E0 448 | internal void method_0(uint uint_3) 449 | { 450 | if (this.uint_0 != uint_3) 451 | { 452 | this.uint_0 = uint_3; 453 | this.uint_1 = Math.Max(this.uint_0, 1u); 454 | uint uint_4 = Math.Max(this.uint_1, 4096u); 455 | this.class4_0.method_0(uint_4); 456 | } 457 | } 458 | 459 | // Token: 0x06000017 RID: 23 RVA: 0x0000218A File Offset: 0x0000218A 460 | internal void method_1(int int_0, int int_1) 461 | { 462 | this.class3_0.method_0(int_0, int_1); 463 | } 464 | 465 | // Token: 0x06000018 RID: 24 RVA: 0x0000322C File Offset: 0x0000322C 466 | internal void method_2(int int_0) 467 | { 468 | uint num = 1u << int_0; 469 | this.class2_0.method_0(num); 470 | this.class2_1.method_0(num); 471 | this.uint_2 = num - 1u; 472 | } 473 | 474 | // Token: 0x06000019 RID: 25 RVA: 0x00003264 File Offset: 0x00003264 475 | internal void method_3(Stream stream_0, Stream stream_1) 476 | { 477 | this.class0_0.method_0(stream_0); 478 | this.class4_0.method_1(stream_1, this.bool_0); 479 | for (uint num = 0u; num < 12u; num += 1u) 480 | { 481 | for (uint num2 = 0u; num2 <= this.uint_2; num2 += 1u) 482 | { 483 | uint num3 = (num << 4) + num2; 484 | this.struct0_0[(int)((UIntPtr)num3)].method_0(); 485 | this.struct0_1[(int)((UIntPtr)num3)].method_0(); 486 | } 487 | this.struct0_2[(int)((UIntPtr)num)].method_0(); 488 | this.struct0_3[(int)((UIntPtr)num)].method_0(); 489 | this.struct0_4[(int)((UIntPtr)num)].method_0(); 490 | this.struct0_5[(int)((UIntPtr)num)].method_0(); 491 | } 492 | this.class3_0.method_1(); 493 | for (uint num = 0u; num < 4u; num += 1u) 494 | { 495 | this.struct1_0[(int)((UIntPtr)num)].method_0(); 496 | } 497 | for (uint num = 0u; num < 114u; num += 1u) 498 | { 499 | this.struct0_6[(int)((UIntPtr)num)].method_0(); 500 | } 501 | this.class2_0.method_1(); 502 | this.class2_1.method_1(); 503 | this.struct1_1.method_0(); 504 | } 505 | 506 | // Token: 0x0600001A RID: 26 RVA: 0x00003390 File Offset: 0x00003390 507 | internal void method_4(Stream stream_0, Stream stream_1, long long_0, long long_1) 508 | { 509 | this.method_3(stream_0, stream_1); 510 | 511 | Struct3 @struct = default(Struct3); 512 | @struct.method_0(); 513 | uint num = 0u; 514 | uint num2 = 0u; 515 | uint num3 = 0u; 516 | uint num4 = 0u; 517 | ulong num5 = 0uL; 518 | if (0L < long_1) 519 | { 520 | this.struct0_0[(int)((UIntPtr)(@struct.uint_0 << 4))].method_1(this.class0_0); 521 | @struct.method_1(); 522 | byte byte_ = this.class3_0.method_3(this.class0_0, 0u, 0); 523 | this.class4_0.method_5(byte_); 524 | num5 += 1uL; 525 | } 526 | while (num5 < (ulong)long_1) 527 | { 528 | uint num6 = (uint)num5 & this.uint_2; 529 | if (this.struct0_0[(int)((UIntPtr)((@struct.uint_0 << 4) + num6))].method_1(this.class0_0) == 0u) 530 | { 531 | byte byte_2 = this.class4_0.method_6(0u); 532 | byte byte_3; 533 | if (!@struct.method_5()) 534 | { 535 | byte_3 = this.class3_0.method_4(this.class0_0, (uint)num5, byte_2, this.class4_0.method_6(num)); 536 | } 537 | else 538 | { 539 | byte_3 = this.class3_0.method_3(this.class0_0, (uint)num5, byte_2); 540 | } 541 | this.class4_0.method_5(byte_3); 542 | @struct.method_1(); 543 | num5 += 1uL; 544 | } 545 | else 546 | { 547 | uint num8; 548 | if (this.struct0_2[(int)((UIntPtr)@struct.uint_0)].method_1(this.class0_0) == 1u) 549 | { 550 | if (this.struct0_3[(int)((UIntPtr)@struct.uint_0)].method_1(this.class0_0) == 0u) 551 | { 552 | if (this.struct0_1[(int)((UIntPtr)((@struct.uint_0 << 4) + num6))].method_1(this.class0_0) == 0u) 553 | { 554 | @struct.method_4(); 555 | this.class4_0.method_5(this.class4_0.method_6(num)); 556 | num5 += 1uL; 557 | continue; 558 | } 559 | } 560 | else 561 | { 562 | uint num7; 563 | if (this.struct0_4[(int)((UIntPtr)@struct.uint_0)].method_1(this.class0_0) == 0u) 564 | { 565 | num7 = num2; 566 | } 567 | else 568 | { 569 | if (this.struct0_5[(int)((UIntPtr)@struct.uint_0)].method_1(this.class0_0) == 0u) 570 | { 571 | num7 = num3; 572 | } 573 | else 574 | { 575 | num7 = num4; 576 | num4 = num3; 577 | } 578 | num3 = num2; 579 | } 580 | num2 = num; 581 | num = num7; 582 | } 583 | num8 = this.class2_1.method_2(this.class0_0, num6) + 2u; 584 | @struct.method_3(); 585 | } 586 | else 587 | { 588 | num4 = num3; 589 | num3 = num2; 590 | num2 = num; 591 | num8 = 2u + this.class2_0.method_2(this.class0_0, num6); 592 | @struct.method_2(); 593 | uint num9 = this.struct1_0[(int)((UIntPtr)Class1.smethod_0(num8))].method_1(this.class0_0); 594 | if (num9 >= 4u) 595 | { 596 | int num10 = (int)((num9 >> 1) - 1u); 597 | num = (2u | (num9 & 1u)) << num10; 598 | if (num9 < 14u) 599 | { 600 | num += Struct1.smethod_0(this.struct0_6, num - num9 - 1u, this.class0_0, num10); 601 | } 602 | else 603 | { 604 | num += this.class0_0.method_3(num10 - 4) << 4; 605 | num += this.struct1_1.method_2(this.class0_0); 606 | } 607 | } 608 | else 609 | { 610 | num = num9; 611 | } 612 | } 613 | if (((ulong)num >= num5 || num >= this.uint_1) && num == 4294967295u) 614 | { 615 | break; 616 | } 617 | this.class4_0.method_4(num, num8); 618 | num5 += (ulong)num8; 619 | } 620 | } 621 | this.class4_0.method_3(); 622 | this.class4_0.method_2(); 623 | this.class0_0.method_1(); 624 | } 625 | 626 | // Token: 0x0600001B RID: 27 RVA: 0x00003704 File Offset: 0x00003704 627 | internal void method_5(byte[] byte_0) 628 | { 629 | int int_ = (int)(byte_0[0] % 9); 630 | int num = (int)(byte_0[0] / 9); 631 | int int_2 = num % 5; 632 | int int_3 = num / 5; 633 | uint num2 = 0u; 634 | for (int i = 0; i < 4; i++) 635 | { 636 | num2 += (uint)((uint)byte_0[1 + i] << i * 8); 637 | } 638 | this.method_0(num2); 639 | this.method_1(int_2, int_); 640 | this.method_2(int_3); 641 | } 642 | internal void method_01(uint uint_3) 643 | { 644 | if (this.uint_0 != uint_3) 645 | { 646 | this.uint_0 = uint_3; 647 | this.uint_1 = Math.Max(this.uint_0, 1u); 648 | uint uint_4 = Math.Max(this.uint_1, 4096u); 649 | this.class4_0.method_0(uint_4); 650 | } 651 | } 652 | 653 | // Token: 0x0600001C RID: 28 RVA: 0x00002199 File Offset: 0x00002199 654 | internal static uint smethod_0(uint uint_3) 655 | { 656 | uint_3 -= 2u; 657 | if (uint_3 < 4u) 658 | { 659 | return uint_3; 660 | } 661 | return 3u; 662 | } 663 | 664 | // Token: 0x04000009 RID: 9 665 | internal readonly Struct0[] struct0_0 = new Struct0[192]; 666 | 667 | // Token: 0x0400000A RID: 10 668 | internal readonly Struct0[] struct0_1 = new Struct0[192]; 669 | 670 | // Token: 0x0400000B RID: 11 671 | internal readonly Struct0[] struct0_2 = new Struct0[12]; 672 | 673 | // Token: 0x0400000C RID: 12 674 | internal readonly Struct0[] struct0_3 = new Struct0[12]; 675 | 676 | // Token: 0x0400000D RID: 13 677 | internal readonly Struct0[] struct0_4 = new Struct0[12]; 678 | 679 | // Token: 0x0400000E RID: 14 680 | internal readonly Struct0[] struct0_5 = new Struct0[12]; 681 | 682 | // Token: 0x0400000F RID: 15 683 | internal readonly Class1.Class2 class2_0 = new Class1.Class2(); 684 | 685 | // Token: 0x04000010 RID: 16 686 | internal readonly Class1.Class3 class3_0 = new Class1.Class3(); 687 | 688 | // Token: 0x04000011 RID: 17 689 | internal readonly Class4 class4_0 = new Class4(); 690 | 691 | // Token: 0x04000012 RID: 18 692 | internal readonly Struct0[] struct0_6 = new Struct0[114]; 693 | 694 | // Token: 0x04000013 RID: 19 695 | internal readonly Struct1[] struct1_0 = new Struct1[4]; 696 | 697 | // Token: 0x04000014 RID: 20 698 | internal readonly Class0 class0_0 = new Class0(); 699 | 700 | // Token: 0x04000015 RID: 21 701 | internal readonly Class1.Class2 class2_1 = new Class1.Class2(); 702 | 703 | // Token: 0x04000016 RID: 22 704 | internal bool bool_0; 705 | 706 | // Token: 0x04000017 RID: 23 707 | internal uint uint_0; 708 | 709 | // Token: 0x04000018 RID: 24 710 | internal uint uint_1; 711 | 712 | // Token: 0x04000019 RID: 25 713 | internal Struct1 struct1_1 = new Struct1(4); 714 | 715 | // Token: 0x0400001A RID: 26 716 | internal uint uint_2; 717 | 718 | // Token: 0x02000006 RID: 6 719 | internal class Class2 720 | { 721 | // Token: 0x0600001D RID: 29 RVA: 0x00003764 File Offset: 0x00003764 722 | internal void method_0(uint uint_1) 723 | { 724 | for (uint num = this.uint_0; num < uint_1; num += 1u) 725 | { 726 | this.struct1_0[(int)((UIntPtr)num)] = new Struct1(3); 727 | this.struct1_1[(int)((UIntPtr)num)] = new Struct1(3); 728 | } 729 | this.uint_0 = uint_1; 730 | } 731 | 732 | // Token: 0x0600001E RID: 30 RVA: 0x000037BC File Offset: 0x000037BC 733 | internal void method_1() 734 | { 735 | this.struct0_0.method_0(); 736 | for (uint num = 0u; num < this.uint_0; num += 1u) 737 | { 738 | this.struct1_0[(int)((UIntPtr)num)].method_0(); 739 | this.struct1_1[(int)((UIntPtr)num)].method_0(); 740 | } 741 | this.struct0_1.method_0(); 742 | this.struct1_2.method_0(); 743 | } 744 | 745 | // Token: 0x0600001F RID: 31 RVA: 0x00003820 File Offset: 0x00003820 746 | internal uint method_2(Class0 class0_0, uint uint_1) 747 | { 748 | if (this.struct0_0.method_1(class0_0) == 0u) 749 | { 750 | return this.struct1_0[(int)((UIntPtr)uint_1)].method_1(class0_0); 751 | } 752 | uint num = 8u; 753 | if (this.struct0_1.method_1(class0_0) == 0u) 754 | { 755 | num += this.struct1_1[(int)((UIntPtr)uint_1)].method_1(class0_0); 756 | } 757 | else 758 | { 759 | num += 8u; 760 | num += this.struct1_2.method_1(class0_0); 761 | } 762 | return num; 763 | } 764 | 765 | // Token: 0x06000020 RID: 32 RVA: 0x0000388C File Offset: 0x0000388C 766 | internal Class2() 767 | { 768 | } 769 | 770 | // Token: 0x0400001B RID: 27 771 | internal readonly Struct1[] struct1_0 = new Struct1[16]; 772 | 773 | // Token: 0x0400001C RID: 28 774 | internal readonly Struct1[] struct1_1 = new Struct1[16]; 775 | 776 | // Token: 0x0400001D RID: 29 777 | internal Struct0 struct0_0 = default(Struct0); 778 | 779 | // Token: 0x0400001E RID: 30 780 | internal Struct0 struct0_1 = default(Struct0); 781 | 782 | // Token: 0x0400001F RID: 31 783 | internal Struct1 struct1_2 = new Struct1(8); 784 | 785 | // Token: 0x04000020 RID: 32 786 | internal uint uint_0; 787 | } 788 | 789 | // Token: 0x02000007 RID: 7 790 | internal class Class3 791 | { 792 | // Token: 0x06000021 RID: 33 RVA: 0x000038E0 File Offset: 0x000038E0 793 | internal void method_0(int int_2, int int_3) 794 | { 795 | if (this.struct2_0 != null && this.int_1 == int_3 && this.int_0 == int_2) 796 | { 797 | return; 798 | } 799 | this.int_0 = int_2; 800 | this.uint_0 = (1u << int_2) - 1u; 801 | this.int_1 = int_3; 802 | uint num = 1u << this.int_1 + this.int_0; 803 | this.struct2_0 = new Class1.Class3.Struct2[num]; 804 | for (uint num2 = 0u; num2 < num; num2 += 1u) 805 | { 806 | this.struct2_0[(int)((UIntPtr)num2)].method_0(); 807 | } 808 | } 809 | 810 | // Token: 0x06000022 RID: 34 RVA: 0x00003964 File Offset: 0x00003964 811 | internal void method_1() 812 | { 813 | uint num = 1u << this.int_1 + this.int_0; 814 | for (uint num2 = 0u; num2 < num; num2 += 1u) 815 | { 816 | this.struct2_0[(int)((UIntPtr)num2)].method_1(); 817 | } 818 | } 819 | 820 | // Token: 0x06000023 RID: 35 RVA: 0x000021A7 File Offset: 0x000021A7 821 | internal uint method_2(uint uint_1, byte byte_0) 822 | { 823 | return ((uint_1 & this.uint_0) << this.int_1) + (uint)(byte_0 >> 8 - this.int_1); 824 | } 825 | 826 | // Token: 0x06000024 RID: 36 RVA: 0x000021C9 File Offset: 0x000021C9 827 | internal byte method_3(Class0 class0_0, uint uint_1, byte byte_0) 828 | { 829 | return this.struct2_0[(int)((UIntPtr)this.method_2(uint_1, byte_0))].method_2(class0_0); 830 | } 831 | 832 | // Token: 0x06000025 RID: 37 RVA: 0x000021E5 File Offset: 0x000021E5 833 | internal byte method_4(Class0 class0_0, uint uint_1, byte byte_0, byte byte_1) 834 | { 835 | return this.struct2_0[(int)((UIntPtr)this.method_2(uint_1, byte_0))].method_3(class0_0, byte_1); 836 | } 837 | 838 | // Token: 0x06000026 RID: 38 RVA: 0x00002182 File Offset: 0x00002182 839 | internal Class3() 840 | { 841 | } 842 | 843 | // Token: 0x04000021 RID: 33 844 | internal Class1.Class3.Struct2[] struct2_0; 845 | 846 | // Token: 0x04000022 RID: 34 847 | internal int int_0; 848 | 849 | // Token: 0x04000023 RID: 35 850 | internal int int_1; 851 | 852 | // Token: 0x04000024 RID: 36 853 | internal uint uint_0; 854 | 855 | // Token: 0x02000008 RID: 8 856 | internal struct Struct2 857 | { 858 | // Token: 0x06000027 RID: 39 RVA: 0x00002203 File Offset: 0x00002203 859 | internal void method_0() 860 | { 861 | this.struct0_0 = new Struct0[768]; 862 | } 863 | 864 | // Token: 0x06000028 RID: 40 RVA: 0x000039A4 File Offset: 0x000039A4 865 | internal void method_1() 866 | { 867 | for (int i = 0; i < 768; i++) 868 | { 869 | this.struct0_0[i].method_0(); 870 | } 871 | } 872 | 873 | // Token: 0x06000029 RID: 41 RVA: 0x000039D4 File Offset: 0x000039D4 874 | internal byte method_2(Class0 class0_0) 875 | { 876 | uint num = 1u; 877 | do 878 | { 879 | num = (num << 1 | this.struct0_0[(int)((UIntPtr)num)].method_1(class0_0)); 880 | } 881 | while (num < 256u); 882 | return (byte)num; 883 | } 884 | 885 | // Token: 0x0600002A RID: 42 RVA: 0x00003A08 File Offset: 0x00003A08 886 | internal byte method_3(Class0 class0_0, byte byte_0) 887 | { 888 | uint num = 1u; 889 | while (true) 890 | { 891 | uint num2 = (uint)(byte_0 >> 7 & 1); 892 | byte_0 = (byte)(byte_0 << 1); 893 | uint num3 = this.struct0_0[(int)((UIntPtr)((1u + num2 << 8) + num))].method_1(class0_0); 894 | num = (num << 1 | num3); 895 | if (num2 != num3) 896 | { 897 | break; 898 | } 899 | if (num >= 256u) 900 | { 901 | goto IL_5E; 902 | } 903 | } 904 | while (num < 256u) 905 | { 906 | num = (num << 1 | this.struct0_0[(int)((UIntPtr)num)].method_1(class0_0)); 907 | } 908 | IL_5E: 909 | return (byte)num; 910 | } 911 | 912 | // Token: 0x04000025 RID: 37 913 | internal Struct0[] struct0_0; 914 | } 915 | } 916 | } 917 | 918 | internal class Struct1 919 | { 920 | internal Struct1(int int_1) 921 | { 922 | this.int_0 = int_1; 923 | this.struct0_0 = new Struct0[1 << int_1]; 924 | } 925 | 926 | // Token: 0x0600000C RID: 12 RVA: 0x00002F18 File Offset: 0x00002F18 927 | internal void method_0() 928 | { 929 | uint num = 1u; 930 | while ((ulong)num < (ulong)(1L << (this.int_0 & 31))) 931 | { 932 | this.struct0_0[(int)((UIntPtr)num)].method_0(); 933 | num += 1u; 934 | } 935 | } 936 | 937 | // Token: 0x0600000D RID: 13 RVA: 0x00002F50 File Offset: 0x00002F50 938 | internal uint method_1(Class0 class0_0) 939 | { 940 | uint num = 1u; 941 | for (int i = this.int_0; i > 0; i--) 942 | { 943 | num = (num << 1) + this.struct0_0[(int)((UIntPtr)num)].method_1(class0_0); 944 | } 945 | return num - (1u << this.int_0); 946 | } 947 | 948 | // Token: 0x0600000E RID: 14 RVA: 0x00002F98 File Offset: 0x00002F98 949 | internal uint method_2(Class0 class0_0) 950 | { 951 | uint num = 1u; 952 | uint num2 = 0u; 953 | for (int i = 0; i < this.int_0; i++) 954 | { 955 | uint num3 = this.struct0_0[(int)((UIntPtr)num)].method_1(class0_0); 956 | num <<= 1; 957 | num += num3; 958 | num2 |= num3 << i; 959 | } 960 | return num2; 961 | } 962 | 963 | // Token: 0x0600000F RID: 15 RVA: 0x00002FE0 File Offset: 0x00002FE0 964 | internal static uint smethod_0(Struct0[] struct0_1, uint uint_0, Class0 class0_0, int int_1) 965 | { 966 | uint num = 1u; 967 | uint num2 = 0u; 968 | for (int i = 0; i < int_1; i++) 969 | { 970 | uint num3 = struct0_1[(int)((UIntPtr)(uint_0 + num))].method_1(class0_0); 971 | num <<= 1; 972 | num += num3; 973 | num2 |= num3 << i; 974 | } 975 | return num2; 976 | } 977 | 978 | // Token: 0x04000004 RID: 4 979 | internal readonly Struct0[] struct0_0; 980 | 981 | // Token: 0x04000005 RID: 5 982 | internal readonly int int_0; 983 | } 984 | internal struct Struct0 985 | { 986 | // Token: 0x06000009 RID: 9 RVA: 0x00002117 File Offset: 0x00002117 987 | internal void method_0() 988 | { 989 | this.uint_0 = 1024u; 990 | } 991 | 992 | // Token: 0x0600000A RID: 10 RVA: 0x00002E2C File Offset: 0x00002E2C 993 | internal uint method_1(Class0 class0_0) 994 | { 995 | uint num = (class0_0.uint_1 >> 11) * this.uint_0; 996 | if (class0_0.uint_0 < num) 997 | { 998 | class0_0.uint_1 = num; 999 | this.uint_0 += 2048u - this.uint_0 >> 5; 1000 | if (class0_0.uint_1 < 16777216u) 1001 | { 1002 | class0_0.uint_0 = (class0_0.uint_0 << 8 | (uint)((byte)class0_0.stream_0.ReadByte())); 1003 | class0_0.uint_1 <<= 8; 1004 | } 1005 | return 0u; 1006 | } 1007 | class0_0.uint_1 -= num; 1008 | class0_0.uint_0 -= num; 1009 | this.uint_0 -= this.uint_0 >> 5; 1010 | if (class0_0.uint_1 < 16777216u) 1011 | { 1012 | class0_0.uint_0 = (class0_0.uint_0 << 8 | (uint)((byte)class0_0.stream_0.ReadByte())); 1013 | class0_0.uint_1 <<= 8; 1014 | } 1015 | return 1u; 1016 | } 1017 | 1018 | // Token: 0x04000003 RID: 3 1019 | internal uint uint_0; 1020 | } 1021 | internal struct Struct3 1022 | { 1023 | // Token: 0x06000033 RID: 51 RVA: 0x00002293 File Offset: 0x00002293 1024 | internal void method_0() 1025 | { 1026 | this.uint_0 = 0u; 1027 | } 1028 | 1029 | // Token: 0x06000034 RID: 52 RVA: 0x0000229C File Offset: 0x0000229C 1030 | internal void method_1() 1031 | { 1032 | if (this.uint_0 < 4u) 1033 | { 1034 | this.uint_0 = 0u; 1035 | return; 1036 | } 1037 | if (this.uint_0 < 10u) 1038 | { 1039 | this.uint_0 -= 3u; 1040 | return; 1041 | } 1042 | this.uint_0 -= 6u; 1043 | } 1044 | 1045 | // Token: 0x06000035 RID: 53 RVA: 0x000022D6 File Offset: 0x000022D6 1046 | internal void method_2() 1047 | { 1048 | this.uint_0 = ((this.uint_0 < 7u) ? 7u : 10u); 1049 | } 1050 | 1051 | // Token: 0x06000036 RID: 54 RVA: 0x000022EC File Offset: 0x000022EC 1052 | internal void method_3() 1053 | { 1054 | this.uint_0 = ((this.uint_0 < 7u) ? 8u : 11u); 1055 | } 1056 | 1057 | // Token: 0x06000037 RID: 55 RVA: 0x00002302 File Offset: 0x00002302 1058 | internal void method_4() 1059 | { 1060 | this.uint_0 = ((this.uint_0 < 7u) ? 9u : 11u); 1061 | } 1062 | 1063 | // Token: 0x06000038 RID: 56 RVA: 0x00002319 File Offset: 0x00002319 1064 | internal bool method_5() 1065 | { 1066 | return this.uint_0 < 7u; 1067 | } 1068 | 1069 | // Token: 0x0400002B RID: 43 1070 | internal uint uint_0; 1071 | } 1072 | internal class Class0 1073 | { 1074 | // Token: 0x06000010 RID: 16 RVA: 0x00003020 File Offset: 0x00003020 1075 | internal void method_0(Stream stream_1) 1076 | { 1077 | this.stream_0 = stream_1; 1078 | this.uint_0 = 0u; 1079 | this.uint_1 = 4294967295u; 1080 | for (int i = 0; i < 5; i++) 1081 | { 1082 | this.uint_0 = (this.uint_0 << 8 | (uint)((byte)this.stream_0.ReadByte())); 1083 | } 1084 | } 1085 | 1086 | // Token: 0x06000011 RID: 17 RVA: 0x0000213E File Offset: 0x0000213E 1087 | internal void method_1() 1088 | { 1089 | this.stream_0 = null; 1090 | } 1091 | 1092 | // Token: 0x06000012 RID: 18 RVA: 0x00002147 File Offset: 0x00002147 1093 | internal void method_2() 1094 | { 1095 | while (this.uint_1 < 16777216u) 1096 | { 1097 | this.uint_0 = (this.uint_0 << 8 | (uint)((byte)this.stream_0.ReadByte())); 1098 | this.uint_1 <<= 8; 1099 | } 1100 | } 1101 | 1102 | // Token: 0x06000013 RID: 19 RVA: 0x0000306C File Offset: 0x0000306C 1103 | internal uint method_3(int int_0) 1104 | { 1105 | uint num = this.uint_1; 1106 | uint num2 = this.uint_0; 1107 | uint num3 = 0u; 1108 | for (int i = int_0; i > 0; i--) 1109 | { 1110 | num >>= 1; 1111 | uint num4 = num2 - num >> 31; 1112 | num2 -= (num & num4 - 1u); 1113 | num3 = (num3 << 1 | 1u - num4); 1114 | if (num < 16777216u) 1115 | { 1116 | num2 = (num2 << 8 | (uint)((byte)this.stream_0.ReadByte())); 1117 | num <<= 8; 1118 | } 1119 | } 1120 | this.uint_1 = num; 1121 | this.uint_0 = num2; 1122 | return num3; 1123 | } 1124 | 1125 | // Token: 0x06000014 RID: 20 RVA: 0x00002182 File Offset: 0x00002182 1126 | internal Class0() 1127 | { 1128 | } 1129 | 1130 | // Token: 0x04000006 RID: 6 1131 | internal uint uint_0; 1132 | 1133 | // Token: 0x04000007 RID: 7 1134 | internal uint uint_1; 1135 | 1136 | // Token: 0x04000008 RID: 8 1137 | internal Stream stream_0; 1138 | } 1139 | internal class Class4 1140 | { 1141 | // Token: 0x0600002B RID: 43 RVA: 0x00002215 File Offset: 0x00002215 1142 | internal void method_0(uint uint_3) 1143 | { 1144 | if (this.uint_2 != uint_3) 1145 | { 1146 | this.byte_0 = new byte[uint_3]; 1147 | } 1148 | this.uint_2 = uint_3; 1149 | this.uint_0 = 0u; 1150 | this.uint_1 = 0u; 1151 | } 1152 | 1153 | // Token: 0x0600002C RID: 44 RVA: 0x00002242 File Offset: 0x00002242 1154 | internal void method_1(Stream stream_1, bool bool_0) 1155 | { 1156 | this.method_2(); 1157 | this.stream_0 = stream_1; 1158 | if (!bool_0) 1159 | { 1160 | this.uint_1 = 0u; 1161 | this.uint_0 = 0u; 1162 | } 1163 | } 1164 | 1165 | // Token: 0x0600002D RID: 45 RVA: 0x00002262 File Offset: 0x00002262 1166 | internal void method_2() 1167 | { 1168 | this.method_3(); 1169 | this.stream_0 = null; 1170 | Buffer.BlockCopy(new byte[this.byte_0.Length], 0, this.byte_0, 0, this.byte_0.Length); 1171 | } 1172 | 1173 | // Token: 0x0600002E RID: 46 RVA: 0x00003A78 File Offset: 0x00003A78 1174 | internal void method_3() 1175 | { 1176 | uint num = this.uint_0 - this.uint_1; 1177 | if (num == 0u) 1178 | { 1179 | return; 1180 | } 1181 | this.stream_0.Write(this.byte_0, (int)this.uint_1, (int)num); 1182 | if (this.uint_0 >= this.uint_2) 1183 | { 1184 | this.uint_0 = 0u; 1185 | } 1186 | this.uint_1 = this.uint_0; 1187 | } 1188 | 1189 | // Token: 0x0600002F RID: 47 RVA: 0x00003AD0 File Offset: 0x00003AD0 1190 | internal void method_4(uint uint_3, uint uint_4) 1191 | { 1192 | uint num = this.uint_0 - uint_3 - 1u; 1193 | if (num >= this.uint_2) 1194 | { 1195 | num += this.uint_2; 1196 | } 1197 | while (uint_4 > 0u) 1198 | { 1199 | if (num >= this.uint_2) 1200 | { 1201 | num = 0u; 1202 | } 1203 | this.byte_0[(int)((UIntPtr)(this.uint_0++))] = this.byte_0[(int)((UIntPtr)(num++))]; 1204 | if (this.uint_0 >= this.uint_2) 1205 | { 1206 | this.method_3(); 1207 | } 1208 | uint_4 -= 1u; 1209 | } 1210 | } 1211 | 1212 | // Token: 0x06000030 RID: 48 RVA: 0x00003B4C File Offset: 0x00003B4C 1213 | internal void method_5(byte byte_1) 1214 | { 1215 | this.byte_0[(int)((UIntPtr)(this.uint_0++))] = byte_1; 1216 | if (this.uint_0 >= this.uint_2) 1217 | { 1218 | this.method_3(); 1219 | } 1220 | } 1221 | 1222 | // Token: 0x06000031 RID: 49 RVA: 0x00003B88 File Offset: 0x00003B88 1223 | internal byte method_6(uint uint_3) 1224 | { 1225 | uint num = this.uint_0 - uint_3 - 1u; 1226 | if (num >= this.uint_2) 1227 | { 1228 | num += this.uint_2; 1229 | } 1230 | return this.byte_0[(int)((UIntPtr)num)]; 1231 | } 1232 | 1233 | // Token: 0x06000032 RID: 50 RVA: 0x00002182 File Offset: 0x00002182 1234 | internal Class4() 1235 | { 1236 | } 1237 | 1238 | // Token: 0x04000026 RID: 38 1239 | internal byte[] byte_0; 1240 | 1241 | // Token: 0x04000027 RID: 39 1242 | internal uint uint_0; 1243 | 1244 | // Token: 0x04000028 RID: 40 1245 | internal Stream stream_0; 1246 | 1247 | // Token: 0x04000029 RID: 41 1248 | internal uint uint_1; 1249 | 1250 | // Token: 0x0400002A RID: 42 1251 | internal uint uint_2; 1252 | } 1253 | } 1254 | -------------------------------------------------------------------------------- /ConfuserEx Dynamic Unpacker/obj/Debug/ConfuserEx Dynamic Unpacker.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\ConfuserEx Dynamic Unpacker.exe.config 2 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\ConfuserEx Dynamic Unpacker.exe 3 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\ConfuserEx Dynamic Unpacker.pdb 4 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\de4dot.blocks.dll 5 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\dnlib.dll 6 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\de4dot.blocks.pdb 7 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\dnlib.pdb 8 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\dnlib.xml 9 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\obj\Debug\ConfuserEx Dynamic Unpacker.exe 10 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\obj\Debug\ConfuserEx Dynamic Unpacker.pdb 11 | c:\users\owner\documents\visual studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\obj\Debug\ConfuserEx Dynamic Unpacker.csprojResolveAssemblyReference.cache 12 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\ConfuserEx Dynamic Unpacker.exe.config 13 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\ConfuserEx Dynamic Unpacker.exe 14 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\ConfuserEx Dynamic Unpacker.pdb 15 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\de4dot.blocks.dll 16 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\dnlib.dll 17 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\de4dot.blocks.pdb 18 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\dnlib.pdb 19 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\bin\Debug\dnlib.xml 20 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\obj\Debug\ConfuserEx Dynamic Unpacker.csprojResolveAssemblyReference.cache 21 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\obj\Debug\ConfuserEx Dynamic Unpacker.exe 22 | D:\backup8-6-17\docs\Visual Studio 2017\Projects\ConfuserEx Dynamic Unpacker\ConfuserEx Dynamic Unpacker\obj\Debug\ConfuserEx Dynamic Unpacker.pdb 23 | -------------------------------------------------------------------------------- /DLLS/de4dot.blocks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uvbs/ConfuserEx-Unpacker/18938d8b51d640a96c58fd8aba8fa6f3b2999730/DLLS/de4dot.blocks.dll -------------------------------------------------------------------------------- /DLLS/de4dot.blocks.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uvbs/ConfuserEx-Unpacker/18938d8b51d640a96c58fd8aba8fa6f3b2999730/DLLS/de4dot.blocks.pdb -------------------------------------------------------------------------------- /DLLS/dnlib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uvbs/ConfuserEx-Unpacker/18938d8b51d640a96c58fd8aba8fa6f3b2999730/DLLS/dnlib.dll -------------------------------------------------------------------------------- /DLLS/dnlib.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uvbs/ConfuserEx-Unpacker/18938d8b51d640a96c58fd8aba8fa6f3b2999730/DLLS/dnlib.pdb -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ConfuserEx-Dynamic-Unpacker 2 | A dynamic confuserex unpacker that relies on invoke for most things 3 | 4 | 5 | #Usage 6 | when using this you there are 2 compulsary commands 7 | the path and either -d or -s for static or dynamic 8 | then you can use -vv for string debug info and control flow info 9 | it will be in a different colour so you know whats verbose 10 | for strings it will give you method name string value and param 11 | control flow it will tell you the case order for the method and for conditionals where it leads to if true or false 12 | 13 | meh had the dynamic version sitting in my github for a while thought id download it fix a few bugs and add a static mode to it 14 | 15 | this is only for VANILLA confuserex 0.5.0 and above by vanilla i mean STANDARD NOT MODIFIED confuserex 16 | 17 | i advise you to rty the static route first it should be stable however i have only tested on 4 files i have faith (probably wont work but let me know) 18 | if static fails try dynamic ode this uses invoke and should be more stable 19 | 20 | the dynamic mode could potentially work on modified confuserex however i havent tested wont test and dont care about modified versions 21 | 22 | this could be a good or bad tool i havent really tested enough coding style has many inconsistencies i have copied and pasted many bits of code from other project to save me as much time as possible. this got boring but i have so many un finished projects thought i might aswell finish this one 23 | 24 | credits - 25 | 26 | SHADOW - PCRET for his anti tamper code and his static packer decryption routine was clever reliable and saved me coming up with my own 27 | 28 | Proxy - control flow - helped me lots on this as stated in my confuserex control flow tool 29 | 30 | 0xd4d - dnlib de4dot obviously 31 | 32 | Codeshark for his isantitampered and ispacked( yet again i know copy and pasting code my bad) 33 | 34 | 35 | --------------------------------------------------------------------------------