Support Confuser 1.9 r77172
This commit is contained in:
parent
40083ad33a
commit
3eb7e5be41
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using SevenZip.Compression.LZMA;
|
||||||
using dnlib.IO;
|
using dnlib.IO;
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
using dnlib.DotNet.Emit;
|
using dnlib.DotNet.Emit;
|
||||||
|
@ -171,5 +173,84 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static byte[] SevenZipDecompress(byte[] data) {
|
||||||
|
var reader = new BinaryReader(new MemoryStream(data));
|
||||||
|
var props = reader.ReadBytes(5);
|
||||||
|
var decoder = new Decoder();
|
||||||
|
decoder.SetDecoderProperties(props);
|
||||||
|
long totalSize = reader.ReadInt64();
|
||||||
|
long compressedSize = data.Length - props.Length - 8;
|
||||||
|
var decompressed = new byte[totalSize];
|
||||||
|
decoder.Code(reader.BaseStream, new MemoryStream(decompressed, true), compressedSize, totalSize, null);
|
||||||
|
return decompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds the Lzma type by finding an instruction that allocates a new Lzma.Decoder
|
||||||
|
public static TypeDef FindLzmaType(MethodDef method) {
|
||||||
|
if (method == null || method.Body == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
foreach (var instr in method.Body.Instructions) {
|
||||||
|
if (instr.OpCode.Code != Code.Newobj)
|
||||||
|
continue;
|
||||||
|
var ctor = instr.Operand as MethodDef;
|
||||||
|
if (ctor == null)
|
||||||
|
continue;
|
||||||
|
var ctorType = ctor.DeclaringType;
|
||||||
|
if (ctorType == null)
|
||||||
|
continue;
|
||||||
|
if (!IsLzmaType(ctorType.DeclaringType))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return ctorType.DeclaringType;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsLzmaType(TypeDef type) {
|
||||||
|
if (type == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (type.NestedTypes.Count != 6)
|
||||||
|
return false;
|
||||||
|
if (!CheckLzmaMethods(type))
|
||||||
|
return false;
|
||||||
|
if (FindLzmaOutWindowType(type.NestedTypes) == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckLzmaMethods(TypeDef type) {
|
||||||
|
int methods = 0;
|
||||||
|
foreach (var m in type.Methods) {
|
||||||
|
if (m.IsStaticConstructor)
|
||||||
|
continue;
|
||||||
|
if (m.IsInstanceConstructor) {
|
||||||
|
if (m.MethodSig.GetParamCount() != 0)
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!DotNetUtils.IsMethod(m, "System.UInt32", "(System.UInt32)"))
|
||||||
|
return false;
|
||||||
|
methods++;
|
||||||
|
}
|
||||||
|
return methods == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static readonly string[] outWindowFields = new string[] {
|
||||||
|
"System.Byte[]",
|
||||||
|
"System.UInt32",
|
||||||
|
"System.IO.Stream",
|
||||||
|
};
|
||||||
|
static TypeDef FindLzmaOutWindowType(IEnumerable<TypeDef> types) {
|
||||||
|
foreach (var type in types) {
|
||||||
|
if (new FieldTypes(type).Exactly(outWindowFields))
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FieldDef FindDataField(MethodDef method, TypeDef declaringType) {
|
public static FieldDef FindDataField_v18_r75367(MethodDef method, TypeDef declaringType) {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 1; i++) {
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
var callvirt = instrs[i];
|
var callvirt = instrs[i];
|
||||||
|
@ -70,6 +70,31 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Normal ("safe") mode only (not dynamic or native)
|
||||||
|
public static FieldDef FindDataField_v19_r77172(MethodDef method, TypeDef declaringType) {
|
||||||
|
var instrs = method.Body.Instructions;
|
||||||
|
for (int i = 0; i < instrs.Count - 1; i++) {
|
||||||
|
var ldloc = instrs[i];
|
||||||
|
if (!ldloc.IsLdloc())
|
||||||
|
continue;
|
||||||
|
var local = ldloc.GetLocal(method.Body.Variables);
|
||||||
|
if (local == null || local.Type.GetFullName() != "System.Byte[]")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var stsfld = instrs[i + 1];
|
||||||
|
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||||
|
continue;
|
||||||
|
var field = stsfld.Operand as FieldDef;
|
||||||
|
if (field == null || field.DeclaringType != declaringType)
|
||||||
|
continue;
|
||||||
|
if (field.FieldType.FullName != "System.Byte[]")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static FieldDef FindStreamField(MethodDef method, TypeDef declaringType) {
|
public static FieldDef FindStreamField(MethodDef method, TypeDef declaringType) {
|
||||||
return FindStreamField(method, declaringType, "System.IO.Stream");
|
return FindStreamField(method, declaringType, "System.IO.Stream");
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
MethodDefAndDeclaringTypeDict<DecrypterInfo> decrypters = new MethodDefAndDeclaringTypeDict<DecrypterInfo>();
|
MethodDefAndDeclaringTypeDict<DecrypterInfo> decrypters = new MethodDefAndDeclaringTypeDict<DecrypterInfo>();
|
||||||
uint key0, key0d;
|
uint key0, key0d;
|
||||||
MethodDef nativeMethod;
|
MethodDef nativeMethod;
|
||||||
|
TypeDef lzmaType;
|
||||||
EmbeddedResource resource;
|
EmbeddedResource resource;
|
||||||
byte[] constants;
|
byte[] constants;
|
||||||
ConfuserVersion version = ConfuserVersion.Unknown;
|
ConfuserVersion version = ConfuserVersion.Unknown;
|
||||||
|
@ -50,6 +51,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
v18_r75369_normal,
|
v18_r75369_normal,
|
||||||
v18_r75369_dynamic,
|
v18_r75369_dynamic,
|
||||||
v18_r75369_native,
|
v18_r75369_native,
|
||||||
|
v19_r77172_normal,
|
||||||
|
v19_r77172_dynamic,
|
||||||
|
v19_r77172_native,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DecrypterInfo {
|
public class DecrypterInfo {
|
||||||
|
@ -105,6 +109,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
case ConfuserVersion.v18_r75369_normal:
|
case ConfuserVersion.v18_r75369_normal:
|
||||||
case ConfuserVersion.v18_r75369_dynamic:
|
case ConfuserVersion.v18_r75369_dynamic:
|
||||||
case ConfuserVersion.v18_r75369_native:
|
case ConfuserVersion.v18_r75369_native:
|
||||||
|
case ConfuserVersion.v19_r77172_normal:
|
||||||
|
case ConfuserVersion.v19_r77172_dynamic:
|
||||||
|
case ConfuserVersion.v19_r77172_native:
|
||||||
return Hash1(key0l * magic);
|
return Hash1(key0l * magic);
|
||||||
default:
|
default:
|
||||||
throw new ApplicationException("Invalid version");
|
throw new ApplicationException("Invalid version");
|
||||||
|
@ -151,6 +158,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
get { return nativeMethod; }
|
get { return nativeMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeDef LzmaType {
|
||||||
|
get { return lzmaType; }
|
||||||
|
}
|
||||||
|
|
||||||
public EmbeddedResource Resource {
|
public EmbeddedResource Resource {
|
||||||
get { return resource; }
|
get { return resource; }
|
||||||
}
|
}
|
||||||
|
@ -177,7 +188,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
|
|
||||||
if ((dictField = ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType)) == null)
|
if ((dictField = ConstantsDecrypterUtils.FindDictField(cctor, cctor.DeclaringType)) == null)
|
||||||
return;
|
return;
|
||||||
if ((dataField = ConstantsDecrypterUtils.FindDataField(cctor, cctor.DeclaringType)) == null)
|
|
||||||
|
if ((dataField = ConstantsDecrypterUtils.FindDataField_v18_r75367(cctor, cctor.DeclaringType)) == null &&
|
||||||
|
(dataField = ConstantsDecrypterUtils.FindDataField_v19_r77172(cctor, cctor.DeclaringType)) == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nativeMethod = FindNativeMethod(cctor, cctor.DeclaringType);
|
nativeMethod = FindNativeMethod(cctor, cctor.DeclaringType);
|
||||||
|
@ -189,8 +202,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
var info = new DecrypterInfo(this, method, ConfuserVersion.Unknown);
|
var info = new DecrypterInfo(this, method, ConfuserVersion.Unknown);
|
||||||
if (FindKeys_v18_r75367(info))
|
if (FindKeys_v18_r75367(info))
|
||||||
InitVersion(cctor, ConfuserVersion.v18_r75367_normal, ConfuserVersion.v18_r75367_dynamic, ConfuserVersion.v18_r75367_native);
|
InitVersion(cctor, ConfuserVersion.v18_r75367_normal, ConfuserVersion.v18_r75367_dynamic, ConfuserVersion.v18_r75367_native);
|
||||||
else if (FindKeys_v18_r75369(info))
|
else if (FindKeys_v18_r75369(info)) {
|
||||||
|
lzmaType = ConfuserUtils.FindLzmaType(cctor);
|
||||||
|
if (lzmaType == null)
|
||||||
InitVersion(cctor, ConfuserVersion.v18_r75369_normal, ConfuserVersion.v18_r75369_dynamic, ConfuserVersion.v18_r75369_native);
|
InitVersion(cctor, ConfuserVersion.v18_r75369_normal, ConfuserVersion.v18_r75369_dynamic, ConfuserVersion.v18_r75369_native);
|
||||||
|
else
|
||||||
|
InitVersion(cctor, ConfuserVersion.v19_r77172_normal, ConfuserVersion.v19_r77172_dynamic, ConfuserVersion.v19_r77172_native);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -380,6 +398,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
case ConfuserVersion.v18_r75369_normal:
|
case ConfuserVersion.v18_r75369_normal:
|
||||||
case ConfuserVersion.v18_r75369_dynamic:
|
case ConfuserVersion.v18_r75369_dynamic:
|
||||||
case ConfuserVersion.v18_r75369_native:
|
case ConfuserVersion.v18_r75369_native:
|
||||||
|
case ConfuserVersion.v19_r77172_normal:
|
||||||
|
case ConfuserVersion.v19_r77172_dynamic:
|
||||||
|
case ConfuserVersion.v19_r77172_native:
|
||||||
return FindKeys_v18_r75369(info);
|
return FindKeys_v18_r75369(info);
|
||||||
default:
|
default:
|
||||||
throw new ApplicationException("Invalid version");
|
throw new ApplicationException("Invalid version");
|
||||||
|
@ -541,18 +562,27 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] Decompress(byte[] compressed) {
|
||||||
|
if (lzmaType != null)
|
||||||
|
return ConfuserUtils.SevenZipDecompress(compressed);
|
||||||
|
return DeobUtils.Inflate(compressed, true);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] DecryptResource(byte[] encrypted) {
|
byte[] DecryptResource(byte[] encrypted) {
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case ConfuserVersion.v18_r75367_normal:
|
case ConfuserVersion.v18_r75367_normal:
|
||||||
case ConfuserVersion.v18_r75369_normal:
|
case ConfuserVersion.v18_r75369_normal:
|
||||||
|
case ConfuserVersion.v19_r77172_normal:
|
||||||
return DecryptResource_v18_r75367_normal(encrypted);
|
return DecryptResource_v18_r75367_normal(encrypted);
|
||||||
|
|
||||||
case ConfuserVersion.v18_r75367_dynamic:
|
case ConfuserVersion.v18_r75367_dynamic:
|
||||||
case ConfuserVersion.v18_r75369_dynamic:
|
case ConfuserVersion.v18_r75369_dynamic:
|
||||||
|
case ConfuserVersion.v19_r77172_dynamic:
|
||||||
return DecryptResource_v18_r75367_dynamic(encrypted);
|
return DecryptResource_v18_r75367_dynamic(encrypted);
|
||||||
|
|
||||||
case ConfuserVersion.v18_r75367_native:
|
case ConfuserVersion.v18_r75367_native:
|
||||||
case ConfuserVersion.v18_r75369_native:
|
case ConfuserVersion.v18_r75369_native:
|
||||||
|
case ConfuserVersion.v19_r77172_native:
|
||||||
return DecryptResource_v18_r75367_native(encrypted);
|
return DecryptResource_v18_r75367_native(encrypted);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -567,7 +597,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
byte[] DecryptResource_v18_r75367_normal(byte[] encrypted) {
|
byte[] DecryptResource_v18_r75367_normal(byte[] encrypted) {
|
||||||
var key = GetSigKey();
|
var key = GetSigKey();
|
||||||
var decrypted = ConfuserUtils.Decrypt(BitConverter.ToUInt32(key, 12) * (uint)key0, encrypted);
|
var decrypted = ConfuserUtils.Decrypt(BitConverter.ToUInt32(key, 12) * (uint)key0, encrypted);
|
||||||
return DeobUtils.Inflate(DeobUtils.AesDecrypt(decrypted, key, DeobUtils.Md5Sum(key)), true);
|
return Decompress(DeobUtils.AesDecrypt(decrypted, key, DeobUtils.Md5Sum(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetDynamicStartIndex(IList<Instruction> instrs, int ldlocIndex) {
|
static int GetDynamicStartIndex(IList<Instruction> instrs, int ldlocIndex) {
|
||||||
|
@ -645,9 +675,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
byte[] DecryptResource(byte[] encrypted, Func<uint, byte> decryptFunc) {
|
byte[] DecryptResource(byte[] encrypted, Func<uint, byte> decryptFunc) {
|
||||||
var key = GetSigKey();
|
var key = GetSigKey();
|
||||||
|
|
||||||
var decrypted = DeobUtils.AesDecrypt(encrypted, key, DeobUtils.Md5Sum(key));
|
byte[] decrypted = DecryptAndDecompress(encrypted, key);
|
||||||
decrypted = DeobUtils.Inflate(decrypted, true);
|
|
||||||
|
|
||||||
var reader = MemoryImageStream.Create(decrypted);
|
var reader = MemoryImageStream.Create(decrypted);
|
||||||
var result = new MemoryStream();
|
var result = new MemoryStream();
|
||||||
var writer = new BinaryWriter(result);
|
var writer = new BinaryWriter(result);
|
||||||
|
@ -659,6 +687,16 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] DecryptAndDecompress(byte[] encrypted, byte[] key) {
|
||||||
|
byte[] iv = DeobUtils.Md5Sum(key);
|
||||||
|
try {
|
||||||
|
return Decompress(DeobUtils.AesDecrypt(encrypted, key, iv));
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
return DeobUtils.AesDecrypt(Decompress(encrypted), key, iv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool VerifyGenericArg(MethodSpec gim, ElementType etype) {
|
static bool VerifyGenericArg(MethodSpec gim, ElementType etype) {
|
||||||
if (gim == null)
|
if (gim == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -729,6 +767,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
case ConfuserVersion.v18_r75369_dynamic:
|
case ConfuserVersion.v18_r75369_dynamic:
|
||||||
case ConfuserVersion.v18_r75369_native:
|
case ConfuserVersion.v18_r75369_native:
|
||||||
minRev = 75369;
|
minRev = 75369;
|
||||||
|
maxRev = 77124;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case ConfuserVersion.v19_r77172_normal:
|
||||||
|
case ConfuserVersion.v19_r77172_dynamic:
|
||||||
|
case ConfuserVersion.v19_r77172_native:
|
||||||
|
minRev = 77172;
|
||||||
maxRev = int.MaxValue;
|
maxRev = int.MaxValue;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -461,6 +461,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
AddTypesToBeRemoved(constantsDecrypterV18.Types, "Constants decrypter type");
|
AddTypesToBeRemoved(constantsDecrypterV18.Types, "Constants decrypter type");
|
||||||
AddFieldsToBeRemoved(constantsDecrypterV18.Fields, "Constants decrypter field");
|
AddFieldsToBeRemoved(constantsDecrypterV18.Fields, "Constants decrypter field");
|
||||||
AddMethodToBeRemoved(constantsDecrypterV18.NativeMethod, "Constants decrypter native method");
|
AddMethodToBeRemoved(constantsDecrypterV18.NativeMethod, "Constants decrypter native method");
|
||||||
|
AddTypeToBeRemoved(constantsDecrypterV18.LzmaType, "LZMA type");
|
||||||
AddResourceToBeRemoved(constantsDecrypterV18.Resource, "Encrypted constants");
|
AddResourceToBeRemoved(constantsDecrypterV18.Resource, "Encrypted constants");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +517,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
AddResourceToBeRemoved(rsrc, "Encrypted resources");
|
AddResourceToBeRemoved(rsrc, "Encrypted resources");
|
||||||
AddMethodToBeRemoved(resourceDecrypter.Handler, "Resource decrypter handler");
|
AddMethodToBeRemoved(resourceDecrypter.Handler, "Resource decrypter handler");
|
||||||
AddFieldsToBeRemoved(resourceDecrypter.Fields, "Resource decrypter field");
|
AddFieldsToBeRemoved(resourceDecrypter.Fields, "Resource decrypter field");
|
||||||
|
AddTypeToBeRemoved(resourceDecrypter.LzmaType, "LZMA type");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveObfuscatorAttribute() {
|
void RemoveObfuscatorAttribute() {
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
MethodDef handler;
|
MethodDef handler;
|
||||||
MethodDef installMethod;
|
MethodDef installMethod;
|
||||||
|
TypeDef lzmaType;
|
||||||
EmbeddedResource resource;
|
EmbeddedResource resource;
|
||||||
Dictionary<FieldDef, bool> fields = new Dictionary<FieldDef, bool>();
|
Dictionary<FieldDef, bool> fields = new Dictionary<FieldDef, bool>();
|
||||||
byte key0, key1;
|
byte key0, key1;
|
||||||
|
@ -42,6 +43,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
v17_r73822,
|
v17_r73822,
|
||||||
v18_r75367,
|
v18_r75367,
|
||||||
v18_r75369,
|
v18_r75369,
|
||||||
|
v19_r77172,
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<FieldDef> Fields {
|
public IEnumerable<FieldDef> Fields {
|
||||||
|
@ -52,6 +54,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
get { return handler; }
|
get { return handler; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeDef LzmaType {
|
||||||
|
get { return lzmaType; }
|
||||||
|
}
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return handler != null; }
|
get { return handler != null; }
|
||||||
}
|
}
|
||||||
|
@ -103,8 +109,13 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
tmpVersion = ConfuserVersion.v17_r73822;
|
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;
|
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)) {
|
||||||
|
lzmaType = ConfuserUtils.FindLzmaType(tmpHandler);
|
||||||
|
if (lzmaType == null)
|
||||||
tmpVersion = ConfuserVersion.v18_r75369;
|
tmpVersion = ConfuserVersion.v18_r75369;
|
||||||
|
else
|
||||||
|
tmpVersion = ConfuserVersion.v19_r77172;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -343,6 +354,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
case ConfuserVersion.v17_r73822: return Decrypt_v17_r73404();
|
case ConfuserVersion.v17_r73822: return Decrypt_v17_r73404();
|
||||||
case ConfuserVersion.v18_r75367: return Decrypt_v18_r75367();
|
case ConfuserVersion.v18_r75367: return Decrypt_v18_r75367();
|
||||||
case ConfuserVersion.v18_r75369: return Decrypt_v18_r75367();
|
case ConfuserVersion.v18_r75369: return Decrypt_v18_r75367();
|
||||||
|
case ConfuserVersion.v19_r77172: return Decrypt_v19_r77172();
|
||||||
default: throw new ApplicationException("Unknown version");
|
default: throw new ApplicationException("Unknown version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,6 +393,17 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
return reader.ReadBytes(reader.ReadInt32());
|
return reader.ReadBytes(reader.ReadInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] Decrypt_v19_r77172() {
|
||||||
|
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(ConfuserUtils.SevenZipDecompress(encrypted)));
|
||||||
|
return reader.ReadBytes(reader.ReadInt32());
|
||||||
|
}
|
||||||
|
|
||||||
public void Deobfuscate(Blocks blocks) {
|
public void Deobfuscate(Blocks blocks) {
|
||||||
if (blocks.Method != installMethod)
|
if (blocks.Method != installMethod)
|
||||||
return;
|
return;
|
||||||
|
@ -415,6 +438,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
|
|
||||||
case ConfuserVersion.v18_r75369:
|
case ConfuserVersion.v18_r75369:
|
||||||
minRev = 75369;
|
minRev = 75369;
|
||||||
|
maxRev = 77124;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case ConfuserVersion.v19_r77172:
|
||||||
|
minRev = 77172;
|
||||||
maxRev = int.MaxValue;
|
maxRev = int.MaxValue;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
v17_r75076,
|
v17_r75076,
|
||||||
v18_r75184,
|
v18_r75184,
|
||||||
v18_r75367,
|
v18_r75367,
|
||||||
|
v19_r77172,
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
|
@ -170,8 +171,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
theVersion = ConfuserVersion.v17_r75076;
|
theVersion = ConfuserVersion.v17_r75076;
|
||||||
else if (module.Name == "Stub.exe")
|
else if (module.Name == "Stub.exe")
|
||||||
theVersion = ConfuserVersion.v18_r75184;
|
theVersion = ConfuserVersion.v18_r75184;
|
||||||
else
|
else if (!IsGetLenToPosStateMethodPrivate(type))
|
||||||
theVersion = ConfuserVersion.v18_r75367;
|
theVersion = ConfuserVersion.v18_r75367;
|
||||||
|
else
|
||||||
|
theVersion = ConfuserVersion.v19_r77172;
|
||||||
}
|
}
|
||||||
else if (IsDecryptMethod_v17_r73404(decyptMethod))
|
else if (IsDecryptMethod_v17_r73404(decyptMethod))
|
||||||
theVersion = ConfuserVersion.v17_r73404;
|
theVersion = ConfuserVersion.v17_r73404;
|
||||||
|
@ -201,6 +204,15 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
version = theVersion;
|
version = theVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsGetLenToPosStateMethodPrivate(TypeDef type) {
|
||||||
|
foreach (var m in type.Methods) {
|
||||||
|
if (!DotNetUtils.IsMethod(m, "System.UInt32", "(System.UInt32)"))
|
||||||
|
continue;
|
||||||
|
return m.IsPrivate;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool FindEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token) {
|
bool FindEntryPointToken(ISimpleDeobfuscator simpleDeobfuscator, MethodDef cctor, MethodDef entryPoint, out uint token) {
|
||||||
token = 0;
|
token = 0;
|
||||||
ulong @base;
|
ulong @base;
|
||||||
|
@ -474,6 +486,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
case ConfuserVersion.v17_r75076: return Decrypt_v17_r75076(data);
|
case ConfuserVersion.v17_r75076: return Decrypt_v17_r75076(data);
|
||||||
case ConfuserVersion.v18_r75184: 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.v18_r75367: return Decrypt_v17_r75076(data);
|
||||||
|
case ConfuserVersion.v19_r77172: return Decrypt_v17_r75076(data);
|
||||||
default: throw new ApplicationException("Unknown version");
|
default: throw new ApplicationException("Unknown version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -535,10 +548,10 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
var reader = new BinaryReader(new MemoryStream(data));
|
var reader = new BinaryReader(new MemoryStream(data));
|
||||||
byte[] key, iv;
|
byte[] key, iv;
|
||||||
data = Decrypt_v15_r60785(reader, out key, out iv);
|
data = Decrypt_v15_r60785(reader, out key, out iv);
|
||||||
return SevenzipDecompress(DeobUtils.AesDecrypt(data, key, 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));
|
var reader = new BinaryReader(new MemoryStream(data));
|
||||||
int totalSize = reader.ReadInt32();
|
int totalSize = reader.ReadInt32();
|
||||||
var props = reader.ReadBytes(5);
|
var props = reader.ReadBytes(5);
|
||||||
|
@ -628,6 +641,11 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
|
|
||||||
case ConfuserVersion.v18_r75367:
|
case ConfuserVersion.v18_r75367:
|
||||||
minRev = 75367;
|
minRev = 75367;
|
||||||
|
maxRev = 77124;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case ConfuserVersion.v19_r77172:
|
||||||
|
minRev = 77172;
|
||||||
maxRev = int.MaxValue;
|
maxRev = int.MaxValue;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
75306, 75318, 75349, 75367, 75369, 75402, 75459, 75461,
|
75306, 75318, 75349, 75367, 75369, 75402, 75459, 75461,
|
||||||
75573, 75719, 75720, 75725, 75806, 75807, 75926, 76101,
|
75573, 75719, 75720, 75725, 75806, 75807, 75926, 76101,
|
||||||
76119, 76163, 76186, 76271, 76360, 76509, 76542, 76548,
|
76119, 76163, 76186, 76271, 76360, 76509, 76542, 76548,
|
||||||
76558, 76580, 76656,
|
76558, 76580, 76656, 76871, 76923, 76924, 76933, 76934,
|
||||||
|
76972, 76974, 77124, 77172,
|
||||||
};
|
};
|
||||||
|
|
||||||
static Dictionary<int, Version> revToVersion = new Dictionary<int, Version> {
|
static Dictionary<int, Version> revToVersion = new Dictionary<int, Version> {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user