diff --git a/de4dot.code/deobfuscators/Confuser/ConfuserUtils.cs b/de4dot.code/deobfuscators/Confuser/ConfuserUtils.cs index 825a3c99..94a15f0f 100644 --- a/de4dot.code/deobfuscators/Confuser/ConfuserUtils.cs +++ b/de4dot.code/deobfuscators/Confuser/ConfuserUtils.cs @@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.Confuser { return decrypted; } - static readonly byte[] defaultDecryptKey = new byte[8]; + static readonly byte[] defaultDecryptKey = new byte[1]; public static byte[] decrypt(uint seed, byte[] encrypted) { return decrypt(seed, encrypted, defaultDecryptKey); } @@ -126,7 +126,7 @@ namespace de4dot.code.deobfuscators.Confuser { ushort _c = (ushort)seed; ushort m = _c; ushort c = _m; for (int i = 0; i < decrypted.Length; i++) { - decrypted[i] = (byte)(encrypted[i] ^ (seed * m + c) ^ key[i & 7]); + decrypted[i] = (byte)(encrypted[i] ^ (seed * m + c) ^ key[i % key.Length]); m = (ushort)(seed * m + _m); c = (ushort)(seed * c + _c); } diff --git a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs index a7ec3caa..3ccbf86d 100644 --- a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs +++ b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterBase.cs @@ -367,7 +367,7 @@ namespace de4dot.code.deobfuscators.Confuser { if (!DotNetUtils.isLdloc(instrs[i + 5])) continue; var ldci4 = instrs[i + 6]; - if (!DotNetUtils.isLdcI4(ldci4) || DotNetUtils.getLdcI4Value(ldci4) != 8) + if (!DotNetUtils.isLdcI4(ldci4) || (DotNetUtils.getLdcI4Value(ldci4) != 8 && DotNetUtils.getLdcI4Value(ldci4) != 16)) continue; if (instrs[i + 7].OpCode.Code != Code.Rem) continue; @@ -400,7 +400,7 @@ namespace de4dot.code.deobfuscators.Confuser { return -1; } - static readonly byte[] defaultDecryptKey_v17 = new byte[8]; + 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); } @@ -423,7 +423,7 @@ namespace de4dot.code.deobfuscators.Confuser { int index = startIndex, result; if (!constReader.getNextInt32(ref index, out result) || index != endIndex) throw new ApplicationException("Could not decrypt integer"); - return (byte)(result ^ key2[i & 7]); + return (byte)(result ^ key2[i % key2.Length]); }); } @@ -433,7 +433,7 @@ namespace de4dot.code.deobfuscators.Confuser { protected byte[] decryptConstant_v17_r73764_native(DecrypterInfo info, byte[] encrypted, uint offs, uint key1, byte[] key2) { var x86Emu = new x86Emulator(new PeImage(fileData)); - return decrypt(encrypted, key1, (magic, i) => (byte)(x86Emu.emulate((uint)nativeMethod.RVA, magic) ^ key2[i & 7])); + 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 decryptFunc) { diff --git a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs index bb121f87..2c4cb447 100644 --- a/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs +++ b/de4dot.code/deobfuscators/Confuser/ConstantsDecrypterV17.cs @@ -30,6 +30,7 @@ namespace de4dot.code.deobfuscators.Confuser { MethodDefinition initMethod; ConfuserVersion version = ConfuserVersion.Unknown; string resourceName; + int keyArraySize; enum ConfuserVersion { Unknown, @@ -45,6 +46,9 @@ namespace de4dot.code.deobfuscators.Confuser { v17_r75056_normal, v17_r75056_dynamic, v17_r75056_native, + v18_r75257_normal, + v18_r75257_dynamic, + v18_r75257_native, } class DecrypterInfoV17 : DecrypterInfo { @@ -103,6 +107,7 @@ namespace de4dot.code.deobfuscators.Confuser { 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); case ConfuserVersion.v17_r74708_dynamic: case ConfuserVersion.v17_r74708_native: @@ -112,6 +117,8 @@ namespace de4dot.code.deobfuscators.Confuser { case ConfuserVersion.v17_r74816_native: case ConfuserVersion.v17_r75056_dynamic: case ConfuserVersion.v17_r75056_native: + case ConfuserVersion.v18_r75257_dynamic: + case ConfuserVersion.v18_r75257_native: return findKey4_other(method, out key); default: throw new ApplicationException("Invalid version"); @@ -172,6 +179,9 @@ namespace de4dot.code.deobfuscators.Confuser { case ConfuserVersion.v17_r75056_normal: case ConfuserVersion.v17_r75056_dynamic: case ConfuserVersion.v17_r75056_native: + case ConfuserVersion.v18_r75257_normal: + case ConfuserVersion.v18_r75257_dynamic: + case ConfuserVersion.v18_r75257_native: return findKey5_v17_r74788(method, out key); default: key = 0; @@ -232,8 +242,16 @@ namespace de4dot.code.deobfuscators.Confuser { resourceName = getResourceName(cctor); - if (resourceName != null) - initVersion(method, ConfuserVersion.v17_r75056_normal, ConfuserVersion.v17_r75056_dynamic, ConfuserVersion.v17_r75056_native); + if (resourceName != null) { + simpleDeobfuscator.deobfuscate(method); + keyArraySize = getKeyArraySize(method); + if (keyArraySize == 8) + 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); + 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)")) @@ -299,6 +317,9 @@ namespace de4dot.code.deobfuscators.Confuser { 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"); } @@ -329,7 +350,10 @@ namespace de4dot.code.deobfuscators.Confuser { } byte[] getKey_v17_r74788(DecrypterInfoV17 info) { - return module.GetSignatureBlob(info.decryptMethod.MetadataToken.ToUInt32() ^ info.key5); + var key = module.GetSignatureBlob(info.decryptMethod.MetadataToken.ToUInt32() ^ info.key5); + if (key.Length != keyArraySize) + throw new ApplicationException("Invalid key size"); + return key; } public override void initialize() { @@ -392,5 +416,25 @@ namespace de4dot.code.deobfuscators.Confuser { } return null; } + + static int getKeyArraySize(MethodDefinition method) { + var instrs = method.Body.Instructions; + for (int i = 0; i < instrs.Count - 4; i++) { + if (!DotNetUtils.isLdloc(instrs[i])) + continue; + if (!DotNetUtils.isLdloc(instrs[i + 1])) + continue; + var ldci4 = instrs[i + 2]; + if (!DotNetUtils.isLdcI4(ldci4)) + continue; + if (instrs[i + 3].OpCode.Code != Code.Rem) + continue; + if (instrs[i + 4].OpCode.Code != Code.Ldelem_U1) + continue; + + return DotNetUtils.getLdcI4Value(ldci4); + } + return -1; + } } }