Use standard .NET naming convention
This commit is contained in:
parent
08ca871406
commit
40083ad33a
|
@ -58,12 +58,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.module = module;
|
||||
}
|
||||
|
||||
public void find() {
|
||||
if (checkMethod(DotNetUtils.getModuleTypeCctor(module)))
|
||||
public void Find() {
|
||||
if (CheckMethod(DotNetUtils.GetModuleTypeCctor(module)))
|
||||
return;
|
||||
}
|
||||
|
||||
bool checkMethod(MethodDef method) {
|
||||
bool CheckMethod(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
|
||||
|
@ -73,13 +73,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var calledMethod = instr.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
||||
if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
|
||||
continue;
|
||||
var type = calledMethod.DeclaringType;
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
if (checkMethod_normal(type, calledMethod) || checkMethod_safe(type, calledMethod)) {
|
||||
if (CheckMethod_normal(type, calledMethod) || CheckMethod_safe(type, calledMethod)) {
|
||||
initMethod = calledMethod;
|
||||
return true;
|
||||
}
|
||||
|
@ -88,27 +88,27 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool checkProfilerStrings1(MethodDef method) {
|
||||
if (!DotNetUtils.hasString(method, "COR_ENABLE_PROFILING"))
|
||||
static bool CheckProfilerStrings1(MethodDef method) {
|
||||
if (!DotNetUtils.HasString(method, "COR_ENABLE_PROFILING"))
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(method, "COR_PROFILER"))
|
||||
if (!DotNetUtils.HasString(method, "COR_PROFILER"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool checkProfilerStrings2(MethodDef method) {
|
||||
if (!DotNetUtils.hasString(method, "COR_"))
|
||||
static bool CheckProfilerStrings2(MethodDef method) {
|
||||
if (!DotNetUtils.HasString(method, "COR_"))
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(method, "ENABLE_PROFILING"))
|
||||
if (!DotNetUtils.HasString(method, "ENABLE_PROFILING"))
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(method, "PROFILER"))
|
||||
if (!DotNetUtils.HasString(method, "PROFILER"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static MethodDef getAntiDebugMethod(TypeDef type, MethodDef initMethod) {
|
||||
static MethodDef GetAntiDebugMethod(TypeDef type, MethodDef initMethod) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (method.Body == null || method == initMethod)
|
||||
continue;
|
||||
|
@ -116,7 +116,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
if (!method.IsPrivate)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.Void", "()") && !DotNetUtils.isMethod(method, "System.Void", "(System.Object)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Void", "()") && !DotNetUtils.IsMethod(method, "System.Void", "(System.Object)"))
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -124,59 +124,59 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
bool checkMethod_normal(TypeDef type, MethodDef initMethod) {
|
||||
var ntQueryInformationProcess = DotNetUtils.getPInvokeMethod(type, "ntdll", "NtQueryInformationProcess");
|
||||
bool CheckMethod_normal(TypeDef type, MethodDef initMethod) {
|
||||
var ntQueryInformationProcess = DotNetUtils.GetPInvokeMethod(type, "ntdll", "NtQueryInformationProcess");
|
||||
if (ntQueryInformationProcess == null)
|
||||
return false;
|
||||
if (DotNetUtils.getPInvokeMethod(type, "ntdll", "NtSetInformationProcess") == null)
|
||||
if (DotNetUtils.GetPInvokeMethod(type, "ntdll", "NtSetInformationProcess") == null)
|
||||
return false;
|
||||
if (DotNetUtils.getPInvokeMethod(type, "kernel32", "CloseHandle") == null)
|
||||
if (DotNetUtils.GetPInvokeMethod(type, "kernel32", "CloseHandle") == null)
|
||||
return false;
|
||||
var antiDebugMethod = getAntiDebugMethod(type, initMethod);
|
||||
var antiDebugMethod = GetAntiDebugMethod(type, initMethod);
|
||||
if (antiDebugMethod == null)
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(antiDebugMethod, "Debugger detected (Managed)"))
|
||||
if (!DotNetUtils.HasString(antiDebugMethod, "Debugger detected (Managed)"))
|
||||
return false;
|
||||
|
||||
if (DotNetUtils.callsMethod(initMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)")) {
|
||||
int failFastCalls = ConfuserUtils.countCalls(antiDebugMethod, "System.Void System.Environment::FailFast(System.String)");
|
||||
if (DotNetUtils.CallsMethod(initMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)")) {
|
||||
int failFastCalls = ConfuserUtils.CountCalls(antiDebugMethod, "System.Void System.Environment::FailFast(System.String)");
|
||||
if (failFastCalls != 6 && failFastCalls != 8)
|
||||
return false;
|
||||
|
||||
if (!checkProfilerStrings1(initMethod))
|
||||
if (!CheckProfilerStrings1(initMethod))
|
||||
return false;
|
||||
|
||||
if (!DotNetUtils.callsMethod(antiDebugMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)")) {
|
||||
if (ConfuserUtils.countCalls(antiDebugMethod, ntQueryInformationProcess) != 2)
|
||||
if (!DotNetUtils.CallsMethod(antiDebugMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)")) {
|
||||
if (ConfuserUtils.CountCalls(antiDebugMethod, ntQueryInformationProcess) != 2)
|
||||
return false;
|
||||
version = ConfuserVersion.v16_r61954_normal;
|
||||
}
|
||||
else if (failFastCalls == 8) {
|
||||
if (ConfuserUtils.countCalls(antiDebugMethod, ntQueryInformationProcess) != 2)
|
||||
if (ConfuserUtils.CountCalls(antiDebugMethod, ntQueryInformationProcess) != 2)
|
||||
return false;
|
||||
version = ConfuserVersion.v17_r73822_normal;
|
||||
}
|
||||
else if (failFastCalls == 6) {
|
||||
if (DotNetUtils.getPInvokeMethod(type, "IsDebuggerPresent") == null)
|
||||
if (DotNetUtils.GetPInvokeMethod(type, "IsDebuggerPresent") == null)
|
||||
return false;
|
||||
if (ConfuserUtils.countCalls(antiDebugMethod, ntQueryInformationProcess) != 0)
|
||||
if (ConfuserUtils.CountCalls(antiDebugMethod, ntQueryInformationProcess) != 0)
|
||||
return false;
|
||||
version = ConfuserVersion.v17_r74021_normal;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (!DotNetUtils.callsMethod(initMethod, "System.Void System.Threading.ThreadStart::.ctor(System.Object,System.IntPtr)")) {
|
||||
if (!DotNetUtils.callsMethod(initMethod, "System.Void System.Diagnostics.Process::EnterDebugMode()"))
|
||||
else if (!DotNetUtils.CallsMethod(initMethod, "System.Void System.Threading.ThreadStart::.ctor(System.Object,System.IntPtr)")) {
|
||||
if (!DotNetUtils.CallsMethod(initMethod, "System.Void System.Diagnostics.Process::EnterDebugMode()"))
|
||||
return false;
|
||||
if (!checkProfilerStrings1(antiDebugMethod))
|
||||
if (!CheckProfilerStrings1(antiDebugMethod))
|
||||
return false;
|
||||
version = ConfuserVersion.v14_r57588_normal;
|
||||
}
|
||||
else {
|
||||
if (!DotNetUtils.callsMethod(initMethod, "System.Void System.Diagnostics.Process::EnterDebugMode()"))
|
||||
if (!DotNetUtils.CallsMethod(initMethod, "System.Void System.Diagnostics.Process::EnterDebugMode()"))
|
||||
return false;
|
||||
if (!checkProfilerStrings1(antiDebugMethod))
|
||||
if (!CheckProfilerStrings1(antiDebugMethod))
|
||||
return false;
|
||||
version = ConfuserVersion.v14_r60785_normal;
|
||||
}
|
||||
|
@ -184,45 +184,45 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool checkMethod_safe(TypeDef type, MethodDef initMethod) {
|
||||
if (type == DotNetUtils.getModuleType(module)) {
|
||||
if (!DotNetUtils.hasString(initMethod, "Debugger detected (Managed)"))
|
||||
bool CheckMethod_safe(TypeDef type, MethodDef initMethod) {
|
||||
if (type == DotNetUtils.GetModuleType(module)) {
|
||||
if (!DotNetUtils.HasString(initMethod, "Debugger detected (Managed)"))
|
||||
return false;
|
||||
if (!checkProfilerStrings1(initMethod))
|
||||
if (!CheckProfilerStrings1(initMethod))
|
||||
return false;
|
||||
|
||||
version = ConfuserVersion.v14_r57588_safe;
|
||||
}
|
||||
else {
|
||||
var ntQueryInformationProcess = DotNetUtils.getPInvokeMethod(type, "ntdll", "NtQueryInformationProcess");
|
||||
var ntQueryInformationProcess = DotNetUtils.GetPInvokeMethod(type, "ntdll", "NtQueryInformationProcess");
|
||||
if (ntQueryInformationProcess == null)
|
||||
return false;
|
||||
if (DotNetUtils.getPInvokeMethod(type, "ntdll", "NtSetInformationProcess") == null)
|
||||
if (DotNetUtils.GetPInvokeMethod(type, "ntdll", "NtSetInformationProcess") == null)
|
||||
return false;
|
||||
if (DotNetUtils.getPInvokeMethod(type, "kernel32", "CloseHandle") == null)
|
||||
if (DotNetUtils.GetPInvokeMethod(type, "kernel32", "CloseHandle") == null)
|
||||
return false;
|
||||
var antiDebugMethod = getAntiDebugMethod(type, initMethod);
|
||||
var antiDebugMethod = GetAntiDebugMethod(type, initMethod);
|
||||
if (antiDebugMethod == null)
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(antiDebugMethod, "Debugger detected (Managed)") &&
|
||||
!DotNetUtils.hasString(antiDebugMethod, "Debugger is detected (Managed)"))
|
||||
if (!DotNetUtils.HasString(antiDebugMethod, "Debugger detected (Managed)") &&
|
||||
!DotNetUtils.HasString(antiDebugMethod, "Debugger is detected (Managed)"))
|
||||
return false;
|
||||
if (!DotNetUtils.callsMethod(initMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)"))
|
||||
if (!DotNetUtils.CallsMethod(initMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)"))
|
||||
return false;
|
||||
if (ConfuserUtils.countCalls(antiDebugMethod, ntQueryInformationProcess) != 0)
|
||||
if (ConfuserUtils.CountCalls(antiDebugMethod, ntQueryInformationProcess) != 0)
|
||||
return false;
|
||||
if (!checkProfilerStrings1(initMethod) && !checkProfilerStrings2(initMethod))
|
||||
if (!CheckProfilerStrings1(initMethod) && !CheckProfilerStrings2(initMethod))
|
||||
return false;
|
||||
|
||||
int failFastCalls = ConfuserUtils.countCalls(antiDebugMethod, "System.Void System.Environment::FailFast(System.String)");
|
||||
int failFastCalls = ConfuserUtils.CountCalls(antiDebugMethod, "System.Void System.Environment::FailFast(System.String)");
|
||||
if (failFastCalls != 2)
|
||||
return false;
|
||||
|
||||
if (!DotNetUtils.callsMethod(antiDebugMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)"))
|
||||
if (!DotNetUtils.CallsMethod(antiDebugMethod, "System.Void System.Threading.Thread::.ctor(System.Threading.ParameterizedThreadStart)"))
|
||||
version = ConfuserVersion.v16_r61954_safe;
|
||||
else if (DotNetUtils.getPInvokeMethod(type, "IsDebuggerPresent") == null)
|
||||
else if (DotNetUtils.GetPInvokeMethod(type, "IsDebuggerPresent") == null)
|
||||
version = ConfuserVersion.v17_r73822_safe;
|
||||
else if (checkProfilerStrings1(initMethod))
|
||||
else if (CheckProfilerStrings1(initMethod))
|
||||
version = ConfuserVersion.v17_r74021_safe;
|
||||
else
|
||||
version = ConfuserVersion.v19_r76119_safe;
|
||||
|
@ -231,7 +231,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -55,12 +55,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.module = module;
|
||||
}
|
||||
|
||||
public void find(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
if (checkMethod(simpleDeobfuscator, DotNetUtils.getModuleTypeCctor(module)))
|
||||
public void Find(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
if (CheckMethod(simpleDeobfuscator, DotNetUtils.GetModuleTypeCctor(module)))
|
||||
return;
|
||||
}
|
||||
|
||||
bool checkMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) {
|
||||
bool CheckMethod(ISimpleDeobfuscator simpleDeobfuscator, MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
|
||||
|
@ -72,14 +72,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
if (calledMethod == null || !calledMethod.IsStatic)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
||||
if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
|
||||
continue;
|
||||
var type = calledMethod.DeclaringType;
|
||||
if (type.NestedTypes.Count > 0)
|
||||
continue;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(calledMethod, true);
|
||||
if (checkType(type, calledMethod)) {
|
||||
simpleDeobfuscator.Deobfuscate(calledMethod, true);
|
||||
if (CheckType(type, calledMethod)) {
|
||||
initMethod = calledMethod;
|
||||
return true;
|
||||
}
|
||||
|
@ -87,52 +87,52 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool checkType(TypeDef type, MethodDef initMethod) {
|
||||
return checkType_v14_r58564(type, initMethod) ||
|
||||
checkType_v14_r58852(type, initMethod);
|
||||
bool CheckType(TypeDef type, MethodDef initMethod) {
|
||||
return CheckType_v14_r58564(type, initMethod) ||
|
||||
CheckType_v14_r58852(type, initMethod);
|
||||
}
|
||||
|
||||
bool checkType_v14_r58564(TypeDef type, MethodDef initMethod) {
|
||||
var virtualProtect = DotNetUtils.getPInvokeMethod(type, "VirtualProtect");
|
||||
bool CheckType_v14_r58564(TypeDef type, MethodDef initMethod) {
|
||||
var virtualProtect = DotNetUtils.GetPInvokeMethod(type, "VirtualProtect");
|
||||
if (virtualProtect == null)
|
||||
return false;
|
||||
if (!DotNetUtils.callsMethod(initMethod, "System.IntPtr System.Runtime.InteropServices.Marshal::GetHINSTANCE(System.Reflection.Module)"))
|
||||
if (!DotNetUtils.CallsMethod(initMethod, "System.IntPtr System.Runtime.InteropServices.Marshal::GetHINSTANCE(System.Reflection.Module)"))
|
||||
return false;
|
||||
if (ConfuserUtils.countCalls(initMethod, virtualProtect) != 3)
|
||||
if (ConfuserUtils.CountCalls(initMethod, virtualProtect) != 3)
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 224))
|
||||
if (!DeobUtils.HasInteger(initMethod, 224))
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 240))
|
||||
if (!DeobUtils.HasInteger(initMethod, 240))
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 267))
|
||||
if (!DeobUtils.HasInteger(initMethod, 267))
|
||||
return false;
|
||||
|
||||
version = ConfuserVersion.v14_r58564;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkType_v14_r58852(TypeDef type, MethodDef initMethod) {
|
||||
var virtualProtect = DotNetUtils.getPInvokeMethod(type, "VirtualProtect");
|
||||
bool CheckType_v14_r58852(TypeDef type, MethodDef initMethod) {
|
||||
var virtualProtect = DotNetUtils.GetPInvokeMethod(type, "VirtualProtect");
|
||||
if (virtualProtect == null)
|
||||
return false;
|
||||
if (!DotNetUtils.callsMethod(initMethod, "System.IntPtr System.Runtime.InteropServices.Marshal::GetHINSTANCE(System.Reflection.Module)"))
|
||||
if (!DotNetUtils.CallsMethod(initMethod, "System.IntPtr System.Runtime.InteropServices.Marshal::GetHINSTANCE(System.Reflection.Module)"))
|
||||
return false;
|
||||
int virtualProtectCalls = ConfuserUtils.countCalls(initMethod, virtualProtect);
|
||||
int virtualProtectCalls = ConfuserUtils.CountCalls(initMethod, virtualProtect);
|
||||
if (virtualProtectCalls != 14 && virtualProtectCalls != 16)
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 0x3C))
|
||||
if (!DeobUtils.HasInteger(initMethod, 0x3C))
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 0x6c64746e))
|
||||
if (!DeobUtils.HasInteger(initMethod, 0x6c64746e))
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 0x6c642e6c))
|
||||
if (!DeobUtils.HasInteger(initMethod, 0x6c642e6c))
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 0x6f43744e))
|
||||
if (!DeobUtils.HasInteger(initMethod, 0x6f43744e))
|
||||
return false;
|
||||
if (!DeobUtils.hasInteger(initMethod, 0x6e69746e))
|
||||
if (!DeobUtils.HasInteger(initMethod, 0x6e69746e))
|
||||
return false;
|
||||
int locallocs = ConfuserUtils.countOpCode(initMethod, Code.Localloc);
|
||||
int locallocs = ConfuserUtils.CountOpCode(initMethod, Code.Localloc);
|
||||
|
||||
if (DeobUtils.hasInteger(initMethod, 0x18))
|
||||
if (DeobUtils.HasInteger(initMethod, 0x18))
|
||||
version = ConfuserVersion.v14_r58852;
|
||||
else if (virtualProtectCalls == 16)
|
||||
version = ConfuserVersion.v16_r69339;
|
||||
|
@ -140,9 +140,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (locallocs == 2)
|
||||
version = ConfuserVersion.v17_r74708;
|
||||
else if (locallocs == 1) {
|
||||
if (DotNetUtils.hasString(initMethod, "<Unknown>"))
|
||||
if (DotNetUtils.HasString(initMethod, "<Unknown>"))
|
||||
version = ConfuserVersion.v18_r75257;
|
||||
else if (isRev75725(initMethod))
|
||||
else if (IsRev75725(initMethod))
|
||||
version = ConfuserVersion.v19_r75725;
|
||||
else
|
||||
version = ConfuserVersion.v19_r76186;
|
||||
|
@ -156,7 +156,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool isRev75725(MethodDef method) {
|
||||
static bool IsRev75725(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 9; i++) {
|
||||
if (!instrs[i].IsLdcI4() || instrs[i].GetLdcI4Value() != 8)
|
||||
|
@ -197,7 +197,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
: base(instrs, emulateConvInstrs) {
|
||||
}
|
||||
|
||||
protected override bool processInstructionInt64(ref int index, Stack<ConstantInfo<long>> stack) {
|
||||
protected override bool ProcessInstructionInt64(ref int index, Stack<ConstantInfo<long>> stack) {
|
||||
if (!firstTime)
|
||||
return false;
|
||||
firstTime = false;
|
||||
|
|
|
@ -26,9 +26,9 @@ using de4dot.blocks;
|
|||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
static class ConfuserUtils {
|
||||
public static int findCallMethod(IList<Instruction> instrs, int index, Code callCode, string methodFullName) {
|
||||
public static int FindCallMethod(IList<Instruction> instrs, int index, Code callCode, string methodFullName) {
|
||||
for (int i = index; i < instrs.Count; i++) {
|
||||
if (!isCallMethod(instrs[i], callCode, methodFullName))
|
||||
if (!IsCallMethod(instrs[i], callCode, methodFullName))
|
||||
continue;
|
||||
|
||||
return i;
|
||||
|
@ -36,9 +36,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public static int findCallMethod(IList<Instr> instrs, int index, Code callCode, string methodFullName) {
|
||||
public static int FindCallMethod(IList<Instr> instrs, int index, Code callCode, string methodFullName) {
|
||||
for (int i = index; i < instrs.Count; i++) {
|
||||
if (!isCallMethod(instrs[i].Instruction, callCode, methodFullName))
|
||||
if (!IsCallMethod(instrs[i].Instruction, callCode, methodFullName))
|
||||
continue;
|
||||
|
||||
return i;
|
||||
|
@ -46,24 +46,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public static bool isCallMethod(Instruction instr, Code callCode, string methodFullName) {
|
||||
public static bool IsCallMethod(Instruction instr, Code callCode, string methodFullName) {
|
||||
if (instr.OpCode.Code != callCode)
|
||||
return false;
|
||||
var calledMethod = instr.Operand as IMethod;
|
||||
return calledMethod != null && calledMethod.FullName == methodFullName;
|
||||
}
|
||||
|
||||
public static bool removeResourceHookCode(Blocks blocks, MethodDef handler) {
|
||||
return removeResolveHandlerCode(blocks, handler, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)");
|
||||
public static bool RemoveResourceHookCode(Blocks blocks, MethodDef handler) {
|
||||
return RemoveResolveHandlerCode(blocks, handler, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)");
|
||||
}
|
||||
|
||||
public static bool removeAssemblyHookCode(Blocks blocks, MethodDef handler) {
|
||||
return removeResolveHandlerCode(blocks, handler, "System.Void System.AppDomain::add_AssemblyResolve(System.ResolveEventHandler)");
|
||||
public static bool RemoveAssemblyHookCode(Blocks blocks, MethodDef handler) {
|
||||
return RemoveResolveHandlerCode(blocks, handler, "System.Void System.AppDomain::add_AssemblyResolve(System.ResolveEventHandler)");
|
||||
}
|
||||
|
||||
static bool removeResolveHandlerCode(Blocks blocks, MethodDef handler, string installHandlerMethod) {
|
||||
static bool RemoveResolveHandlerCode(Blocks blocks, MethodDef handler, string installHandlerMethod) {
|
||||
bool modified = false;
|
||||
foreach (var block in blocks.MethodBlocks.getAllBlocks()) {
|
||||
foreach (var block in blocks.MethodBlocks.GetAllBlocks()) {
|
||||
var instrs = block.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
var call = instrs[i];
|
||||
|
@ -96,19 +96,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (calledMethod == null || calledMethod.FullName != installHandlerMethod)
|
||||
continue;
|
||||
|
||||
block.remove(i, 5);
|
||||
block.Remove(i, 5);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
public static byte[] decryptCompressedInt32Data(Arg64ConstantsReader constReader, int exprStart, int exprEnd, IBinaryReader reader, byte[] decrypted) {
|
||||
public static byte[] DecryptCompressedInt32Data(Arg64ConstantsReader constReader, int exprStart, int exprEnd, IBinaryReader reader, byte[] decrypted) {
|
||||
for (int i = 0; i < decrypted.Length; i++) {
|
||||
constReader.Arg = reader.Read7BitEncodedInt32();
|
||||
int index = exprStart;
|
||||
long result;
|
||||
if (!constReader.getInt64(ref index, out result) || index != exprEnd)
|
||||
if (!constReader.GetInt64(ref index, out result) || index != exprEnd)
|
||||
throw new ApplicationException("Could not decrypt integer");
|
||||
decrypted[i] = (byte)result;
|
||||
}
|
||||
|
@ -116,11 +116,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
static readonly byte[] defaultDecryptKey = new byte[1];
|
||||
public static byte[] decrypt(uint seed, byte[] encrypted) {
|
||||
return decrypt(seed, encrypted, defaultDecryptKey);
|
||||
public static byte[] Decrypt(uint seed, byte[] encrypted) {
|
||||
return Decrypt(seed, encrypted, defaultDecryptKey);
|
||||
}
|
||||
|
||||
public static byte[] decrypt(uint seed, byte[] encrypted, byte[] key) {
|
||||
public static byte[] Decrypt(uint seed, byte[] encrypted, byte[] key) {
|
||||
var decrypted = new byte[encrypted.Length];
|
||||
ushort _m = (ushort)(seed >> 16);
|
||||
ushort _c = (ushort)seed;
|
||||
|
@ -133,7 +133,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decrypted;
|
||||
}
|
||||
|
||||
public static int countCalls(MethodDef method, string methodFullName) {
|
||||
public static int CountCalls(MethodDef method, string methodFullName) {
|
||||
if (method == null || method.Body == null)
|
||||
return 0;
|
||||
int count = 0;
|
||||
|
@ -147,7 +147,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return count;
|
||||
}
|
||||
|
||||
public static int countCalls(MethodDef method, MethodDef calledMethod) {
|
||||
public static int CountCalls(MethodDef method, MethodDef calledMethod) {
|
||||
if (method == null || method.Body == null)
|
||||
return 0;
|
||||
int count = 0;
|
||||
|
@ -160,7 +160,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return count;
|
||||
}
|
||||
|
||||
public static int countOpCode(MethodDef method, Code code) {
|
||||
public static int CountOpCode(MethodDef method, Code code) {
|
||||
if (method == null || method.Body == null)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -41,25 +41,25 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public uint key0, key1, key2, key3;
|
||||
public byte doubleType, singleType, int32Type, int64Type, stringType;
|
||||
|
||||
public void initialize() {
|
||||
if (!initializeKeys())
|
||||
public void Initialize() {
|
||||
if (!InitializeKeys())
|
||||
throw new ApplicationException("Could not find all keys");
|
||||
if (!initializeTypeCodes())
|
||||
if (!InitializeTypeCodes())
|
||||
throw new ApplicationException("Could not find all type codes");
|
||||
}
|
||||
|
||||
protected virtual bool initializeKeys() {
|
||||
if (!findKey0(decryptMethod, out key0))
|
||||
protected virtual bool InitializeKeys() {
|
||||
if (!FindKey0(decryptMethod, out key0))
|
||||
return false;
|
||||
if (!findKey1(decryptMethod, out key1))
|
||||
if (!FindKey1(decryptMethod, out key1))
|
||||
return false;
|
||||
if (!findKey2Key3(decryptMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(decryptMethod, out key2, out key3))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static bool findKey0(MethodDef method, out uint key) {
|
||||
protected static bool FindKey0(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (!instrs[i].IsLdloc())
|
||||
|
@ -83,10 +83,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1(MethodDef method, out uint key) {
|
||||
static bool FindKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index + 2 > instrs.Count)
|
||||
|
@ -104,7 +104,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey2Key3(MethodDef method, out uint key2, out uint key3) {
|
||||
protected static bool FindKey2Key3(MethodDef method, out uint key2, out uint key3) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
|
@ -127,31 +127,31 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool initializeTypeCodes() {
|
||||
var allBlocks = new Blocks(decryptMethod).MethodBlocks.getAllBlocks();
|
||||
if (!findTypeCode(allBlocks, out doubleType, Code.Call, "System.Double System.BitConverter::ToDouble(System.Byte[],System.Int32)"))
|
||||
bool InitializeTypeCodes() {
|
||||
var allBlocks = new Blocks(decryptMethod).MethodBlocks.GetAllBlocks();
|
||||
if (!FindTypeCode(allBlocks, out doubleType, Code.Call, "System.Double System.BitConverter::ToDouble(System.Byte[],System.Int32)"))
|
||||
return false;
|
||||
if (!findTypeCode(allBlocks, out singleType, Code.Call, "System.Single System.BitConverter::ToSingle(System.Byte[],System.Int32)"))
|
||||
if (!FindTypeCode(allBlocks, out singleType, Code.Call, "System.Single System.BitConverter::ToSingle(System.Byte[],System.Int32)"))
|
||||
return false;
|
||||
if (!findTypeCode(allBlocks, out int32Type, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)"))
|
||||
if (!FindTypeCode(allBlocks, out int32Type, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)"))
|
||||
return false;
|
||||
if (!findTypeCode(allBlocks, out int64Type, Code.Call, "System.Int64 System.BitConverter::ToInt64(System.Byte[],System.Int32)"))
|
||||
if (!FindTypeCode(allBlocks, out int64Type, Code.Call, "System.Int64 System.BitConverter::ToInt64(System.Byte[],System.Int32)"))
|
||||
return false;
|
||||
if (!findTypeCode(allBlocks, out stringType, Code.Callvirt, "System.String System.Text.Encoding::GetString(System.Byte[])") &&
|
||||
!findTypeCode(allBlocks, out stringType, Code.Callvirt, "System.String System.Text.Encoding::GetString(System.Byte[],System.Int32,System.Int32)"))
|
||||
if (!FindTypeCode(allBlocks, out stringType, Code.Callvirt, "System.String System.Text.Encoding::GetString(System.Byte[])") &&
|
||||
!FindTypeCode(allBlocks, out stringType, Code.Callvirt, "System.String System.Text.Encoding::GetString(System.Byte[],System.Int32,System.Int32)"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findTypeCode(IList<Block> allBlocks, out byte typeCode, Code callCode, string bitConverterMethod) {
|
||||
static bool FindTypeCode(IList<Block> allBlocks, out byte typeCode, Code callCode, string bitConverterMethod) {
|
||||
foreach (var block in allBlocks) {
|
||||
if (block.Sources.Count != 1)
|
||||
continue;
|
||||
int index = ConfuserUtils.findCallMethod(block.Instructions, 0, callCode, bitConverterMethod);
|
||||
int index = ConfuserUtils.FindCallMethod(block.Instructions, 0, callCode, bitConverterMethod);
|
||||
if (index < 0)
|
||||
continue;
|
||||
|
||||
if (!findTypeCode(block.Sources[0], out typeCode))
|
||||
if (!FindTypeCode(block.Sources[0], out typeCode))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
|
@ -160,10 +160,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static Block fixBlock(Block block) {
|
||||
static Block FixBlock(Block block) {
|
||||
if (block.Sources.Count != 1)
|
||||
return block;
|
||||
if (block.getOnlyTarget() == null)
|
||||
if (block.GetOnlyTarget() == null)
|
||||
return block;
|
||||
if (block.Instructions.Count == 0) {
|
||||
}
|
||||
|
@ -174,8 +174,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return block.Sources[0];
|
||||
}
|
||||
|
||||
static bool findTypeCode(Block block, out byte typeCode) {
|
||||
block = fixBlock(block);
|
||||
static bool FindTypeCode(Block block, out byte typeCode) {
|
||||
block = FixBlock(block);
|
||||
|
||||
var instrs = block.Instructions;
|
||||
int numCeq = 0;
|
||||
|
@ -197,7 +197,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public uint calcHash(uint x) {
|
||||
public uint CalcHash(uint x) {
|
||||
uint h0 = key1 ^ x;
|
||||
uint h1 = key2;
|
||||
uint h2 = key3;
|
||||
|
@ -240,7 +240,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
public IEnumerable<FieldDef> Fields {
|
||||
get { return fields.getKeys(); }
|
||||
get { return fields.GetKeys(); }
|
||||
}
|
||||
|
||||
protected bool HasDecrypterInfos {
|
||||
|
@ -248,7 +248,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
public IEnumerable<DecrypterInfo> DecrypterInfos {
|
||||
get { return methodToDecrypterInfo.getValues(); }
|
||||
get { return methodToDecrypterInfo.GetValues(); }
|
||||
}
|
||||
|
||||
public ConstantsDecrypterBase(ModuleDefMD module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
|
@ -257,36 +257,36 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
}
|
||||
|
||||
public abstract bool getRevisionRange(out int minRev, out int maxRev);
|
||||
public abstract void initialize();
|
||||
public abstract bool GetRevisionRange(out int minRev, out int maxRev);
|
||||
public abstract void Initialize();
|
||||
|
||||
protected void add(DecrypterInfo info) {
|
||||
methodToDecrypterInfo.add(info.decryptMethod, info);
|
||||
protected void Add(DecrypterInfo info) {
|
||||
methodToDecrypterInfo.Add(info.decryptMethod, info);
|
||||
}
|
||||
|
||||
protected bool add(FieldDef field) {
|
||||
protected bool Add(FieldDef field) {
|
||||
if (field == null)
|
||||
return false;
|
||||
fields.add(field, true);
|
||||
fields.Add(field, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void initializeDecrypterInfos() {
|
||||
foreach (var info in methodToDecrypterInfo.getValues()) {
|
||||
simpleDeobfuscator.deobfuscate(info.decryptMethod);
|
||||
info.initialize();
|
||||
protected void InitializeDecrypterInfos() {
|
||||
foreach (var info in methodToDecrypterInfo.GetValues()) {
|
||||
simpleDeobfuscator.Deobfuscate(info.decryptMethod);
|
||||
info.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setConstantsData(byte[] constants) {
|
||||
protected void SetConstantsData(byte[] constants) {
|
||||
reader = MemoryImageStream.Create(constants);
|
||||
}
|
||||
|
||||
protected EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
protected EmbeddedResource FindResource(MethodDef method) {
|
||||
return DotNetUtils.GetResource(module, DotNetUtils.GetCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
protected static MethodDef findNativeMethod(MethodDef method) {
|
||||
protected static MethodDef FindNativeMethod(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
var call = instrs[i];
|
||||
|
@ -295,7 +295,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic || !calledMethod.IsNative)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||
if (!DotNetUtils.IsMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||
continue;
|
||||
|
||||
return calledMethod;
|
||||
|
@ -303,10 +303,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static Local getDynamicLocal_v17_r73740(MethodDef method) {
|
||||
static Local GetDynamicLocal_v17_r73740(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte System.IO.BinaryReader::ReadByte()");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Byte System.IO.BinaryReader::ReadByte()");
|
||||
if (i < 0 || i + 5 >= instrs.Count)
|
||||
break;
|
||||
if (!instrs[i + 1].IsStloc())
|
||||
|
@ -327,7 +327,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static int getDynamicEndIndex_v17_r73740(MethodDef method, Local local) {
|
||||
static int GetDynamicEndIndex_v17_r73740(MethodDef method, Local local) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
int index = i;
|
||||
|
@ -358,7 +358,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int getDynamicEndIndex_v17_r74788(MethodDef method, Local local) {
|
||||
static int GetDynamicEndIndex_v17_r74788(MethodDef method, Local local) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 11; i++) {
|
||||
var stloc = instrs[i];
|
||||
|
@ -393,7 +393,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int getDynamicStartIndex_v17_r73740(MethodDef method, int endIndex) {
|
||||
static int GetDynamicStartIndex_v17_r73740(MethodDef method, int endIndex) {
|
||||
if (endIndex < 0)
|
||||
return -1;
|
||||
var instrs = method.Body.Instructions;
|
||||
|
@ -409,42 +409,42 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
static readonly byte[] defaultDecryptKey_v17 = new byte[1];
|
||||
protected byte[] decryptConstant_v17_r73740_dynamic(DecrypterInfo info, byte[] encrypted, uint offs, uint key) {
|
||||
return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, key, defaultDecryptKey_v17);
|
||||
protected byte[] DecryptConstant_v17_r73740_dynamic(DecrypterInfo info, byte[] encrypted, uint offs, uint key) {
|
||||
return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, key, defaultDecryptKey_v17);
|
||||
}
|
||||
|
||||
protected byte[] decryptConstant_v17_r73740_dynamic(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) {
|
||||
var local = getDynamicLocal_v17_r73740(info.decryptMethod);
|
||||
protected byte[] DecryptConstant_v17_r73740_dynamic(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) {
|
||||
var local = GetDynamicLocal_v17_r73740(info.decryptMethod);
|
||||
if (local == null)
|
||||
throw new ApplicationException("Could not find local");
|
||||
|
||||
int endIndex = getDynamicEndIndex_v17_r73740(info.decryptMethod, local);
|
||||
int endIndex = GetDynamicEndIndex_v17_r73740(info.decryptMethod, local);
|
||||
if (endIndex < 0)
|
||||
endIndex = getDynamicEndIndex_v17_r74788(info.decryptMethod, local);
|
||||
int startIndex = getDynamicStartIndex_v17_r73740(info.decryptMethod, endIndex);
|
||||
endIndex = GetDynamicEndIndex_v17_r74788(info.decryptMethod, local);
|
||||
int startIndex = GetDynamicStartIndex_v17_r73740(info.decryptMethod, endIndex);
|
||||
if (startIndex < 0)
|
||||
throw new ApplicationException("Could not find start/end index");
|
||||
|
||||
var constReader = new ConstantsReader(info.decryptMethod);
|
||||
return decrypt(encrypted, key1, (magic, i) => {
|
||||
constReader.setConstantInt32(local, magic);
|
||||
return Decrypt(encrypted, key1, (magic, i) => {
|
||||
constReader.SetConstantInt32(local, magic);
|
||||
int index = startIndex, result;
|
||||
if (!constReader.getNextInt32(ref index, out result) || index != endIndex)
|
||||
if (!constReader.GetNextInt32(ref index, out result) || index != endIndex)
|
||||
throw new ApplicationException("Could not decrypt integer");
|
||||
return (byte)(result ^ key2[i % key2.Length]);
|
||||
});
|
||||
}
|
||||
|
||||
protected byte[] decryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key) {
|
||||
return decryptConstant_v17_r73764_native(info, encrypted, offs, key, defaultDecryptKey_v17);
|
||||
protected byte[] DecryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key) {
|
||||
return DecryptConstant_v17_r73764_native(info, encrypted, offs, key, defaultDecryptKey_v17);
|
||||
}
|
||||
|
||||
protected byte[] decryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) {
|
||||
protected byte[] DecryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) {
|
||||
using (var x86Emu = new x86Emulator(fileData))
|
||||
return decrypt(encrypted, key1, (magic, i) => (byte)(x86Emu.emulate((uint)nativeMethod.RVA, magic) ^ key2[i % key2.Length]));
|
||||
return Decrypt(encrypted, key1, (magic, i) => (byte)(x86Emu.Emulate((uint)nativeMethod.RVA, magic) ^ key2[i % key2.Length]));
|
||||
}
|
||||
|
||||
static byte[] decrypt(byte[] encrypted, uint key, Func<uint, int, byte> decryptFunc) {
|
||||
static byte[] Decrypt(byte[] encrypted, uint key, Func<uint, int, byte> decryptFunc) {
|
||||
var reader = MemoryImageStream.Create(encrypted);
|
||||
var decrypted = new byte[reader.ReadInt32() ^ key];
|
||||
for (int i = 0; i < decrypted.Length; i++) {
|
||||
|
@ -455,10 +455,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decrypted;
|
||||
}
|
||||
|
||||
public object decryptInt32(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
public object DecryptInt32(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.Find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
var data = DecryptData(info, caller, args, out typeCode);
|
||||
if (typeCode != info.int32Type)
|
||||
return null;
|
||||
if (data.Length != 4)
|
||||
|
@ -466,10 +466,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToInt32(data, 0);
|
||||
}
|
||||
|
||||
public object decryptInt64(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
public object DecryptInt64(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.Find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
var data = DecryptData(info, caller, args, out typeCode);
|
||||
if (typeCode != info.int64Type)
|
||||
return null;
|
||||
if (data.Length != 8)
|
||||
|
@ -477,10 +477,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToInt64(data, 0);
|
||||
}
|
||||
|
||||
public object decryptSingle(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
public object DecryptSingle(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.Find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
var data = DecryptData(info, caller, args, out typeCode);
|
||||
if (typeCode != info.singleType)
|
||||
return null;
|
||||
if (data.Length != 4)
|
||||
|
@ -488,10 +488,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToSingle(data, 0);
|
||||
}
|
||||
|
||||
public object decryptDouble(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
public object DecryptDouble(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.Find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
var data = DecryptData(info, caller, args, out typeCode);
|
||||
if (typeCode != info.doubleType)
|
||||
return null;
|
||||
if (data.Length != 8)
|
||||
|
@ -499,15 +499,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return BitConverter.ToDouble(data, 0);
|
||||
}
|
||||
|
||||
public string decryptString(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.find(decryptMethod);
|
||||
public string DecryptString(MethodDef caller, MethodDef decryptMethod, object[] args) {
|
||||
var info = methodToDecrypterInfo.Find(decryptMethod);
|
||||
byte typeCode;
|
||||
var data = decryptData(info, caller, args, out typeCode);
|
||||
var data = DecryptData(info, caller, args, out typeCode);
|
||||
if (typeCode != info.stringType)
|
||||
return null;
|
||||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
|
||||
protected abstract byte[] decryptData(DecrypterInfo info, MethodDef caller, object[] args, out byte typeCode);
|
||||
protected abstract byte[] DecryptData(DecrypterInfo info, MethodDef caller, object[] args, out byte typeCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ using dnlib.DotNet.Emit;
|
|||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
static class ConstantsDecrypterUtils {
|
||||
public static FieldDef findDictField(MethodDef method, TypeDef declaringType) {
|
||||
public static FieldDef FindDictField(MethodDef method, TypeDef declaringType) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var newobj = instrs[i];
|
||||
|
@ -46,7 +46,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static FieldDef findDataField(MethodDef method, TypeDef declaringType) {
|
||||
public static FieldDef FindDataField(MethodDef method, TypeDef declaringType) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var callvirt = instrs[i];
|
||||
|
@ -70,15 +70,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static FieldDef findStreamField(MethodDef method, TypeDef declaringType) {
|
||||
return findStreamField(method, declaringType, "System.IO.Stream");
|
||||
public static FieldDef FindStreamField(MethodDef method, TypeDef declaringType) {
|
||||
return FindStreamField(method, declaringType, "System.IO.Stream");
|
||||
}
|
||||
|
||||
public static FieldDef findMemoryStreamField(MethodDef method, TypeDef declaringType) {
|
||||
return findStreamField(method, declaringType, "System.IO.MemoryStream");
|
||||
public static FieldDef FindMemoryStreamField(MethodDef method, TypeDef declaringType) {
|
||||
return FindStreamField(method, declaringType, "System.IO.MemoryStream");
|
||||
}
|
||||
|
||||
public static FieldDef findStreamField(MethodDef method, TypeDef declaringType, string fieldTypeName) {
|
||||
public static FieldDef FindStreamField(MethodDef method, TypeDef declaringType, string fieldTypeName) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var newobj = instrs[i];
|
||||
|
|
|
@ -69,28 +69,28 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.IO.Compression.DeflateStream",
|
||||
"System.Reflection.Assembly",
|
||||
};
|
||||
public void find() {
|
||||
var type = DotNetUtils.getModuleType(module);
|
||||
public void Find() {
|
||||
var type = DotNetUtils.GetModuleType(module);
|
||||
if (type == null)
|
||||
return;
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.Object", "(System.UInt32)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Object", "(System.UInt32)"))
|
||||
continue;
|
||||
|
||||
DecrypterInfo info = new DecrypterInfo();
|
||||
var localTypes = new LocalTypes(method);
|
||||
if (localTypes.all(requiredLocals1)) {
|
||||
if (localTypes.exists("System.Collections.BitArray")) // or System.Random
|
||||
if (localTypes.All(requiredLocals1)) {
|
||||
if (localTypes.Exists("System.Collections.BitArray")) // or System.Random
|
||||
version = ConfuserVersion.v15_r60785_normal;
|
||||
else if (DeobUtils.hasInteger(method, 0x100) &&
|
||||
DeobUtils.hasInteger(method, 0x10000) &&
|
||||
DeobUtils.hasInteger(method, 0xFFFF))
|
||||
else if (DeobUtils.HasInteger(method, 0x100) &&
|
||||
DeobUtils.HasInteger(method, 0x10000) &&
|
||||
DeobUtils.HasInteger(method, 0xFFFF))
|
||||
version = ConfuserVersion.v17_r73404_normal;
|
||||
else if (DotNetUtils.callsMethod(method, "System.String System.Text.Encoding::GetString(System.Byte[])")) {
|
||||
if (findInstruction(method.Body.Instructions, 0, Code.Conv_I8) >= 0) {
|
||||
if (DotNetUtils.callsMethod(method, "System.Void System.Console::WriteLine()"))
|
||||
else if (DotNetUtils.CallsMethod(method, "System.String System.Text.Encoding::GetString(System.Byte[])")) {
|
||||
if (FindInstruction(method.Body.Instructions, 0, Code.Conv_I8) >= 0) {
|
||||
if (DotNetUtils.CallsMethod(method, "System.Void System.Console::WriteLine()"))
|
||||
version = ConfuserVersion.v15_r60785_dynamic;
|
||||
else
|
||||
version = ConfuserVersion.v17_r72989_dynamic;
|
||||
|
@ -98,8 +98,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
else
|
||||
version = ConfuserVersion.v17_r73740_dynamic;
|
||||
}
|
||||
else if (DotNetUtils.callsMethod(method, "System.String System.Text.Encoding::GetString(System.Byte[],System.Int32,System.Int32)")) {
|
||||
if ((nativeMethod = findNativeMethod(method)) == null)
|
||||
else if (DotNetUtils.CallsMethod(method, "System.String System.Text.Encoding::GetString(System.Byte[],System.Int32,System.Int32)")) {
|
||||
if ((nativeMethod = FindNativeMethod(method)) == null)
|
||||
version = ConfuserVersion.v17_r73764_dynamic;
|
||||
else
|
||||
version = ConfuserVersion.v17_r73764_native;
|
||||
|
@ -107,18 +107,18 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
else
|
||||
continue;
|
||||
}
|
||||
else if (localTypes.all(requiredLocals2)) {
|
||||
if (DeobUtils.hasInteger(method, 0x100) &&
|
||||
DeobUtils.hasInteger(method, 0x10000) &&
|
||||
DeobUtils.hasInteger(method, 0xFFFF))
|
||||
else if (localTypes.All(requiredLocals2)) {
|
||||
if (DeobUtils.HasInteger(method, 0x100) &&
|
||||
DeobUtils.HasInteger(method, 0x10000) &&
|
||||
DeobUtils.HasInteger(method, 0xFFFF))
|
||||
version = ConfuserVersion.v17_r73822_normal;
|
||||
else if (DotNetUtils.callsMethod(method, "System.Int32 System.Object::GetHashCode()")) {
|
||||
if ((nativeMethod = findNativeMethod(method)) == null)
|
||||
else if (DotNetUtils.CallsMethod(method, "System.Int32 System.Object::GetHashCode()")) {
|
||||
if ((nativeMethod = FindNativeMethod(method)) == null)
|
||||
version = ConfuserVersion.v17_r74021_dynamic;
|
||||
else
|
||||
version = ConfuserVersion.v17_r74021_native;
|
||||
}
|
||||
else if ((nativeMethod = findNativeMethod(method)) == null)
|
||||
else if ((nativeMethod = FindNativeMethod(method)) == null)
|
||||
version = ConfuserVersion.v17_r73822_dynamic;
|
||||
else
|
||||
version = ConfuserVersion.v17_r73822_native;
|
||||
|
@ -128,32 +128,32 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
info.decryptMethod = method;
|
||||
theDecrypterInfo = info;
|
||||
add(info);
|
||||
Add(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void initialize() {
|
||||
if ((resource = findResource(theDecrypterInfo.decryptMethod)) == null)
|
||||
public override void Initialize() {
|
||||
if ((resource = FindResource(theDecrypterInfo.decryptMethod)) == null)
|
||||
throw new ApplicationException("Could not find encrypted consts resource");
|
||||
|
||||
initializeDecrypterInfos();
|
||||
if (!initializeFields(theDecrypterInfo))
|
||||
InitializeDecrypterInfos();
|
||||
if (!InitializeFields(theDecrypterInfo))
|
||||
throw new ApplicationException("Could not find all fields");
|
||||
|
||||
setConstantsData(DeobUtils.inflate(resource.GetResourceData(), true));
|
||||
SetConstantsData(DeobUtils.Inflate(resource.GetResourceData(), true));
|
||||
}
|
||||
|
||||
bool initializeFields(DecrypterInfo info) {
|
||||
bool InitializeFields(DecrypterInfo info) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r73822_normal:
|
||||
case ConfuserVersion.v17_r73822_dynamic:
|
||||
case ConfuserVersion.v17_r73822_native:
|
||||
case ConfuserVersion.v17_r74021_dynamic:
|
||||
case ConfuserVersion.v17_r74021_native:
|
||||
if (!add(ConstantsDecrypterUtils.findDictField(info.decryptMethod, info.decryptMethod.DeclaringType)))
|
||||
if (!Add(ConstantsDecrypterUtils.FindDictField(info.decryptMethod, info.decryptMethod.DeclaringType)))
|
||||
return false;
|
||||
if (!add(ConstantsDecrypterUtils.findMemoryStreamField(info.decryptMethod, info.decryptMethod.DeclaringType)))
|
||||
if (!Add(ConstantsDecrypterUtils.FindMemoryStreamField(info.decryptMethod, info.decryptMethod.DeclaringType)))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
@ -164,8 +164,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected override byte[] decryptData(DecrypterInfo info, MethodDef caller, object[] args, out byte typeCode) {
|
||||
uint offs = info.calcHash(caller.MDToken.ToUInt32()) ^ (uint)args[0];
|
||||
protected override byte[] DecryptData(DecrypterInfo info, MethodDef caller, object[] args, out byte typeCode) {
|
||||
uint offs = info.CalcHash(caller.MDToken.ToUInt32()) ^ (uint)args[0];
|
||||
reader.Position = offs;
|
||||
typeCode = reader.ReadByte();
|
||||
if (typeCode != info.int32Type && typeCode != info.int64Type &&
|
||||
|
@ -174,28 +174,28 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Invalid type code");
|
||||
|
||||
var encrypted = reader.ReadBytes(reader.ReadInt32());
|
||||
return decryptConstant(info, encrypted, offs);
|
||||
return DecryptConstant(info, encrypted, offs);
|
||||
}
|
||||
|
||||
byte[] decryptConstant(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
byte[] DecryptConstant(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v15_r60785_normal: return decryptConstant_v15_r60785_normal(info, encrypted, offs);
|
||||
case ConfuserVersion.v15_r60785_dynamic: return decryptConstant_v15_r60785_dynamic(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r72989_dynamic: return decryptConstant_v15_r60785_dynamic(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r73404_normal: return decryptConstant_v17_r73404_normal(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r73740_dynamic: return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73764_dynamic: return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73764_native: return decryptConstant_v17_r73764_native(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73822_normal: return decryptConstant_v17_r73404_normal(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r73822_dynamic: return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73822_native: return decryptConstant_v17_r73764_native(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r74021_dynamic: return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r74021_native: return decryptConstant_v17_r73764_native(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v15_r60785_normal: return DecryptConstant_v15_r60785_normal(info, encrypted, offs);
|
||||
case ConfuserVersion.v15_r60785_dynamic: return DecryptConstant_v15_r60785_dynamic(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r72989_dynamic: return DecryptConstant_v15_r60785_dynamic(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r73404_normal: return DecryptConstant_v17_r73404_normal(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r73740_dynamic: return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73764_dynamic: return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73764_native: return DecryptConstant_v17_r73764_native(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73822_normal: return DecryptConstant_v17_r73404_normal(info, encrypted, offs);
|
||||
case ConfuserVersion.v17_r73822_dynamic: return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r73822_native: return DecryptConstant_v17_r73764_native(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r74021_dynamic: return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, 0);
|
||||
case ConfuserVersion.v17_r74021_native: return DecryptConstant_v17_r73764_native(info, encrypted, offs, 0);
|
||||
default: throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v15_r60785_normal(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
byte[] DecryptConstant_v15_r60785_normal(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
var rand = new Random((int)(info.key0 ^ offs));
|
||||
var decrypted = new byte[encrypted.Length];
|
||||
rand.NextBytes(decrypted);
|
||||
|
@ -204,30 +204,30 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decrypted;
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v15_r60785_dynamic(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
byte[] DecryptConstant_v15_r60785_dynamic(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
var instrs = info.decryptMethod.Body.Instructions;
|
||||
int startIndex = getDynamicStartIndex_v15_r60785(instrs);
|
||||
int endIndex = getDynamicEndIndex_v15_r60785(instrs, startIndex);
|
||||
int startIndex = GetDynamicStartIndex_v15_r60785(instrs);
|
||||
int endIndex = GetDynamicEndIndex_v15_r60785(instrs, startIndex);
|
||||
if (endIndex < 0)
|
||||
throw new ApplicationException("Could not find start/endIndex");
|
||||
|
||||
var dataReader = MemoryImageStream.Create(encrypted);
|
||||
var decrypted = new byte[dataReader.ReadInt32()];
|
||||
var constReader = new Arg64ConstantsReader(instrs, false);
|
||||
ConfuserUtils.decryptCompressedInt32Data(constReader, startIndex, endIndex, dataReader, decrypted);
|
||||
ConfuserUtils.DecryptCompressedInt32Data(constReader, startIndex, endIndex, dataReader, decrypted);
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
static int getDynamicStartIndex_v15_r60785(IList<Instruction> instrs) {
|
||||
int index = findInstruction(instrs, 0, Code.Conv_I8);
|
||||
static int GetDynamicStartIndex_v15_r60785(IList<Instruction> instrs) {
|
||||
int index = FindInstruction(instrs, 0, Code.Conv_I8);
|
||||
if (index < 0)
|
||||
return -1;
|
||||
if (findInstruction(instrs, index + 1, Code.Conv_I8) >= 0)
|
||||
if (FindInstruction(instrs, index + 1, Code.Conv_I8) >= 0)
|
||||
return -1;
|
||||
return index;
|
||||
}
|
||||
|
||||
static int getDynamicEndIndex_v15_r60785(IList<Instruction> instrs, int index) {
|
||||
static int GetDynamicEndIndex_v15_r60785(IList<Instruction> instrs, int index) {
|
||||
if (index < 0)
|
||||
return -1;
|
||||
for (int i = index; i < instrs.Count; i++) {
|
||||
|
@ -240,7 +240,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int findInstruction(IList<Instruction> instrs, int index, Code code) {
|
||||
static int FindInstruction(IList<Instruction> instrs, int index, Code code) {
|
||||
for (int i = index; i < instrs.Count; i++) {
|
||||
if (instrs[i].OpCode.Code == code)
|
||||
return i;
|
||||
|
@ -248,11 +248,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r73404_normal(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
return ConfuserUtils.decrypt(info.key0 ^ offs, encrypted);
|
||||
byte[] DecryptConstant_v17_r73404_normal(DecrypterInfo info, byte[] encrypted, uint offs) {
|
||||
return ConfuserUtils.Decrypt(info.key0 ^ offs, encrypted);
|
||||
}
|
||||
|
||||
public override bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public override bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -62,22 +62,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.decryptMethod = decryptMethod;
|
||||
}
|
||||
|
||||
protected override bool initializeKeys() {
|
||||
if (!findKey0(decryptMethod, out key0))
|
||||
protected override bool InitializeKeys() {
|
||||
if (!FindKey0(decryptMethod, out key0))
|
||||
return false;
|
||||
if (!findKey1_v17(decryptMethod, out key1))
|
||||
if (!FindKey1_v17(decryptMethod, out key1))
|
||||
return false;
|
||||
if (!findKey2Key3(decryptMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(decryptMethod, out key2, out key3))
|
||||
return false;
|
||||
if (!findKey4(decryptMethod, out key4))
|
||||
if (!FindKey4(decryptMethod, out key4))
|
||||
return false;
|
||||
if (!findKey5(decryptMethod, out key5))
|
||||
if (!FindKey5(decryptMethod, out key5))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findKey1_v17(MethodDef method, out uint key) {
|
||||
static bool FindKey1_v17(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
var stloc = instrs[i];
|
||||
|
@ -103,14 +103,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool findKey4(MethodDef method, out uint key) {
|
||||
bool FindKey4(MethodDef method, out uint key) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r74708_normal:
|
||||
case ConfuserVersion.v17_r74788_normal:
|
||||
case ConfuserVersion.v17_r74816_normal:
|
||||
case ConfuserVersion.v17_r75056_normal:
|
||||
case ConfuserVersion.v18_r75257_normal:
|
||||
return findKey4_normal(method, out key);
|
||||
return FindKey4_normal(method, out key);
|
||||
case ConfuserVersion.v17_r74708_dynamic:
|
||||
case ConfuserVersion.v17_r74708_native:
|
||||
case ConfuserVersion.v17_r74788_dynamic:
|
||||
|
@ -121,13 +121,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
case ConfuserVersion.v17_r75056_native:
|
||||
case ConfuserVersion.v18_r75257_dynamic:
|
||||
case ConfuserVersion.v18_r75257_native:
|
||||
return findKey4_other(method, out key);
|
||||
return FindKey4_other(method, out key);
|
||||
default:
|
||||
throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
static bool findKey4_normal(MethodDef method, out uint key) {
|
||||
static bool FindKey4_normal(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (!instrs[i].IsLdloc())
|
||||
|
@ -151,10 +151,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey4_other(MethodDef method, out uint key) {
|
||||
static bool FindKey4_other(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index + 1 >= instrs.Count)
|
||||
|
@ -170,7 +170,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool findKey5(MethodDef method, out uint key) {
|
||||
bool FindKey5(MethodDef method, out uint key) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r74788_normal:
|
||||
case ConfuserVersion.v17_r74788_dynamic:
|
||||
|
@ -184,17 +184,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
case ConfuserVersion.v18_r75257_normal:
|
||||
case ConfuserVersion.v18_r75257_dynamic:
|
||||
case ConfuserVersion.v18_r75257_native:
|
||||
return findKey5_v17_r74788(method, out key);
|
||||
return FindKey5_v17_r74788(method, out key);
|
||||
default:
|
||||
key = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool findKey5_v17_r74788(MethodDef method, out uint key) {
|
||||
static bool FindKey5_v17_r74788(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.Assembly::GetModule(System.String)");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.Assembly::GetModule(System.String)");
|
||||
if (i < 0)
|
||||
break;
|
||||
if (i + 1 >= instrs.Count)
|
||||
|
@ -225,64 +225,64 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.Byte[]",
|
||||
"System.Int32",
|
||||
};
|
||||
public void find() {
|
||||
var cctor = DotNetUtils.getModuleTypeCctor(module);
|
||||
public void Find() {
|
||||
var cctor = DotNetUtils.GetModuleTypeCctor(module);
|
||||
if (cctor == null)
|
||||
return;
|
||||
if (!new LocalTypes(cctor).all(requiredLocalsCctor))
|
||||
if (!new LocalTypes(cctor).All(requiredLocalsCctor))
|
||||
return;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(cctor, true);
|
||||
if (!add(ConstantsDecrypterUtils.findDictField(cctor, cctor.DeclaringType)))
|
||||
simpleDeobfuscator.Deobfuscate(cctor, true);
|
||||
if (!Add(ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType)))
|
||||
return;
|
||||
if (!add(ConstantsDecrypterUtils.findStreamField(cctor, cctor.DeclaringType)))
|
||||
if (!Add(ConstantsDecrypterUtils.FindStreamField(cctor, cctor.DeclaringType)))
|
||||
return;
|
||||
|
||||
var method = getDecryptMethod();
|
||||
var method = GetDecryptMethod();
|
||||
if (method == null)
|
||||
return;
|
||||
|
||||
resourceName = getResourceName(cctor);
|
||||
resourceName = GetResourceName(cctor);
|
||||
|
||||
if (resourceName != null) {
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
keyArraySize = getKeyArraySize(method);
|
||||
simpleDeobfuscator.Deobfuscate(method);
|
||||
keyArraySize = GetKeyArraySize(method);
|
||||
if (keyArraySize == 8)
|
||||
initVersion(method, ConfuserVersion.v17_r75056_normal, ConfuserVersion.v17_r75056_dynamic, ConfuserVersion.v17_r75056_native);
|
||||
InitVersion(method, ConfuserVersion.v17_r75056_normal, ConfuserVersion.v17_r75056_dynamic, ConfuserVersion.v17_r75056_native);
|
||||
else if (keyArraySize == 16)
|
||||
initVersion(method, ConfuserVersion.v18_r75257_normal, ConfuserVersion.v18_r75257_dynamic, ConfuserVersion.v18_r75257_native);
|
||||
InitVersion(method, ConfuserVersion.v18_r75257_normal, ConfuserVersion.v18_r75257_dynamic, ConfuserVersion.v18_r75257_native);
|
||||
else
|
||||
return;
|
||||
}
|
||||
else if (DotNetUtils.callsMethod(method, "System.String System.Reflection.Module::get_ScopeName()"))
|
||||
initVersion(method, ConfuserVersion.v17_r74816_normal, ConfuserVersion.v17_r74816_dynamic, ConfuserVersion.v17_r74816_native);
|
||||
else if (DotNetUtils.callsMethod(method, "System.Reflection.Module System.Reflection.Assembly::GetModule(System.String)"))
|
||||
initVersion(method, ConfuserVersion.v17_r74788_normal, ConfuserVersion.v17_r74788_dynamic, ConfuserVersion.v17_r74788_native);
|
||||
else if (DotNetUtils.CallsMethod(method, "System.String System.Reflection.Module::get_ScopeName()"))
|
||||
InitVersion(method, ConfuserVersion.v17_r74816_normal, ConfuserVersion.v17_r74816_dynamic, ConfuserVersion.v17_r74816_native);
|
||||
else if (DotNetUtils.CallsMethod(method, "System.Reflection.Module System.Reflection.Assembly::GetModule(System.String)"))
|
||||
InitVersion(method, ConfuserVersion.v17_r74788_normal, ConfuserVersion.v17_r74788_dynamic, ConfuserVersion.v17_r74788_native);
|
||||
else
|
||||
initVersion(method, ConfuserVersion.v17_r74708_normal, ConfuserVersion.v17_r74708_dynamic, ConfuserVersion.v17_r74708_native);
|
||||
InitVersion(method, ConfuserVersion.v17_r74708_normal, ConfuserVersion.v17_r74708_dynamic, ConfuserVersion.v17_r74708_native);
|
||||
|
||||
initMethod = cctor;
|
||||
}
|
||||
|
||||
void initVersion(MethodDef method, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
if (DeobUtils.hasInteger(method, 0x100) &&
|
||||
DeobUtils.hasInteger(method, 0x10000) &&
|
||||
DeobUtils.hasInteger(method, 0xFFFF))
|
||||
void InitVersion(MethodDef method, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
if (DeobUtils.HasInteger(method, 0x100) &&
|
||||
DeobUtils.HasInteger(method, 0x10000) &&
|
||||
DeobUtils.HasInteger(method, 0xFFFF))
|
||||
version = normal;
|
||||
else if ((nativeMethod = findNativeMethod(method)) == null)
|
||||
else if ((nativeMethod = FindNativeMethod(method)) == null)
|
||||
version = dynamic;
|
||||
else
|
||||
version = native;
|
||||
}
|
||||
|
||||
MethodDef getDecryptMethod() {
|
||||
MethodDef GetDecryptMethod() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.Attributes != (TypeAttributes.Abstract | TypeAttributes.Sealed))
|
||||
continue;
|
||||
if (!checkMethods(type.Methods))
|
||||
if (!CheckMethods(type.Methods))
|
||||
continue;
|
||||
foreach (var method in type.Methods) {
|
||||
if (!DotNetUtils.isMethod(method, "System.Object", "(System.UInt32,System.UInt32)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Object", "(System.UInt32,System.UInt32)"))
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -291,9 +291,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected override byte[] decryptData(DecrypterInfo info2, MethodDef caller, object[] args, out byte typeCode) {
|
||||
protected override byte[] DecryptData(DecrypterInfo info2, MethodDef caller, object[] args, out byte typeCode) {
|
||||
var info = (DecrypterInfoV17)info2;
|
||||
uint offs = info.calcHash(info2.decryptMethod.MDToken.ToUInt32() ^ (info2.decryptMethod.DeclaringType.MDToken.ToUInt32() * (uint)args[0])) ^ (uint)args[1];
|
||||
uint offs = info.CalcHash(info2.decryptMethod.MDToken.ToUInt32() ^ (info2.decryptMethod.DeclaringType.MDToken.ToUInt32() * (uint)args[0])) ^ (uint)args[1];
|
||||
reader.Position = offs;
|
||||
typeCode = reader.ReadByte();
|
||||
if (typeCode != info.int32Type && typeCode != info.int64Type &&
|
||||
|
@ -302,100 +302,100 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Invalid type code");
|
||||
|
||||
var encrypted = reader.ReadBytes(reader.ReadInt32());
|
||||
return decryptConstant(info, encrypted, offs, typeCode);
|
||||
return DecryptConstant(info, encrypted, offs, typeCode);
|
||||
}
|
||||
|
||||
byte[] decryptConstant(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
byte[] DecryptConstant(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
switch (info.version) {
|
||||
case ConfuserVersion.v17_r74708_normal: return decryptConstant_v17_r74708_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74708_dynamic: return decryptConstant_v17_r74708_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74708_native: return decryptConstant_v17_r74708_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74788_normal: return decryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74788_dynamic: return decryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74788_native: return decryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74816_normal: return decryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74816_dynamic: return decryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74816_native: return decryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r75056_normal: return decryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r75056_dynamic: return decryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r75056_native: return decryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v18_r75257_normal: return decryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v18_r75257_dynamic: return decryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v18_r75257_native: return decryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74708_normal: return DecryptConstant_v17_r74708_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74708_dynamic: return DecryptConstant_v17_r74708_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74708_native: return DecryptConstant_v17_r74708_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74788_normal: return DecryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74788_dynamic: return DecryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74788_native: return DecryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74816_normal: return DecryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74816_dynamic: return DecryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r74816_native: return DecryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r75056_normal: return DecryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r75056_dynamic: return DecryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v17_r75056_native: return DecryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v18_r75257_normal: return DecryptConstant_v17_r74788_normal(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v18_r75257_dynamic: return DecryptConstant_v17_r74788_dynamic(info, encrypted, offs, typeCode);
|
||||
case ConfuserVersion.v18_r75257_native: return DecryptConstant_v17_r74788_native(info, encrypted, offs, typeCode);
|
||||
default:
|
||||
throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r74708_normal(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return ConfuserUtils.decrypt(info.key4 * (offs + typeCode), encrypted);
|
||||
byte[] DecryptConstant_v17_r74708_normal(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return ConfuserUtils.Decrypt(info.key4 * (offs + typeCode), encrypted);
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r74708_dynamic(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, info.key4);
|
||||
byte[] DecryptConstant_v17_r74708_dynamic(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, info.key4);
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r74708_native(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return decryptConstant_v17_r73764_native(info, encrypted, offs, info.key4);
|
||||
byte[] DecryptConstant_v17_r74708_native(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return DecryptConstant_v17_r73764_native(info, encrypted, offs, info.key4);
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r74788_normal(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return ConfuserUtils.decrypt(info.key4 * (offs + typeCode), encrypted, getKey_v17_r74788(info));
|
||||
byte[] DecryptConstant_v17_r74788_normal(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return ConfuserUtils.Decrypt(info.key4 * (offs + typeCode), encrypted, GetKey_v17_r74788(info));
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r74788_dynamic(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return decryptConstant_v17_r73740_dynamic(info, encrypted, offs, info.key4, getKey_v17_r74788(info));
|
||||
byte[] DecryptConstant_v17_r74788_dynamic(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return DecryptConstant_v17_r73740_dynamic(info, encrypted, offs, info.key4, GetKey_v17_r74788(info));
|
||||
}
|
||||
|
||||
byte[] decryptConstant_v17_r74788_native(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return decryptConstant_v17_r73764_native(info, encrypted, offs, info.key4, getKey_v17_r74788(info));
|
||||
byte[] DecryptConstant_v17_r74788_native(DecrypterInfoV17 info, byte[] encrypted, uint offs, byte typeCode) {
|
||||
return DecryptConstant_v17_r73764_native(info, encrypted, offs, info.key4, GetKey_v17_r74788(info));
|
||||
}
|
||||
|
||||
byte[] getKey_v17_r74788(DecrypterInfoV17 info) {
|
||||
byte[] GetKey_v17_r74788(DecrypterInfoV17 info) {
|
||||
var key = module.ReadBlob(info.decryptMethod.MDToken.ToUInt32() ^ info.key5);
|
||||
if (key.Length != keyArraySize)
|
||||
throw new ApplicationException("Invalid key size");
|
||||
return key;
|
||||
}
|
||||
|
||||
public override void initialize() {
|
||||
public override void Initialize() {
|
||||
if (resourceName != null)
|
||||
resource = DotNetUtils.getResource(module, resourceName) as EmbeddedResource;
|
||||
resource = DotNetUtils.GetResource(module, resourceName) as EmbeddedResource;
|
||||
else
|
||||
resource = findResource(initMethod);
|
||||
resource = FindResource(initMethod);
|
||||
if (resource == null)
|
||||
throw new ApplicationException("Could not find encrypted consts resource");
|
||||
|
||||
findDecrypterInfos();
|
||||
initializeDecrypterInfos();
|
||||
FindDecrypterInfos();
|
||||
InitializeDecrypterInfos();
|
||||
|
||||
setConstantsData(DeobUtils.inflate(resource.GetResourceData(), true));
|
||||
SetConstantsData(DeobUtils.Inflate(resource.GetResourceData(), true));
|
||||
}
|
||||
|
||||
void findDecrypterInfos() {
|
||||
void FindDecrypterInfos() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.Attributes != (TypeAttributes.Abstract | TypeAttributes.Sealed))
|
||||
continue;
|
||||
if (!checkMethods(type.Methods))
|
||||
if (!CheckMethods(type.Methods))
|
||||
continue;
|
||||
foreach (var method in type.Methods) {
|
||||
if (!DotNetUtils.isMethod(method, "System.Object", "(System.UInt32,System.UInt32)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Object", "(System.UInt32,System.UInt32)"))
|
||||
continue;
|
||||
|
||||
var info = new DecrypterInfoV17(version, method);
|
||||
add(info);
|
||||
Add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool checkMethods(IEnumerable<MethodDef> methods) {
|
||||
static bool CheckMethods(IEnumerable<MethodDef> methods) {
|
||||
int numMethods = 0;
|
||||
foreach (var method in methods) {
|
||||
if (method.Name == ".ctor" || method.Name == ".cctor")
|
||||
return false;
|
||||
if (method.Attributes != (MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.CompilerControlled))
|
||||
return false;
|
||||
if (!DotNetUtils.isMethod(method, "System.Object", "(System.UInt32,System.UInt32)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Object", "(System.UInt32,System.UInt32)"))
|
||||
return false;
|
||||
|
||||
numMethods++;
|
||||
|
@ -403,10 +403,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return numMethods > 0;
|
||||
}
|
||||
|
||||
static string getResourceName(MethodDef method) {
|
||||
static string GetResourceName(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
if (i < 0)
|
||||
break;
|
||||
if (i == 0)
|
||||
|
@ -419,7 +419,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static int getKeyArraySize(MethodDef method) {
|
||||
static int GetKeyArraySize(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (!instrs[i].IsLdloc())
|
||||
|
@ -439,7 +439,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public override bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public override bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -65,28 +65,28 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.version = version;
|
||||
}
|
||||
|
||||
public string decryptString(uint magic1, ulong magic2) {
|
||||
return Encoding.UTF8.GetString(decrypt(magic1, magic2));
|
||||
public string DecryptString(uint magic1, ulong magic2) {
|
||||
return Encoding.UTF8.GetString(Decrypt(magic1, magic2));
|
||||
}
|
||||
|
||||
public int decryptInt32(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToInt32(decrypt(magic1, magic2), 0);
|
||||
public int DecryptInt32(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToInt32(Decrypt(magic1, magic2), 0);
|
||||
}
|
||||
|
||||
public long decryptInt64(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToInt64(decrypt(magic1, magic2), 0);
|
||||
public long DecryptInt64(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToInt64(Decrypt(magic1, magic2), 0);
|
||||
}
|
||||
|
||||
public float decryptSingle(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToSingle(decrypt(magic1, magic2), 0);
|
||||
public float DecryptSingle(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToSingle(Decrypt(magic1, magic2), 0);
|
||||
}
|
||||
|
||||
public double decryptDouble(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToDouble(decrypt(magic1, magic2), 0);
|
||||
public double DecryptDouble(uint magic1, ulong magic2) {
|
||||
return BitConverter.ToDouble(Decrypt(magic1, magic2), 0);
|
||||
}
|
||||
|
||||
byte[] decrypt(uint magic1, ulong magic2) {
|
||||
ulong info = hash(method.DeclaringType.MDToken.ToUInt32() * magic1) ^ magic2;
|
||||
byte[] Decrypt(uint magic1, ulong magic2) {
|
||||
ulong info = Hash(method.DeclaringType.MDToken.ToUInt32() * magic1) ^ magic2;
|
||||
int offset = (int)(info >> 32);
|
||||
int len = (int)info;
|
||||
var decrypted = new byte[len];
|
||||
|
@ -96,22 +96,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decrypted;
|
||||
}
|
||||
|
||||
ulong hash(uint magic) {
|
||||
ulong Hash(uint magic) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v18_r75367_normal:
|
||||
case ConfuserVersion.v18_r75367_dynamic:
|
||||
case ConfuserVersion.v18_r75367_native:
|
||||
return hash1(key0l ^ magic);
|
||||
return Hash1(key0l ^ magic);
|
||||
case ConfuserVersion.v18_r75369_normal:
|
||||
case ConfuserVersion.v18_r75369_dynamic:
|
||||
case ConfuserVersion.v18_r75369_native:
|
||||
return hash1(key0l * magic);
|
||||
return Hash1(key0l * magic);
|
||||
default:
|
||||
throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
ulong hash1(ulong h0) {
|
||||
ulong Hash1(ulong h0) {
|
||||
ulong h1 = key1l;
|
||||
ulong h2 = key2l;
|
||||
h1 *= h0;
|
||||
|
@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public IEnumerable<TypeDef> Types {
|
||||
get {
|
||||
var types = new List<TypeDef>();
|
||||
foreach (var info in decrypters.getValues())
|
||||
foreach (var info in decrypters.GetValues())
|
||||
types.Add(info.method.DeclaringType);
|
||||
return types;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
public IEnumerable<DecrypterInfo> Decrypters {
|
||||
get { return decrypters.getValues(); }
|
||||
get { return decrypters.GetValues(); }
|
||||
}
|
||||
|
||||
public bool Detected {
|
||||
|
@ -169,78 +169,78 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
}
|
||||
|
||||
public void find() {
|
||||
var cctor = DotNetUtils.getModuleTypeCctor(module);
|
||||
public void Find() {
|
||||
var cctor = DotNetUtils.GetModuleTypeCctor(module);
|
||||
if (cctor == null)
|
||||
return;
|
||||
simpleDeobfuscator.deobfuscate(cctor, true);
|
||||
simpleDeobfuscator.Deobfuscate(cctor, true);
|
||||
|
||||
if ((dictField = ConstantsDecrypterUtils.findDictField(cctor, cctor.DeclaringType)) == null)
|
||||
if ((dictField = ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType)) == null)
|
||||
return;
|
||||
if ((dataField = ConstantsDecrypterUtils.findDataField(cctor, cctor.DeclaringType)) == null)
|
||||
if ((dataField = ConstantsDecrypterUtils.FindDataField(cctor, cctor.DeclaringType)) == null)
|
||||
return;
|
||||
|
||||
nativeMethod = findNativeMethod(cctor, cctor.DeclaringType);
|
||||
nativeMethod = FindNativeMethod(cctor, cctor.DeclaringType);
|
||||
|
||||
var method = getDecryptMethod();
|
||||
var method = GetDecryptMethod();
|
||||
if (method == null)
|
||||
return;
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
simpleDeobfuscator.Deobfuscate(method);
|
||||
var info = new DecrypterInfo(this, method, ConfuserVersion.Unknown);
|
||||
if (findKeys_v18_r75367(info))
|
||||
initVersion(cctor, ConfuserVersion.v18_r75367_normal, ConfuserVersion.v18_r75367_dynamic, ConfuserVersion.v18_r75367_native);
|
||||
else if (findKeys_v18_r75369(info))
|
||||
initVersion(cctor, ConfuserVersion.v18_r75369_normal, ConfuserVersion.v18_r75369_dynamic, ConfuserVersion.v18_r75369_native);
|
||||
if (FindKeys_v18_r75367(info))
|
||||
InitVersion(cctor, ConfuserVersion.v18_r75367_normal, ConfuserVersion.v18_r75367_dynamic, ConfuserVersion.v18_r75367_native);
|
||||
else if (FindKeys_v18_r75369(info))
|
||||
InitVersion(cctor, ConfuserVersion.v18_r75369_normal, ConfuserVersion.v18_r75369_dynamic, ConfuserVersion.v18_r75369_native);
|
||||
else
|
||||
return;
|
||||
|
||||
installMethod = cctor;
|
||||
}
|
||||
|
||||
void initVersion(MethodDef installMethod, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
void InitVersion(MethodDef installMethod, ConfuserVersion normal, ConfuserVersion dynamic, ConfuserVersion native) {
|
||||
if (nativeMethod != null)
|
||||
version = native;
|
||||
else if (DeobUtils.hasInteger(installMethod, 0x10000))
|
||||
else if (DeobUtils.HasInteger(installMethod, 0x10000))
|
||||
version = normal;
|
||||
else
|
||||
version = dynamic;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
public void Initialize() {
|
||||
if (installMethod == null)
|
||||
return;
|
||||
|
||||
if (!findKeys())
|
||||
if (!FindKeys())
|
||||
throw new ApplicationException("Could not find keys");
|
||||
|
||||
if ((resource = findResource(key0)) == null)
|
||||
if ((resource = FindResource(key0)) == null)
|
||||
throw new ApplicationException("Could not find resource");
|
||||
constants = decryptResource(resource.GetResourceData());
|
||||
constants = DecryptResource(resource.GetResourceData());
|
||||
|
||||
findDecrypters();
|
||||
FindDecrypters();
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(uint magic) {
|
||||
EmbeddedResource FindResource(uint magic) {
|
||||
var name = Encoding.UTF8.GetString(BitConverter.GetBytes(magic));
|
||||
return DotNetUtils.getResource(module, name) as EmbeddedResource;
|
||||
return DotNetUtils.GetResource(module, name) as EmbeddedResource;
|
||||
}
|
||||
|
||||
bool findKeys() {
|
||||
if (!findKey0(installMethod, out key0))
|
||||
bool FindKeys() {
|
||||
if (!FindKey0(installMethod, out key0))
|
||||
return false;
|
||||
if (!findKey0d(installMethod, out key0d))
|
||||
if (!FindKey0d(installMethod, out key0d))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findKey0(MethodDef method, out uint key) {
|
||||
static bool FindKey0(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Text.Encoding System.Text.Encoding::get_UTF8()");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Call, "System.Text.Encoding System.Text.Encoding::get_UTF8()");
|
||||
if (index < 0)
|
||||
break;
|
||||
int index2 = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
int index2 = ConfuserUtils.FindCallMethod(instrs, i, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
if (index2 - index != 2)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
|
@ -255,13 +255,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0d(MethodDef method, out uint key) {
|
||||
static bool FindKey0d(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
if (index < 0)
|
||||
break;
|
||||
int index2 = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
int index2 = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
if (index2 - index != 3)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
|
@ -278,7 +278,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static MethodDef findNativeMethod(MethodDef method, TypeDef declaringType) {
|
||||
static MethodDef FindNativeMethod(MethodDef method, TypeDef declaringType) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
if (!instrs[i].IsLdloc())
|
||||
|
@ -289,7 +289,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null || !calledMethod.IsStatic || !calledMethod.IsNative)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||
if (!DotNetUtils.IsMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||
continue;
|
||||
|
||||
return calledMethod;
|
||||
|
@ -297,26 +297,26 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
MethodDef getDecryptMethod() {
|
||||
MethodDef GetDecryptMethod() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.Attributes != (TypeAttributes.Abstract | TypeAttributes.Sealed))
|
||||
continue;
|
||||
if (!checkMethods(type.Methods))
|
||||
if (!CheckMethods(type.Methods))
|
||||
continue;
|
||||
foreach (var method in type.Methods) {
|
||||
if (isDecryptMethodSignature(method))
|
||||
if (IsDecryptMethodSignature(method))
|
||||
return method;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool checkMethods(IEnumerable<MethodDef> methods) {
|
||||
static bool CheckMethods(IEnumerable<MethodDef> methods) {
|
||||
int numMethods = 0;
|
||||
foreach (var method in methods) {
|
||||
if (method.Name == ".ctor" || method.Name == ".cctor")
|
||||
return false;
|
||||
if (!isDecryptMethodSignature(method))
|
||||
if (!IsDecryptMethodSignature(method))
|
||||
return false;
|
||||
|
||||
numMethods++;
|
||||
|
@ -324,7 +324,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return numMethods > 0;
|
||||
}
|
||||
|
||||
static bool isDecryptMethodSignature(MethodDef method) {
|
||||
static bool IsDecryptMethodSignature(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
if (method.Attributes != (MethodAttributes.Static | MethodAttributes.HideBySig | MethodAttributes.CompilerControlled))
|
||||
|
@ -345,68 +345,68 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
void findDecrypters() {
|
||||
void FindDecrypters() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.Attributes != (TypeAttributes.Abstract | TypeAttributes.Sealed))
|
||||
continue;
|
||||
if (!checkMethods(type.Methods))
|
||||
if (!CheckMethods(type.Methods))
|
||||
continue;
|
||||
foreach (var method in type.Methods) {
|
||||
var info = createDecrypterInfo(method);
|
||||
var info = CreateDecrypterInfo(method);
|
||||
if (info != null)
|
||||
decrypters.add(info.method, info);
|
||||
decrypters.Add(info.method, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecrypterInfo createDecrypterInfo(MethodDef method) {
|
||||
if (!isDecryptMethodSignature(method))
|
||||
DecrypterInfo CreateDecrypterInfo(MethodDef method) {
|
||||
if (!IsDecryptMethodSignature(method))
|
||||
return null;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
simpleDeobfuscator.Deobfuscate(method);
|
||||
var info = new DecrypterInfo(this, method, version);
|
||||
if (!findKeys(info))
|
||||
if (!FindKeys(info))
|
||||
return null;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
bool findKeys(DecrypterInfo info) {
|
||||
bool FindKeys(DecrypterInfo info) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v18_r75367_normal:
|
||||
case ConfuserVersion.v18_r75367_dynamic:
|
||||
case ConfuserVersion.v18_r75367_native:
|
||||
return findKeys_v18_r75367(info);
|
||||
return FindKeys_v18_r75367(info);
|
||||
case ConfuserVersion.v18_r75369_normal:
|
||||
case ConfuserVersion.v18_r75369_dynamic:
|
||||
case ConfuserVersion.v18_r75369_native:
|
||||
return findKeys_v18_r75369(info);
|
||||
return FindKeys_v18_r75369(info);
|
||||
default:
|
||||
throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
static bool findKeys_v18_r75367(DecrypterInfo info) {
|
||||
if (!findLKeys_v18_r75367(info))
|
||||
static bool FindKeys_v18_r75367(DecrypterInfo info) {
|
||||
if (!FindLKeys_v18_r75367(info))
|
||||
return false;
|
||||
if (!findKey0_v18_r75367(info))
|
||||
if (!FindKey0_v18_r75367(info))
|
||||
return false;
|
||||
if (!findKey0d_v18_r75367(info))
|
||||
if (!FindKey0d_v18_r75367(info))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findKeys_v18_r75369(DecrypterInfo info) {
|
||||
if (!findLKeys_v18_r75369(info))
|
||||
static bool FindKeys_v18_r75369(DecrypterInfo info) {
|
||||
if (!FindLKeys_v18_r75369(info))
|
||||
return false;
|
||||
if (!findKey0_v18_r75369(info))
|
||||
if (!FindKey0_v18_r75369(info))
|
||||
return false;
|
||||
if (!findKey0d_v18_r75367(info))
|
||||
if (!FindKey0d_v18_r75367(info))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findLKeys_v18_r75367(DecrypterInfo info) {
|
||||
static bool FindLKeys_v18_r75367(DecrypterInfo info) {
|
||||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 10; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
|
@ -443,7 +443,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v18_r75367(DecrypterInfo info) {
|
||||
static bool FindKey0_v18_r75367(DecrypterInfo info) {
|
||||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Xor)
|
||||
|
@ -464,13 +464,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0d_v18_r75367(DecrypterInfo info) {
|
||||
static bool FindKey0d_v18_r75367(DecrypterInfo info) {
|
||||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.Reflection.MemberInfo::get_MetadataToken()");
|
||||
if (index < 0)
|
||||
break;
|
||||
int index2 = ConfuserUtils.findCallMethod(instrs, index, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
int index2 = ConfuserUtils.FindCallMethod(instrs, index, Code.Call, "System.Byte[] System.BitConverter::GetBytes(System.Int32)");
|
||||
if (index2 < 0)
|
||||
break;
|
||||
if (index2 - index != 3)
|
||||
|
@ -487,7 +487,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findLKeys_v18_r75369(DecrypterInfo info) {
|
||||
static bool FindLKeys_v18_r75369(DecrypterInfo info) {
|
||||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 8; i++) {
|
||||
var ldci8_1 = instrs[i];
|
||||
|
@ -520,7 +520,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v18_r75369(DecrypterInfo info) {
|
||||
static bool FindKey0_v18_r75369(DecrypterInfo info) {
|
||||
var instrs = info.method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (!instrs[i].IsLdloc())
|
||||
|
@ -541,36 +541,36 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
byte[] decryptResource(byte[] encrypted) {
|
||||
byte[] DecryptResource(byte[] encrypted) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v18_r75367_normal:
|
||||
case ConfuserVersion.v18_r75369_normal:
|
||||
return decryptResource_v18_r75367_normal(encrypted);
|
||||
return DecryptResource_v18_r75367_normal(encrypted);
|
||||
|
||||
case ConfuserVersion.v18_r75367_dynamic:
|
||||
case ConfuserVersion.v18_r75369_dynamic:
|
||||
return decryptResource_v18_r75367_dynamic(encrypted);
|
||||
return DecryptResource_v18_r75367_dynamic(encrypted);
|
||||
|
||||
case ConfuserVersion.v18_r75367_native:
|
||||
case ConfuserVersion.v18_r75369_native:
|
||||
return decryptResource_v18_r75367_native(encrypted);
|
||||
return DecryptResource_v18_r75367_native(encrypted);
|
||||
|
||||
default:
|
||||
throw new ApplicationException("Unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] getSigKey() {
|
||||
byte[] GetSigKey() {
|
||||
return module.ReadBlob(key0d ^ installMethod.MDToken.ToUInt32());
|
||||
}
|
||||
|
||||
byte[] decryptResource_v18_r75367_normal(byte[] encrypted) {
|
||||
var key = getSigKey();
|
||||
var decrypted = ConfuserUtils.decrypt(BitConverter.ToUInt32(key, 12) * (uint)key0, encrypted);
|
||||
return DeobUtils.inflate(DeobUtils.aesDecrypt(decrypted, key, DeobUtils.md5Sum(key)), true);
|
||||
byte[] DecryptResource_v18_r75367_normal(byte[] encrypted) {
|
||||
var key = GetSigKey();
|
||||
var decrypted = ConfuserUtils.Decrypt(BitConverter.ToUInt32(key, 12) * (uint)key0, encrypted);
|
||||
return DeobUtils.Inflate(DeobUtils.AesDecrypt(decrypted, key, DeobUtils.Md5Sum(key)), true);
|
||||
}
|
||||
|
||||
static int getDynamicStartIndex(IList<Instruction> instrs, int ldlocIndex) {
|
||||
static int GetDynamicStartIndex(IList<Instruction> instrs, int ldlocIndex) {
|
||||
for (int i = ldlocIndex - 1; i >= 0; i--) {
|
||||
if (instrs[i].OpCode.FlowControl != FlowControl.Next)
|
||||
return i + 1;
|
||||
|
@ -578,7 +578,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int getDynamicEndIndex(int startIndex, Local local) {
|
||||
int GetDynamicEndIndex(int startIndex, Local local) {
|
||||
if (startIndex < 0)
|
||||
return -1;
|
||||
var instrs = installMethod.Body.Instructions;
|
||||
|
@ -590,10 +590,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
Local getDynamicLocal(out int instrIndex) {
|
||||
Local GetDynamicLocal(out int instrIndex) {
|
||||
var instrs = installMethod.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Void System.IO.BinaryWriter::Write(System.Byte)");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Void System.IO.BinaryWriter::Write(System.Byte)");
|
||||
if (i < 0)
|
||||
break;
|
||||
int index = i - 2;
|
||||
|
@ -612,24 +612,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
byte[] decryptResource_v18_r75367_dynamic(byte[] encrypted) {
|
||||
byte[] DecryptResource_v18_r75367_dynamic(byte[] encrypted) {
|
||||
int ldlocIndex;
|
||||
var local = getDynamicLocal(out ldlocIndex);
|
||||
var local = GetDynamicLocal(out ldlocIndex);
|
||||
if (local == null)
|
||||
throw new ApplicationException("Could not find local");
|
||||
|
||||
var instrs = installMethod.Body.Instructions;
|
||||
int startIndex = getDynamicStartIndex(instrs, ldlocIndex);
|
||||
int endIndex = getDynamicEndIndex(startIndex, local);
|
||||
int startIndex = GetDynamicStartIndex(instrs, ldlocIndex);
|
||||
int endIndex = GetDynamicEndIndex(startIndex, local);
|
||||
if (endIndex < 0)
|
||||
throw new ApplicationException("Could not find endIndex");
|
||||
|
||||
var constReader = new ConstantsReader(installMethod);
|
||||
|
||||
return decryptResource(encrypted, magic => {
|
||||
constReader.setConstantInt32(local, magic);
|
||||
return DecryptResource(encrypted, magic => {
|
||||
constReader.SetConstantInt32(local, magic);
|
||||
int index = startIndex, result;
|
||||
if (!constReader.getNextInt32(ref index, out result))
|
||||
if (!constReader.GetNextInt32(ref index, out result))
|
||||
throw new ApplicationException("Could not get constant");
|
||||
if (index != endIndex)
|
||||
throw new ApplicationException("Wrong constant");
|
||||
|
@ -637,16 +637,16 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
});
|
||||
}
|
||||
|
||||
byte[] decryptResource_v18_r75367_native(byte[] encrypted) {
|
||||
byte[] DecryptResource_v18_r75367_native(byte[] encrypted) {
|
||||
using (var x86Emu = new x86Emulator(fileData))
|
||||
return decryptResource(encrypted, magic => (byte)x86Emu.emulate((uint)nativeMethod.RVA, magic));
|
||||
return DecryptResource(encrypted, magic => (byte)x86Emu.Emulate((uint)nativeMethod.RVA, magic));
|
||||
}
|
||||
|
||||
byte[] decryptResource(byte[] encrypted, Func<uint, byte> decryptFunc) {
|
||||
var key = getSigKey();
|
||||
byte[] DecryptResource(byte[] encrypted, Func<uint, byte> decryptFunc) {
|
||||
var key = GetSigKey();
|
||||
|
||||
var decrypted = DeobUtils.aesDecrypt(encrypted, key, DeobUtils.md5Sum(key));
|
||||
decrypted = DeobUtils.inflate(decrypted, true);
|
||||
var decrypted = DeobUtils.AesDecrypt(encrypted, key, DeobUtils.Md5Sum(key));
|
||||
decrypted = DeobUtils.Inflate(decrypted, true);
|
||||
|
||||
var reader = MemoryImageStream.Create(decrypted);
|
||||
var result = new MemoryStream();
|
||||
|
@ -659,7 +659,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return result.ToArray();
|
||||
}
|
||||
|
||||
static bool verifyGenericArg(MethodSpec gim, ElementType etype) {
|
||||
static bool VerifyGenericArg(MethodSpec gim, ElementType etype) {
|
||||
if (gim == null)
|
||||
return false;
|
||||
var gims = gim.GenericInstMethodSig;
|
||||
|
@ -668,42 +668,42 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return gims.GenericArguments[0].GetElementType() == etype;
|
||||
}
|
||||
|
||||
public string decryptString(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.String))
|
||||
public string DecryptString(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!VerifyGenericArg(gim, ElementType.String))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptString(magic1, magic2);
|
||||
var info = decrypters.Find(method);
|
||||
return info.DecryptString(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptInt32(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.I4))
|
||||
public object DecryptInt32(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!VerifyGenericArg(gim, ElementType.I4))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptInt32(magic1, magic2);
|
||||
var info = decrypters.Find(method);
|
||||
return info.DecryptInt32(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptInt64(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.I8))
|
||||
public object DecryptInt64(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!VerifyGenericArg(gim, ElementType.I8))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptInt64(magic1, magic2);
|
||||
var info = decrypters.Find(method);
|
||||
return info.DecryptInt64(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptSingle(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.R4))
|
||||
public object DecryptSingle(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!VerifyGenericArg(gim, ElementType.R4))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptSingle(magic1, magic2);
|
||||
var info = decrypters.Find(method);
|
||||
return info.DecryptSingle(magic1, magic2);
|
||||
}
|
||||
|
||||
public object decryptDouble(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!verifyGenericArg(gim, ElementType.R8))
|
||||
public object DecryptDouble(MethodDef method, MethodSpec gim, uint magic1, ulong magic2) {
|
||||
if (!VerifyGenericArg(gim, ElementType.R8))
|
||||
return null;
|
||||
var info = decrypters.find(method);
|
||||
return info.decryptDouble(magic1, magic2);
|
||||
var info = decrypters.Find(method);
|
||||
return info.DecryptDouble(magic1, magic2);
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
public void CleanUp() {
|
||||
if (installMethod == null)
|
||||
return;
|
||||
|
||||
|
@ -712,7 +712,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
installMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -24,42 +24,42 @@ using de4dot.blocks.cflow;
|
|||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
class ConstantsFolder : BlockDeobfuscator {
|
||||
protected override bool deobfuscate(Block block) {
|
||||
protected override bool Deobfuscate(Block block) {
|
||||
bool modified = false;
|
||||
|
||||
var instrs = block.Instructions;
|
||||
var constantsReader = createConstantsReader(instrs);
|
||||
var constantsReader = CreateConstantsReader(instrs);
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = 0;
|
||||
Instruction newInstr = null;
|
||||
var instr = instrs[i];
|
||||
if (constantsReader.isLoadConstantInt32(instr.Instruction)) {
|
||||
if (constantsReader.IsLoadConstantInt32(instr.Instruction)) {
|
||||
index = i;
|
||||
int val;
|
||||
if (!constantsReader.getInt32(ref index, out val))
|
||||
if (!constantsReader.GetInt32(ref index, out val))
|
||||
continue;
|
||||
newInstr = Instruction.CreateLdcI4(val);
|
||||
}
|
||||
else if (constantsReader.isLoadConstantInt64(instr.Instruction)) {
|
||||
else if (constantsReader.IsLoadConstantInt64(instr.Instruction)) {
|
||||
index = i;
|
||||
long val;
|
||||
if (!constantsReader.getInt64(ref index, out val))
|
||||
if (!constantsReader.GetInt64(ref index, out val))
|
||||
continue;
|
||||
newInstr = Instruction.Create(OpCodes.Ldc_I8, val);
|
||||
}
|
||||
else if (constantsReader.isLoadConstantDouble(instr.Instruction)) {
|
||||
else if (constantsReader.IsLoadConstantDouble(instr.Instruction)) {
|
||||
index = i;
|
||||
double val;
|
||||
if (!constantsReader.getDouble(ref index, out val))
|
||||
if (!constantsReader.GetDouble(ref index, out val))
|
||||
continue;
|
||||
newInstr = Instruction.Create(OpCodes.Ldc_R8, val);
|
||||
}
|
||||
|
||||
if (newInstr != null && index - i > 1) {
|
||||
block.insert(index++, Instruction.Create(OpCodes.Pop));
|
||||
block.insert(index++, newInstr);
|
||||
block.Insert(index++, Instruction.Create(OpCodes.Pop));
|
||||
block.Insert(index++, newInstr);
|
||||
i = index - 1;
|
||||
constantsReader = createConstantsReader(instrs);
|
||||
constantsReader = CreateConstantsReader(instrs);
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -101,8 +101,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
}
|
||||
if (newInstr != null) {
|
||||
block.replace(i, 2, newInstr);
|
||||
constantsReader = createConstantsReader(instrs);
|
||||
block.Replace(i, 2, newInstr);
|
||||
constantsReader = CreateConstantsReader(instrs);
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return modified;
|
||||
}
|
||||
|
||||
static ConstantsReader createConstantsReader(IList<Instr> instrs) {
|
||||
static ConstantsReader CreateConstantsReader(IList<Instr> instrs) {
|
||||
return new ConstantsReader(instrs, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,17 +38,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.doubleValueInliner = doubleValueInliner;
|
||||
}
|
||||
|
||||
public void deobfuscateBegin(Blocks blocks) {
|
||||
public void DeobfuscateBegin(Blocks blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public bool deobfuscate(List<Block> allBlocks) {
|
||||
public bool Deobfuscate(List<Block> allBlocks) {
|
||||
bool modified = false;
|
||||
foreach (var block in allBlocks) {
|
||||
modified |= int32ValueInliner.decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= int64ValueInliner.decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= singleValueInliner.decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= doubleValueInliner.decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= int32ValueInliner.Decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= int64ValueInliner.Decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= singleValueInliner.Decrypt(blocks.Method, allBlocks) != 0;
|
||||
modified |= doubleValueInliner.Decrypt(blocks.Method, allBlocks) != 0;
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
public DeobfuscatorInfo()
|
||||
: base() {
|
||||
removeAntiDebug = new BoolOption(null, makeArgName("antidb"), "Remove anti debug code", true);
|
||||
removeAntiDump = new BoolOption(null, makeArgName("antidump"), "Remove anti dump code", true);
|
||||
decryptMainAsm = new BoolOption(null, makeArgName("decrypt-main"), "Decrypt main embedded assembly", true);
|
||||
removeAntiDebug = new BoolOption(null, MakeArgName("antidb"), "Remove anti debug code", true);
|
||||
removeAntiDump = new BoolOption(null, MakeArgName("antidump"), "Remove anti dump code", true);
|
||||
decryptMainAsm = new BoolOption(null, MakeArgName("decrypt-main"), "Decrypt main embedded assembly", true);
|
||||
}
|
||||
|
||||
public override string Name {
|
||||
|
@ -47,7 +47,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
get { return THE_TYPE; }
|
||||
}
|
||||
|
||||
public override IDeobfuscator createDeobfuscator() {
|
||||
public override IDeobfuscator CreateDeobfuscator() {
|
||||
return new Deobfuscator(new Deobfuscator.Options {
|
||||
ValidNameRegex = validNameRegex.get(),
|
||||
RemoveAntiDebug = removeAntiDebug.get(),
|
||||
|
@ -56,7 +56,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
});
|
||||
}
|
||||
|
||||
protected override IEnumerable<Option> getOptionsInternal() {
|
||||
protected override IEnumerable<Option> GetOptionsInternal() {
|
||||
return new List<Option>() {
|
||||
removeAntiDebug,
|
||||
removeAntiDump,
|
||||
|
@ -128,88 +128,88 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
StringFeatures = StringFeatures.AllowStaticDecryption | StringFeatures.AllowDynamicDecryption;
|
||||
}
|
||||
|
||||
protected override int detectInternal() {
|
||||
protected override int DetectInternal() {
|
||||
int val = 0;
|
||||
|
||||
int sum = toInt32(jitMethodsDecrypter != null ? jitMethodsDecrypter.Detected : false) +
|
||||
toInt32(memoryMethodsDecrypter != null ? memoryMethodsDecrypter.Detected : false) +
|
||||
toInt32(proxyCallFixer != null ? proxyCallFixer.Detected : false) +
|
||||
toInt32(antiDebugger != null ? antiDebugger.Detected : false) +
|
||||
toInt32(antiDumping != null ? antiDumping.Detected : false) +
|
||||
toInt32(resourceDecrypter != null ? resourceDecrypter.Detected : false) +
|
||||
toInt32(constantsDecrypterV18 != null ? constantsDecrypterV18.Detected : false) +
|
||||
toInt32(constantsDecrypterV15 != null ? constantsDecrypterV15.Detected : false) +
|
||||
toInt32(constantsDecrypterV17 != null ? constantsDecrypterV17.Detected : false) +
|
||||
toInt32(stringDecrypter != null ? stringDecrypter.Detected : false) +
|
||||
toInt32(unpacker != null ? unpacker.Detected : false);
|
||||
int sum = ToInt32(jitMethodsDecrypter != null ? jitMethodsDecrypter.Detected : false) +
|
||||
ToInt32(memoryMethodsDecrypter != null ? memoryMethodsDecrypter.Detected : false) +
|
||||
ToInt32(proxyCallFixer != null ? proxyCallFixer.Detected : false) +
|
||||
ToInt32(antiDebugger != null ? antiDebugger.Detected : false) +
|
||||
ToInt32(antiDumping != null ? antiDumping.Detected : false) +
|
||||
ToInt32(resourceDecrypter != null ? resourceDecrypter.Detected : false) +
|
||||
ToInt32(constantsDecrypterV18 != null ? constantsDecrypterV18.Detected : false) +
|
||||
ToInt32(constantsDecrypterV15 != null ? constantsDecrypterV15.Detected : false) +
|
||||
ToInt32(constantsDecrypterV17 != null ? constantsDecrypterV17.Detected : false) +
|
||||
ToInt32(stringDecrypter != null ? stringDecrypter.Detected : false) +
|
||||
ToInt32(unpacker != null ? unpacker.Detected : false);
|
||||
if (sum > 0)
|
||||
val += 100 + 10 * (sum - 1);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
protected override void scanForObfuscator() {
|
||||
removeObfuscatorAttribute();
|
||||
protected override void ScanForObfuscator() {
|
||||
RemoveObfuscatorAttribute();
|
||||
jitMethodsDecrypter = new JitMethodsDecrypter(module, DeobfuscatedFile);
|
||||
try {
|
||||
jitMethodsDecrypter.find();
|
||||
jitMethodsDecrypter.Find();
|
||||
}
|
||||
catch {
|
||||
}
|
||||
if (jitMethodsDecrypter.Detected) {
|
||||
initializeObfuscatorName();
|
||||
InitializeObfuscatorName();
|
||||
return;
|
||||
}
|
||||
memoryMethodsDecrypter = new MemoryMethodsDecrypter(module, DeobfuscatedFile);
|
||||
memoryMethodsDecrypter.find();
|
||||
memoryMethodsDecrypter.Find();
|
||||
if (memoryMethodsDecrypter.Detected) {
|
||||
initializeObfuscatorName();
|
||||
InitializeObfuscatorName();
|
||||
return;
|
||||
}
|
||||
initTheRest(null);
|
||||
InitializeTheRest(null);
|
||||
}
|
||||
|
||||
void initTheRest(Deobfuscator oldOne) {
|
||||
void InitializeTheRest(Deobfuscator oldOne) {
|
||||
resourceDecrypter = new ResourceDecrypter(module, DeobfuscatedFile);
|
||||
resourceDecrypter.find();
|
||||
resourceDecrypter.Find();
|
||||
|
||||
constantsDecrypterV18 = new ConstantsDecrypterV18(module, getFileData(), DeobfuscatedFile);
|
||||
constantsDecrypterV17 = new ConstantsDecrypterV17(module, getFileData(), DeobfuscatedFile);
|
||||
constantsDecrypterV15 = new ConstantsDecrypterV15(module, getFileData(), DeobfuscatedFile);
|
||||
constantsDecrypterV18 = new ConstantsDecrypterV18(module, GetFileData(), DeobfuscatedFile);
|
||||
constantsDecrypterV17 = new ConstantsDecrypterV17(module, GetFileData(), DeobfuscatedFile);
|
||||
constantsDecrypterV15 = new ConstantsDecrypterV15(module, GetFileData(), DeobfuscatedFile);
|
||||
do {
|
||||
constantsDecrypterV18.find();
|
||||
constantsDecrypterV18.Find();
|
||||
if (constantsDecrypterV18.Detected) {
|
||||
initializeConstantsDecrypterV18();
|
||||
InitializeConstantsDecrypterV18();
|
||||
break;
|
||||
}
|
||||
constantsDecrypterV17.find();
|
||||
constantsDecrypterV17.Find();
|
||||
if (constantsDecrypterV17.Detected) {
|
||||
initializeConstantsDecrypterV17();
|
||||
InitializeConstantsDecrypterV17();
|
||||
break;
|
||||
}
|
||||
constantsDecrypterV15.find();
|
||||
constantsDecrypterV15.Find();
|
||||
if (constantsDecrypterV15.Detected) {
|
||||
initializeConstantsDecrypterV15();
|
||||
InitializeConstantsDecrypterV15();
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
proxyCallFixer = new ProxyCallFixer(module, getFileData());
|
||||
proxyCallFixer.findDelegateCreator(DeobfuscatedFile);
|
||||
proxyCallFixer = new ProxyCallFixer(module, GetFileData());
|
||||
proxyCallFixer.FindDelegateCreator(DeobfuscatedFile);
|
||||
antiDebugger = new AntiDebugger(module);
|
||||
antiDebugger.find();
|
||||
antiDebugger.Find();
|
||||
antiDumping = new AntiDumping(module);
|
||||
antiDumping.find(DeobfuscatedFile);
|
||||
antiDumping.Find(DeobfuscatedFile);
|
||||
stringDecrypter = new StringDecrypter(module);
|
||||
stringDecrypter.find(DeobfuscatedFile);
|
||||
initializeStringDecrypter();
|
||||
stringDecrypter.Find(DeobfuscatedFile);
|
||||
InitializeStringDecrypter();
|
||||
unpacker = new Unpacker(module, oldOne == null ? null : oldOne.unpacker);
|
||||
unpacker.find(DeobfuscatedFile, this);
|
||||
initializeObfuscatorName();
|
||||
unpacker.Find(DeobfuscatedFile, this);
|
||||
InitializeObfuscatorName();
|
||||
}
|
||||
|
||||
void initializeObfuscatorName() {
|
||||
var versionString = getVersionString();
|
||||
void InitializeObfuscatorName() {
|
||||
var versionString = GetVersionString();
|
||||
if (string.IsNullOrEmpty(versionString))
|
||||
obfuscatorName = DeobfuscatorInfo.THE_NAME;
|
||||
else
|
||||
|
@ -217,7 +217,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
const bool useAttributeVersion = true;
|
||||
string getVersionString() {
|
||||
string GetVersionString() {
|
||||
var versionProviders = new IVersionProvider[] {
|
||||
jitMethodsDecrypter,
|
||||
memoryMethodsDecrypter,
|
||||
|
@ -237,23 +237,23 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (versionProvider == null)
|
||||
continue;
|
||||
int minRev, maxRev;
|
||||
if (versionProvider.getRevisionRange(out minRev, out maxRev)) {
|
||||
if (versionProvider.GetRevisionRange(out minRev, out maxRev)) {
|
||||
if (maxRev == int.MaxValue)
|
||||
Logger.v("r{0}-latest : {1}", minRev, versionProvider.GetType().Name);
|
||||
else
|
||||
Logger.v("r{0}-r{1} : {2}", minRev, maxRev, versionProvider.GetType().Name);
|
||||
vd.addRevs(minRev, maxRev);
|
||||
vd.AddRevs(minRev, maxRev);
|
||||
}
|
||||
}
|
||||
if (useAttributeVersion)
|
||||
vd.setVersion(approxVersion);
|
||||
return vd.getVersionString();
|
||||
vd.SetVersion(approxVersion);
|
||||
return vd.GetVersionString();
|
||||
}
|
||||
|
||||
byte[] getFileData() {
|
||||
byte[] GetFileData() {
|
||||
if (ModuleBytes != null)
|
||||
return ModuleBytes;
|
||||
return ModuleBytes = DeobUtils.readModule(module);
|
||||
return ModuleBytes = DeobUtils.ReadModule(module);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
@ -263,22 +263,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
DecryptState decryptState = DecryptState.CanDecryptMethods | DecryptState.CanUnpack;
|
||||
bool hasUnpacked = false;
|
||||
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) {
|
||||
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) {
|
||||
hasUnpacked = false;
|
||||
byte[] fileData = getFileData();
|
||||
byte[] fileData = GetFileData();
|
||||
|
||||
using (var peImage = new MyPEImage(fileData)) {
|
||||
if ((decryptState & DecryptState.CanDecryptMethods) != 0) {
|
||||
bool decrypted = false;
|
||||
if (jitMethodsDecrypter != null && jitMethodsDecrypter.Detected) {
|
||||
jitMethodsDecrypter.initialize();
|
||||
if (!jitMethodsDecrypter.decrypt(peImage, fileData, ref dumpedMethods))
|
||||
jitMethodsDecrypter.Initialize();
|
||||
if (!jitMethodsDecrypter.Decrypt(peImage, fileData, ref dumpedMethods))
|
||||
return false;
|
||||
decrypted = true;
|
||||
}
|
||||
else if (memoryMethodsDecrypter != null && memoryMethodsDecrypter.Detected) {
|
||||
memoryMethodsDecrypter.initialize();
|
||||
if (!memoryMethodsDecrypter.decrypt(peImage, fileData))
|
||||
memoryMethodsDecrypter.Initialize();
|
||||
if (!memoryMethodsDecrypter.Decrypt(peImage, fileData))
|
||||
return false;
|
||||
decrypted = true;
|
||||
}
|
||||
|
@ -297,18 +297,18 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (unpacker != null && unpacker.Detected) {
|
||||
if (options.DecryptMainAsm) {
|
||||
decryptState |= DecryptState.CanDecryptMethods | DecryptState.CanUnpack;
|
||||
var mainInfo = unpacker.unpackMainAssembly(true);
|
||||
var mainInfo = unpacker.UnpackMainAssembly(true);
|
||||
newFileData = mainInfo.data;
|
||||
realAssemblyInfo = mainInfo.realAssemblyInfo;
|
||||
embeddedAssemblyInfos.AddRange(unpacker.getEmbeddedAssemblyInfos());
|
||||
embeddedAssemblyInfos.AddRange(unpacker.GetEmbeddedAssemblyInfos());
|
||||
ModuleBytes = newFileData;
|
||||
hasUnpacked = true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
decryptState &= ~DecryptState.CanUnpack;
|
||||
mainAsmInfo = unpacker.unpackMainAssembly(false);
|
||||
embeddedAssemblyInfos.AddRange(unpacker.getEmbeddedAssemblyInfos());
|
||||
mainAsmInfo = unpacker.UnpackMainAssembly(false);
|
||||
embeddedAssemblyInfos.AddRange(unpacker.GetEmbeddedAssemblyInfos());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public override IDeobfuscator moduleReloaded(ModuleDefMD module) {
|
||||
public override IDeobfuscator ModuleReloaded(ModuleDefMD module) {
|
||||
if (module.Assembly != null)
|
||||
realAssemblyInfo = null;
|
||||
if (realAssemblyInfo != null) {
|
||||
|
@ -329,19 +329,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
var newOne = new Deobfuscator(options);
|
||||
DeobfuscatedFile.setDeobfuscator(newOne);
|
||||
DeobfuscatedFile.SetDeobfuscator(newOne);
|
||||
newOne.realAssemblyInfo = realAssemblyInfo;
|
||||
newOne.decryptState = decryptState;
|
||||
newOne.DeobfuscatedFile = DeobfuscatedFile;
|
||||
newOne.ModuleBytes = ModuleBytes;
|
||||
newOne.embeddedAssemblyInfos.AddRange(embeddedAssemblyInfos);
|
||||
newOne.setModule(module);
|
||||
newOne.removeObfuscatorAttribute();
|
||||
newOne.SetModule(module);
|
||||
newOne.RemoveObfuscatorAttribute();
|
||||
newOne.jitMethodsDecrypter = hasUnpacked ? new JitMethodsDecrypter(module, DeobfuscatedFile) :
|
||||
new JitMethodsDecrypter(module, DeobfuscatedFile, jitMethodsDecrypter);
|
||||
if ((newOne.decryptState & DecryptState.CanDecryptMethods) != 0) {
|
||||
try {
|
||||
newOne.jitMethodsDecrypter.find();
|
||||
newOne.jitMethodsDecrypter.Find();
|
||||
}
|
||||
catch {
|
||||
}
|
||||
|
@ -351,185 +351,185 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
newOne.memoryMethodsDecrypter = hasUnpacked ? new MemoryMethodsDecrypter(module, DeobfuscatedFile) :
|
||||
new MemoryMethodsDecrypter(module, DeobfuscatedFile, memoryMethodsDecrypter);
|
||||
if ((newOne.decryptState & DecryptState.CanDecryptMethods) != 0) {
|
||||
newOne.memoryMethodsDecrypter.find();
|
||||
newOne.memoryMethodsDecrypter.Find();
|
||||
if (newOne.memoryMethodsDecrypter.Detected)
|
||||
return newOne;
|
||||
}
|
||||
newOne.initTheRest(this);
|
||||
newOne.InitializeTheRest(this);
|
||||
return newOne;
|
||||
}
|
||||
|
||||
public override void deobfuscateBegin() {
|
||||
base.deobfuscateBegin();
|
||||
public override void DeobfuscateBegin() {
|
||||
base.DeobfuscateBegin();
|
||||
|
||||
Logger.v("Detected {0}", obfuscatorName);
|
||||
|
||||
initializeConstantsDecrypterV18();
|
||||
initializeConstantsDecrypterV17();
|
||||
initializeConstantsDecrypterV15();
|
||||
initializeStringDecrypter();
|
||||
InitializeConstantsDecrypterV18();
|
||||
InitializeConstantsDecrypterV17();
|
||||
InitializeConstantsDecrypterV15();
|
||||
InitializeStringDecrypter();
|
||||
|
||||
if (jitMethodsDecrypter != null) {
|
||||
addModuleCctorInitCallToBeRemoved(jitMethodsDecrypter.InitMethod);
|
||||
addTypeToBeRemoved(jitMethodsDecrypter.Type, "Method decrypter (JIT) type");
|
||||
AddModuleCctorInitCallToBeRemoved(jitMethodsDecrypter.InitMethod);
|
||||
AddTypeToBeRemoved(jitMethodsDecrypter.Type, "Method decrypter (JIT) type");
|
||||
}
|
||||
|
||||
if (memoryMethodsDecrypter != null) {
|
||||
addModuleCctorInitCallToBeRemoved(memoryMethodsDecrypter.InitMethod);
|
||||
addTypeToBeRemoved(memoryMethodsDecrypter.Type, "Method decrypter (memory) type");
|
||||
AddModuleCctorInitCallToBeRemoved(memoryMethodsDecrypter.InitMethod);
|
||||
AddTypeToBeRemoved(memoryMethodsDecrypter.Type, "Method decrypter (memory) type");
|
||||
}
|
||||
|
||||
if (options.RemoveAntiDebug && antiDebugger != null) {
|
||||
addModuleCctorInitCallToBeRemoved(antiDebugger.InitMethod);
|
||||
addTypeToBeRemoved(antiDebugger.Type, "Anti debugger type");
|
||||
if (antiDebugger.Type == DotNetUtils.getModuleType(module))
|
||||
addMethodToBeRemoved(antiDebugger.InitMethod, "Anti debugger method");
|
||||
AddModuleCctorInitCallToBeRemoved(antiDebugger.InitMethod);
|
||||
AddTypeToBeRemoved(antiDebugger.Type, "Anti debugger type");
|
||||
if (antiDebugger.Type == DotNetUtils.GetModuleType(module))
|
||||
AddMethodToBeRemoved(antiDebugger.InitMethod, "Anti debugger method");
|
||||
}
|
||||
|
||||
if (options.RemoveAntiDump && antiDumping != null) {
|
||||
addModuleCctorInitCallToBeRemoved(antiDumping.InitMethod);
|
||||
addTypeToBeRemoved(antiDumping.Type, "Anti dumping type");
|
||||
AddModuleCctorInitCallToBeRemoved(antiDumping.InitMethod);
|
||||
AddTypeToBeRemoved(antiDumping.Type, "Anti dumping type");
|
||||
}
|
||||
|
||||
if (proxyCallFixer != null)
|
||||
proxyCallFixer.find();
|
||||
proxyCallFixer.Find();
|
||||
|
||||
removeInvalidResources();
|
||||
dumpEmbeddedAssemblies();
|
||||
RemoveInvalidResources();
|
||||
DumpEmbeddedAssemblies();
|
||||
|
||||
startedDeobfuscating = true;
|
||||
}
|
||||
|
||||
void dumpEmbeddedAssemblies() {
|
||||
void DumpEmbeddedAssemblies() {
|
||||
if (mainAsmInfo != null) {
|
||||
var asm = module.Assembly;
|
||||
var name = (asm == null ? module.Name : asm.Name).String;
|
||||
DeobfuscatedFile.createAssemblyFile(mainAsmInfo.data, name + "_real", mainAsmInfo.extension);
|
||||
addResourceToBeRemoved(mainAsmInfo.resource, string.Format("Embedded assembly: {0}", mainAsmInfo.asmFullName));
|
||||
DeobfuscatedFile.CreateAssemblyFile(mainAsmInfo.data, name + "_real", mainAsmInfo.extension);
|
||||
AddResourceToBeRemoved(mainAsmInfo.resource, string.Format("Embedded assembly: {0}", mainAsmInfo.asmFullName));
|
||||
}
|
||||
foreach (var info in embeddedAssemblyInfos) {
|
||||
if (module.Assembly == null || info.asmFullName != module.Assembly.FullName)
|
||||
DeobfuscatedFile.createAssemblyFile(info.data, info.asmSimpleName, info.extension);
|
||||
addResourceToBeRemoved(info.resource, string.Format("Embedded assembly: {0}", info.asmFullName));
|
||||
DeobfuscatedFile.CreateAssemblyFile(info.data, info.asmSimpleName, info.extension);
|
||||
AddResourceToBeRemoved(info.resource, string.Format("Embedded assembly: {0}", info.asmFullName));
|
||||
}
|
||||
embeddedAssemblyInfos.Clear();
|
||||
}
|
||||
|
||||
void removeInvalidResources() {
|
||||
void RemoveInvalidResources() {
|
||||
foreach (var rsrc in module.Resources) {
|
||||
var resource = rsrc as EmbeddedResource;
|
||||
if (resource == null)
|
||||
continue;
|
||||
if (resource.Offset != 0xFFFFFFFF)
|
||||
continue;
|
||||
addResourceToBeRemoved(resource, "Invalid resource");
|
||||
AddResourceToBeRemoved(resource, "Invalid resource");
|
||||
}
|
||||
}
|
||||
|
||||
bool hasInitializedStringDecrypter = false;
|
||||
void initializeStringDecrypter() {
|
||||
void InitializeStringDecrypter() {
|
||||
if (hasInitializedStringDecrypter || (stringDecrypter== null || !stringDecrypter.Detected))
|
||||
return;
|
||||
hasInitializedStringDecrypter = true;
|
||||
|
||||
decryptResources();
|
||||
stringDecrypter.initialize();
|
||||
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt(staticStringInliner.Method, (int)args[0]));
|
||||
DeobfuscatedFile.stringDecryptersAdded();
|
||||
DecryptResources();
|
||||
stringDecrypter.Initialize();
|
||||
staticStringInliner.Add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.Decrypt(staticStringInliner.Method, (int)args[0]));
|
||||
DeobfuscatedFile.StringDecryptersAdded();
|
||||
}
|
||||
|
||||
bool hasInitializedConstantsDecrypter = false;
|
||||
void initializeConstantsDecrypterV18() {
|
||||
void InitializeConstantsDecrypterV18() {
|
||||
if (hasInitializedConstantsDecrypter || (constantsDecrypterV18 == null || !constantsDecrypterV18.Detected))
|
||||
return;
|
||||
hasInitializedConstantsDecrypter = true;
|
||||
|
||||
decryptResources();
|
||||
constantsDecrypterV18.initialize();
|
||||
DecryptResources();
|
||||
constantsDecrypterV18.Initialize();
|
||||
int32ValueInliner = new Int32ValueInliner();
|
||||
int64ValueInliner = new Int64ValueInliner();
|
||||
singleValueInliner = new SingleValueInliner();
|
||||
doubleValueInliner = new DoubleValueInliner();
|
||||
foreach (var info in constantsDecrypterV18.Decrypters) {
|
||||
staticStringInliner.add(info.method, (method, gim, args) => constantsDecrypterV18.decryptString(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
int32ValueInliner.add(info.method, (method, gim, args) => constantsDecrypterV18.decryptInt32(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
int64ValueInliner.add(info.method, (method, gim, args) => constantsDecrypterV18.decryptInt64(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
singleValueInliner.add(info.method, (method, gim, args) => constantsDecrypterV18.decryptSingle(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
doubleValueInliner.add(info.method, (method, gim, args) => constantsDecrypterV18.decryptDouble(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
staticStringInliner.Add(info.method, (method, gim, args) => constantsDecrypterV18.DecryptString(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
int32ValueInliner.Add(info.method, (method, gim, args) => constantsDecrypterV18.DecryptInt32(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
int64ValueInliner.Add(info.method, (method, gim, args) => constantsDecrypterV18.DecryptInt64(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
singleValueInliner.Add(info.method, (method, gim, args) => constantsDecrypterV18.DecryptSingle(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
doubleValueInliner.Add(info.method, (method, gim, args) => constantsDecrypterV18.DecryptDouble(method, gim, (uint)args[0], (ulong)args[1]));
|
||||
}
|
||||
DeobfuscatedFile.stringDecryptersAdded();
|
||||
addTypesToBeRemoved(constantsDecrypterV18.Types, "Constants decrypter type");
|
||||
addFieldsToBeRemoved(constantsDecrypterV18.Fields, "Constants decrypter field");
|
||||
addMethodToBeRemoved(constantsDecrypterV18.NativeMethod, "Constants decrypter native method");
|
||||
addResourceToBeRemoved(constantsDecrypterV18.Resource, "Encrypted constants");
|
||||
DeobfuscatedFile.StringDecryptersAdded();
|
||||
AddTypesToBeRemoved(constantsDecrypterV18.Types, "Constants decrypter type");
|
||||
AddFieldsToBeRemoved(constantsDecrypterV18.Fields, "Constants decrypter field");
|
||||
AddMethodToBeRemoved(constantsDecrypterV18.NativeMethod, "Constants decrypter native method");
|
||||
AddResourceToBeRemoved(constantsDecrypterV18.Resource, "Encrypted constants");
|
||||
}
|
||||
|
||||
bool hasInitializedConstantsDecrypter15 = false;
|
||||
void initializeConstantsDecrypterV15() {
|
||||
initialize(constantsDecrypterV15, ref hasInitializedConstantsDecrypter15);
|
||||
void InitializeConstantsDecrypterV15() {
|
||||
Initialize(constantsDecrypterV15, ref hasInitializedConstantsDecrypter15);
|
||||
}
|
||||
|
||||
bool hasInitializedConstantsDecrypter17 = false;
|
||||
void initializeConstantsDecrypterV17() {
|
||||
initialize(constantsDecrypterV17, ref hasInitializedConstantsDecrypter17);
|
||||
void InitializeConstantsDecrypterV17() {
|
||||
Initialize(constantsDecrypterV17, ref hasInitializedConstantsDecrypter17);
|
||||
}
|
||||
|
||||
void initialize(ConstantsDecrypterBase constDecrypter, ref bool hasInitialized) {
|
||||
void Initialize(ConstantsDecrypterBase constDecrypter, ref bool hasInitialized) {
|
||||
if (hasInitialized || (constDecrypter == null || !constDecrypter.Detected))
|
||||
return;
|
||||
hasInitializedConstantsDecrypter15 = true;
|
||||
|
||||
decryptResources();
|
||||
constDecrypter.initialize();
|
||||
DecryptResources();
|
||||
constDecrypter.Initialize();
|
||||
int32ValueInliner = new Int32ValueInliner();
|
||||
int64ValueInliner = new Int64ValueInliner();
|
||||
singleValueInliner = new SingleValueInliner();
|
||||
doubleValueInliner = new DoubleValueInliner();
|
||||
foreach (var info in constDecrypter.DecrypterInfos) {
|
||||
staticStringInliner.add(info.decryptMethod, (method, gim, args) => constDecrypter.decryptString(staticStringInliner.Method, method, args));
|
||||
int32ValueInliner.add(info.decryptMethod, (method, gim, args) => constDecrypter.decryptInt32(int32ValueInliner.Method, method, args));
|
||||
int64ValueInliner.add(info.decryptMethod, (method, gim, args) => constDecrypter.decryptInt64(int64ValueInliner.Method, method, args));
|
||||
singleValueInliner.add(info.decryptMethod, (method, gim, args) => constDecrypter.decryptSingle(singleValueInliner.Method, method, args));
|
||||
doubleValueInliner.add(info.decryptMethod, (method, gim, args) => constDecrypter.decryptDouble(doubleValueInliner.Method, method, args));
|
||||
staticStringInliner.Add(info.decryptMethod, (method, gim, args) => constDecrypter.DecryptString(staticStringInliner.Method, method, args));
|
||||
int32ValueInliner.Add(info.decryptMethod, (method, gim, args) => constDecrypter.DecryptInt32(int32ValueInliner.Method, method, args));
|
||||
int64ValueInliner.Add(info.decryptMethod, (method, gim, args) => constDecrypter.DecryptInt64(int64ValueInliner.Method, method, args));
|
||||
singleValueInliner.Add(info.decryptMethod, (method, gim, args) => constDecrypter.DecryptSingle(singleValueInliner.Method, method, args));
|
||||
doubleValueInliner.Add(info.decryptMethod, (method, gim, args) => constDecrypter.DecryptDouble(doubleValueInliner.Method, method, args));
|
||||
}
|
||||
int32ValueInliner.RemoveUnbox = true;
|
||||
int64ValueInliner.RemoveUnbox = true;
|
||||
singleValueInliner.RemoveUnbox = true;
|
||||
doubleValueInliner.RemoveUnbox = true;
|
||||
DeobfuscatedFile.stringDecryptersAdded();
|
||||
addFieldsToBeRemoved(constDecrypter.Fields, "Constants decrypter field");
|
||||
var moduleType = DotNetUtils.getModuleType(module);
|
||||
DeobfuscatedFile.StringDecryptersAdded();
|
||||
AddFieldsToBeRemoved(constDecrypter.Fields, "Constants decrypter field");
|
||||
var moduleType = DotNetUtils.GetModuleType(module);
|
||||
foreach (var info in constDecrypter.DecrypterInfos) {
|
||||
if (info.decryptMethod.DeclaringType == moduleType)
|
||||
addMethodToBeRemoved(info.decryptMethod, "Constants decrypter method");
|
||||
AddMethodToBeRemoved(info.decryptMethod, "Constants decrypter method");
|
||||
else
|
||||
addTypeToBeRemoved(info.decryptMethod.DeclaringType, "Constants decrypter type");
|
||||
AddTypeToBeRemoved(info.decryptMethod.DeclaringType, "Constants decrypter type");
|
||||
}
|
||||
addMethodToBeRemoved(constDecrypter.NativeMethod, "Constants decrypter native method");
|
||||
addResourceToBeRemoved(constDecrypter.Resource, "Encrypted constants");
|
||||
AddMethodToBeRemoved(constDecrypter.NativeMethod, "Constants decrypter native method");
|
||||
AddResourceToBeRemoved(constDecrypter.Resource, "Encrypted constants");
|
||||
}
|
||||
|
||||
void decryptResources() {
|
||||
var rsrc = resourceDecrypter.mergeResources();
|
||||
void DecryptResources() {
|
||||
var rsrc = resourceDecrypter.MergeResources();
|
||||
if (rsrc == null)
|
||||
return;
|
||||
addResourceToBeRemoved(rsrc, "Encrypted resources");
|
||||
addMethodToBeRemoved(resourceDecrypter.Handler, "Resource decrypter handler");
|
||||
addFieldsToBeRemoved(resourceDecrypter.Fields, "Resource decrypter field");
|
||||
AddResourceToBeRemoved(rsrc, "Encrypted resources");
|
||||
AddMethodToBeRemoved(resourceDecrypter.Handler, "Resource decrypter handler");
|
||||
AddFieldsToBeRemoved(resourceDecrypter.Fields, "Resource decrypter field");
|
||||
}
|
||||
|
||||
void removeObfuscatorAttribute() {
|
||||
void RemoveObfuscatorAttribute() {
|
||||
foreach (var type in module.Types) {
|
||||
if (type.FullName == "ConfusedByAttribute") {
|
||||
setConfuserVersion(type);
|
||||
addAttributeToBeRemoved(type, "Obfuscator attribute");
|
||||
SetConfuserVersion(type);
|
||||
AddAttributeToBeRemoved(type, "Obfuscator attribute");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setConfuserVersion(TypeDef type) {
|
||||
var s = DotNetUtils.getCustomArgAsString(getModuleAttribute(type) ?? getAssemblyAttribute(type), 0);
|
||||
void SetConfuserVersion(TypeDef type) {
|
||||
var s = DotNetUtils.GetCustomArgAsString(GetModuleAttribute(type) ?? GetAssemblyAttribute(type), 0);
|
||||
if (s == null)
|
||||
return;
|
||||
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Confuser v(\d+)\.(\d+)\.(\d+)\.(\d+)$");
|
||||
|
@ -541,42 +541,42 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
int.Parse(val.Groups[4].ToString()));
|
||||
}
|
||||
|
||||
public override void deobfuscateMethodEnd(Blocks blocks) {
|
||||
public override void DeobfuscateMethodEnd(Blocks blocks) {
|
||||
if (proxyCallFixer != null)
|
||||
proxyCallFixer.deobfuscate(blocks);
|
||||
resourceDecrypter.deobfuscate(blocks);
|
||||
unpacker.deobfuscate(blocks);
|
||||
proxyCallFixer.Deobfuscate(blocks);
|
||||
resourceDecrypter.Deobfuscate(blocks);
|
||||
unpacker.Deobfuscate(blocks);
|
||||
if (int32ValueInliner != null) {
|
||||
int32ValueInliner.decrypt(blocks);
|
||||
int64ValueInliner.decrypt(blocks);
|
||||
singleValueInliner.decrypt(blocks);
|
||||
doubleValueInliner.decrypt(blocks);
|
||||
int32ValueInliner.Decrypt(blocks);
|
||||
int64ValueInliner.Decrypt(blocks);
|
||||
singleValueInliner.Decrypt(blocks);
|
||||
doubleValueInliner.Decrypt(blocks);
|
||||
}
|
||||
base.deobfuscateMethodEnd(blocks);
|
||||
base.DeobfuscateMethodEnd(blocks);
|
||||
}
|
||||
|
||||
public override void deobfuscateEnd() {
|
||||
public override void DeobfuscateEnd() {
|
||||
if (proxyCallFixer != null) {
|
||||
if (removeProxyDelegates(proxyCallFixer))
|
||||
addFieldsToBeRemoved(proxyCallFixer.Fields, "Proxy delegate instance field");
|
||||
proxyCallFixer.cleanUp();
|
||||
if (RemoveProxyDelegates(proxyCallFixer))
|
||||
AddFieldsToBeRemoved(proxyCallFixer.Fields, "Proxy delegate instance field");
|
||||
proxyCallFixer.CleanUp();
|
||||
}
|
||||
if (constantsDecrypterV18 != null)
|
||||
constantsDecrypterV18.cleanUp();
|
||||
constantsDecrypterV18.CleanUp();
|
||||
|
||||
if (CanRemoveStringDecrypterType) {
|
||||
if (stringDecrypter != null) {
|
||||
addMethodToBeRemoved(stringDecrypter.Method, "String decrypter method");
|
||||
addResourceToBeRemoved(stringDecrypter.Resource, "Encrypted strings");
|
||||
AddMethodToBeRemoved(stringDecrypter.Method, "String decrypter method");
|
||||
AddResourceToBeRemoved(stringDecrypter.Resource, "Encrypted strings");
|
||||
}
|
||||
}
|
||||
|
||||
module.IsILOnly = true;
|
||||
|
||||
base.deobfuscateEnd();
|
||||
base.DeobfuscateEnd();
|
||||
}
|
||||
|
||||
public override IEnumerable<int> getStringDecrypterMethods() {
|
||||
public override IEnumerable<int> GetStringDecrypterMethods() {
|
||||
var list = new List<int>();
|
||||
if (stringDecrypter != null && stringDecrypter.Method != null)
|
||||
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
|
||||
namespace de4dot.code.deobfuscators.Confuser {
|
||||
interface IVersionProvider {
|
||||
bool getRevisionRange(out int minRev, out int maxRev);
|
||||
bool GetRevisionRange(out int minRev, out int maxRev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,15 +65,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.version = other.version;
|
||||
}
|
||||
|
||||
protected override bool checkType(TypeDef type, MethodDef initMethod) {
|
||||
protected override bool CheckType(TypeDef type, MethodDef initMethod) {
|
||||
if (type == null)
|
||||
return false;
|
||||
|
||||
compileMethod = findCompileMethod(type);
|
||||
compileMethod = FindCompileMethod(type);
|
||||
if (compileMethod == null)
|
||||
return false;
|
||||
|
||||
decryptMethod = findDecryptMethod(type);
|
||||
decryptMethod = FindDecryptMethod(type);
|
||||
if (decryptMethod == null)
|
||||
return false;
|
||||
|
||||
|
@ -89,7 +89,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
|
||||
case 38:
|
||||
switch (countInt32s(compileMethod, 0xFF)) {
|
||||
switch (CountInt32s(compileMethod, 0xFF)) {
|
||||
case 2: theVersion = ConfuserVersion.v17_r73477; break;
|
||||
case 4: theVersion = ConfuserVersion.v17_r73479; break;
|
||||
default: return false;
|
||||
|
@ -97,20 +97,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
break;
|
||||
|
||||
case 39:
|
||||
if (!DotNetUtils.callsMethod(initMethod, "System.Void System.Console::WriteLine(System.Char)")) {
|
||||
if (DotNetUtils.callsMethod(decryptMethod, "System.Security.Cryptography.Rijndael System.Security.Cryptography.Rijndael::Create()"))
|
||||
if (!DotNetUtils.CallsMethod(initMethod, "System.Void System.Console::WriteLine(System.Char)")) {
|
||||
if (DotNetUtils.CallsMethod(decryptMethod, "System.Security.Cryptography.Rijndael System.Security.Cryptography.Rijndael::Create()"))
|
||||
theVersion = ConfuserVersion.v17_r74021;
|
||||
else
|
||||
theVersion = ConfuserVersion.v18_r75291;
|
||||
}
|
||||
else if (DotNetUtils.callsMethod(decryptMethod, "System.Security.Cryptography.Rijndael System.Security.Cryptography.Rijndael::Create()"))
|
||||
else if (DotNetUtils.CallsMethod(decryptMethod, "System.Security.Cryptography.Rijndael System.Security.Cryptography.Rijndael::Create()"))
|
||||
theVersion = ConfuserVersion.v18_r75257;
|
||||
else
|
||||
theVersion = ConfuserVersion.v18_r75288;
|
||||
break;
|
||||
|
||||
case 27:
|
||||
if (DotNetUtils.callsMethod(initMethod, "System.Int32 System.String::get_Length()"))
|
||||
if (DotNetUtils.CallsMethod(initMethod, "System.Int32 System.String::get_Length()"))
|
||||
theVersion = ConfuserVersion.v18_r75402;
|
||||
else
|
||||
theVersion = ConfuserVersion.v19_r75725;
|
||||
|
@ -121,7 +121,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
if (theVersion >= ConfuserVersion.v17_r73477) {
|
||||
hookConstructStr = findHookConstructStr(type);
|
||||
hookConstructStr = FindHookConstructStr(type);
|
||||
if (hookConstructStr == null)
|
||||
return false;
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int countInt32s(MethodDef method, int val) {
|
||||
static int CountInt32s(MethodDef method, int val) {
|
||||
int count = 0;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
if (!instr.IsLdcI4())
|
||||
|
@ -141,7 +141,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return count;
|
||||
}
|
||||
|
||||
static MethodDef findCompileMethod(TypeDef type) {
|
||||
static MethodDef FindCompileMethod(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
|
@ -164,7 +164,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static MethodDef findHookConstructStr(TypeDef type) {
|
||||
static MethodDef FindHookConstructStr(TypeDef type) {
|
||||
foreach (var nested in type.NestedTypes) {
|
||||
if (nested.Fields.Count != 8 && nested.Fields.Count != 10)
|
||||
continue;
|
||||
|
@ -189,79 +189,79 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
public void Initialize() {
|
||||
if (initMethod == null)
|
||||
return;
|
||||
if (!initializeKeys())
|
||||
if (!InitializeKeys())
|
||||
throw new ApplicationException("Could not find all decryption keys");
|
||||
if (!initializeMethodDataIndexes(compileMethod))
|
||||
if (!InitializeMethodDataIndexes(compileMethod))
|
||||
throw new ApplicationException("Could not find MethodData indexes");
|
||||
}
|
||||
|
||||
bool initializeKeys() {
|
||||
bool InitializeKeys() {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r73404: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r73430: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r73477: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r73479: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r74021: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75257: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75288: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75291: return initializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75402: return initializeKeys_v18_r75402();
|
||||
case ConfuserVersion.v19_r75725: return initializeKeys_v18_r75402();
|
||||
case ConfuserVersion.v17_r73404: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r73430: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r73477: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r73479: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v17_r74021: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75257: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75288: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75291: return InitializeKeys_v17_r73404();
|
||||
case ConfuserVersion.v18_r75402: return InitializeKeys_v18_r75402();
|
||||
case ConfuserVersion.v19_r75725: return InitializeKeys_v18_r75402();
|
||||
default: throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
bool initializeKeys_v17_r73404() {
|
||||
simpleDeobfuscator.deobfuscate(initMethod);
|
||||
if (!findLKey0(initMethod, out lkey0))
|
||||
bool InitializeKeys_v17_r73404() {
|
||||
simpleDeobfuscator.Deobfuscate(initMethod);
|
||||
if (!FindLKey0(initMethod, out lkey0))
|
||||
return false;
|
||||
if (!findKey0_v16_r71742(initMethod, out key0))
|
||||
if (!FindKey0_v16_r71742(initMethod, out key0))
|
||||
return false;
|
||||
if (!findKey1(initMethod, out key1))
|
||||
if (!FindKey1(initMethod, out key1))
|
||||
return false;
|
||||
if (!findKey2Key3(initMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(initMethod, out key2, out key3))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(decryptMethod);
|
||||
if (!findKey6(decryptMethod, out key6))
|
||||
simpleDeobfuscator.Deobfuscate(decryptMethod);
|
||||
if (!FindKey6(decryptMethod, out key6))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initializeKeys_v18_r75402() {
|
||||
simpleDeobfuscator.deobfuscate(initMethod);
|
||||
if (!findLKey0(initMethod, out lkey0))
|
||||
bool InitializeKeys_v18_r75402() {
|
||||
simpleDeobfuscator.Deobfuscate(initMethod);
|
||||
if (!FindLKey0(initMethod, out lkey0))
|
||||
return false;
|
||||
if (!findKey0_v16_r71742(initMethod, out key0))
|
||||
if (!FindKey0_v16_r71742(initMethod, out key0))
|
||||
return false;
|
||||
if (!findKey1(initMethod, out key1))
|
||||
if (!FindKey1(initMethod, out key1))
|
||||
return false;
|
||||
if (!findKey2Key3(initMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(initMethod, out key2, out key3))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(compileMethod);
|
||||
if (!findKey4(compileMethod, out key4))
|
||||
simpleDeobfuscator.Deobfuscate(compileMethod);
|
||||
if (!FindKey4(compileMethod, out key4))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(hookConstructStr);
|
||||
if (!findKey5(hookConstructStr, out key5))
|
||||
simpleDeobfuscator.Deobfuscate(hookConstructStr);
|
||||
if (!FindKey5(hookConstructStr, out key5))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(decryptMethod);
|
||||
if (!findKey6(decryptMethod, out key6))
|
||||
simpleDeobfuscator.Deobfuscate(decryptMethod);
|
||||
if (!FindKey6(decryptMethod, out key6))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findKey4(MethodDef method, out uint key) {
|
||||
static bool FindKey4(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = ConfuserUtils.findCallMethod(instrs, index, Code.Call, "System.Void System.Runtime.InteropServices.Marshal::Copy(System.Byte[],System.Int32,System.IntPtr,System.Int32)");
|
||||
index = ConfuserUtils.FindCallMethod(instrs, index, Code.Call, "System.Void System.Runtime.InteropServices.Marshal::Copy(System.Byte[],System.Int32,System.IntPtr,System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index + 2 >= instrs.Count)
|
||||
|
@ -280,7 +280,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey5(MethodDef method, out uint key) {
|
||||
static bool FindKey5(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 4 < instrs.Count; i++) {
|
||||
int index = i;
|
||||
|
@ -305,50 +305,50 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool initializeMethodDataIndexes(MethodDef compileMethod) {
|
||||
bool InitializeMethodDataIndexes(MethodDef compileMethod) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r73404: return true;
|
||||
case ConfuserVersion.v17_r73430: return true;
|
||||
case ConfuserVersion.v17_r73477: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v17_r73479: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v17_r74021: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75257: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75288: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75291: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75402: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v19_r75725: return initializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v17_r73477: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v17_r73479: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v17_r74021: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75257: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75288: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75291: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v18_r75402: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
case ConfuserVersion.v19_r75725: return InitializeMethodDataIndexes_v17_r73477(compileMethod);
|
||||
default: throw new ApplicationException("Invalid version");
|
||||
}
|
||||
}
|
||||
|
||||
bool initializeMethodDataIndexes_v17_r73477(MethodDef method) {
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
var methodDataType = findFirstThreeIndexes(method, out methodDataIndexes.maxStack, out methodDataIndexes.ehs, out methodDataIndexes.options);
|
||||
bool InitializeMethodDataIndexes_v17_r73477(MethodDef method) {
|
||||
simpleDeobfuscator.Deobfuscate(method);
|
||||
var methodDataType = FindFirstThreeIndexes(method, out methodDataIndexes.maxStack, out methodDataIndexes.ehs, out methodDataIndexes.options);
|
||||
if (methodDataType == null)
|
||||
return false;
|
||||
|
||||
if (!findLocalVarSigTokIndex(method, methodDataType, out methodDataIndexes.localVarSigTok))
|
||||
if (!FindLocalVarSigTokIndex(method, methodDataType, out methodDataIndexes.localVarSigTok))
|
||||
return false;
|
||||
|
||||
if (!findCodeSizeIndex(method, methodDataType, out methodDataIndexes.codeSize))
|
||||
if (!FindCodeSizeIndex(method, methodDataType, out methodDataIndexes.codeSize))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static TypeDef findFirstThreeIndexes(MethodDef method, out int maxStackIndex, out int ehsIndex, out int optionsIndex) {
|
||||
static TypeDef FindFirstThreeIndexes(MethodDef method, out int maxStackIndex, out int ehsIndex, out int optionsIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index1 = findLdfldStind(instrs, i, false, true);
|
||||
int index1 = FindLdfldStind(instrs, i, false, true);
|
||||
if (index1 < 0)
|
||||
break;
|
||||
i = index1;
|
||||
|
||||
int index2 = findLdfldStind(instrs, index1 + 1, true, true);
|
||||
int index2 = FindLdfldStind(instrs, index1 + 1, true, true);
|
||||
if (index2 < 0)
|
||||
continue;
|
||||
|
||||
int index3 = findLdfldStind(instrs, index2 + 1, true, false);
|
||||
int index3 = FindLdfldStind(instrs, index2 + 1, true, false);
|
||||
if (index3 < 0)
|
||||
continue;
|
||||
|
||||
|
@ -360,9 +360,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (field1.DeclaringType != field2.DeclaringType || field1.DeclaringType != field3.DeclaringType)
|
||||
continue;
|
||||
|
||||
maxStackIndex = getInstanceFieldIndex(field1);
|
||||
ehsIndex = getInstanceFieldIndex(field2);
|
||||
optionsIndex = getInstanceFieldIndex(field3);
|
||||
maxStackIndex = GetInstanceFieldIndex(field1);
|
||||
ehsIndex = GetInstanceFieldIndex(field2);
|
||||
optionsIndex = GetInstanceFieldIndex(field3);
|
||||
return field1.DeclaringType;
|
||||
}
|
||||
|
||||
|
@ -372,7 +372,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findLocalVarSigTokIndex(MethodDef method, TypeDef methodDataType, out int localVarSigTokIndex) {
|
||||
static bool FindLocalVarSigTokIndex(MethodDef method, TypeDef methodDataType, out int localVarSigTokIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldfld = instrs[i];
|
||||
|
@ -389,7 +389,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (calledMethod == null || !calledMethod.IsStatic || calledMethod.DeclaringType != method.DeclaringType)
|
||||
continue;
|
||||
|
||||
localVarSigTokIndex = getInstanceFieldIndex(field);
|
||||
localVarSigTokIndex = GetInstanceFieldIndex(field);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findCodeSizeIndex(MethodDef method, TypeDef methodDataType, out int codeSizeIndex) {
|
||||
static bool FindCodeSizeIndex(MethodDef method, TypeDef methodDataType, out int codeSizeIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldfld = instrs[i];
|
||||
|
@ -410,7 +410,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (instrs[i+1].OpCode.Code != Code.Stfld)
|
||||
continue;
|
||||
|
||||
codeSizeIndex = getInstanceFieldIndex(field);
|
||||
codeSizeIndex = GetInstanceFieldIndex(field);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static int getInstanceFieldIndex(FieldDef field) {
|
||||
static int GetInstanceFieldIndex(FieldDef field) {
|
||||
int i = 0;
|
||||
foreach (var f in field.DeclaringType.Fields) {
|
||||
if (f.IsStatic)
|
||||
|
@ -430,7 +430,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Could not find field");
|
||||
}
|
||||
|
||||
static int findLdfldStind(IList<Instruction> instrs, int index, bool onlyInBlock, bool checkStindi4) {
|
||||
static int FindLdfldStind(IList<Instruction> instrs, int index, bool onlyInBlock, bool checkStindi4) {
|
||||
for (int i = index; i < instrs.Count - 1; i++) {
|
||||
var ldfld = instrs[i];
|
||||
if (onlyInBlock && ldfld.OpCode.FlowControl != FlowControl.Next)
|
||||
|
@ -448,106 +448,106 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public bool decrypt(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
public bool Decrypt(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
if (initMethod == null)
|
||||
return false;
|
||||
|
||||
switch (version) {
|
||||
case ConfuserVersion.v17_r73404: return decrypt_v17_r73404(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73430: return decrypt_v17_r73404(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73477: return decrypt_v17_r73477(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73479: return decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r74021: return decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75257: return decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75288: return decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75291: return decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75402: return decrypt_v18_r75402(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v19_r75725: return decrypt_v18_r75402(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73404: return Decrypt_v17_r73404(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73430: return Decrypt_v17_r73404(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73477: return Decrypt_v17_r73477(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r73479: return Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v17_r74021: return Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75257: return Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75288: return Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75291: return Decrypt_v17_r73479(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v18_r75402: return Decrypt_v18_r75402(peImage, fileData, ref dumpedMethods);
|
||||
case ConfuserVersion.v19_r75725: return Decrypt_v18_r75402(peImage, fileData, ref dumpedMethods);
|
||||
default: throw new ApplicationException("Unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
bool decrypt_v17_r73404(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
methodsData = decryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = decrypt_v17_r73404(peImage, fileData);
|
||||
bool Decrypt_v17_r73404(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
methodsData = DecryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = Decrypt_v17_r73404(peImage, fileData);
|
||||
return dumpedMethods != null;
|
||||
}
|
||||
|
||||
DumpedMethods decrypt_v17_r73404(MyPEImage peImage, byte[] fileData) {
|
||||
DumpedMethods Decrypt_v17_r73404(MyPEImage peImage, byte[] fileData) {
|
||||
var dumpedMethods = new DumpedMethods();
|
||||
|
||||
var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
|
||||
for (uint rid = 1; rid <= methodDef.Rows; rid++) {
|
||||
var dm = new DumpedMethod();
|
||||
peImage.readMethodTableRowTo(dm, rid);
|
||||
peImage.ReadMethodTableRowTo(dm, rid);
|
||||
|
||||
if (dm.mdRVA == 0)
|
||||
continue;
|
||||
uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
|
||||
uint bodyOffset = peImage.RvaToOffset(dm.mdRVA);
|
||||
|
||||
if (!isEncryptedMethod(fileData, (int)bodyOffset))
|
||||
if (!IsEncryptedMethod(fileData, (int)bodyOffset))
|
||||
continue;
|
||||
|
||||
int key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6);
|
||||
int mdOffs = BitConverter.ToInt32(fileData, (int)bodyOffset + 2) ^ key;
|
||||
int len = BitConverter.ToInt32(fileData, (int)bodyOffset + 11) ^ ~key;
|
||||
var codeData = decryptMethodData_v17_r73404(methodsData, mdOffs + 2, (uint)key, len);
|
||||
var codeData = DecryptMethodData_v17_r73404(methodsData, mdOffs + 2, (uint)key, len);
|
||||
|
||||
var reader = MemoryImageStream.Create(codeData);
|
||||
var mbHeader = MethodBodyParser.parseMethodBody(reader, out dm.code, out dm.extraSections);
|
||||
var mbHeader = MethodBodyParser.ParseMethodBody(reader, out dm.code, out dm.extraSections);
|
||||
if (reader.Position != reader.Length)
|
||||
throw new ApplicationException("Invalid method data");
|
||||
|
||||
peImage.updateMethodHeaderInfo(dm, mbHeader);
|
||||
peImage.UpdateMethodHeaderInfo(dm, mbHeader);
|
||||
|
||||
dumpedMethods.add(dm);
|
||||
dumpedMethods.Add(dm);
|
||||
}
|
||||
|
||||
return dumpedMethods;
|
||||
}
|
||||
|
||||
bool decrypt_v17_r73477(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
methodsData = decryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = decrypt_v17_r73477(peImage, fileData);
|
||||
bool Decrypt_v17_r73477(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
methodsData = DecryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = Decrypt_v17_r73477(peImage, fileData);
|
||||
return dumpedMethods != null;
|
||||
}
|
||||
|
||||
DumpedMethods decrypt_v17_r73477(MyPEImage peImage, byte[] fileData) {
|
||||
return decrypt(peImage, fileData, new DecryptMethodData_v17_r73477());
|
||||
DumpedMethods Decrypt_v17_r73477(MyPEImage peImage, byte[] fileData) {
|
||||
return Decrypt(peImage, fileData, new DecryptMethodData_v17_r73477());
|
||||
}
|
||||
|
||||
bool decrypt_v17_r73479(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
methodsData = decryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = decrypt_v17_r73479(peImage, fileData);
|
||||
bool Decrypt_v17_r73479(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
methodsData = DecryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = Decrypt_v17_r73479(peImage, fileData);
|
||||
return dumpedMethods != null;
|
||||
}
|
||||
|
||||
DumpedMethods decrypt_v17_r73479(MyPEImage peImage, byte[] fileData) {
|
||||
return decrypt(peImage, fileData, new DecryptMethodData_v17_r73479());
|
||||
DumpedMethods Decrypt_v17_r73479(MyPEImage peImage, byte[] fileData) {
|
||||
return Decrypt(peImage, fileData, new DecryptMethodData_v17_r73479());
|
||||
}
|
||||
|
||||
bool decrypt_v18_r75402(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
bool Decrypt_v18_r75402(MyPEImage peImage, byte[] fileData, ref DumpedMethods dumpedMethods) {
|
||||
if (peImage.OptionalHeader.CheckSum == 0)
|
||||
return false;
|
||||
methodsData = decryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = decrypt_v18_r75402(peImage, fileData);
|
||||
methodsData = DecryptMethodsData_v17_r73404(peImage);
|
||||
dumpedMethods = Decrypt_v18_r75402(peImage, fileData);
|
||||
return dumpedMethods != null;
|
||||
}
|
||||
|
||||
DumpedMethods decrypt_v18_r75402(MyPEImage peImage, byte[] fileData) {
|
||||
return decrypt(peImage, fileData, new DecryptMethodData_v18_r75402(this));
|
||||
DumpedMethods Decrypt_v18_r75402(MyPEImage peImage, byte[] fileData) {
|
||||
return Decrypt(peImage, fileData, new DecryptMethodData_v18_r75402(this));
|
||||
}
|
||||
|
||||
abstract class DecryptMethodData {
|
||||
public abstract void decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData);
|
||||
public abstract void Decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData);
|
||||
|
||||
public bool isCodeFollowedByExtraSections(uint options) {
|
||||
public bool IsCodeFollowedByExtraSections(uint options) {
|
||||
return (options >> 8) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
class DecryptMethodData_v17_r73477 : DecryptMethodData {
|
||||
public override void decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) {
|
||||
public override void Decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) {
|
||||
var data = new byte[size];
|
||||
Array.Copy(fileData, offset, data, 0, data.Length);
|
||||
var key = BitConverter.GetBytes(k1);
|
||||
|
@ -562,7 +562,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
class DecryptMethodData_v17_r73479 : DecryptMethodData {
|
||||
public override void decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) {
|
||||
public override void Decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) {
|
||||
var data = new byte[size];
|
||||
Array.Copy(fileData, offset, data, 0, data.Length);
|
||||
uint k = k1;
|
||||
|
@ -585,7 +585,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.jitDecrypter = jitDecrypter;
|
||||
}
|
||||
|
||||
public override void decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) {
|
||||
public override void Decrypt(byte[] fileData, int offset, uint k1, int size, out uint[] methodData, out byte[] codeData) {
|
||||
var data = new byte[size];
|
||||
Array.Copy(fileData, offset, data, 0, data.Length);
|
||||
uint k2 = jitDecrypter.key4 * k1;
|
||||
|
@ -601,19 +601,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
DumpedMethods decrypt(MyPEImage peImage, byte[] fileData, DecryptMethodData decrypter) {
|
||||
DumpedMethods Decrypt(MyPEImage peImage, byte[] fileData, DecryptMethodData decrypter) {
|
||||
var dumpedMethods = new DumpedMethods();
|
||||
|
||||
var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
|
||||
for (uint rid = 1; rid <= methodDef.Rows; rid++) {
|
||||
var dm = new DumpedMethod();
|
||||
peImage.readMethodTableRowTo(dm, rid);
|
||||
peImage.ReadMethodTableRowTo(dm, rid);
|
||||
|
||||
if (dm.mdRVA == 0)
|
||||
continue;
|
||||
uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
|
||||
uint bodyOffset = peImage.RvaToOffset(dm.mdRVA);
|
||||
|
||||
if (!isEncryptedMethod(fileData, (int)bodyOffset))
|
||||
if (!IsEncryptedMethod(fileData, (int)bodyOffset))
|
||||
continue;
|
||||
|
||||
int key = BitConverter.ToInt32(fileData, (int)bodyOffset + 6);
|
||||
|
@ -622,7 +622,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
int methodDataOffset = mdOffs + 2;
|
||||
uint[] methodData;
|
||||
byte[] codeData;
|
||||
decrypter.decrypt(methodsData, methodDataOffset, (uint)key, len, out methodData, out codeData);
|
||||
decrypter.Decrypt(methodsData, methodDataOffset, (uint)key, len, out methodData, out codeData);
|
||||
|
||||
dm.mhFlags = 0x03;
|
||||
int maxStack = (int)methodData[methodDataIndexes.maxStack];
|
||||
|
@ -635,12 +635,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
int codeSize = (int)methodData[methodDataIndexes.codeSize];
|
||||
|
||||
var codeDataReader = MemoryImageStream.Create(codeData);
|
||||
if (decrypter.isCodeFollowedByExtraSections(options)) {
|
||||
if (decrypter.IsCodeFollowedByExtraSections(options)) {
|
||||
dm.code = codeDataReader.ReadBytes(codeSize);
|
||||
dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions);
|
||||
dm.extraSections = ReadExceptionHandlers(codeDataReader, numExceptions);
|
||||
}
|
||||
else {
|
||||
dm.extraSections = readExceptionHandlers(codeDataReader, numExceptions);
|
||||
dm.extraSections = ReadExceptionHandlers(codeDataReader, numExceptions);
|
||||
dm.code = codeDataReader.ReadBytes(codeSize);
|
||||
}
|
||||
if (codeDataReader.Position != codeDataReader.Length)
|
||||
|
@ -658,20 +658,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
dm.mhFlags |= 0x10; // Set 'init locals'
|
||||
dm.mhFlags |= (ushort)(options & 0x10); // copy 'init locals' bit
|
||||
|
||||
dumpedMethods.add(dm);
|
||||
dumpedMethods.Add(dm);
|
||||
}
|
||||
|
||||
return dumpedMethods;
|
||||
}
|
||||
|
||||
static bool isEncryptedMethod(byte[] fileData, int offset) {
|
||||
static bool IsEncryptedMethod(byte[] fileData, int offset) {
|
||||
return fileData[offset] == 0x46 &&
|
||||
fileData[offset + 1] == 0x21 &&
|
||||
fileData[offset + 10] == 0x20 &&
|
||||
fileData[offset + 15] == 0x26;
|
||||
}
|
||||
|
||||
static byte[] readExceptionHandlers(IBinaryReader reader, int numExceptions) {
|
||||
static byte[] ReadExceptionHandlers(IBinaryReader reader, int numExceptions) {
|
||||
if (numExceptions == 0)
|
||||
return null;
|
||||
|
||||
|
@ -694,7 +694,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return memStream.ToArray();
|
||||
}
|
||||
|
||||
byte[] decryptMethodData_v17_r73404(byte[] fileData, int offset, uint k1, int size) {
|
||||
byte[] DecryptMethodData_v17_r73404(byte[] fileData, int offset, uint k1, int size) {
|
||||
var data = new byte[size];
|
||||
var kbytes = BitConverter.GetBytes(k1);
|
||||
for (int i = 0; i < size; i++)
|
||||
|
@ -718,7 +718,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public override bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public override bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -52,25 +52,25 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.version = other.version;
|
||||
}
|
||||
|
||||
protected override bool checkType(TypeDef type, MethodDef initMethod) {
|
||||
protected override bool CheckType(TypeDef type, MethodDef initMethod) {
|
||||
if (type == null)
|
||||
return false;
|
||||
if (type.Methods.Count != 3)
|
||||
return false;
|
||||
var virtProtect = DotNetUtils.getPInvokeMethod(type, "kernel32", "VirtualProtect");
|
||||
var virtProtect = DotNetUtils.GetPInvokeMethod(type, "kernel32", "VirtualProtect");
|
||||
if (virtProtect == null)
|
||||
return false;
|
||||
if (!DotNetUtils.hasString(initMethod, "Broken file"))
|
||||
if (!DotNetUtils.HasString(initMethod, "Broken file"))
|
||||
return false;
|
||||
|
||||
if ((decryptMethod = findDecryptMethod(type)) == null)
|
||||
if ((decryptMethod = FindDecryptMethod(type)) == null)
|
||||
return false;
|
||||
|
||||
bool callsFileStreamCtor = DotNetUtils.callsMethod(initMethod, "System.Void System.IO.FileStream::.ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)");
|
||||
if (!DotNetUtils.hasString(initMethod, "Module error"))
|
||||
bool callsFileStreamCtor = DotNetUtils.CallsMethod(initMethod, "System.Void System.IO.FileStream::.ctor(System.String,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare)");
|
||||
if (!DotNetUtils.HasString(initMethod, "Module error"))
|
||||
version = ConfuserVersion.v14_r57884;
|
||||
else if (virtProtect.IsPrivate && callsFileStreamCtor) {
|
||||
int calls = ConfuserUtils.countCalls(initMethod, "System.Void System.Buffer::BlockCopy(System.Array,System.Int32,System.Array,System.Int32,System.Int32)");
|
||||
int calls = ConfuserUtils.CountCalls(initMethod, "System.Void System.Buffer::BlockCopy(System.Array,System.Int32,System.Array,System.Int32,System.Int32)");
|
||||
if (calls <= 1)
|
||||
version = ConfuserVersion.v14_r58564;
|
||||
else if (calls == 2)
|
||||
|
@ -82,15 +82,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
else if (callsFileStreamCtor)
|
||||
version = ConfuserVersion.v14_r58004;
|
||||
else if (DotNetUtils.callsMethod(initMethod, "System.Int32 System.Object::GetHashCode()")) {
|
||||
if (DotNetUtils.hasString(initMethod, "<Unknown>"))
|
||||
else if (DotNetUtils.CallsMethod(initMethod, "System.Int32 System.Object::GetHashCode()")) {
|
||||
if (DotNetUtils.HasString(initMethod, "<Unknown>"))
|
||||
version = ConfuserVersion.v17_r72989;
|
||||
else
|
||||
version = ConfuserVersion.v16_r71742;
|
||||
}
|
||||
else if (DotNetUtils.callsMethod(decryptMethod, "System.Security.Cryptography.Rijndael System.Security.Cryptography.Rijndael::Create()"))
|
||||
else if (DotNetUtils.CallsMethod(decryptMethod, "System.Security.Cryptography.Rijndael System.Security.Cryptography.Rijndael::Create()"))
|
||||
version = ConfuserVersion.v17_r73605;
|
||||
else if (DotNetUtils.hasString(initMethod, "<Unknown>"))
|
||||
else if (DotNetUtils.HasString(initMethod, "<Unknown>"))
|
||||
version = ConfuserVersion.v18_r75288;
|
||||
else
|
||||
version = ConfuserVersion.v19_r75725;
|
||||
|
@ -98,15 +98,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
public void Initialize() {
|
||||
if (initMethod == null)
|
||||
return;
|
||||
|
||||
if (!initializeKeys())
|
||||
if (!InitializeKeys())
|
||||
throw new ApplicationException("Could not find all decryption keys");
|
||||
}
|
||||
|
||||
bool initializeKeys() {
|
||||
bool InitializeKeys() {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v14_r57884:
|
||||
case ConfuserVersion.v14_r58004:
|
||||
|
@ -115,88 +115,88 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
case ConfuserVersion.v14_r58564:
|
||||
case ConfuserVersion.v14_r58852:
|
||||
case ConfuserVersion.v15_r59014:
|
||||
return initializeKeys_v14_r58564();
|
||||
return InitializeKeys_v14_r58564();
|
||||
|
||||
case ConfuserVersion.v16_r71742:
|
||||
case ConfuserVersion.v17_r72989:
|
||||
return initializeKeys_v16_r71742();
|
||||
return InitializeKeys_v16_r71742();
|
||||
|
||||
case ConfuserVersion.v17_r73605:
|
||||
case ConfuserVersion.v18_r75288:
|
||||
case ConfuserVersion.v19_r75725:
|
||||
return initializeKeys_v17_r73605();
|
||||
return InitializeKeys_v17_r73605();
|
||||
|
||||
default:
|
||||
throw new ApplicationException("Unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
bool initializeKeys_v14_r58564() {
|
||||
simpleDeobfuscator.deobfuscate(initMethod);
|
||||
if (!findLKey0(initMethod, out lkey0))
|
||||
bool InitializeKeys_v14_r58564() {
|
||||
simpleDeobfuscator.Deobfuscate(initMethod);
|
||||
if (!FindLKey0(initMethod, out lkey0))
|
||||
return false;
|
||||
if (!findKey0_v14_r58564(initMethod, out key0))
|
||||
if (!FindKey0_v14_r58564(initMethod, out key0))
|
||||
return false;
|
||||
if (!findKey2Key3(initMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(initMethod, out key2, out key3))
|
||||
return false;
|
||||
if (!findKey4(initMethod, out key4))
|
||||
if (!FindKey4(initMethod, out key4))
|
||||
return false;
|
||||
if (!findKey5(initMethod, out key5))
|
||||
if (!FindKey5(initMethod, out key5))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(decryptMethod);
|
||||
if (!findKey6(decryptMethod, out key6))
|
||||
simpleDeobfuscator.Deobfuscate(decryptMethod);
|
||||
if (!FindKey6(decryptMethod, out key6))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initializeKeys_v16_r71742() {
|
||||
simpleDeobfuscator.deobfuscate(initMethod);
|
||||
if (!findLKey0(initMethod, out lkey0))
|
||||
bool InitializeKeys_v16_r71742() {
|
||||
simpleDeobfuscator.Deobfuscate(initMethod);
|
||||
if (!FindLKey0(initMethod, out lkey0))
|
||||
return false;
|
||||
if (!findKey0_v16_r71742(initMethod, out key0))
|
||||
if (!FindKey0_v16_r71742(initMethod, out key0))
|
||||
return false;
|
||||
if (!findKey2Key3(initMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(initMethod, out key2, out key3))
|
||||
return false;
|
||||
if (!findKey4(initMethod, out key4))
|
||||
if (!FindKey4(initMethod, out key4))
|
||||
return false;
|
||||
if (!findKey5(initMethod, out key5))
|
||||
if (!FindKey5(initMethod, out key5))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(decryptMethod);
|
||||
if (!findKey6(decryptMethod, out key6))
|
||||
simpleDeobfuscator.Deobfuscate(decryptMethod);
|
||||
if (!FindKey6(decryptMethod, out key6))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool initializeKeys_v17_r73605() {
|
||||
simpleDeobfuscator.deobfuscate(initMethod);
|
||||
if (!findLKey0(initMethod, out lkey0))
|
||||
bool InitializeKeys_v17_r73605() {
|
||||
simpleDeobfuscator.Deobfuscate(initMethod);
|
||||
if (!FindLKey0(initMethod, out lkey0))
|
||||
return false;
|
||||
if (!findKey0_v16_r71742(initMethod, out key0))
|
||||
if (!FindKey0_v16_r71742(initMethod, out key0))
|
||||
return false;
|
||||
if (!findKey1(initMethod, out key1))
|
||||
if (!FindKey1(initMethod, out key1))
|
||||
return false;
|
||||
if (!findKey2Key3(initMethod, out key2, out key3))
|
||||
if (!FindKey2Key3(initMethod, out key2, out key3))
|
||||
return false;
|
||||
if (!findKey4(initMethod, out key4))
|
||||
if (!FindKey4(initMethod, out key4))
|
||||
return false;
|
||||
if (!findKey5(initMethod, out key5))
|
||||
if (!FindKey5(initMethod, out key5))
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(decryptMethod);
|
||||
if (!findKey6(decryptMethod, out key6))
|
||||
simpleDeobfuscator.Deobfuscate(decryptMethod);
|
||||
if (!FindKey6(decryptMethod, out key6))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool findKey4(MethodDef method, out uint key) {
|
||||
static bool FindKey4(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = findCallvirtReadUInt32(instrs, i);
|
||||
i = FindCallvirtReadUInt32(instrs, i);
|
||||
if (i < 0)
|
||||
break;
|
||||
if (i >= 2) {
|
||||
|
@ -228,13 +228,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey5(MethodDef method, out uint key) {
|
||||
static bool FindKey5(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = findCallvirtReadUInt32(instrs, i);
|
||||
i = FindCallvirtReadUInt32(instrs, i);
|
||||
if (i < 0)
|
||||
break;
|
||||
int index2 = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
int index2 = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
if (index2 < 0)
|
||||
break;
|
||||
if (index2 - i != 6)
|
||||
|
@ -264,27 +264,27 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool decrypt(MyPEImage peImage, byte[] fileData) {
|
||||
public bool Decrypt(MyPEImage peImage, byte[] fileData) {
|
||||
if (initMethod == null)
|
||||
return false;
|
||||
|
||||
switch (version) {
|
||||
case ConfuserVersion.v14_r57884: return decrypt_v14_r57884(peImage, fileData);
|
||||
case ConfuserVersion.v14_r58004: return decrypt_v14_r58004(peImage, fileData);
|
||||
case ConfuserVersion.v14_r58564: return decrypt_v14_r58004(peImage, fileData);
|
||||
case ConfuserVersion.v14_r58852: return decrypt_v14_r58004(peImage, fileData);
|
||||
case ConfuserVersion.v15_r59014: return decrypt_v15_r59014(peImage, fileData);
|
||||
case ConfuserVersion.v16_r71742: return decrypt_v16_r71742(peImage, fileData);
|
||||
case ConfuserVersion.v17_r72989: return decrypt_v16_r71742(peImage, fileData);
|
||||
case ConfuserVersion.v17_r73605: return decrypt_v17_r73605(peImage, fileData);
|
||||
case ConfuserVersion.v18_r75288: return decrypt_v17_r73605(peImage, fileData);
|
||||
case ConfuserVersion.v19_r75725: return decrypt_v17_r73605(peImage, fileData);
|
||||
case ConfuserVersion.v14_r57884: return Decrypt_v14_r57884(peImage, fileData);
|
||||
case ConfuserVersion.v14_r58004: return Decrypt_v14_r58004(peImage, fileData);
|
||||
case ConfuserVersion.v14_r58564: return Decrypt_v14_r58004(peImage, fileData);
|
||||
case ConfuserVersion.v14_r58852: return Decrypt_v14_r58004(peImage, fileData);
|
||||
case ConfuserVersion.v15_r59014: return Decrypt_v15_r59014(peImage, fileData);
|
||||
case ConfuserVersion.v16_r71742: return Decrypt_v16_r71742(peImage, fileData);
|
||||
case ConfuserVersion.v17_r72989: return Decrypt_v16_r71742(peImage, fileData);
|
||||
case ConfuserVersion.v17_r73605: return Decrypt_v17_r73605(peImage, fileData);
|
||||
case ConfuserVersion.v18_r75288: return Decrypt_v17_r73605(peImage, fileData);
|
||||
case ConfuserVersion.v19_r75725: return Decrypt_v17_r73605(peImage, fileData);
|
||||
default: throw new ApplicationException("Unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
bool decrypt_v14_r57884(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = decryptMethodsData_v14_r57884(peImage, false);
|
||||
bool Decrypt_v14_r57884(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = DecryptMethodsData_v14_r57884(peImage, false);
|
||||
|
||||
var reader = new BinaryReader(new MemoryStream(methodsData));
|
||||
reader.ReadInt16(); // sig
|
||||
|
@ -294,48 +294,48 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
uint rva = reader.ReadUInt32();
|
||||
if (rva == 0)
|
||||
continue;
|
||||
writer.BaseStream.Position = peImage.rvaToOffset(rva);
|
||||
writer.BaseStream.Position = peImage.RvaToOffset(rva);
|
||||
writer.Write(reader.ReadBytes(reader.ReadInt32()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
byte[] decryptMethodsData_v14_r57884(MyPEImage peImage, bool hasStrongNameInfo) {
|
||||
byte[] DecryptMethodsData_v14_r57884(MyPEImage peImage, bool hasStrongNameInfo) {
|
||||
var reader = peImage.Reader;
|
||||
reader.Position = 0;
|
||||
var md5SumData = reader.ReadBytes((int)peImage.OptionalHeader.CheckSum ^ (int)key0);
|
||||
|
||||
int csOffs = (int)peImage.OptionalHeader.StartOffset + 0x40;
|
||||
Array.Clear(md5SumData, csOffs, 4);
|
||||
var md5Sum = DeobUtils.md5Sum(md5SumData);
|
||||
var md5Sum = DeobUtils.Md5Sum(md5SumData);
|
||||
ulong checkSum = reader.ReadUInt64() ^ lkey0;
|
||||
if (hasStrongNameInfo) {
|
||||
int sn = reader.ReadInt32();
|
||||
int snLen = reader.ReadInt32();
|
||||
if (sn != 0) {
|
||||
if (peImage.rvaToOffset((uint)peImage.Cor20Header.StrongNameSignature.VirtualAddress) != sn ||
|
||||
if (peImage.RvaToOffset((uint)peImage.Cor20Header.StrongNameSignature.VirtualAddress) != sn ||
|
||||
peImage.Cor20Header.StrongNameSignature.Size != snLen)
|
||||
throw new ApplicationException("Invalid sn and snLen");
|
||||
Array.Clear(md5SumData, sn, snLen);
|
||||
}
|
||||
}
|
||||
if (checkSum != calcChecksum(md5SumData))
|
||||
if (checkSum != CalcChecksum(md5SumData))
|
||||
throw new ApplicationException("Invalid checksum. File has been modified.");
|
||||
var iv = reader.ReadBytes(reader.ReadInt32() ^ (int)key2);
|
||||
var encrypted = reader.ReadBytes(reader.ReadInt32() ^ (int)key3);
|
||||
var decrypted = decrypt(encrypted, iv, md5SumData);
|
||||
var decrypted = Decrypt(encrypted, iv, md5SumData);
|
||||
if (BitConverter.ToInt16(decrypted, 0) != 0x6FD6)
|
||||
throw new ApplicationException("Invalid magic");
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
bool decrypt_v14_r58004(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = decryptMethodsData_v14_r57884(peImage, false);
|
||||
return decryptImage_v14_r58004(peImage, fileData);
|
||||
bool Decrypt_v14_r58004(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = DecryptMethodsData_v14_r57884(peImage, false);
|
||||
return DecryptImage_v14_r58004(peImage, fileData);
|
||||
}
|
||||
|
||||
bool decryptImage_v14_r58004(MyPEImage peImage, byte[] fileData) {
|
||||
bool DecryptImage_v14_r58004(MyPEImage peImage, byte[] fileData) {
|
||||
var reader = new BinaryReader(new MemoryStream(methodsData));
|
||||
reader.ReadInt16(); // sig
|
||||
var writer = new BinaryWriter(new MemoryStream(fileData));
|
||||
|
@ -345,34 +345,34 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (offs == 0)
|
||||
continue;
|
||||
uint rva = reader.ReadUInt32() ^ key4;
|
||||
if (peImage.rvaToOffset(rva) != offs)
|
||||
if (peImage.RvaToOffset(rva) != offs)
|
||||
throw new ApplicationException("Invalid offs & rva");
|
||||
writer.BaseStream.Position = peImage.rvaToOffset(rva);
|
||||
writer.BaseStream.Position = peImage.RvaToOffset(rva);
|
||||
writer.Write(reader.ReadBytes(reader.ReadInt32()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool decrypt_v15_r59014(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = decryptMethodsData_v14_r57884(peImage, true);
|
||||
return decryptImage_v14_r58004(peImage, fileData);
|
||||
bool Decrypt_v15_r59014(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = DecryptMethodsData_v14_r57884(peImage, true);
|
||||
return DecryptImage_v14_r58004(peImage, fileData);
|
||||
}
|
||||
|
||||
bool decrypt_v16_r71742(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_v16_r71742(peImage.Sections));
|
||||
return decryptImage_v16_r71742(peImage, fileData);
|
||||
bool Decrypt_v16_r71742(MyPEImage peImage, byte[] fileData) {
|
||||
methodsData = DecryptMethodsData_v16_r71742(peImage, GetEncryptedHeaderOffset_v16_r71742(peImage.Sections));
|
||||
return DecryptImage_v16_r71742(peImage, fileData);
|
||||
}
|
||||
|
||||
bool decrypt_v17_r73605(MyPEImage peImage, byte[] fileData) {
|
||||
bool Decrypt_v17_r73605(MyPEImage peImage, byte[] fileData) {
|
||||
if (peImage.OptionalHeader.CheckSum == 0)
|
||||
return false;
|
||||
|
||||
methodsData = decryptMethodsData_v17_r73404(peImage);
|
||||
return decryptImage_v16_r71742(peImage, fileData);
|
||||
methodsData = DecryptMethodsData_v17_r73404(peImage);
|
||||
return DecryptImage_v16_r71742(peImage, fileData);
|
||||
}
|
||||
|
||||
bool decryptImage_v16_r71742(MyPEImage peImage, byte[] fileData) {
|
||||
bool DecryptImage_v16_r71742(MyPEImage peImage, byte[] fileData) {
|
||||
var reader = new BinaryReader(new MemoryStream(methodsData));
|
||||
reader.ReadInt16(); // sig
|
||||
int numInfos = reader.ReadInt32();
|
||||
|
@ -381,7 +381,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (offs == 0)
|
||||
continue;
|
||||
uint rva = reader.ReadUInt32() ^ key5;
|
||||
if (peImage.rvaToOffset(rva) != offs)
|
||||
if (peImage.RvaToOffset(rva) != offs)
|
||||
throw new ApplicationException("Invalid offs & rva");
|
||||
int len = reader.ReadInt32();
|
||||
for (int j = 0; j < len; j++)
|
||||
|
@ -390,7 +390,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
public override bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public override bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -57,20 +57,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.module = module;
|
||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
if (other != null)
|
||||
this.initMethod = lookup(other.initMethod, "Could not find initMethod");
|
||||
this.initMethod = Lookup(other.initMethod, "Could not find initMethod");
|
||||
}
|
||||
|
||||
T lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
|
||||
return DeobUtils.lookup(module, def, errorMessage);
|
||||
T Lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
|
||||
return DeobUtils.Lookup(module, def, errorMessage);
|
||||
}
|
||||
|
||||
public abstract bool getRevisionRange(out int minRev, out int maxRev);
|
||||
public abstract bool GetRevisionRange(out int minRev, out int maxRev);
|
||||
|
||||
public void find() {
|
||||
find(DotNetUtils.getModuleTypeCctor(module));
|
||||
public void Find() {
|
||||
Find(DotNetUtils.GetModuleTypeCctor(module));
|
||||
}
|
||||
|
||||
bool find(MethodDef method) {
|
||||
bool Find(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
|
@ -85,9 +85,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
catch {
|
||||
continue;
|
||||
}
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
|
||||
if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
|
||||
continue;
|
||||
if (!checkType(calledMethod.DeclaringType, calledMethod))
|
||||
if (!CheckType(calledMethod.DeclaringType, calledMethod))
|
||||
continue;
|
||||
|
||||
initMethod = calledMethod;
|
||||
|
@ -96,13 +96,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected abstract bool checkType(TypeDef type, MethodDef initMethod);
|
||||
protected abstract bool CheckType(TypeDef type, MethodDef initMethod);
|
||||
|
||||
protected static MethodDef findDecryptMethod(TypeDef type) {
|
||||
protected static MethodDef FindDecryptMethod(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte[],System.Byte[],System.Byte[])"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Byte[]", "(System.Byte[],System.Byte[],System.Byte[])"))
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -110,10 +110,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected static bool findLKey0(MethodDef method, out ulong key) {
|
||||
protected static bool FindLKey0(MethodDef method, out ulong key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = findCallvirtReadUInt64(instrs, index);
|
||||
index = FindCallvirtReadUInt64(instrs, index);
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index + 1 >= instrs.Count)
|
||||
|
@ -130,10 +130,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey0_v16_r71742(MethodDef method, out uint key) {
|
||||
protected static bool FindKey0_v16_r71742(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 5 < instrs.Count; i++) {
|
||||
i = findCallvirtReadUInt32(instrs, i);
|
||||
i = FindCallvirtReadUInt32(instrs, i);
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
|
@ -161,10 +161,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey0_v14_r58564(MethodDef method, out uint key) {
|
||||
protected static bool FindKey0_v14_r58564(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 5 < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()");
|
||||
if (i < 0)
|
||||
break;
|
||||
|
||||
|
@ -192,22 +192,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static bool findKey1(MethodDef method, out uint key) {
|
||||
protected static bool FindKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = findCallvirtReadUInt32(instrs, index);
|
||||
index = FindCallvirtReadUInt32(instrs, index);
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index == 0)
|
||||
continue;
|
||||
int i = index - 1;
|
||||
if (!checkCallvirtReadUInt32(instrs, ref i))
|
||||
if (!CheckCallvirtReadUInt32(instrs, ref i))
|
||||
continue;
|
||||
if (!checkCallvirtReadUInt32(instrs, ref i))
|
||||
if (!CheckCallvirtReadUInt32(instrs, ref i))
|
||||
continue;
|
||||
if (!checkCallvirtReadUInt32(instrs, ref i))
|
||||
if (!CheckCallvirtReadUInt32(instrs, ref i))
|
||||
continue;
|
||||
if (!checkCallvirtReadUInt32(instrs, ref i))
|
||||
if (!CheckCallvirtReadUInt32(instrs, ref i))
|
||||
continue;
|
||||
|
||||
if (i + 1 >= instrs.Count)
|
||||
|
@ -226,13 +226,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool checkCallvirtReadUInt32(IList<Instruction> instrs, ref int index) {
|
||||
static bool CheckCallvirtReadUInt32(IList<Instruction> instrs, ref int index) {
|
||||
if (index + 2 >= instrs.Count)
|
||||
return false;
|
||||
|
||||
if (!instrs[index].IsLdloc())
|
||||
return false;
|
||||
if (!ConfuserUtils.isCallMethod(instrs[index + 1], Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()"))
|
||||
if (!ConfuserUtils.IsCallMethod(instrs[index + 1], Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()"))
|
||||
return false;
|
||||
if (!instrs[index + 2].IsStloc() && instrs[index + 2].OpCode.Code != Code.Pop)
|
||||
return false;
|
||||
|
@ -241,13 +241,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected static bool findKey2Key3(MethodDef method, out uint key2, out uint key3) {
|
||||
protected static bool FindKey2Key3(MethodDef method, out uint key2, out uint key3) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = i;
|
||||
if (!findKey2OrKey3(instrs, ref index, out key2))
|
||||
if (!FindKey2OrKey3(instrs, ref index, out key2))
|
||||
continue;
|
||||
if (!findKey2OrKey3(instrs, ref index, out key3))
|
||||
if (!FindKey2OrKey3(instrs, ref index, out key3))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
|
@ -258,7 +258,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey2OrKey3(IList<Instruction> instrs, ref int index, out uint key) {
|
||||
static bool FindKey2OrKey3(IList<Instruction> instrs, ref int index, out uint key) {
|
||||
key = 0;
|
||||
if (index + 6 >= instrs.Count)
|
||||
return false;
|
||||
|
@ -267,14 +267,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
if (!instrs[i++].IsLdloc())
|
||||
return false;
|
||||
if (!ConfuserUtils.isCallMethod(instrs[i++], Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()"))
|
||||
if (!ConfuserUtils.IsCallMethod(instrs[i++], Code.Callvirt, "System.Int32 System.IO.BinaryReader::ReadInt32()"))
|
||||
return false;
|
||||
var ldci4 = instrs[i++];
|
||||
if (!ldci4.IsLdcI4())
|
||||
return false;
|
||||
if (instrs[i++].OpCode.Code != Code.Xor)
|
||||
return false;
|
||||
if (!ConfuserUtils.isCallMethod(instrs[i++], Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)"))
|
||||
if (!ConfuserUtils.IsCallMethod(instrs[i++], Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)"))
|
||||
return false;
|
||||
if (!instrs[i++].IsStloc())
|
||||
return false;
|
||||
|
@ -284,7 +284,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected static bool findKey6(MethodDef method, out uint key) {
|
||||
protected static bool FindKey6(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i + 4 < instrs.Count; i++) {
|
||||
int index = i;
|
||||
|
@ -310,19 +310,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected static int findCallvirtReadUInt32(IList<Instruction> instrs, int index) {
|
||||
return ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()");
|
||||
protected static int FindCallvirtReadUInt32(IList<Instruction> instrs, int index) {
|
||||
return ConfuserUtils.FindCallMethod(instrs, index, Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()");
|
||||
}
|
||||
|
||||
static int findCallvirtReadUInt64(IList<Instruction> instrs, int index) {
|
||||
return ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.UInt64 System.IO.BinaryReader::ReadUInt64()");
|
||||
static int FindCallvirtReadUInt64(IList<Instruction> instrs, int index) {
|
||||
return ConfuserUtils.FindCallMethod(instrs, index, Code.Callvirt, "System.UInt64 System.IO.BinaryReader::ReadUInt64()");
|
||||
}
|
||||
|
||||
protected byte[] decryptMethodsData_v17_r73404(MyPEImage peImage) {
|
||||
return decryptMethodsData_v16_r71742(peImage, getEncryptedHeaderOffset_vXX(peImage.Sections));
|
||||
protected byte[] DecryptMethodsData_v17_r73404(MyPEImage peImage) {
|
||||
return DecryptMethodsData_v16_r71742(peImage, GetEncryptedHeaderOffset_vXX(peImage.Sections));
|
||||
}
|
||||
|
||||
protected byte[] decryptMethodsData_v16_r71742(MyPEImage peImage, uint encryptedHeaderOffset) {
|
||||
protected byte[] DecryptMethodsData_v16_r71742(MyPEImage peImage, uint encryptedHeaderOffset) {
|
||||
uint mdRva = peImage.OptionalHeader.CheckSum ^ (uint)key0;
|
||||
if ((RVA)mdRva != peImage.Cor20Header.MetaData.VirtualAddress)
|
||||
throw new ApplicationException("Invalid metadata rva");
|
||||
|
@ -333,16 +333,16 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
reader.ReadInt32(); // strong name len
|
||||
var iv = reader.ReadBytes(reader.ReadInt32() ^ (int)key2);
|
||||
var encrypted = reader.ReadBytes(reader.ReadInt32() ^ (int)key3);
|
||||
var streamsBuffer = getStreamsBuffer(peImage);
|
||||
if (checkSum != calcChecksum(streamsBuffer))
|
||||
var streamsBuffer = GetStreamsBuffer(peImage);
|
||||
if (checkSum != CalcChecksum(streamsBuffer))
|
||||
throw new ApplicationException("Invalid checksum. File has been modified.");
|
||||
var decrypted = decrypt(encrypted, iv, streamsBuffer);
|
||||
var decrypted = Decrypt(encrypted, iv, streamsBuffer);
|
||||
if (BitConverter.ToInt16(decrypted, 0) != 0x6FD6)
|
||||
throw new ApplicationException("Invalid magic");
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
protected uint getEncryptedHeaderOffset_v16_r71742(IList<ImageSectionHeader> sections) {
|
||||
protected uint GetEncryptedHeaderOffset_v16_r71742(IList<ImageSectionHeader> sections) {
|
||||
for (int i = sections.Count - 1; i >= 0; i--) {
|
||||
var section = sections[i];
|
||||
if (section.DisplayName == ".confuse")
|
||||
|
@ -351,16 +351,16 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Could not find encrypted section");
|
||||
}
|
||||
|
||||
uint getEncryptedHeaderOffset_vXX(IList<ImageSectionHeader> sections) {
|
||||
uint GetEncryptedHeaderOffset_vXX(IList<ImageSectionHeader> sections) {
|
||||
for (int i = sections.Count - 1; i >= 0; i--) {
|
||||
var section = sections[i];
|
||||
if (getSectionNameHash(section) == (uint)key1)
|
||||
if (GetSectionNameHash(section) == (uint)key1)
|
||||
return section.PointerToRawData;
|
||||
}
|
||||
throw new ApplicationException("Could not find encrypted section");
|
||||
}
|
||||
|
||||
static byte[] getStreamsBuffer(MyPEImage peImage) {
|
||||
static byte[] GetStreamsBuffer(MyPEImage peImage) {
|
||||
var memStream = new MemoryStream();
|
||||
var writer = new BinaryWriter(memStream);
|
||||
var reader = peImage.Reader;
|
||||
|
@ -371,20 +371,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return memStream.ToArray();
|
||||
}
|
||||
|
||||
protected static ulong calcChecksum(byte[] data) {
|
||||
var sum = DeobUtils.md5Sum(data);
|
||||
protected static ulong CalcChecksum(byte[] data) {
|
||||
var sum = DeobUtils.Md5Sum(data);
|
||||
return BitConverter.ToUInt64(sum, 0) ^ BitConverter.ToUInt64(sum, 8);
|
||||
}
|
||||
|
||||
static uint getSectionNameHash(ImageSectionHeader section) {
|
||||
static uint GetSectionNameHash(ImageSectionHeader section) {
|
||||
uint hash = 0;
|
||||
foreach (var c in section.Name)
|
||||
hash += c;
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected byte[] decrypt(byte[] encrypted, byte[] iv, byte[] streamsBuffer) {
|
||||
var decrypted = DeobUtils.aesDecrypt(encrypted, DeobUtils.sha256Sum(streamsBuffer), iv);
|
||||
protected byte[] Decrypt(byte[] encrypted, byte[] iv, byte[] streamsBuffer) {
|
||||
var decrypted = DeobUtils.AesDecrypt(encrypted, DeobUtils.Sha256Sum(streamsBuffer), iv);
|
||||
var sha = SHA512.Create();
|
||||
var hash = sha.ComputeHash(streamsBuffer);
|
||||
for (int i = 0; i < decrypted.Length; i += 64) {
|
||||
|
|
|
@ -109,8 +109,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
public IEnumerable<FieldDef> Fields {
|
||||
get {
|
||||
var fields = new List<FieldDef>(fieldToMethods.getKeys());
|
||||
var type = DotNetUtils.getModuleType(module);
|
||||
var fields = new List<FieldDef>(fieldToMethods.GetKeys());
|
||||
var type = DotNetUtils.GetModuleType(module);
|
||||
if (fields.Count > 0 && type != null) {
|
||||
foreach (var field in type.Fields) {
|
||||
var fieldType = field.FieldType.TryGetTypeDef();
|
||||
|
@ -125,7 +125,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
public override IEnumerable<Tuple<MethodDef, string>> OtherMethods {
|
||||
get {
|
||||
var list = new List<Tuple<MethodDef, string>>();
|
||||
foreach (var info in methodToInfo.getValues()) {
|
||||
foreach (var info in methodToInfo.GetValues()) {
|
||||
list.Add(new Tuple<MethodDef, string> {
|
||||
Item1 = info.creatorMethod,
|
||||
Item2 = "Delegate creator method",
|
||||
|
@ -135,7 +135,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
Item2 = "Calculate RID native method",
|
||||
});
|
||||
}
|
||||
foreach (var methods in fieldToMethods.getValues()) {
|
||||
foreach (var methods in fieldToMethods.GetValues()) {
|
||||
foreach (var method in methods) {
|
||||
list.Add(new Tuple<MethodDef, string> {
|
||||
Item1 = method,
|
||||
|
@ -156,7 +156,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
ourAsm = module.Assembly.FullName;
|
||||
}
|
||||
|
||||
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
||||
protected override object CheckCctor(TypeDef type, MethodDef cctor) {
|
||||
// Here if 1.2 r54564 (almost 1.3) or later
|
||||
|
||||
var fieldToInfo = new FieldDefAndDeclaringTypeDict<DelegateInitInfo>();
|
||||
|
@ -176,33 +176,33 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var calledMethod = call.Operand as MethodDef;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (!isDelegateCreatorMethod(calledMethod))
|
||||
if (!IsDelegateCreatorMethod(calledMethod))
|
||||
continue;
|
||||
var info = methodToInfo.find(calledMethod);
|
||||
var info = methodToInfo.Find(calledMethod);
|
||||
if (info == null)
|
||||
continue;
|
||||
|
||||
i++;
|
||||
fieldToInfo.add(field, new DelegateInitInfo(field, calledMethod));
|
||||
fieldToInfo.Add(field, new DelegateInitInfo(field, calledMethod));
|
||||
}
|
||||
return fieldToInfo.Count == 0 ? null : fieldToInfo;
|
||||
}
|
||||
|
||||
protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
protected override void GetCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var info = context as DelegateInitInfo;
|
||||
if (info == null) {
|
||||
var fieldToInfo = context as FieldDefAndDeclaringTypeDict<DelegateInitInfo>;
|
||||
if (fieldToInfo != null)
|
||||
info = fieldToInfo.find(field);
|
||||
info = fieldToInfo.Find(field);
|
||||
}
|
||||
if (info == null)
|
||||
throw new ApplicationException("Couldn't get the delegate info");
|
||||
var creatorInfo = methodToInfo.find(info.creatorMethod);
|
||||
var creatorInfo = methodToInfo.Find(info.creatorMethod);
|
||||
|
||||
switch (creatorInfo.version) {
|
||||
case ConfuserVersion.v10_r42915:
|
||||
case ConfuserVersion.v10_r42919:
|
||||
getCallInfo_v10_r42915(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v10_r42915(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
case ConfuserVersion.v10_r48717:
|
||||
|
@ -212,36 +212,36 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
case ConfuserVersion.v13_r55604:
|
||||
case ConfuserVersion.v14_r58564:
|
||||
case ConfuserVersion.v14_r58802:
|
||||
getCallInfo_v10_r48717(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v10_r48717(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
case ConfuserVersion.v14_r58857:
|
||||
case ConfuserVersion.v16_r66631:
|
||||
case ConfuserVersion.v16_r70489:
|
||||
case ConfuserVersion.v17_r73479:
|
||||
getCallInfo_v14_r58857(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v14_r58857(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
case ConfuserVersion.v17_r73740_normal:
|
||||
case ConfuserVersion.v17_r74708_normal:
|
||||
getCallInfo_v17_r73740_normal(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v17_r73740_normal(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
case ConfuserVersion.v17_r73740_native:
|
||||
case ConfuserVersion.v17_r74708_native:
|
||||
getCallInfo_v17_r73740_native(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v17_r73740_native(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
case ConfuserVersion.v18_r75367_normal:
|
||||
case ConfuserVersion.v18_r75369_normal:
|
||||
case ConfuserVersion.v19_r76101_normal:
|
||||
getCallInfo_v18_r75367_normal(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v18_r75367_normal(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
case ConfuserVersion.v18_r75367_native:
|
||||
case ConfuserVersion.v18_r75369_native:
|
||||
case ConfuserVersion.v19_r76101_native:
|
||||
getCallInfo_v18_r75367_native(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
GetCallInfo_v18_r75367_native(info, creatorInfo, out calledMethod, out callOpcode);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -254,14 +254,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
void getCallInfo_v10_r42915(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
void GetCallInfo_v10_r42915(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var reader = new BinaryReader(new MemoryStream(info.data));
|
||||
|
||||
bool isCallvirt = false;
|
||||
if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt)
|
||||
isCallvirt = reader.ReadBoolean();
|
||||
|
||||
var asmRef = readAssemblyNameReference(reader);
|
||||
var asmRef = ReadAssemblyNameReference(reader);
|
||||
// If < 1.0 r42919, then high byte is 06, else it's cleared.
|
||||
uint token = (reader.ReadUInt32() & 0x00FFFFFF) | 0x06000000;
|
||||
if (reader.BaseStream.Position != reader.BaseStream.Length)
|
||||
|
@ -270,12 +270,12 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (asmRef.FullName == ourAsm)
|
||||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
else
|
||||
calledMethod = createMethodReference(asmRef, token);
|
||||
calledMethod = CreateMethodReference(asmRef, token);
|
||||
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v10_r48717(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
void GetCallInfo_v10_r48717(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
bool isNew = creatorInfo.version == ConfuserVersion.v14_r58802;
|
||||
|
||||
int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 2 : 1;
|
||||
|
@ -303,18 +303,18 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
else {
|
||||
var asmRef = module.ResolveAssemblyRef((uint)info.field.Name.String[0] - 2 + 1);
|
||||
calledMethod = createMethodReference(asmRef, token);
|
||||
calledMethod = CreateMethodReference(asmRef, token);
|
||||
}
|
||||
|
||||
bool isCallvirt = false;
|
||||
if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && info.field.Name.String[callvirtOffs] == '\r')
|
||||
isCallvirt = true;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v14_r58857(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
void GetCallInfo_v14_r58857(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
int offs = creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt ? 1 : 0;
|
||||
var nameInfo = decryptFieldName(info.field.Name.String);
|
||||
var nameInfo = DecryptFieldName(info.field.Name.String);
|
||||
|
||||
uint token = BitConverter.ToUInt32(nameInfo, offs) ^ creatorInfo.magic;
|
||||
uint table = token >> 24;
|
||||
|
@ -326,17 +326,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
bool isCallvirt = false;
|
||||
if (creatorInfo.proxyCreatorType == ProxyCreatorType.CallOrCallvirt && nameInfo[0] == '\r')
|
||||
isCallvirt = true;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
static byte[] decryptFieldName(string name) {
|
||||
static byte[] DecryptFieldName(string name) {
|
||||
var chars = new char[name.Length];
|
||||
for (int i = 0; i < chars.Length; i++)
|
||||
chars[i] = (char)((byte)name[i] ^ i);
|
||||
return Convert.FromBase64CharArray(chars, 0, chars.Length);
|
||||
}
|
||||
|
||||
void extract_v17_r73740(ProxyCreatorInfo creatorInfo, byte[] nameInfo, out uint arg, out uint table, out bool isCallvirt) {
|
||||
void Extract_v17_r73740(ProxyCreatorInfo creatorInfo, byte[] nameInfo, out uint arg, out uint table, out bool isCallvirt) {
|
||||
switch (creatorInfo.proxyCreatorType) {
|
||||
case ProxyCreatorType.CallOrCallvirt:
|
||||
arg = BitConverter.ToUInt32(nameInfo, 1);
|
||||
|
@ -355,43 +355,43 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
void getCallInfo_v17_r73740_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = decryptFieldName(info.field.Name.String);
|
||||
void GetCallInfo_v17_r73740_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = DecryptFieldName(info.field.Name.String);
|
||||
uint arg, table;
|
||||
bool isCallvirt;
|
||||
extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
|
||||
Extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
|
||||
uint token = (arg ^ creatorInfo.magic) | table;
|
||||
|
||||
calledMethod = module.ResolveToken((int)token) as IMethod;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v17_r73740_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = decryptFieldName(info.field.Name.String);
|
||||
void GetCallInfo_v17_r73740_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
var nameInfo = DecryptFieldName(info.field.Name.String);
|
||||
uint arg, table;
|
||||
bool isCallvirt;
|
||||
extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
|
||||
Extract_v17_r73740(creatorInfo, nameInfo, out arg, out table, out isCallvirt);
|
||||
if (x86emu == null)
|
||||
x86emu = new x86Emulator(fileData);
|
||||
uint token = x86emu.emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table;
|
||||
uint token = x86emu.Emulate((uint)creatorInfo.nativeMethod.RVA, arg) | table;
|
||||
|
||||
calledMethod = module.ResolveToken((int)token) as IMethod;
|
||||
callOpcode = getCallOpCode(creatorInfo, isCallvirt);
|
||||
callOpcode = GetCallOpCode(creatorInfo, isCallvirt);
|
||||
}
|
||||
|
||||
void getCallInfo_v18_r75367_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
getCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => creatorInfo2.magic ^ magic);
|
||||
void GetCallInfo_v18_r75367_normal(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
GetCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => creatorInfo2.magic ^ magic);
|
||||
}
|
||||
|
||||
void getCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
getCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => {
|
||||
void GetCallInfo_v18_r75367_native(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode) {
|
||||
GetCallInfo_v18_r75367(info, creatorInfo, out calledMethod, out callOpcode, (creatorInfo2, magic) => {
|
||||
if (x86emu == null)
|
||||
x86emu = new x86Emulator(fileData);
|
||||
return x86emu.emulate((uint)creatorInfo2.nativeMethod.RVA, magic);
|
||||
return x86emu.Emulate((uint)creatorInfo2.nativeMethod.RVA, magic);
|
||||
});
|
||||
}
|
||||
|
||||
void getCallInfo_v18_r75367(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode, Func<ProxyCreatorInfo, uint, uint> getRid) {
|
||||
void GetCallInfo_v18_r75367(DelegateInitInfo info, ProxyCreatorInfo creatorInfo, out IMethod calledMethod, out OpCode callOpcode, Func<ProxyCreatorInfo, uint, uint> getRid) {
|
||||
var sig = module.ReadBlob(info.field.MDToken.Raw);
|
||||
int len = sig.Length;
|
||||
uint magic = (uint)((sig[len - 2] << 24) | (sig[len - 3] << 16) | (sig[len - 5] << 8) | sig[len - 6]);
|
||||
|
@ -401,10 +401,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (table != 6 && table != 0x0A && table != 0x2B)
|
||||
throw new ApplicationException("Invalid method token");
|
||||
calledMethod = module.ResolveToken(token) as IMethod;
|
||||
callOpcode = getCallOpCode(creatorInfo, info.field);
|
||||
callOpcode = GetCallOpCode(creatorInfo, info.field);
|
||||
}
|
||||
|
||||
static OpCode getCallOpCode(ProxyCreatorInfo info, FieldDef field) {
|
||||
static OpCode GetCallOpCode(ProxyCreatorInfo info, FieldDef field) {
|
||||
switch (info.proxyCreatorType) {
|
||||
case ProxyCreatorType.CallOrCallvirt:
|
||||
if (field.Name.String.Length > 0 && field.Name.String[0] == info.callvirtChar)
|
||||
|
@ -420,7 +420,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
// A method token is not a stable value so this method can fail to return the correct method!
|
||||
// There's nothing I can do about that. It's an obfuscator bug. It was fixed in 1.3 r55346.
|
||||
IMethod createMethodReference(AssemblyRef asmRef, uint methodToken) {
|
||||
IMethod CreateMethodReference(AssemblyRef asmRef, uint methodToken) {
|
||||
var asm = module.Context.AssemblyResolver.Resolve(asmRef, module);
|
||||
if (asm == null)
|
||||
return null;
|
||||
|
@ -432,15 +432,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return module.Import(method);
|
||||
}
|
||||
|
||||
AssemblyRef readAssemblyNameReference(BinaryReader reader) {
|
||||
var name = readString(reader);
|
||||
AssemblyRef ReadAssemblyNameReference(BinaryReader reader) {
|
||||
var name = ReadString(reader);
|
||||
var version = new Version(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16());
|
||||
var culture = readString(reader);
|
||||
var culture = ReadString(reader);
|
||||
byte[] pkt = reader.ReadBoolean() ? reader.ReadBytes(8) : null;
|
||||
return module.UpdateRowId(new AssemblyRefUser(name, version, pkt == null ? null : new PublicKeyToken(pkt), culture));
|
||||
}
|
||||
|
||||
static string readString(BinaryReader reader) {
|
||||
static string ReadString(BinaryReader reader) {
|
||||
int len = reader.ReadByte();
|
||||
var bytes = new byte[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
|
@ -448,7 +448,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
|
||||
static OpCode getCallOpCode(ProxyCreatorInfo info, bool isCallvirt) {
|
||||
static OpCode GetCallOpCode(ProxyCreatorInfo info, bool isCallvirt) {
|
||||
switch (info.proxyCreatorType) {
|
||||
case ProxyCreatorType.Newobj:
|
||||
return OpCodes.Newobj;
|
||||
|
@ -460,8 +460,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public void findDelegateCreator(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
var type = DotNetUtils.getModuleType(module);
|
||||
public void FindDelegateCreator(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
var type = DotNetUtils.GetModuleType(module);
|
||||
if (type == null)
|
||||
return;
|
||||
foreach (var method in type.Methods) {
|
||||
|
@ -469,90 +469,90 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
ConfuserVersion theVersion = ConfuserVersion.Unknown;
|
||||
|
||||
if (DotNetUtils.isMethod(method, "System.Void", "(System.String,System.RuntimeFieldHandle)"))
|
||||
if (DotNetUtils.IsMethod(method, "System.Void", "(System.String,System.RuntimeFieldHandle)"))
|
||||
theVersion = ConfuserVersion.v10_r42915;
|
||||
else if (DotNetUtils.isMethod(method, "System.Void", "(System.RuntimeFieldHandle)"))
|
||||
else if (DotNetUtils.IsMethod(method, "System.Void", "(System.RuntimeFieldHandle)"))
|
||||
theVersion = ConfuserVersion.v10_r48717;
|
||||
else
|
||||
continue;
|
||||
|
||||
var proxyType = getProxyCreatorType(method);
|
||||
var proxyType = GetProxyCreatorType(method);
|
||||
if (proxyType == ProxyCreatorType.None)
|
||||
continue;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
simpleDeobfuscator.Deobfuscate(method);
|
||||
MethodDef nativeMethod = null;
|
||||
uint magic;
|
||||
if (findMagic_v14_r58564(method, out magic)) {
|
||||
if (!DotNetUtils.callsMethod(method, "System.Byte[] System.Convert::FromBase64String(System.String)")) {
|
||||
if (!isMethodCreator_v14_r58802(method, proxyType))
|
||||
if (FindMagic_v14_r58564(method, out magic)) {
|
||||
if (!DotNetUtils.CallsMethod(method, "System.Byte[] System.Convert::FromBase64String(System.String)")) {
|
||||
if (!IsMethodCreator_v14_r58802(method, proxyType))
|
||||
theVersion = ConfuserVersion.v14_r58564;
|
||||
else
|
||||
theVersion = ConfuserVersion.v14_r58802;
|
||||
}
|
||||
else if (DotNetUtils.callsMethod(method, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()"))
|
||||
else if (DotNetUtils.CallsMethod(method, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()"))
|
||||
theVersion = ConfuserVersion.v17_r73479;
|
||||
else if (proxyType != ProxyCreatorType.CallOrCallvirt || !hasFieldReference(method, "System.Reflection.Emit.OpCode System.Reflection.Emit.OpCodes::Castclass"))
|
||||
else if (proxyType != ProxyCreatorType.CallOrCallvirt || !HasFieldReference(method, "System.Reflection.Emit.OpCode System.Reflection.Emit.OpCodes::Castclass"))
|
||||
theVersion = ConfuserVersion.v14_r58857;
|
||||
else if (proxyType == ProxyCreatorType.CallOrCallvirt && DotNetUtils.callsMethod(method, "System.Void System.Reflection.Emit.DynamicMethod::.ctor(System.String,System.Type,System.Type[],System.Boolean)"))
|
||||
else if (proxyType == ProxyCreatorType.CallOrCallvirt && DotNetUtils.CallsMethod(method, "System.Void System.Reflection.Emit.DynamicMethod::.ctor(System.String,System.Type,System.Type[],System.Boolean)"))
|
||||
theVersion = ConfuserVersion.v16_r66631;
|
||||
else if (proxyType == ProxyCreatorType.CallOrCallvirt)
|
||||
theVersion = ConfuserVersion.v16_r70489;
|
||||
}
|
||||
else if (!DotNetUtils.callsMethod(method, "System.Byte[] System.Convert::FromBase64String(System.String)") &&
|
||||
DotNetUtils.callsMethod(method, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)")) {
|
||||
if (proxyType == ProxyCreatorType.CallOrCallvirt && !findCallvirtChar(method, out callvirtChar))
|
||||
else if (!DotNetUtils.CallsMethod(method, "System.Byte[] System.Convert::FromBase64String(System.String)") &&
|
||||
DotNetUtils.CallsMethod(method, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)")) {
|
||||
if (proxyType == ProxyCreatorType.CallOrCallvirt && !FindCallvirtChar(method, out callvirtChar))
|
||||
continue;
|
||||
if ((nativeMethod = findNativeMethod_v18_r75367(method)) != null)
|
||||
if ((nativeMethod = FindNativeMethod_v18_r75367(method)) != null)
|
||||
theVersion = proxyType != ProxyCreatorType.CallOrCallvirt || callvirtChar == 9 ? ConfuserVersion.v18_r75367_native : ConfuserVersion.v18_r75369_native;
|
||||
else if (findMagic_v18_r75367(method, out magic))
|
||||
else if (FindMagic_v18_r75367(method, out magic))
|
||||
theVersion = proxyType != ProxyCreatorType.CallOrCallvirt || callvirtChar == 9 ? ConfuserVersion.v18_r75367_normal : ConfuserVersion.v18_r75369_normal;
|
||||
else if (findMagic_v19_r76101(method, out magic))
|
||||
else if (FindMagic_v19_r76101(method, out magic))
|
||||
theVersion = ConfuserVersion.v19_r76101_normal;
|
||||
else if ((nativeMethod = findNativeMethod_v19_r76101(method)) != null)
|
||||
else if ((nativeMethod = FindNativeMethod_v19_r76101(method)) != null)
|
||||
theVersion = ConfuserVersion.v19_r76101_native;
|
||||
else {
|
||||
if (proxyType == ProxyCreatorType.CallOrCallvirt && !DotNetUtils.callsMethod(method, "System.Int32 System.String::get_Length()"))
|
||||
if (proxyType == ProxyCreatorType.CallOrCallvirt && !DotNetUtils.CallsMethod(method, "System.Int32 System.String::get_Length()"))
|
||||
theVersion = ConfuserVersion.v11_r50378;
|
||||
int numCalls = ConfuserUtils.countCalls(method, "System.Byte[] System.Text.Encoding::GetBytes(System.Char[],System.Int32,System.Int32)");
|
||||
int numCalls = ConfuserUtils.CountCalls(method, "System.Byte[] System.Text.Encoding::GetBytes(System.Char[],System.Int32,System.Int32)");
|
||||
if (numCalls == 2)
|
||||
theVersion = ConfuserVersion.v12_r54564;
|
||||
if (!DotNetUtils.callsMethod(method, "System.Reflection.Assembly System.Reflection.Assembly::Load(System.Reflection.AssemblyName)"))
|
||||
if (!DotNetUtils.CallsMethod(method, "System.Reflection.Assembly System.Reflection.Assembly::Load(System.Reflection.AssemblyName)"))
|
||||
theVersion = ConfuserVersion.v13_r55346;
|
||||
if (DotNetUtils.callsMethod(method, "System.Void System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor(System.RuntimeTypeHandle)"))
|
||||
if (DotNetUtils.CallsMethod(method, "System.Void System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor(System.RuntimeTypeHandle)"))
|
||||
theVersion = ConfuserVersion.v13_r55604;
|
||||
}
|
||||
}
|
||||
else if (is_v17_r73740(method)) {
|
||||
if (DotNetUtils.callsMethod(method, "System.Boolean System.Type::get_IsArray()")) {
|
||||
if ((nativeMethod = findNativeMethod_v17_r73740(method)) != null)
|
||||
else if (Is_v17_r73740(method)) {
|
||||
if (DotNetUtils.CallsMethod(method, "System.Boolean System.Type::get_IsArray()")) {
|
||||
if ((nativeMethod = FindNativeMethod_v17_r73740(method)) != null)
|
||||
theVersion = ConfuserVersion.v17_r74708_native;
|
||||
else if (findMagic_v17_r73740(method, out magic))
|
||||
else if (FindMagic_v17_r73740(method, out magic))
|
||||
theVersion = ConfuserVersion.v17_r74708_normal;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
if ((nativeMethod = findNativeMethod_v17_r73740(method)) != null)
|
||||
if ((nativeMethod = FindNativeMethod_v17_r73740(method)) != null)
|
||||
theVersion = ConfuserVersion.v17_r73740_native;
|
||||
else if (findMagic_v17_r73740(method, out magic))
|
||||
else if (FindMagic_v17_r73740(method, out magic))
|
||||
theVersion = ConfuserVersion.v17_r73740_normal;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (theVersion == ConfuserVersion.v10_r42915) {
|
||||
if (DeobUtils.hasInteger(method, 0x06000000))
|
||||
if (DeobUtils.HasInteger(method, 0x06000000))
|
||||
theVersion = ConfuserVersion.v10_r42919;
|
||||
}
|
||||
|
||||
setDelegateCreatorMethod(method);
|
||||
methodToInfo.add(method, new ProxyCreatorInfo(method, proxyType, theVersion, magic, nativeMethod, callvirtChar));
|
||||
SetDelegateCreatorMethod(method);
|
||||
methodToInfo.Add(method, new ProxyCreatorInfo(method, proxyType, theVersion, magic, nativeMethod, callvirtChar));
|
||||
version = (ConfuserVersion)Math.Max((int)version, (int)theVersion);
|
||||
}
|
||||
}
|
||||
|
||||
static bool hasFieldReference(MethodDef method, string fieldFullName) {
|
||||
static bool HasFieldReference(MethodDef method, string fieldFullName) {
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var field = instr.Operand as IField;
|
||||
if (field == null)
|
||||
|
@ -563,8 +563,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isMethodCreator_v14_r58802(MethodDef method, ProxyCreatorType proxyType) {
|
||||
int index = getFieldNameIndex(method);
|
||||
static bool IsMethodCreator_v14_r58802(MethodDef method, ProxyCreatorType proxyType) {
|
||||
int index = GetFieldNameIndex(method);
|
||||
if (index < 0)
|
||||
throw new ApplicationException("Could not find field name index");
|
||||
switch (proxyType) {
|
||||
|
@ -588,10 +588,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Could not find field name index");
|
||||
}
|
||||
|
||||
static int getFieldNameIndex(MethodDef method) {
|
||||
static int GetFieldNameIndex(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.Text.Encoding::GetBytes(System.Char[],System.Int32,System.Int32)");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.Text.Encoding::GetBytes(System.Char[],System.Int32,System.Int32)");
|
||||
if (i < 0)
|
||||
break;
|
||||
if (i < 2)
|
||||
|
@ -605,7 +605,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static bool findMagic_v19_r76101(MethodDef method, out uint magic) {
|
||||
static bool FindMagic_v19_r76101(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 7; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
|
@ -634,7 +634,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static MethodDef findNativeMethod_v19_r76101(MethodDef method) {
|
||||
static MethodDef FindNativeMethod_v19_r76101(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 6; i++) {
|
||||
var ldci4 = instrs[i];
|
||||
|
@ -662,10 +662,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findMagic_v18_r75367(MethodDef method, out uint magic) {
|
||||
static bool FindMagic_v18_r75367(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
if (i < 0 || i + 3 >= instrs.Count)
|
||||
break;
|
||||
|
||||
|
@ -684,10 +684,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static MethodDef findNativeMethod_v18_r75367(MethodDef method) {
|
||||
static MethodDef FindNativeMethod_v18_r75367(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Reflection.Module System.Reflection.MemberInfo::get_Module()");
|
||||
if (i < 0 || i + 2 >= instrs.Count)
|
||||
break;
|
||||
|
||||
|
@ -706,10 +706,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findMagic_v17_r73740(MethodDef method, out uint magic) {
|
||||
static bool FindMagic_v17_r73740(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index < 1 || index + 2 >= instrs.Count)
|
||||
|
@ -730,10 +730,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static MethodDef findNativeMethod_v17_r73740(MethodDef method) {
|
||||
static MethodDef FindNativeMethod_v17_r73740(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index < 1 || index + 1 >= instrs.Count)
|
||||
|
@ -753,10 +753,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool is_v17_r73740(MethodDef method) {
|
||||
static bool Is_v17_r73740(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index < 3)
|
||||
|
@ -776,13 +776,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findMagic_v14_r58564(MethodDef method, out uint magic) {
|
||||
static bool FindMagic_v14_r58564(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Call, "System.Int32 System.BitConverter::ToInt32(System.Byte[],System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
int index2 = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
|
||||
int index2 = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
|
||||
if (index2 < 0 || index2 - index != 3)
|
||||
continue;
|
||||
var ldci4 = instrs[index + 1];
|
||||
|
@ -798,7 +798,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static ProxyCreatorType getProxyCreatorType(MethodDef method) {
|
||||
static ProxyCreatorType GetProxyCreatorType(MethodDef method) {
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var field = instr.Operand as IField;
|
||||
if (field == null)
|
||||
|
@ -815,21 +815,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return ProxyCreatorType.None;
|
||||
}
|
||||
|
||||
public new void find() {
|
||||
public new void Find() {
|
||||
if (delegateCreatorMethods.Count == 0)
|
||||
return;
|
||||
var cctor = DotNetUtils.getModuleTypeCctor(module);
|
||||
var cctor = DotNetUtils.GetModuleTypeCctor(module);
|
||||
if (cctor == null)
|
||||
return;
|
||||
|
||||
Logger.v("Finding all proxy delegates");
|
||||
|
||||
var delegateInfos = createDelegateInitInfos(cctor);
|
||||
fieldToMethods = createFieldToMethodsDictionary(cctor.DeclaringType);
|
||||
var delegateInfos = CreateDelegateInitInfos(cctor);
|
||||
fieldToMethods = CreateFieldToMethodsDictionary(cctor.DeclaringType);
|
||||
if (delegateInfos.Count < fieldToMethods.Count)
|
||||
throw new ApplicationException("Missing proxy delegates");
|
||||
var delegateToFields = new Dictionary<TypeDef, List<FieldDef>>();
|
||||
foreach (var field in fieldToMethods.getKeys()) {
|
||||
foreach (var field in fieldToMethods.GetKeys()) {
|
||||
List<FieldDef> list;
|
||||
if (!delegateToFields.TryGetValue(field.FieldType.TryGetTypeDef(), out list))
|
||||
delegateToFields[field.FieldType.TryGetTypeDef()] = list = new List<FieldDef>();
|
||||
|
@ -840,52 +840,52 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var type = kv.Key;
|
||||
var fields = kv.Value;
|
||||
|
||||
Logger.v("Found proxy delegate: {0} ({1:X8})", Utils.removeNewlines(type), type.MDToken.ToInt32());
|
||||
Logger.v("Found proxy delegate: {0} ({1:X8})", Utils.RemoveNewlines(type), type.MDToken.ToInt32());
|
||||
RemovedDelegateCreatorCalls++;
|
||||
|
||||
Logger.Instance.indent();
|
||||
Logger.Instance.Indent();
|
||||
foreach (var field in fields) {
|
||||
var proxyMethods = fieldToMethods.find(field);
|
||||
var proxyMethods = fieldToMethods.Find(field);
|
||||
if (proxyMethods == null)
|
||||
continue;
|
||||
var info = delegateInfos.find(field);
|
||||
var info = delegateInfos.Find(field);
|
||||
if (info == null)
|
||||
throw new ApplicationException("Missing proxy info");
|
||||
|
||||
IMethod calledMethod;
|
||||
OpCode callOpcode;
|
||||
getCallInfo(info, field, out calledMethod, out callOpcode);
|
||||
GetCallInfo(info, field, out calledMethod, out callOpcode);
|
||||
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
foreach (var proxyMethod in proxyMethods) {
|
||||
add(proxyMethod, new DelegateInfo(field, calledMethod, callOpcode));
|
||||
Add(proxyMethod, new DelegateInfo(field, calledMethod, callOpcode));
|
||||
Logger.v("Field: {0}, Opcode: {1}, Method: {2} ({3:X8})",
|
||||
Utils.removeNewlines(field.Name),
|
||||
Utils.RemoveNewlines(field.Name),
|
||||
callOpcode,
|
||||
Utils.removeNewlines(calledMethod),
|
||||
Utils.RemoveNewlines(calledMethod),
|
||||
calledMethod.MDToken.ToUInt32());
|
||||
}
|
||||
}
|
||||
Logger.Instance.deIndent();
|
||||
Logger.Instance.DeIndent();
|
||||
delegateTypesDict[type] = true;
|
||||
}
|
||||
|
||||
// 1.2 r54564 (almost 1.3) now moves method proxy init code to the delegate cctors
|
||||
find2();
|
||||
Find2();
|
||||
}
|
||||
|
||||
FieldDefAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos(MethodDef method) {
|
||||
FieldDefAndDeclaringTypeDict<DelegateInitInfo> CreateDelegateInitInfos(MethodDef method) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v10_r42915:
|
||||
case ConfuserVersion.v10_r42919:
|
||||
return createDelegateInitInfos_v10_r42915(method);
|
||||
return CreateDelegateInitInfos_v10_r42915(method);
|
||||
default:
|
||||
return createDelegateInitInfos_v10_r48717(method);
|
||||
return CreateDelegateInitInfos_v10_r48717(method);
|
||||
}
|
||||
}
|
||||
|
||||
FieldDefAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r42915(MethodDef method) {
|
||||
FieldDefAndDeclaringTypeDict<DelegateInitInfo> CreateDelegateInitInfos_v10_r42915(MethodDef method) {
|
||||
var infos = new FieldDefAndDeclaringTypeDict<DelegateInitInfo>();
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
|
@ -903,23 +903,23 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (delegateField == null)
|
||||
continue;
|
||||
var delegateType = delegateField.FieldType.TryGetTypeDef();
|
||||
if (!DotNetUtils.derivesFromDelegate(delegateType))
|
||||
if (!DotNetUtils.DerivesFromDelegate(delegateType))
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 2];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var delegateCreatorMethod = call.Operand as MethodDef;
|
||||
if (delegateCreatorMethod == null || !isDelegateCreatorMethod(delegateCreatorMethod))
|
||||
if (delegateCreatorMethod == null || !IsDelegateCreatorMethod(delegateCreatorMethod))
|
||||
continue;
|
||||
|
||||
infos.add(delegateField, new DelegateInitInfo(info, delegateField, delegateCreatorMethod));
|
||||
infos.Add(delegateField, new DelegateInitInfo(info, delegateField, delegateCreatorMethod));
|
||||
i += 2;
|
||||
}
|
||||
return infos;
|
||||
}
|
||||
|
||||
FieldDefAndDeclaringTypeDict<DelegateInitInfo> createDelegateInitInfos_v10_r48717(MethodDef method) {
|
||||
FieldDefAndDeclaringTypeDict<DelegateInitInfo> CreateDelegateInitInfos_v10_r48717(MethodDef method) {
|
||||
var infos = new FieldDefAndDeclaringTypeDict<DelegateInitInfo>();
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
|
@ -930,39 +930,39 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (delegateField == null)
|
||||
continue;
|
||||
var delegateType = delegateField.FieldType.TryGetTypeDef();
|
||||
if (!DotNetUtils.derivesFromDelegate(delegateType))
|
||||
if (!DotNetUtils.DerivesFromDelegate(delegateType))
|
||||
continue;
|
||||
|
||||
var call = instrs[i + 1];
|
||||
if (call.OpCode.Code != Code.Call)
|
||||
continue;
|
||||
var delegateCreatorMethod = call.Operand as MethodDef;
|
||||
if (delegateCreatorMethod == null || !isDelegateCreatorMethod(delegateCreatorMethod))
|
||||
if (delegateCreatorMethod == null || !IsDelegateCreatorMethod(delegateCreatorMethod))
|
||||
continue;
|
||||
|
||||
infos.add(delegateField, new DelegateInitInfo(delegateField, delegateCreatorMethod));
|
||||
infos.Add(delegateField, new DelegateInitInfo(delegateField, delegateCreatorMethod));
|
||||
i += 1;
|
||||
}
|
||||
return infos;
|
||||
}
|
||||
|
||||
static FieldDefAndDeclaringTypeDict<List<MethodDef>> createFieldToMethodsDictionary(TypeDef type) {
|
||||
static FieldDefAndDeclaringTypeDict<List<MethodDef>> CreateFieldToMethodsDictionary(TypeDef type) {
|
||||
var dict = new FieldDefAndDeclaringTypeDict<List<MethodDef>>();
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null || method.Name == ".cctor")
|
||||
continue;
|
||||
var delegateField = getDelegateField(method);
|
||||
var delegateField = GetDelegateField(method);
|
||||
if (delegateField == null)
|
||||
continue;
|
||||
var methods = dict.find(delegateField);
|
||||
var methods = dict.Find(delegateField);
|
||||
if (methods == null)
|
||||
dict.add(delegateField, methods = new List<MethodDef>());
|
||||
dict.Add(delegateField, methods = new List<MethodDef>());
|
||||
methods.Add(method);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
static FieldDef getDelegateField(MethodDef method) {
|
||||
static FieldDef GetDelegateField(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return null;
|
||||
|
||||
|
@ -975,7 +975,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
continue;
|
||||
if (field != null)
|
||||
return null;
|
||||
if (!DotNetUtils.derivesFromDelegate(field2.FieldType.TryGetTypeDef()))
|
||||
if (!DotNetUtils.DerivesFromDelegate(field2.FieldType.TryGetTypeDef()))
|
||||
continue;
|
||||
field = field2;
|
||||
}
|
||||
|
@ -987,10 +987,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return foundInvoke ? field : null;
|
||||
}
|
||||
|
||||
static bool findCallvirtChar(MethodDef method, out ushort callvirtChar) {
|
||||
static bool FindCallvirtChar(MethodDef method, out ushort callvirtChar) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.Char System.String::get_Chars(System.Int32)");
|
||||
index = ConfuserUtils.FindCallMethod(instrs, index, Code.Callvirt, "System.Char System.String::get_Chars(System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
|
@ -1008,17 +1008,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
public void CleanUp() {
|
||||
if (!Detected)
|
||||
return;
|
||||
var cctor = DotNetUtils.getModuleTypeCctor(module);
|
||||
var cctor = DotNetUtils.GetModuleTypeCctor(module);
|
||||
if (cctor == null)
|
||||
return;
|
||||
cctor.Body.Instructions.Clear();
|
||||
cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -61,49 +61,49 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||
}
|
||||
|
||||
public void find() {
|
||||
if (checkMethod(DotNetUtils.getModuleTypeCctor(module)))
|
||||
public void Find() {
|
||||
if (CheckMethod(DotNetUtils.GetModuleTypeCctor(module)))
|
||||
return;
|
||||
}
|
||||
|
||||
bool checkMethod(MethodDef method) {
|
||||
bool CheckMethod(MethodDef method) {
|
||||
if (method == null || method.Body == null)
|
||||
return false;
|
||||
if (!DotNetUtils.callsMethod(method, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)"))
|
||||
if (!DotNetUtils.CallsMethod(method, "System.Void System.AppDomain::add_ResourceResolve(System.ResolveEventHandler)"))
|
||||
return false;
|
||||
simpleDeobfuscator.deobfuscate(method, true);
|
||||
simpleDeobfuscator.Deobfuscate(method, true);
|
||||
fields.Clear();
|
||||
|
||||
var tmpHandler = getHandler(method);
|
||||
var tmpHandler = GetHandler(method);
|
||||
if (tmpHandler == null || tmpHandler.DeclaringType != method.DeclaringType)
|
||||
return false;
|
||||
|
||||
var tmpResource = findResource(tmpHandler);
|
||||
var tmpResource = FindResource(tmpHandler);
|
||||
if (tmpResource == null)
|
||||
return false;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(tmpHandler, true);
|
||||
simpleDeobfuscator.Deobfuscate(tmpHandler, true);
|
||||
ConfuserVersion tmpVersion = ConfuserVersion.Unknown;
|
||||
if (DotNetUtils.callsMethod(tmpHandler, "System.Object System.AppDomain::GetData(System.String)")) {
|
||||
if (!DotNetUtils.callsMethod(tmpHandler, "System.Void System.Buffer::BlockCopy(System.Array,System.Int32,System.Array,System.Int32,System.Int32)")) {
|
||||
if (!findKey0Key1_v14_r55802(tmpHandler, out key0, out key1))
|
||||
if (DotNetUtils.CallsMethod(tmpHandler, "System.Object System.AppDomain::GetData(System.String)")) {
|
||||
if (!DotNetUtils.CallsMethod(tmpHandler, "System.Void System.Buffer::BlockCopy(System.Array,System.Int32,System.Array,System.Int32,System.Int32)")) {
|
||||
if (!FindKey0Key1_v14_r55802(tmpHandler, out key0, out key1))
|
||||
return false;
|
||||
tmpVersion = ConfuserVersion.v14_r55802;
|
||||
}
|
||||
else if (findKey0_v17_r73404(tmpHandler, out key0) && findKey1_v17_r73404(tmpHandler, out key1))
|
||||
else if (FindKey0_v17_r73404(tmpHandler, out key0) && FindKey1_v17_r73404(tmpHandler, out key1))
|
||||
tmpVersion = ConfuserVersion.v17_r73404;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (addFields(findFields(tmpHandler, method.DeclaringType)) != 1)
|
||||
if (AddFields(FindFields(tmpHandler, method.DeclaringType)) != 1)
|
||||
return false;
|
||||
|
||||
if (findKey0_v17_r73404(tmpHandler, out key0) && findKey1_v17_r73404(tmpHandler, out key1))
|
||||
if (FindKey0_v17_r73404(tmpHandler, out key0) && FindKey1_v17_r73404(tmpHandler, out key1))
|
||||
tmpVersion = ConfuserVersion.v17_r73822;
|
||||
else if (findKey0_v18_r75367(tmpHandler, out key0) && findKey1_v17_r73404(tmpHandler, out key1))
|
||||
else if (FindKey0_v18_r75367(tmpHandler, out key0) && FindKey1_v17_r73404(tmpHandler, out key1))
|
||||
tmpVersion = ConfuserVersion.v18_r75367;
|
||||
else if (findKey0_v18_r75369(tmpHandler, out key0) && findKey1_v18_r75369(tmpHandler, out key1))
|
||||
else if (FindKey0_v18_r75369(tmpHandler, out key0) && FindKey1_v18_r75369(tmpHandler, out key1))
|
||||
tmpVersion = ConfuserVersion.v18_r75369;
|
||||
else
|
||||
return false;
|
||||
|
@ -116,7 +116,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static MethodDef getHandler(MethodDef method) {
|
||||
static MethodDef GetHandler(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
var ldftn = instrs[i];
|
||||
|
@ -144,16 +144,16 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
int addFields(IEnumerable<FieldDef> moreFields) {
|
||||
int AddFields(IEnumerable<FieldDef> moreFields) {
|
||||
int count = 0;
|
||||
foreach (var field in moreFields) {
|
||||
if (addField(field))
|
||||
if (AddField(field))
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool addField(FieldDef field) {
|
||||
bool AddField(FieldDef field) {
|
||||
if (field == null)
|
||||
return false;
|
||||
if (fields.ContainsKey(field))
|
||||
|
@ -162,7 +162,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static IEnumerable<FieldDef> findFields(MethodDef method, TypeDef declaringType) {
|
||||
static IEnumerable<FieldDef> FindFields(MethodDef method, TypeDef declaringType) {
|
||||
var fields = new List<FieldDef>();
|
||||
foreach (var instr in method.Body.Instructions) {
|
||||
var field = instr.Operand as FieldDef;
|
||||
|
@ -172,14 +172,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return fields;
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
EmbeddedResource FindResource(MethodDef method) {
|
||||
return DotNetUtils.GetResource(module, DotNetUtils.GetCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
static bool findKey0_v18_r75367(MethodDef method, out byte key0) {
|
||||
static bool FindKey0_v18_r75367(MethodDef method, out byte key0) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
i = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)");
|
||||
i = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)");
|
||||
if (i < 0)
|
||||
break;
|
||||
if (i + 3 >= instrs.Count)
|
||||
|
@ -201,10 +201,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v18_r75369(MethodDef method, out byte key0) {
|
||||
static bool FindKey0_v18_r75369(MethodDef method, out byte key0) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int index = 0; index < instrs.Count; index++) {
|
||||
index = ConfuserUtils.findCallMethod(instrs, index, Code.Callvirt, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)");
|
||||
index = ConfuserUtils.FindCallMethod(instrs, index, Code.Callvirt, "System.Int32 System.IO.Stream::Read(System.Byte[],System.Int32,System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
|
||||
|
@ -230,7 +230,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1_v18_r75369(MethodDef method, out byte key1) {
|
||||
static bool FindKey1_v18_r75369(MethodDef method, out byte key1) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
int index = i;
|
||||
|
@ -255,7 +255,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0Key1_v14_r55802(MethodDef method, out byte key0, out byte key1) {
|
||||
static bool FindKey0Key1_v14_r55802(MethodDef method, out byte key0, out byte key1) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (!instrs[i].IsLdcI4())
|
||||
|
@ -282,10 +282,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v17_r73404(MethodDef method, out byte key) {
|
||||
static bool FindKey0_v17_r73404(MethodDef method, out byte key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index + 3 >= instrs.Count)
|
||||
|
@ -306,7 +306,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1_v17_r73404(MethodDef method, out byte key) {
|
||||
static bool FindKey1_v17_r73404(MethodDef method, out byte key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
|
@ -327,40 +327,40 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public EmbeddedResource mergeResources() {
|
||||
public EmbeddedResource MergeResources() {
|
||||
if (resource == null)
|
||||
return null;
|
||||
DeobUtils.decryptAndAddResources(module, resource.Name.String, () => decryptResource());
|
||||
DeobUtils.DecryptAndAddResources(module, resource.Name.String, () => DecryptResource());
|
||||
var tmpResource = resource;
|
||||
resource = null;
|
||||
return tmpResource;
|
||||
}
|
||||
|
||||
byte[] decryptResource() {
|
||||
byte[] DecryptResource() {
|
||||
switch (version) {
|
||||
case ConfuserVersion.v14_r55802: return decrypt_v14_r55802();
|
||||
case ConfuserVersion.v17_r73404: return decrypt_v17_r73404();
|
||||
case ConfuserVersion.v17_r73822: return decrypt_v17_r73404();
|
||||
case ConfuserVersion.v18_r75367: return decrypt_v18_r75367();
|
||||
case ConfuserVersion.v18_r75369: return decrypt_v18_r75367();
|
||||
case ConfuserVersion.v14_r55802: return Decrypt_v14_r55802();
|
||||
case ConfuserVersion.v17_r73404: return Decrypt_v17_r73404();
|
||||
case ConfuserVersion.v17_r73822: return Decrypt_v17_r73404();
|
||||
case ConfuserVersion.v18_r75367: return Decrypt_v18_r75367();
|
||||
case ConfuserVersion.v18_r75369: return Decrypt_v18_r75367();
|
||||
default: throw new ApplicationException("Unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] decrypt_v14_r55802() {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(resource.GetResourceData(), true)));
|
||||
byte[] Decrypt_v14_r55802() {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(resource.GetResourceData(), true)));
|
||||
var encypted = reader.ReadBytes(reader.ReadInt32());
|
||||
if ((encypted.Length & 1) != 0)
|
||||
throw new ApplicationException("Invalid resource data length");
|
||||
var decrypted = new byte[encypted.Length / 2];
|
||||
for (int i = 0; i < decrypted.Length; i++)
|
||||
decrypted[i] = (byte)((encypted[i * 2 + 1] ^ key0) * key1 + (encypted[i * 2] ^ key0));
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(decrypted, true)));
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(decrypted, true)));
|
||||
return reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
||||
byte[] decrypt_v17_r73404() {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(resource.GetResourceData(), true)));
|
||||
byte[] Decrypt_v17_r73404() {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(resource.GetResourceData(), true)));
|
||||
var decrypted = reader.ReadBytes(reader.ReadInt32());
|
||||
byte k = key0;
|
||||
for (int i = 0; i < decrypted.Length; i++) {
|
||||
|
@ -370,24 +370,24 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decrypted;
|
||||
}
|
||||
|
||||
byte[] decrypt_v18_r75367() {
|
||||
byte[] Decrypt_v18_r75367() {
|
||||
var encrypted = resource.GetResourceData();
|
||||
byte k = key0;
|
||||
for (int i = 0; i < encrypted.Length; i++) {
|
||||
encrypted[i] ^= k;
|
||||
k *= key1;
|
||||
}
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(encrypted, true)));
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(encrypted, true)));
|
||||
return reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
||||
public void deobfuscate(Blocks blocks) {
|
||||
public void Deobfuscate(Blocks blocks) {
|
||||
if (blocks.Method != installMethod)
|
||||
return;
|
||||
ConfuserUtils.removeResourceHookCode(blocks, handler);
|
||||
ConfuserUtils.RemoveResourceHookCode(blocks, handler);
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.stringDecrypter = stringDecrypter;
|
||||
}
|
||||
|
||||
public abstract string decrypt(MethodDef caller, int magic);
|
||||
public abstract string Decrypt(MethodDef caller, int magic);
|
||||
}
|
||||
|
||||
class Decrypter_v10_r42915 : Decrypter {
|
||||
|
@ -69,7 +69,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.key = key;
|
||||
}
|
||||
|
||||
public override string decrypt(MethodDef caller, int magic) {
|
||||
public override string Decrypt(MethodDef caller, int magic) {
|
||||
var reader = stringDecrypter.reader;
|
||||
reader.Position = (caller.MDToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
int len = reader.ReadInt32() ^ (int)~stringDecrypter.magic2;
|
||||
|
@ -93,7 +93,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
: base(stringDecrypter) {
|
||||
}
|
||||
|
||||
public override string decrypt(MethodDef caller, int magic) {
|
||||
public override string Decrypt(MethodDef caller, int magic) {
|
||||
var reader = stringDecrypter.reader;
|
||||
reader.Position = (caller.MDToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
int len = reader.ReadInt32() ^ (int)~stringDecrypter.magic2;
|
||||
|
@ -101,7 +101,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
var instrs = stringDecrypter.decryptMethod.Body.Instructions;
|
||||
constReader = new PolyConstantsReader(instrs, false);
|
||||
int polyIndex = ConfuserUtils.findCallMethod(instrs, 0, Code.Callvirt, "System.Int64 System.IO.BinaryReader::ReadInt64()");
|
||||
int polyIndex = ConfuserUtils.FindCallMethod(instrs, 0, Code.Callvirt, "System.Int64 System.IO.BinaryReader::ReadInt64()");
|
||||
if (polyIndex < 0)
|
||||
throw new ApplicationException("Could not find start of decrypt code");
|
||||
|
||||
|
@ -110,7 +110,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
constReader.Arg = reader.ReadInt64();
|
||||
int index = polyIndex;
|
||||
long val;
|
||||
if (!constReader.getInt64(ref index, out val) || instrs[index].OpCode.Code != Code.Conv_I8)
|
||||
if (!constReader.GetInt64(ref index, out val) || instrs[index].OpCode.Code != Code.Conv_I8)
|
||||
throw new ApplicationException("Could not get string int64 value");
|
||||
Array.Copy(BitConverter.GetBytes(val ^ rand.Next()), 0, decrypted, i, Math.Min(8, len - i));
|
||||
}
|
||||
|
@ -124,39 +124,39 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
: base(stringDecrypter) {
|
||||
}
|
||||
|
||||
public override string decrypt(MethodDef caller, int magic) {
|
||||
public override string Decrypt(MethodDef caller, int magic) {
|
||||
var reader = stringDecrypter.reader;
|
||||
reader.Position = (caller.MDToken.ToInt32() ^ magic) - stringDecrypter.magic1;
|
||||
int len = reader.ReadInt32() ^ (int)~stringDecrypter.magic2;
|
||||
var decrypted = new byte[len];
|
||||
|
||||
int startIndex, endIndex;
|
||||
if (!findPolyStartEndIndexes(out startIndex, out endIndex))
|
||||
if (!FindPolyStartEndIndexes(out startIndex, out endIndex))
|
||||
throw new ApplicationException("Could not get start/end indexes");
|
||||
|
||||
var constReader = new Arg64ConstantsReader(stringDecrypter.decryptMethod.Body.Instructions, false);
|
||||
ConfuserUtils.decryptCompressedInt32Data(constReader, startIndex, endIndex, reader, decrypted);
|
||||
ConfuserUtils.DecryptCompressedInt32Data(constReader, startIndex, endIndex, reader, decrypted);
|
||||
return Encoding.Unicode.GetString(decrypted);
|
||||
}
|
||||
|
||||
bool findPolyStartEndIndexes(out int startIndex, out int endIndex) {
|
||||
bool FindPolyStartEndIndexes(out int startIndex, out int endIndex) {
|
||||
startIndex = 0;
|
||||
endIndex = 0;
|
||||
|
||||
var local = findLocal(stringDecrypter.decryptMethod);
|
||||
var local = FindLocal(stringDecrypter.decryptMethod);
|
||||
if (local == null)
|
||||
return false;
|
||||
|
||||
if ((endIndex = findEndIndex(stringDecrypter.decryptMethod)) < 0)
|
||||
if ((endIndex = FindEndIndex(stringDecrypter.decryptMethod)) < 0)
|
||||
return false;
|
||||
|
||||
if ((startIndex = findStartIndex(stringDecrypter.decryptMethod, endIndex)) < 0)
|
||||
if ((startIndex = FindStartIndex(stringDecrypter.decryptMethod, endIndex)) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Local findLocal(MethodDef method) {
|
||||
static Local FindLocal(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.And)
|
||||
|
@ -172,7 +172,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static int findEndIndex(MethodDef method) {
|
||||
static int FindEndIndex(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 5; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Conv_U1)
|
||||
|
@ -192,7 +192,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int findStartIndex(MethodDef method, int endIndex) {
|
||||
static int FindStartIndex(MethodDef method, int endIndex) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = endIndex; i >= 0; i--) {
|
||||
var instr = instrs[i];
|
||||
|
@ -217,7 +217,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
: base(instrs, emulateConvInstrs) {
|
||||
}
|
||||
|
||||
protected override bool processInstructionInt64(ref int index, Stack<ConstantInfo<long>> stack) {
|
||||
protected override bool ProcessInstructionInt64(ref int index, Stack<ConstantInfo<long>> stack) {
|
||||
int i = index;
|
||||
|
||||
if (instructions[i].IsLdloc()) {
|
||||
|
@ -259,52 +259,52 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.IO.BinaryReader",
|
||||
"System.Reflection.Assembly",
|
||||
};
|
||||
public void find(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
var type = DotNetUtils.getModuleType(module);
|
||||
public void Find(ISimpleDeobfuscator simpleDeobfuscator) {
|
||||
var type = DotNetUtils.GetModuleType(module);
|
||||
if (type == null)
|
||||
return;
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.String", "(System.Int32)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.String", "(System.Int32)"))
|
||||
continue;
|
||||
var localTypes = new LocalTypes(method);
|
||||
if (!localTypes.all(requiredLocals))
|
||||
if (!localTypes.All(requiredLocals))
|
||||
continue;
|
||||
|
||||
simpleDeobfuscator.deobfuscate(method);
|
||||
simpleDeobfuscator.Deobfuscate(method);
|
||||
|
||||
bool foundOldMagic1;
|
||||
if (findMagic1(method, out magic1))
|
||||
if (FindMagic1(method, out magic1))
|
||||
foundOldMagic1 = true;
|
||||
else if (findNewMagic1(method, out magic1))
|
||||
else if (FindNewMagic1(method, out magic1))
|
||||
foundOldMagic1 = false;
|
||||
else
|
||||
continue;
|
||||
if (!findMagic2(method, out magic2))
|
||||
if (!FindMagic2(method, out magic2))
|
||||
continue;
|
||||
|
||||
version = ConfuserVersion.Unknown;
|
||||
if (DotNetUtils.callsMethod(method, "System.Text.Encoding System.Text.Encoding::get_UTF8()")) {
|
||||
if (DotNetUtils.CallsMethod(method, "System.Text.Encoding System.Text.Encoding::get_UTF8()")) {
|
||||
if (foundOldMagic1) {
|
||||
if (DotNetUtils.callsMethod(method, "System.Object System.AppDomain::GetData(System.String)"))
|
||||
if (DotNetUtils.CallsMethod(method, "System.Object System.AppDomain::GetData(System.String)"))
|
||||
version = ConfuserVersion.v13_r55604_safe;
|
||||
else
|
||||
version = ConfuserVersion.v10_r42915;
|
||||
}
|
||||
else {
|
||||
if (!findSafeKey1(method, out key1))
|
||||
if (!FindSafeKey1(method, out key1))
|
||||
continue;
|
||||
version = ConfuserVersion.v14_r58802_safe;
|
||||
}
|
||||
}
|
||||
else if (!localTypes.exists("System.Random")) {
|
||||
else if (!localTypes.Exists("System.Random")) {
|
||||
if (foundOldMagic1)
|
||||
version = ConfuserVersion.v11_r49299;
|
||||
else
|
||||
version = ConfuserVersion.v14_r58802_dynamic;
|
||||
}
|
||||
else if (localTypes.exists("System.Collections.Generic.Dictionary`2<System.Int32,System.String>"))
|
||||
else if (localTypes.Exists("System.Collections.Generic.Dictionary`2<System.Int32,System.String>"))
|
||||
version = ConfuserVersion.v10_r48832;
|
||||
if (version == ConfuserVersion.Unknown)
|
||||
continue;
|
||||
|
@ -314,14 +314,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
EmbeddedResource FindResource(MethodDef method) {
|
||||
return DotNetUtils.GetResource(module, DotNetUtils.GetCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
static bool findMagic1(MethodDef method, out uint magic) {
|
||||
static bool FindMagic1(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.Byte[] System.IO.BinaryReader::ReadBytes(System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index < 4)
|
||||
|
@ -345,7 +345,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findNewMagic1(MethodDef method, out uint magic) {
|
||||
static bool FindNewMagic1(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Ldarg_0)
|
||||
|
@ -367,10 +367,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findMagic2(MethodDef method, out uint magic) {
|
||||
static bool FindMagic2(MethodDef method, out uint magic) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Callvirt, "System.UInt32 System.IO.BinaryReader::ReadUInt32()");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index + 4 >= instrs.Count)
|
||||
|
@ -393,10 +393,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findSafeKey1(MethodDef method, out uint key) {
|
||||
static bool FindSafeKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count; i++) {
|
||||
int index = ConfuserUtils.findCallMethod(instrs, i, Code.Newobj, "System.Void System.Random::.ctor(System.Int32)");
|
||||
int index = ConfuserUtils.FindCallMethod(instrs, i, Code.Newobj, "System.Void System.Random::.ctor(System.Int32)");
|
||||
if (index < 0)
|
||||
break;
|
||||
if (index == 0)
|
||||
|
@ -413,14 +413,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
public void Initialize() {
|
||||
if (decryptMethod == null)
|
||||
return;
|
||||
|
||||
resource = findResource(decryptMethod);
|
||||
resource = FindResource(decryptMethod);
|
||||
if (resource == null)
|
||||
throw new ApplicationException("Could not find encrypted strings resource");
|
||||
reader = MemoryImageStream.Create(DeobUtils.inflate(resource.GetResourceData(), true));
|
||||
reader = MemoryImageStream.Create(DeobUtils.Inflate(resource.GetResourceData(), true));
|
||||
|
||||
switch (version) {
|
||||
case ConfuserVersion.v10_r42915:
|
||||
|
@ -446,11 +446,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public string decrypt(MethodDef caller, int magic) {
|
||||
return decrypter.decrypt(caller, magic);
|
||||
public string Decrypt(MethodDef caller, int magic) {
|
||||
return decrypter.Decrypt(caller, magic);
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.realAssembly = realAssembly;
|
||||
this.entryPointToken = entryPointToken;
|
||||
this.kind = kind;
|
||||
this.moduleName = realAssembly.Name.String + DeobUtils.getExtension(kind);
|
||||
this.moduleName = realAssembly.Name.String + DeobUtils.GetExtension(kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,9 +53,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.resource = resource;
|
||||
this.data = data;
|
||||
this.asmFullName = asmFullName;
|
||||
this.asmSimpleName = Utils.getAssemblySimpleName(asmFullName);
|
||||
this.asmSimpleName = Utils.GetAssemblySimpleName(asmFullName);
|
||||
this.kind = kind;
|
||||
this.extension = DeobUtils.getExtension(kind);
|
||||
this.extension = DeobUtils.GetExtension(kind);
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
|
@ -106,31 +106,31 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.IO.BinaryReader",
|
||||
"System.IO.Stream",
|
||||
};
|
||||
public void find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
|
||||
public void Find(ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
|
||||
var entryPoint = module.EntryPoint;
|
||||
if (entryPoint == null)
|
||||
return;
|
||||
if (!new LocalTypes(entryPoint).all(requiredEntryPointLocals))
|
||||
if (!new LocalTypes(entryPoint).All(requiredEntryPointLocals))
|
||||
return;
|
||||
var type = entryPoint.DeclaringType;
|
||||
if (!new FieldTypes(type).all(requiredFields))
|
||||
if (!new FieldTypes(type).All(requiredFields))
|
||||
return;
|
||||
|
||||
bool use7zip = type.NestedTypes.Count == 6;
|
||||
MethodDef decyptMethod;
|
||||
if (use7zip)
|
||||
decyptMethod = findDecryptMethod_7zip(type);
|
||||
decyptMethod = FindDecryptMethod_7zip(type);
|
||||
else
|
||||
decyptMethod = findDecryptMethod_inflate(type);
|
||||
decyptMethod = FindDecryptMethod_inflate(type);
|
||||
if (decyptMethod == null)
|
||||
return;
|
||||
|
||||
ConfuserVersion theVersion = ConfuserVersion.Unknown;
|
||||
var decryptLocals = new LocalTypes(decyptMethod);
|
||||
if (decryptLocals.exists("System.IO.MemoryStream")) {
|
||||
if (DotNetUtils.callsMethod(entryPoint, "System.Void", "(System.String,System.Byte[])"))
|
||||
if (decryptLocals.Exists("System.IO.MemoryStream")) {
|
||||
if (DotNetUtils.CallsMethod(entryPoint, "System.Void", "(System.String,System.Byte[])"))
|
||||
theVersion = ConfuserVersion.v10_r42915;
|
||||
else if (DotNetUtils.callsMethod(entryPoint, "System.Void", "(System.Security.Permissions.PermissionState)"))
|
||||
else if (DotNetUtils.CallsMethod(entryPoint, "System.Void", "(System.Security.Permissions.PermissionState)"))
|
||||
theVersion = ConfuserVersion.v10_r48717;
|
||||
else
|
||||
theVersion = ConfuserVersion.v14_r57778;
|
||||
|
@ -142,10 +142,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
if (cctor == null)
|
||||
return;
|
||||
|
||||
if ((asmResolverMethod = findAssemblyResolverMethod(entryPoint.DeclaringType)) != null) {
|
||||
if ((asmResolverMethod = FindAssemblyResolverMethod(entryPoint.DeclaringType)) != null) {
|
||||
theVersion = ConfuserVersion.v14_r58802;
|
||||
simpleDeobfuscator.deobfuscate(asmResolverMethod);
|
||||
if (!findKey1(asmResolverMethod, out key1))
|
||||
simpleDeobfuscator.Deobfuscate(asmResolverMethod);
|
||||
if (!FindKey1(asmResolverMethod, out key1))
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -157,23 +157,23 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
|
||||
case ConfuserVersion.v14_r58564:
|
||||
case ConfuserVersion.v14_r58802:
|
||||
simpleDeobfuscator.deobfuscate(decyptMethod);
|
||||
if (findKey0_v14_r58564(decyptMethod, out key0))
|
||||
simpleDeobfuscator.Deobfuscate(decyptMethod);
|
||||
if (FindKey0_v14_r58564(decyptMethod, out key0))
|
||||
break;
|
||||
if (findKey0_v14_r58852(decyptMethod, out key0)) {
|
||||
if (!decryptLocals.exists("System.Security.Cryptography.RijndaelManaged")) {
|
||||
if (FindKey0_v14_r58852(decyptMethod, out key0)) {
|
||||
if (!decryptLocals.Exists("System.Security.Cryptography.RijndaelManaged")) {
|
||||
theVersion = ConfuserVersion.v14_r58852;
|
||||
break;
|
||||
}
|
||||
if (use7zip) {
|
||||
if (new LocalTypes(decyptMethod).exists("System.IO.MemoryStream"))
|
||||
if (new LocalTypes(decyptMethod).Exists("System.IO.MemoryStream"))
|
||||
theVersion = ConfuserVersion.v17_r75076;
|
||||
else if (module.Name == "Stub.exe")
|
||||
theVersion = ConfuserVersion.v18_r75184;
|
||||
else
|
||||
theVersion = ConfuserVersion.v18_r75367;
|
||||
}
|
||||
else if (isDecryptMethod_v17_r73404(decyptMethod))
|
||||
else if (IsDecryptMethod_v17_r73404(decyptMethod))
|
||||
theVersion = ConfuserVersion.v17_r73404;
|
||||
else
|
||||
theVersion = ConfuserVersion.v15_r60785;
|
||||
|
@ -185,44 +185,44 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException("Invalid version");
|
||||
}
|
||||
|
||||
simpleDeobfuscator.deobfuscate(cctor);
|
||||
simpleDeobfuscator.decryptStrings(cctor, deob);
|
||||
simpleDeobfuscator.Deobfuscate(cctor);
|
||||
simpleDeobfuscator.DecryptStrings(cctor, deob);
|
||||
|
||||
if (findEntryPointToken(simpleDeobfuscator, cctor, entryPoint, out entryPointToken) && !use7zip) {
|
||||
if (DotNetUtils.callsMethod(asmResolverMethod, "System.Void", "(System.String)"))
|
||||
if (FindEntryPointToken(simpleDeobfuscator, cctor, entryPoint, out entryPointToken) && !use7zip) {
|
||||
if (DotNetUtils.CallsMethod(asmResolverMethod, "System.Void", "(System.String)"))
|
||||
theVersion = ConfuserVersion.v17_r73477;
|
||||
else
|
||||
theVersion = ConfuserVersion.v17_r73566;
|
||||
}
|
||||
|
||||
mainAsmResource = findResource(cctor);
|
||||
mainAsmResource = FindResource(cctor);
|
||||
if (mainAsmResource == null)
|
||||
throw new ApplicationException("Could not find main assembly resource");
|
||||
version = theVersion;
|
||||
}
|
||||
|
||||
bool findEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token) {
|
||||
bool FindEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token) {
|
||||
token = 0;
|
||||
ulong @base;
|
||||
if (!findBase(cctor, out @base))
|
||||
if (!FindBase(cctor, out @base))
|
||||
return false;
|
||||
|
||||
var modPowMethod = DotNetUtils.getMethod(cctor.DeclaringType, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)");
|
||||
var modPowMethod = DotNetUtils.GetMethod(cctor.DeclaringType, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)");
|
||||
if (modPowMethod == null)
|
||||
throw new ApplicationException("Could not find modPow()");
|
||||
|
||||
simpleDeobfuscator.deobfuscate(entryPoint);
|
||||
simpleDeobfuscator.Deobfuscate(entryPoint);
|
||||
ulong mod;
|
||||
if (!findMod(entryPoint, out mod))
|
||||
if (!FindMod(entryPoint, out mod))
|
||||
throw new ApplicationException("Could not find modulus");
|
||||
|
||||
token = 0x06000000 | (uint)modPow(@base, 0x47, mod);
|
||||
token = 0x06000000 | (uint)ModPow(@base, 0x47, mod);
|
||||
if ((token >> 24) != 0x06)
|
||||
throw new ApplicationException("Illegal entry point token");
|
||||
return true;
|
||||
}
|
||||
|
||||
static ulong modPow(ulong @base, ulong pow, ulong mod) {
|
||||
static ulong ModPow(ulong @base, ulong pow, ulong mod) {
|
||||
ulong m = 1;
|
||||
while (pow > 0) {
|
||||
if ((pow & 1) != 0)
|
||||
|
@ -233,7 +233,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return m;
|
||||
}
|
||||
|
||||
static bool findMod(MethodDef method, out ulong mod) {
|
||||
static bool FindMod(MethodDef method, out ulong mod) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||
var ldci8 = instrs[i];
|
||||
|
@ -246,7 +246,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
var calledMethod = call.Operand as IMethod;
|
||||
if (calledMethod == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(calledMethod, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)"))
|
||||
if (!DotNetUtils.IsMethod(calledMethod, "System.UInt64", "(System.UInt64,System.UInt64,System.UInt64)"))
|
||||
continue;
|
||||
|
||||
mod = (ulong)(long)ldci8.Operand;
|
||||
|
@ -256,7 +256,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findBase(MethodDef method, out ulong @base) {
|
||||
static bool FindBase(MethodDef method, out ulong @base) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
var ldci8 = instrs[i];
|
||||
|
@ -278,13 +278,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool isDecryptMethod_v17_r73404(MethodDef method) {
|
||||
static bool IsDecryptMethod_v17_r73404(MethodDef method) {
|
||||
var instrs = method.Body.Instructions;
|
||||
if (instrs.Count < 4)
|
||||
return false;
|
||||
if (!instrs[0].IsLdarg())
|
||||
return false;
|
||||
if (!isCallorNewobj(instrs[1]) && !isCallorNewobj(instrs[2]))
|
||||
if (!IsCallorNewobj(instrs[1]) && !IsCallorNewobj(instrs[2]))
|
||||
return false;
|
||||
var stloc = instrs[3];
|
||||
if (!stloc.IsStloc())
|
||||
|
@ -296,15 +296,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool isCallorNewobj(Instruction instr) {
|
||||
static bool IsCallorNewobj(Instruction instr) {
|
||||
return instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Newobj;
|
||||
}
|
||||
|
||||
static MethodDef findAssemblyResolverMethod(TypeDef type) {
|
||||
static MethodDef FindAssemblyResolverMethod(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -312,7 +312,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
static bool findKey0_v14_r58564(MethodDef method, out uint key) {
|
||||
static bool FindKey0_v14_r58564(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 2; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Xor)
|
||||
|
@ -330,7 +330,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey0_v14_r58852(MethodDef method, out uint key) {
|
||||
static bool FindKey0_v14_r58852(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||
var ldci4_1 = instrs[i];
|
||||
|
@ -351,7 +351,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool findKey1(MethodDef method, out uint key) {
|
||||
static bool FindKey1(MethodDef method, out uint key) {
|
||||
var instrs = method.Body.Instructions;
|
||||
for (int i = 0; i < instrs.Count - 4; i++) {
|
||||
if (instrs[i].OpCode.Code != Code.Ldelem_U1)
|
||||
|
@ -373,21 +373,21 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return false;
|
||||
}
|
||||
|
||||
EmbeddedResource findResource(MethodDef method) {
|
||||
return DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(method)) as EmbeddedResource;
|
||||
EmbeddedResource FindResource(MethodDef method) {
|
||||
return DotNetUtils.GetResource(module, DotNetUtils.GetCodeStrings(method)) as EmbeddedResource;
|
||||
}
|
||||
|
||||
static string[] requiredDecryptLocals_inflate = new string[] {
|
||||
"System.Byte[]",
|
||||
"System.IO.Compression.DeflateStream",
|
||||
};
|
||||
static MethodDef findDecryptMethod_inflate(TypeDef type) {
|
||||
static MethodDef FindDecryptMethod_inflate(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte[])"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Byte[]", "(System.Byte[])"))
|
||||
continue;
|
||||
if (!new LocalTypes(method).all(requiredDecryptLocals_inflate))
|
||||
if (!new LocalTypes(method).All(requiredDecryptLocals_inflate))
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -402,13 +402,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
"System.Security.Cryptography.CryptoStream",
|
||||
"System.Security.Cryptography.RijndaelManaged",
|
||||
};
|
||||
static MethodDef findDecryptMethod_7zip(TypeDef type) {
|
||||
static MethodDef FindDecryptMethod_7zip(TypeDef type) {
|
||||
foreach (var method in type.Methods) {
|
||||
if (!method.IsStatic || method.Body == null)
|
||||
continue;
|
||||
if (!DotNetUtils.isMethod(method, "System.Byte[]", "(System.Byte[])"))
|
||||
if (!DotNetUtils.IsMethod(method, "System.Byte[]", "(System.Byte[])"))
|
||||
continue;
|
||||
if (!new LocalTypes(method).all(requiredDecryptLocals_7zip))
|
||||
if (!new LocalTypes(method).All(requiredDecryptLocals_7zip))
|
||||
continue;
|
||||
|
||||
return method;
|
||||
|
@ -416,14 +416,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public EmbeddedAssemblyInfo unpackMainAssembly(bool createAssembly) {
|
||||
public EmbeddedAssemblyInfo UnpackMainAssembly(bool createAssembly) {
|
||||
if (mainAsmResource == null)
|
||||
return null;
|
||||
var info = createEmbeddedAssemblyInfo(mainAsmResource, decrypt(mainAsmResource));
|
||||
var info = CreateEmbeddedAssemblyInfo(mainAsmResource, Decrypt(mainAsmResource));
|
||||
|
||||
var asm = module.Assembly;
|
||||
if (createAssembly && asm != null && entryPointToken != 0 && info.kind == ModuleKind.NetModule) {
|
||||
info.extension = DeobUtils.getExtension(module.Kind);
|
||||
info.extension = DeobUtils.GetExtension(module.Kind);
|
||||
info.kind = module.Kind;
|
||||
|
||||
var realAsm = module.UpdateRowId(new AssemblyDefUser(asm.Name, new Version(0, 0, 0, 0)));
|
||||
|
@ -437,14 +437,14 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return info;
|
||||
}
|
||||
|
||||
public List<EmbeddedAssemblyInfo> getEmbeddedAssemblyInfos() {
|
||||
public List<EmbeddedAssemblyInfo> GetEmbeddedAssemblyInfos() {
|
||||
var infos = new List<EmbeddedAssemblyInfo>();
|
||||
foreach (var rsrc in module.Resources) {
|
||||
var resource = rsrc as EmbeddedResource;
|
||||
if (resource == null || resource == mainAsmResource)
|
||||
continue;
|
||||
try {
|
||||
infos.Add(createEmbeddedAssemblyInfo(resource, decrypt(resource)));
|
||||
infos.Add(CreateEmbeddedAssemblyInfo(resource, Decrypt(resource)));
|
||||
}
|
||||
catch {
|
||||
}
|
||||
|
@ -452,45 +452,45 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return infos;
|
||||
}
|
||||
|
||||
static EmbeddedAssemblyInfo createEmbeddedAssemblyInfo(EmbeddedResource resource, byte[] data) {
|
||||
static EmbeddedAssemblyInfo CreateEmbeddedAssemblyInfo(EmbeddedResource resource, byte[] data) {
|
||||
var mod = ModuleDefMD.Load(data);
|
||||
var asmFullName = mod.Assembly != null ? mod.Assembly.FullName : mod.Name.String;
|
||||
return new EmbeddedAssemblyInfo(resource, data, asmFullName, mod.Kind);
|
||||
}
|
||||
|
||||
byte[] decrypt(EmbeddedResource resource) {
|
||||
byte[] Decrypt(EmbeddedResource resource) {
|
||||
var data = resource.GetResourceData();
|
||||
switch (version) {
|
||||
case ConfuserVersion.v10_r42915: return decrypt_v10_r42915(data);
|
||||
case ConfuserVersion.v10_r48717: return decrypt_v10_r42915(data);
|
||||
case ConfuserVersion.v14_r57778: return decrypt_v10_r42915(data);
|
||||
case ConfuserVersion.v14_r58564: return decrypt_v14_r58564(data);
|
||||
case ConfuserVersion.v14_r58802: return decrypt_v14_r58564(data);
|
||||
case ConfuserVersion.v14_r58852: return decrypt_v14_r58852(data);
|
||||
case ConfuserVersion.v15_r60785: return decrypt_v15_r60785(data);
|
||||
case ConfuserVersion.v17_r73404: return decrypt_v17_r73404(data);
|
||||
case ConfuserVersion.v17_r73477: return decrypt_v17_r73404(data);
|
||||
case ConfuserVersion.v17_r73566: return decrypt_v17_r73404(data);
|
||||
case ConfuserVersion.v17_r75076: return decrypt_v17_r75076(data);
|
||||
case ConfuserVersion.v18_r75184: return decrypt_v17_r75076(data);
|
||||
case ConfuserVersion.v18_r75367: return decrypt_v17_r75076(data);
|
||||
case ConfuserVersion.v10_r42915: return Decrypt_v10_r42915(data);
|
||||
case ConfuserVersion.v10_r48717: return Decrypt_v10_r42915(data);
|
||||
case ConfuserVersion.v14_r57778: return Decrypt_v10_r42915(data);
|
||||
case ConfuserVersion.v14_r58564: return Decrypt_v14_r58564(data);
|
||||
case ConfuserVersion.v14_r58802: return Decrypt_v14_r58564(data);
|
||||
case ConfuserVersion.v14_r58852: return Decrypt_v14_r58852(data);
|
||||
case ConfuserVersion.v15_r60785: return Decrypt_v15_r60785(data);
|
||||
case ConfuserVersion.v17_r73404: return Decrypt_v17_r73404(data);
|
||||
case ConfuserVersion.v17_r73477: return Decrypt_v17_r73404(data);
|
||||
case ConfuserVersion.v17_r73566: return Decrypt_v17_r73404(data);
|
||||
case ConfuserVersion.v17_r75076: return Decrypt_v17_r75076(data);
|
||||
case ConfuserVersion.v18_r75184: return Decrypt_v17_r75076(data);
|
||||
case ConfuserVersion.v18_r75367: return Decrypt_v17_r75076(data);
|
||||
default: throw new ApplicationException("Unknown version");
|
||||
}
|
||||
}
|
||||
|
||||
byte[] decrypt_v10_r42915(byte[] data) {
|
||||
byte[] Decrypt_v10_r42915(byte[] data) {
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
data[i] ^= (byte)(i ^ key0);
|
||||
return DeobUtils.inflate(data, true);
|
||||
return DeobUtils.Inflate(data, true);
|
||||
}
|
||||
|
||||
byte[] decrypt_v14_r58564(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(decrypt_v10_r42915(data)));
|
||||
byte[] Decrypt_v14_r58564(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(Decrypt_v10_r42915(data)));
|
||||
return reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
||||
byte[] decrypt_v14_r58852(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(data, true)));
|
||||
byte[] Decrypt_v14_r58852(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(data, true)));
|
||||
data = reader.ReadBytes(reader.ReadInt32());
|
||||
for (int i = 0; i < data.Length; i++) {
|
||||
if ((i & 1) == 0)
|
||||
|
@ -502,15 +502,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return data;
|
||||
}
|
||||
|
||||
byte[] decrypt_v15_r60785(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(data, true)));
|
||||
byte[] Decrypt_v15_r60785(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(data, true)));
|
||||
byte[] key, iv;
|
||||
data = decrypt_v15_r60785(reader, out key, out iv);
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.aesDecrypt(data, key, iv)));
|
||||
data = Decrypt_v15_r60785(reader, out key, out iv);
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.AesDecrypt(data, key, iv)));
|
||||
return reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
||||
byte[] decrypt_v15_r60785(BinaryReader reader, out byte[] key, out byte[] iv) {
|
||||
byte[] Decrypt_v15_r60785(BinaryReader reader, out byte[] key, out byte[] iv) {
|
||||
var encrypted = reader.ReadBytes(reader.ReadInt32());
|
||||
iv = reader.ReadBytes(reader.ReadInt32());
|
||||
key = reader.ReadBytes(reader.ReadInt32());
|
||||
|
@ -523,22 +523,22 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return encrypted;
|
||||
}
|
||||
|
||||
byte[] decrypt_v17_r73404(byte[] data) {
|
||||
byte[] Decrypt_v17_r73404(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(data));
|
||||
byte[] key, iv;
|
||||
data = decrypt_v15_r60785(reader, out key, out iv);
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.inflate(DeobUtils.aesDecrypt(data, key, iv), true)));
|
||||
data = Decrypt_v15_r60785(reader, out key, out iv);
|
||||
reader = new BinaryReader(new MemoryStream(DeobUtils.Inflate(DeobUtils.AesDecrypt(data, key, iv), true)));
|
||||
return reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
||||
byte[] decrypt_v17_r75076(byte[] data) {
|
||||
byte[] Decrypt_v17_r75076(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(data));
|
||||
byte[] key, iv;
|
||||
data = decrypt_v15_r60785(reader, out key, out iv);
|
||||
return sevenzipDecompress(DeobUtils.aesDecrypt(data, key, iv));
|
||||
data = Decrypt_v15_r60785(reader, out key, out iv);
|
||||
return SevenzipDecompress(DeobUtils.AesDecrypt(data, key, iv));
|
||||
}
|
||||
|
||||
static byte[] sevenzipDecompress(byte[] data) {
|
||||
static byte[] SevenzipDecompress(byte[] data) {
|
||||
var reader = new BinaryReader(new MemoryStream(data));
|
||||
int totalSize = reader.ReadInt32();
|
||||
var props = reader.ReadBytes(5);
|
||||
|
@ -552,15 +552,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return decompressed;
|
||||
}
|
||||
|
||||
public void deobfuscate(Blocks blocks) {
|
||||
public void Deobfuscate(Blocks blocks) {
|
||||
if (asmResolverMethod == null)
|
||||
return;
|
||||
if (blocks.Method != DotNetUtils.getModuleTypeCctor(module))
|
||||
if (blocks.Method != DotNetUtils.GetModuleTypeCctor(module))
|
||||
return;
|
||||
ConfuserUtils.removeResourceHookCode(blocks, asmResolverMethod);
|
||||
ConfuserUtils.RemoveResourceHookCode(blocks, asmResolverMethod);
|
||||
}
|
||||
|
||||
public bool getRevisionRange(out int minRev, out int maxRev) {
|
||||
public bool GetRevisionRange(out int minRev, out int maxRev) {
|
||||
switch (version) {
|
||||
case ConfuserVersion.Unknown:
|
||||
minRev = maxRev = 0;
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
public void addRevs(int min, int max) {
|
||||
public void AddRevs(int min, int max) {
|
||||
if (min < 0 || max < 0 || min > max)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
if (!revToVersion.ContainsKey(min) || (max != int.MaxValue && !revToVersion.ContainsKey(max)))
|
||||
|
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
maxRev = max;
|
||||
}
|
||||
|
||||
public void setVersion(Version version) {
|
||||
public void SetVersion(Version version) {
|
||||
if (version == null)
|
||||
return;
|
||||
int minRev = int.MaxValue, maxRev = int.MinValue;
|
||||
|
@ -104,10 +104,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return;
|
||||
if (maxRev == revs[revs.Length - 1])
|
||||
maxRev = int.MaxValue;
|
||||
addRevs(minRev, maxRev);
|
||||
AddRevs(minRev, maxRev);
|
||||
}
|
||||
|
||||
public string getVersionString() {
|
||||
public string GetVersionString() {
|
||||
if (minRev > maxRev || minRev < 0)
|
||||
return null;
|
||||
var minVersion = revToVersion[minRev];
|
||||
|
@ -130,7 +130,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
public override string ToString() {
|
||||
return getVersionString() ?? "<no version>";
|
||||
return GetVersionString() ?? "<no version>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,20 +126,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
this.reader = peImage.Reader;
|
||||
}
|
||||
|
||||
public uint emulate(uint rva, uint arg) {
|
||||
return emulate(rva, new uint[] { arg });
|
||||
public uint Emulate(uint rva, uint arg) {
|
||||
return Emulate(rva, new uint[] { arg });
|
||||
}
|
||||
|
||||
public uint emulate(uint rva, uint[] args) {
|
||||
initialize(args);
|
||||
public uint Emulate(uint rva, uint[] args) {
|
||||
Initialize(args);
|
||||
|
||||
reader.Position = peImage.rvaToOffset(rva);
|
||||
reader.Position = peImage.RvaToOffset(rva);
|
||||
byte[] prolog, epilog;
|
||||
if (isBytes(prolog1)) {
|
||||
if (IsBytes(prolog1)) {
|
||||
prolog = prolog1;
|
||||
epilog = epilog1;
|
||||
}
|
||||
else if (isBytes(prolog2)) {
|
||||
else if (IsBytes(prolog2)) {
|
||||
prolog = prolog2;
|
||||
epilog = epilog2;
|
||||
}
|
||||
|
@ -147,20 +147,20 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new ApplicationException(string.Format("Missing prolog @ RVA {0:X8}", rva));
|
||||
reader.Position += prolog.Length;
|
||||
|
||||
while (!isBytes(epilog))
|
||||
emulate();
|
||||
while (!IsBytes(epilog))
|
||||
Emulate();
|
||||
|
||||
return regs[0];
|
||||
}
|
||||
|
||||
void initialize(uint[] args) {
|
||||
void Initialize(uint[] args) {
|
||||
this.args = args;
|
||||
nextArgIndex = 0;
|
||||
for (int i = 0; i < regs.Length; i++)
|
||||
regs[i] = 0;
|
||||
}
|
||||
|
||||
bool isBytes(IList<byte> bytes) {
|
||||
bool IsBytes(IList<byte> bytes) {
|
||||
long oldPos = reader.Position;
|
||||
bool result = true;
|
||||
for (int i = 0; i < bytes.Count; i++) {
|
||||
|
@ -173,57 +173,57 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return result;
|
||||
}
|
||||
|
||||
void emulate() {
|
||||
var instr = decode();
|
||||
void Emulate() {
|
||||
var instr = Decode();
|
||||
switch (instr.opCode) {
|
||||
case OpCode.Add_RI:
|
||||
case OpCode.Add_RR:
|
||||
writeReg(instr.op1, readOp(instr.op1) + readOp(instr.op2));
|
||||
WriteReg(instr.op1, ReadOp(instr.op1) + ReadOp(instr.op2));
|
||||
break;
|
||||
|
||||
case OpCode.Mov_RI:
|
||||
case OpCode.Mov_RR:
|
||||
writeReg(instr.op1, readOp(instr.op2));
|
||||
WriteReg(instr.op1, ReadOp(instr.op2));
|
||||
break;
|
||||
|
||||
case OpCode.Neg_R:
|
||||
writeReg(instr.op1, (uint)-(int)readOp(instr.op1));
|
||||
WriteReg(instr.op1, (uint)-(int)ReadOp(instr.op1));
|
||||
break;
|
||||
|
||||
case OpCode.Not_R:
|
||||
writeReg(instr.op1, ~readOp(instr.op1));
|
||||
WriteReg(instr.op1, ~ReadOp(instr.op1));
|
||||
break;
|
||||
|
||||
case OpCode.Pop_R:
|
||||
writeReg(instr.op1, getNextArg());
|
||||
WriteReg(instr.op1, GetNextArg());
|
||||
break;
|
||||
|
||||
case OpCode.Sub_RI:
|
||||
case OpCode.Sub_RR:
|
||||
writeReg(instr.op1, readOp(instr.op1) - readOp(instr.op2));
|
||||
WriteReg(instr.op1, ReadOp(instr.op1) - ReadOp(instr.op2));
|
||||
break;
|
||||
|
||||
case OpCode.Xor_RI:
|
||||
case OpCode.Xor_RR:
|
||||
writeReg(instr.op1, readOp(instr.op1) ^ readOp(instr.op2));
|
||||
WriteReg(instr.op1, ReadOp(instr.op1) ^ ReadOp(instr.op2));
|
||||
break;
|
||||
|
||||
default: throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
uint getNextArg() {
|
||||
uint GetNextArg() {
|
||||
if (nextArgIndex >= args.Length)
|
||||
throw new ApplicationException("No more args");
|
||||
return args[nextArgIndex++];
|
||||
}
|
||||
|
||||
void writeReg(IOperand op, uint val) {
|
||||
void WriteReg(IOperand op, uint val) {
|
||||
var regOp = (RegOperand)op;
|
||||
regs[regOp.reg] = val;
|
||||
}
|
||||
|
||||
uint readOp(IOperand op) {
|
||||
uint ReadOp(IOperand op) {
|
||||
var regOp = op as RegOperand;
|
||||
if (regOp != null)
|
||||
return regs[regOp.reg];
|
||||
|
@ -235,19 +235,19 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
Instruction decode() {
|
||||
Instruction Decode() {
|
||||
byte opc = reader.ReadByte();
|
||||
switch (opc) {
|
||||
case 0x01: // ADD Ed,Gd
|
||||
parseModRM();
|
||||
ParseModRM();
|
||||
return new Instruction(OpCode.Add_RR, new RegOperand(rm), new RegOperand(reg));
|
||||
|
||||
case 0x29: // SUB Ed,Gd
|
||||
parseModRM();
|
||||
ParseModRM();
|
||||
return new Instruction(OpCode.Sub_RR, new RegOperand(rm), new RegOperand(reg));
|
||||
|
||||
case 0x31: // XOR Ed,Gd
|
||||
parseModRM();
|
||||
ParseModRM();
|
||||
return new Instruction(OpCode.Xor_RR, new RegOperand(rm), new RegOperand(reg));
|
||||
|
||||
case 0x58: // POP EAX
|
||||
|
@ -261,7 +261,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return new Instruction(OpCode.Pop_R, new RegOperand(opc - 0x58));
|
||||
|
||||
case 0x81: // Grp1 Ed,Id
|
||||
parseModRM();
|
||||
ParseModRM();
|
||||
switch (reg) {
|
||||
case 0: return new Instruction(OpCode.Add_RI, new RegOperand(rm), new ImmOperand(reader.ReadInt32()));
|
||||
case 5: return new Instruction(OpCode.Sub_RI, new RegOperand(rm), new ImmOperand(reader.ReadInt32()));
|
||||
|
@ -270,7 +270,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
|
||||
case 0x89: // MOV Ed,Gd
|
||||
parseModRM();
|
||||
ParseModRM();
|
||||
return new Instruction(OpCode.Mov_RR, new RegOperand(rm), new RegOperand(reg));
|
||||
|
||||
case 0xB8: // MOV EAX,Id
|
||||
|
@ -284,7 +284,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
return new Instruction(OpCode.Mov_RI, new RegOperand(opc - 0xB8), new ImmOperand(reader.ReadInt32()));
|
||||
|
||||
case 0xF7: // Grp3 Ev
|
||||
parseModRM();
|
||||
ParseModRM();
|
||||
switch (reg) {
|
||||
case 2: return new Instruction(OpCode.Not_R, new RegOperand(rm));
|
||||
case 3: return new Instruction(OpCode.Neg_R, new RegOperand(rm));
|
||||
|
@ -295,7 +295,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
|||
}
|
||||
}
|
||||
|
||||
void parseModRM() {
|
||||
void ParseModRM() {
|
||||
modRM = reader.ReadByte();
|
||||
mod = (byte)((modRM >> 6) & 7);
|
||||
reg = (byte)((modRM >> 3) & 7);
|
||||
|
|
Loading…
Reference in New Issue
Block a user