Support Confuser 1.7 r73764 constants encrypter
This commit is contained in:
parent
bc1a3e5ece
commit
13d0cff55b
|
@ -24,12 +24,15 @@ using System.Text;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using Mono.Cecil.Cil;
|
using Mono.Cecil.Cil;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
using de4dot.PE;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Confuser {
|
namespace de4dot.code.deobfuscators.Confuser {
|
||||||
class ConstantsDecrypterV15 {
|
class ConstantsDecrypterV15 {
|
||||||
ModuleDefinition module;
|
ModuleDefinition module;
|
||||||
|
byte[] fileData;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
MethodDefinition decryptMethod;
|
MethodDefinition decryptMethod;
|
||||||
|
MethodDefinition nativeMethod;
|
||||||
EmbeddedResource resource;
|
EmbeddedResource resource;
|
||||||
uint key0, key1, key2, key3;
|
uint key0, key1, key2, key3;
|
||||||
byte doubleType, singleType, int32Type, int64Type, stringType;
|
byte doubleType, singleType, int32Type, int64Type, stringType;
|
||||||
|
@ -42,12 +45,18 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
v15_r60785_dynamic,
|
v15_r60785_dynamic,
|
||||||
v17_r73404_normal,
|
v17_r73404_normal,
|
||||||
v17_r73740_dynamic,
|
v17_r73740_dynamic,
|
||||||
|
v17_r73764_dynamic,
|
||||||
|
v17_r73764_native,
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDefinition Method {
|
public MethodDefinition Method {
|
||||||
get { return decryptMethod; }
|
get { return decryptMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MethodDefinition NativeMethod {
|
||||||
|
get { return nativeMethod; }
|
||||||
|
}
|
||||||
|
|
||||||
public EmbeddedResource Resource {
|
public EmbeddedResource Resource {
|
||||||
get { return resource; }
|
get { return resource; }
|
||||||
}
|
}
|
||||||
|
@ -56,8 +65,9 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
get { return decryptMethod != null; }
|
get { return decryptMethod != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantsDecrypterV15(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
public ConstantsDecrypterV15(ModuleDefinition module, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
|
this.fileData = fileData;
|
||||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,16 +97,43 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
DeobUtils.hasInteger(method, 0x10000) &&
|
DeobUtils.hasInteger(method, 0x10000) &&
|
||||||
DeobUtils.hasInteger(method, 0xFFFF))
|
DeobUtils.hasInteger(method, 0xFFFF))
|
||||||
version = ConfuserVersion.v17_r73404_normal;
|
version = ConfuserVersion.v17_r73404_normal;
|
||||||
else if (findInstruction(method.Body.Instructions, 0, Code.Conv_I8) >= 0)
|
else if (DotNetUtils.callsMethod(method, "System.String System.Text.Encoding::GetString(System.Byte[])")) {
|
||||||
|
if (findInstruction(method.Body.Instructions, 0, Code.Conv_I8) >= 0)
|
||||||
version = ConfuserVersion.v15_r60785_dynamic;
|
version = ConfuserVersion.v15_r60785_dynamic;
|
||||||
else
|
else
|
||||||
version = ConfuserVersion.v17_r73740_dynamic;
|
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)
|
||||||
|
version = ConfuserVersion.v17_r73764_dynamic;
|
||||||
|
else
|
||||||
|
version = ConfuserVersion.v17_r73764_native;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
decryptMethod = method;
|
decryptMethod = method;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MethodDefinition findNativeMethod(MethodDefinition method) {
|
||||||
|
var instrs = method.Body.Instructions;
|
||||||
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
|
var call = instrs[i];
|
||||||
|
if (call.OpCode.Code != Code.Call)
|
||||||
|
continue;
|
||||||
|
var calledMethod = call.Operand as MethodDefinition;
|
||||||
|
if (calledMethod == null || !calledMethod.IsStatic || !calledMethod.IsNative)
|
||||||
|
continue;
|
||||||
|
if (!DotNetUtils.isMethod(calledMethod, "System.Int32", "(System.Int32)"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return calledMethod;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
if ((resource = findResource(decryptMethod)) == null)
|
if ((resource = findResource(decryptMethod)) == null)
|
||||||
throw new ApplicationException("Could not find encrypted consts resource");
|
throw new ApplicationException("Could not find encrypted consts resource");
|
||||||
|
@ -200,7 +237,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
return false;
|
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;
|
return false;
|
||||||
if (!findTypeCode(allBlocks, out stringType, Code.Callvirt, "System.String System.Text.Encoding::GetString(System.Byte[])"))
|
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 false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -330,6 +368,8 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
case ConfuserVersion.v15_r60785_dynamic: return decryptConstant_v15_r60785_dynamic(encrypted, offs);
|
case ConfuserVersion.v15_r60785_dynamic: return decryptConstant_v15_r60785_dynamic(encrypted, offs);
|
||||||
case ConfuserVersion.v17_r73404_normal: return decryptConstant_v17_r73404_normal(encrypted, offs);
|
case ConfuserVersion.v17_r73404_normal: return decryptConstant_v17_r73404_normal(encrypted, offs);
|
||||||
case ConfuserVersion.v17_r73740_dynamic: return decryptConstant_v17_r73740_dynamic(encrypted, offs);
|
case ConfuserVersion.v17_r73740_dynamic: return decryptConstant_v17_r73740_dynamic(encrypted, offs);
|
||||||
|
case ConfuserVersion.v17_r73764_dynamic: return decryptConstant_v17_r73740_dynamic(encrypted, offs);
|
||||||
|
case ConfuserVersion.v17_r73764_native: return decryptConstant_v17_r73764_native(encrypted, offs);
|
||||||
default: throw new ApplicationException("Invalid version");
|
default: throw new ApplicationException("Invalid version");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,19 +504,28 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
throw new ApplicationException("Could not find start/end index");
|
throw new ApplicationException("Could not find start/end index");
|
||||||
|
|
||||||
var constReader = new ConstantsReader(decryptMethod);
|
var constReader = new ConstantsReader(decryptMethod);
|
||||||
var dataReader = new BinaryReader(new MemoryStream(encrypted));
|
return decrypt(encrypted, magic => {
|
||||||
var decrypted = new byte[dataReader.ReadInt32()];
|
constReader.setConstantInt32(local, magic);
|
||||||
return decryptCompressedInt32Data(constReader, local, startIndex, endIndex, dataReader, decrypted);
|
int index = startIndex, result;
|
||||||
|
if (!constReader.getNextInt32(ref index, out result) || index != endIndex)
|
||||||
|
throw new ApplicationException("Could not decrypt integer");
|
||||||
|
return (byte)result;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte[] decryptCompressedInt32Data(ConstantsReader constReader, VariableDefinition local, int exprStart, int exprEnd, BinaryReader reader, byte[] decrypted) {
|
byte[] decryptConstant_v17_r73764_native(byte[] encrypted, uint offs) {
|
||||||
for (int i = 0; i < decrypted.Length; i++) {
|
var x86Emu = new x86Emulator(new PeImage(fileData));
|
||||||
constReader.setConstantInt32(local, Utils.readEncodedInt32(reader));
|
return decrypt(encrypted, magic => (byte)x86Emu.emulate((uint)nativeMethod.RVA, magic));
|
||||||
int index = exprStart, result;
|
|
||||||
if (!constReader.getNextInt32(ref index, out result) || index != exprEnd)
|
|
||||||
throw new ApplicationException("Could not decrypt integer");
|
|
||||||
decrypted[i] = (byte)result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] decrypt(byte[] encrypted, Func<uint, byte> decryptFunc) {
|
||||||
|
var reader = new BinaryReader(new MemoryStream(encrypted));
|
||||||
|
var decrypted = new byte[reader.ReadInt32()];
|
||||||
|
for (int i = 0; i < decrypted.Length; i++) {
|
||||||
|
uint magic = Utils.readEncodedUInt32(reader);
|
||||||
|
decrypted[i] = decryptFunc(magic);
|
||||||
|
}
|
||||||
|
|
||||||
return decrypted;
|
return decrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
resourceDecrypter.find();
|
resourceDecrypter.find();
|
||||||
constantsDecrypter = new ConstantsDecrypter(module, getFileData(), DeobfuscatedFile);
|
constantsDecrypter = new ConstantsDecrypter(module, getFileData(), DeobfuscatedFile);
|
||||||
constantsDecrypter.find();
|
constantsDecrypter.find();
|
||||||
constantsDecrypterV15 = new ConstantsDecrypterV15(module, DeobfuscatedFile);
|
constantsDecrypterV15 = new ConstantsDecrypterV15(module, getFileData(), DeobfuscatedFile);
|
||||||
if (!constantsDecrypter.Detected)
|
if (!constantsDecrypter.Detected)
|
||||||
constantsDecrypterV15.find();
|
constantsDecrypterV15.find();
|
||||||
if (constantsDecrypter.Detected)
|
if (constantsDecrypter.Detected)
|
||||||
|
@ -421,6 +421,7 @@ namespace de4dot.code.deobfuscators.Confuser {
|
||||||
doubleValueInliner.RemoveUnbox = true;
|
doubleValueInliner.RemoveUnbox = true;
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
addMethodToBeRemoved(constantsDecrypterV15.Method, "Constants decrypter method");
|
addMethodToBeRemoved(constantsDecrypterV15.Method, "Constants decrypter method");
|
||||||
|
addMethodToBeRemoved(constantsDecrypterV15.NativeMethod, "Constants decrypter native method");
|
||||||
addResourceToBeRemoved(constantsDecrypterV15.Resource, "Encrypted constants");
|
addResourceToBeRemoved(constantsDecrypterV15.Resource, "Encrypted constants");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user