├── .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 |
--------------------------------------------------------------------------------