Support Confuser 1.9 r78963

This commit is contained in:
de4dot 2013-09-22 16:07:15 +02:00
parent df2c8dc27f
commit 3447efba31
2 changed files with 60 additions and 14 deletions

View File

@ -34,6 +34,7 @@ namespace de4dot.code.deobfuscators.Confuser {
byte[] fileData; byte[] fileData;
x86Emulator x86emu; x86Emulator x86emu;
ushort callvirtChar; ushort callvirtChar;
bool foundNewobjProxy;
enum ConfuserVersion { enum ConfuserVersion {
Unknown, Unknown,
@ -62,6 +63,8 @@ namespace de4dot.code.deobfuscators.Confuser {
v19_r76101_native, v19_r76101_native,
v19_r78363_normal, v19_r78363_normal,
v19_r78363_native, v19_r78363_native,
v19_r78963_normal_Newobj,
v19_r78963_native_Newobj,
} }
enum ProxyCreatorType { enum ProxyCreatorType {
@ -238,6 +241,7 @@ namespace de4dot.code.deobfuscators.Confuser {
case ConfuserVersion.v18_r75369_normal: case ConfuserVersion.v18_r75369_normal:
case ConfuserVersion.v19_r76101_normal: case ConfuserVersion.v19_r76101_normal:
case ConfuserVersion.v19_r78363_normal: case ConfuserVersion.v19_r78363_normal:
case ConfuserVersion.v19_r78963_normal_Newobj:
GetCallInfo_v18_r75367_normal(info, creatorInfo, out calledMethod, out callOpcode); GetCallInfo_v18_r75367_normal(info, creatorInfo, out calledMethod, out callOpcode);
break; break;
@ -245,6 +249,7 @@ namespace de4dot.code.deobfuscators.Confuser {
case ConfuserVersion.v18_r75369_native: case ConfuserVersion.v18_r75369_native:
case ConfuserVersion.v19_r76101_native: case ConfuserVersion.v19_r76101_native:
case ConfuserVersion.v19_r78363_native: case ConfuserVersion.v19_r78363_native:
case ConfuserVersion.v19_r78963_native_Newobj:
GetCallInfo_v18_r75367_native(info, creatorInfo, out calledMethod, out callOpcode); GetCallInfo_v18_r75367_native(info, creatorInfo, out calledMethod, out callOpcode);
break; break;
@ -484,6 +489,8 @@ namespace de4dot.code.deobfuscators.Confuser {
var proxyType = GetProxyCreatorType(method, simpleDeobfuscator, out tmpVer); var proxyType = GetProxyCreatorType(method, simpleDeobfuscator, out tmpVer);
if (proxyType == ProxyCreatorType.None) if (proxyType == ProxyCreatorType.None)
continue; continue;
if (proxyType == ProxyCreatorType.Newobj)
foundNewobjProxy = true;
simpleDeobfuscator.Deobfuscate(method); simpleDeobfuscator.Deobfuscate(method);
MethodDef nativeMethod = null; MethodDef nativeMethod = null;
@ -512,18 +519,10 @@ namespace de4dot.code.deobfuscators.Confuser {
theVersion = proxyType != ProxyCreatorType.CallOrCallvirt || callvirtChar == 9 ? ConfuserVersion.v18_r75367_native : ConfuserVersion.v18_r75369_native; 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; 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))
if (tmpVer == 1) CommonCheckVersion19(method, true, tmpVer, ref theVersion);
theVersion = ConfuserVersion.v19_r76101_normal; else if ((nativeMethod = FindNativeMethod_v19_r76101(method)) != null)
else if (tmpVer == 2) CommonCheckVersion19(method, false, tmpVer, ref theVersion);
theVersion = ConfuserVersion.v19_r78363_normal;
}
else if ((nativeMethod = FindNativeMethod_v19_r76101(method)) != null) {
if (tmpVer == 1)
theVersion = ConfuserVersion.v19_r76101_native;
else if (tmpVer == 2)
theVersion = ConfuserVersion.v19_r78363_native;
}
else { 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; theVersion = ConfuserVersion.v11_r50378;
@ -565,6 +564,22 @@ namespace de4dot.code.deobfuscators.Confuser {
} }
} }
static bool CommonCheckVersion19(MethodDef method, bool isNormal, int tmpProxyVer, ref ConfuserVersion theVersion) {
if (tmpProxyVer == 1) {
theVersion = isNormal ? ConfuserVersion.v19_r76101_normal : ConfuserVersion.v19_r76101_native;
return true;
}
else if (tmpProxyVer == 2) {
if (!CheckCtorProxyType_v19_r78963(method))
theVersion = isNormal ? ConfuserVersion.v19_r78363_normal : ConfuserVersion.v19_r78363_native;
else
theVersion = isNormal ? ConfuserVersion.v19_r78963_normal_Newobj : ConfuserVersion.v19_r78963_native_Newobj;
return true;
}
return false;
}
static bool HasFieldReference(MethodDef method, string fieldFullName) { static bool HasFieldReference(MethodDef method, string fieldFullName) {
foreach (var instr in method.Body.Instructions) { foreach (var instr in method.Body.Instructions) {
var field = instr.Operand as IField; var field = instr.Operand as IField;
@ -861,7 +876,7 @@ namespace de4dot.code.deobfuscators.Confuser {
static bool CheckCtorProxyTypeV2(MethodDef method) { static bool CheckCtorProxyTypeV2(MethodDef method) {
var instrs = method.Body.Instructions; var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count; i++) { for (int i = 0; i < instrs.Count - 3; i++) {
var ldci4 = instrs[i]; var ldci4 = instrs[i];
if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 2) if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 2)
continue; continue;
@ -883,6 +898,24 @@ namespace de4dot.code.deobfuscators.Confuser {
DeobUtils.HasInteger(method, 0x6F); DeobUtils.HasInteger(method, 0x6F);
} }
// r78963 adds a 'castclass' opcode to the generated code. This code assumes
// CheckCtorProxyTypeV2() has returned true.
static bool CheckCtorProxyType_v19_r78963(MethodDef method) {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
if (instrs[i].OpCode.Code != Code.Add)
continue;
var ldci4 = instrs[i + 1];
if (!ldci4.IsLdcI4() || ldci4.GetLdcI4Value() != 0x74)
continue;
if (instrs[i + 2].OpCode.Code != Code.Stelem_I1)
continue;
return true;
}
return false;
}
public new void Find() { public new void Find() {
if (delegateCreatorMethods.Count == 0) if (delegateCreatorMethods.Count == 0)
return; return;
@ -1190,6 +1223,18 @@ namespace de4dot.code.deobfuscators.Confuser {
case ConfuserVersion.v19_r78363_normal: case ConfuserVersion.v19_r78363_normal:
case ConfuserVersion.v19_r78363_native: case ConfuserVersion.v19_r78363_native:
minRev = 78363; minRev = 78363;
// We can only detect the r78963 version if a method ctor proxy is used.
// If it's not used, then maxRev must be the same maxRev as in the next case.
// If a method ctor proxy is found, then we know that rev <= 78962.
if (foundNewobjProxy)
maxRev = 78962;
else
maxRev = int.MaxValue;
return true;
case ConfuserVersion.v19_r78963_normal_Newobj:
case ConfuserVersion.v19_r78963_native_Newobj:
minRev = 78963;
maxRev = int.MaxValue; maxRev = int.MaxValue;
return true; return true;

View File

@ -45,7 +45,8 @@ namespace de4dot.code.deobfuscators.Confuser {
76119, 76163, 76186, 76271, 76360, 76509, 76542, 76548, 76119, 76163, 76186, 76271, 76360, 76509, 76542, 76548,
76558, 76580, 76656, 76871, 76923, 76924, 76933, 76934, 76558, 76580, 76656, 76871, 76923, 76924, 76933, 76934,
76972, 76974, 77124, 77172, 77447, 77501, 78056, 78072, 76972, 76974, 77124, 77172, 77447, 77501, 78056, 78072,
78086, 78196, 78197, 78342, 78363, 78377, 78086, 78196, 78197, 78342, 78363, 78377, 78612, 78638,
78642, 78730, 78731, 78962, 78963,
}; };
static Dictionary<int, Version> revToVersion = new Dictionary<int, Version> { static Dictionary<int, Version> revToVersion = new Dictionary<int, Version> {