Skip to content

Commit 3e3a29f

Browse files
authored
Add files via upload
1 parent 396e003 commit 3e3a29f

File tree

1 file changed

+336
-0
lines changed

1 file changed

+336
-0
lines changed

ILProtectorUnpacker.cs

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
//css_co /unsafe
2+
//css_ref dnlib.dll
3+
using System;
4+
using dnlib.DotNet;
5+
using dnlib.DotNet.Emit;
6+
using dnlib.DotNet.Writer;
7+
using System.Diagnostics;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Reflection;
11+
using System.Windows.Forms;
12+
using System.IO;
13+
using System.Threading;
14+
using System.Runtime.CompilerServices;
15+
using System.Runtime.InteropServices;
16+
17+
class Script
18+
{
19+
public static AssemblyWriter assemblyWriter;
20+
public static Assembly assembly;
21+
public static MethodDef currentMethod;
22+
public static List<TypeDef> junkType = new List<TypeDef>();
23+
24+
[STAThread]
25+
static public void Main(string[] args)
26+
{
27+
try
28+
{
29+
Console.BackgroundColor = ConsoleColor.White;
30+
Console.ForegroundColor = ConsoleColor.Black;
31+
Console.WriteLine("*********************************");
32+
Console.WriteLine("*** ***");
33+
Console.WriteLine("*** ILProtector Unpacker ***");
34+
Console.WriteLine("*** Coded By RexProg ***");
35+
Console.WriteLine("*** ***");
36+
Console.WriteLine("*********************************");
37+
Console.ForegroundColor = ConsoleColor.Blue;
38+
Console.WriteLine("[?] Enter Your Program Path : ");
39+
Console.ForegroundColor = ConsoleColor.Red;
40+
41+
var path = Console.ReadLine();
42+
43+
if (path == string.Empty)
44+
return;
45+
if (path.StartsWith("\"") && path[path.Length - 1] == '"')
46+
path = path.Substring(1, path.Length - 2);
47+
48+
if (!File.Exists(path))
49+
{
50+
Console.ForegroundColor = ConsoleColor.Blue;
51+
Console.WriteLine("[!] File not found");
52+
Console.WriteLine("[!] Press key to exit...");
53+
Console.Read();
54+
return;
55+
}
56+
Console.ForegroundColor = ConsoleColor.DarkRed;
57+
58+
assemblyWriter = new AssemblyWriter(path);
59+
assembly = Assembly.LoadFrom(path);
60+
Console.WriteLine("[+] Wait...");
61+
62+
Memory.Hook(typeof(StackTrace).GetMethod("GetFrame", BindingFlags.Instance | BindingFlags.Public), typeof(Script).GetMethod("Hook", BindingFlags.Instance | BindingFlags.Public));
63+
64+
var types = assemblyWriter.moduleDef.GetTypes();
65+
var list = (types as IList<TypeDef>) ?? types.ToList<TypeDef>();
66+
67+
var globalType = assemblyWriter.moduleDef.GlobalType;
68+
69+
var fieldMDToken = 0;
70+
71+
foreach (FieldDef fieldDef in globalType.Fields)
72+
{
73+
if (fieldDef.Name == "Invoke")
74+
fieldMDToken = fieldDef.MDToken.ToInt32();
75+
}
76+
if (fieldMDToken == 0)
77+
Console.WriteLine("[!] Couldn't find Invoke");
78+
79+
var fieldValue = assembly.Modules.FirstOrDefault<Module>().ResolveField(fieldMDToken).GetValue(null);
80+
81+
var method = fieldValue.GetType().GetMethod("Invoke");
82+
83+
if (method == null)
84+
Console.WriteLine("[!] Couldn't find InvokeMethod");
85+
86+
InvokeDelegates(list, method, fieldValue);
87+
88+
StringDecrypter stringDecrypter = new StringDecrypter(assembly);
89+
stringDecrypter.ReplaceStrings(list);
90+
91+
foreach (var typeDef in junkType)
92+
{
93+
typeDef.DeclaringType.NestedTypes.Remove(typeDef);
94+
}
95+
MethodDef methodDef = globalType.FindStaticConstructor();
96+
97+
if (methodDef.HasBody)
98+
{
99+
var startIndex = methodDef.Body.Instructions.IndexOf(methodDef.Body.Instructions.FirstOrDefault(inst =>
100+
(inst.OpCode == OpCodes.Call
101+
&& ((IMethod)inst.Operand).Name == "GetIUnknownForObject"))) - 2;
102+
103+
var endindex = methodDef.Body.Instructions.IndexOf(methodDef.Body.Instructions.FirstOrDefault(inst =>
104+
(inst.OpCode == OpCodes.Call
105+
&& ((IMethod)inst.Operand).Name == "Release"))) + 2;
106+
107+
methodDef.Body.ExceptionHandlers.Remove(methodDef.Body.ExceptionHandlers.FirstOrDefault(exh => exh.HandlerEnd == methodDef.Body.Instructions[endindex + 1]));
108+
109+
for (int i = startIndex; i <= endindex; i++)
110+
methodDef.Body.Instructions.Remove(methodDef.Body.Instructions[startIndex]);
111+
}
112+
113+
foreach (var meth in globalType.Methods.Where(met => (met.ImplMap?.Module.Name.ToString() == "Protect32.dll" || met.ImplMap?.Module.Name.ToString() == "Protect64.dll")).ToList())
114+
globalType.Remove(meth);
115+
116+
var invokeField = globalType.Fields.FirstOrDefault(fld => fld.Name == "Invoke");
117+
assemblyWriter.moduleDef.Types.Remove(invokeField.FieldType.ToTypeDefOrRef().ResolveTypeDef());
118+
globalType.Fields.Remove(invokeField);
119+
120+
assemblyWriter.Save();
121+
Console.ForegroundColor = ConsoleColor.Blue;
122+
Console.WriteLine("[!] Program Unpacked");
123+
}
124+
catch (Exception ex)
125+
{
126+
Console.WriteLine("[!] Exception :\n" + ex.Message);
127+
}
128+
Console.WriteLine("[!] Press key to exit...");
129+
Console.Read();
130+
}
131+
132+
private static void InvokeDelegates(IList<TypeDef> typeDefs, MethodInfo invokeMethod, object invokeField)
133+
{
134+
foreach (TypeDef typeDef in typeDefs)
135+
{
136+
foreach (MethodDef methodDef in typeDef.Methods)
137+
{
138+
if (!(methodDef.Module.Name != assembly.ManifestModule.ScopeName) && methodDef.HasBody && methodDef.Body.Instructions.Count > 2 && methodDef.Body.Instructions[0].OpCode == OpCodes.Ldsfld && methodDef.Body.Instructions[0].Operand.ToString().Contains("Invoke") && methodDef.Body.Instructions[1].IsLdcI4())
139+
{
140+
currentMethod = methodDef;
141+
142+
var _MDToken = ((IType)methodDef.Body.Instructions[3].Operand).MDToken.ToInt32();
143+
junkType.Add(typeDef.NestedTypes.FirstOrDefault(net => net.MDToken.ToInt32() == _MDToken));
144+
145+
object method = invokeMethod.Invoke(invokeField, new object[] { (int)methodDef.Body.Instructions[1].Operand });
146+
147+
try
148+
{
149+
var dynamicMethodBodyReader = new DynamicMethodBodyReader(assemblyWriter.moduleDef, method);
150+
dynamicMethodBodyReader.Read();
151+
var method2 = dynamicMethodBodyReader.GetMethod();
152+
assemblyWriter.WriteMethod(method2);
153+
}
154+
catch (Exception ex)
155+
{
156+
Console.WriteLine("Error in Read(): " + ex.Message + "\nMethod : " + method.ToString());
157+
}
158+
}
159+
}
160+
}
161+
}
162+
163+
public StackFrame Hook(int num)
164+
{
165+
StackFrame[] frames = new StackTrace().GetFrames();
166+
167+
for (int i = 0; i < frames.Length; i++)
168+
{
169+
MethodBase method = frames[i].GetMethod();
170+
171+
if (num == 0 && method.ToString().StartsWith("System.Delegate ("))
172+
{
173+
return frames[i];
174+
}
175+
if (num == 1 && method.ToString().StartsWith("System.Delegate ("))
176+
{
177+
MethodBase value = assembly.Modules.FirstOrDefault<Module>().ResolveMethod(currentMethod.MDToken.ToInt32());
178+
typeof(StackFrame).GetField("method", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(frames[i + 1], value);
179+
return frames[i + 1];
180+
}
181+
}
182+
return null;
183+
}
184+
}
185+
186+
internal class StringDecrypter
187+
{
188+
private readonly Assembly assembly;
189+
private object _decryptField;
190+
private MethodInfo decryptMethod;
191+
192+
internal StringDecrypter(Assembly assembly)
193+
{
194+
this.assembly = assembly;
195+
}
196+
197+
internal void ReplaceStrings(IList<TypeDef> typeDefs)
198+
{
199+
foreach (TypeDef typeDef in typeDefs)
200+
{
201+
foreach (MethodDef methodDef in typeDef.Methods)
202+
{
203+
if (methodDef.HasBody)
204+
{
205+
IList<Instruction> instructions = methodDef.Body.Instructions;
206+
207+
for (int i = 0; i < instructions.Count; i++)
208+
{
209+
Instruction instruction = instructions[i];
210+
211+
if (instruction.OpCode == OpCodes.Ldsfld && instruction.Operand.ToString().Contains("<Module>::String") && instructions[i + 1].IsLdcI4() && instructions[i + 2].OpCode == OpCodes.Callvirt && instructions[i + 2].Operand.ToString().Contains("Invoke"))
212+
{
213+
if (this._decryptField == null)
214+
{
215+
FieldDef fieldDef = (FieldDef)instruction.Operand;
216+
this.InitDecryptor(fieldDef);
217+
}
218+
int idx = (int)instructions[i + 1].Operand;
219+
instructions[i].OpCode = OpCodes.Ldstr;
220+
instructions[i].Operand = this.GetString(idx);
221+
instructions[i + 1].OpCode = OpCodes.Nop;
222+
instructions[i + 2].OpCode = OpCodes.Nop;
223+
}
224+
}
225+
}
226+
}
227+
}
228+
}
229+
230+
private void InitDecryptor(FieldDef fieldDef)
231+
{
232+
FieldInfo fieldInfo = this.assembly.Modules.FirstOrDefault<Module>().ResolveField(fieldDef.MDToken.ToInt32());
233+
this._decryptField = fieldInfo.GetValue(null);
234+
this.decryptMethod = this._decryptField.GetType().GetMethod("Invoke");
235+
}
236+
237+
private string GetString(int idx)
238+
{
239+
return (string)this.decryptMethod.Invoke(this._decryptField, new object[] { idx });
240+
}
241+
}
242+
243+
internal static class Memory
244+
{
245+
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
246+
private static extern bool VirtualProtect(IntPtr lpAddress, IntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
247+
248+
internal unsafe static void Hook(MethodBase from, MethodBase to)
249+
{
250+
IntPtr address = Memory.GetAddress(from);
251+
IntPtr address2 = Memory.GetAddress(to);
252+
uint flNewProtect;
253+
Memory.VirtualProtect(address, (IntPtr)5, 64u, out flNewProtect);
254+
if (IntPtr.Size == 8)
255+
{
256+
byte* ptr = (byte*)address.ToPointer();
257+
*ptr = 73;
258+
ptr[1] = 187;
259+
*(long*)(ptr + 2) = address2.ToInt64();
260+
ptr[10] = 65;
261+
ptr[11] = byte.MaxValue;
262+
ptr[12] = 227;
263+
}
264+
else if (IntPtr.Size == 4)
265+
{
266+
byte* ptr2 = (byte*)address.ToPointer();
267+
*ptr2 = 233;
268+
*(long*)(ptr2 + 1) = (long)(address2.ToInt32() - address.ToInt32() - 5);
269+
ptr2[5] = 195;
270+
}
271+
uint num;
272+
Memory.VirtualProtect(address, (IntPtr)5, flNewProtect, out num);
273+
}
274+
275+
public static IntPtr GetAddress(MethodBase methodBase)
276+
{
277+
RuntimeHelpers.PrepareMethod(methodBase.MethodHandle);
278+
return methodBase.MethodHandle.GetFunctionPointer();
279+
}
280+
}
281+
282+
internal class AssemblyWriter
283+
{
284+
private readonly string assemblyPath;
285+
286+
internal ModuleDefMD moduleDef;
287+
internal AssemblyWriter(string assemblyPath)
288+
{
289+
this.assemblyPath = assemblyPath;
290+
291+
AssemblyResolver assemblyResolver = new AssemblyResolver();
292+
ModuleContext moduleContext = new ModuleContext(assemblyResolver);
293+
assemblyResolver.EnableTypeDefCache = true;
294+
assemblyResolver.DefaultModuleContext = moduleContext;
295+
moduleDef = ModuleDefMD.Load(assemblyPath, moduleContext);
296+
moduleDef.Context = moduleContext;
297+
moduleDef.Context.AssemblyResolver.AddToCache(moduleDef);
298+
}
299+
300+
internal void WriteMethod(MethodDef methodDef)
301+
{
302+
MethodDef executingMethod = Script.currentMethod;
303+
304+
if (executingMethod == null)
305+
{
306+
Console.WriteLine("[!] Failed to write " + methodDef);
307+
return;
308+
}
309+
Script.currentMethod = null;
310+
executingMethod.FreeMethodBody();
311+
executingMethod.Body = methodDef.Body;
312+
}
313+
314+
internal void Save()
315+
{
316+
try
317+
{
318+
string text = Path.GetDirectoryName(assemblyPath);
319+
320+
if (!text.EndsWith("\\"))
321+
{
322+
text += "\\";
323+
}
324+
325+
string filename = text + Path.GetFileNameWithoutExtension(assemblyPath) + "_Unpacked" + Path.GetExtension(assemblyPath);
326+
ModuleWriterOptions options = new ModuleWriterOptions(moduleDef);
327+
options.Logger = DummyLogger.NoThrowInstance;
328+
moduleDef.Write(filename, options);
329+
}
330+
catch (Exception ex)
331+
{
332+
Console.WriteLine("[!] Exception :\n" + ex.Message);
333+
}
334+
}
335+
336+
}

0 commit comments

Comments
 (0)