Merge pull request #111 from angelsl/master

CryptoObfuscator: Detect if decrypter should skip before reading flag or vice versa
This commit is contained in:
0xd4d 2015-08-29 12:24:29 +02:00
commit 21318d2161

View File

@ -38,6 +38,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
byte bitwiseNotEncryptedFlag;
FrameworkType frameworkType;
bool flipFlagsBits;
bool skipBeforeFlag;
int skipBytes;
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
@ -179,21 +180,22 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
bitwiseNotEncryptedFlag = 4;
}
static bool CheckFlipBits(MethodDef method) {
int nots = 0;
static bool CheckFlipBits(MethodDef method, out int index) {
int nots = 0, i;
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) {
index = -1;
for (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.GetElementType().GetPrimitiveSize() < 0)
continue;
if (instrs[i + 1].OpCode.Code == Code.Not)
if (instrs[i + 1].OpCode.Code == Code.Not) {
nots++;
index = i + 1;
}
}
return (nots & 1) == 1;
}
@ -223,8 +225,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
constants.Add(flagValue);
}
flipFlagsBits = CheckFlipBits(method);
skipBytes = GetHeaderSkipBytes(method);
int notIndex, skipIndex;
flipFlagsBits = CheckFlipBits(method, out notIndex);
skipBytes = GetHeaderSkipBytes(method, out skipIndex);
skipBeforeFlag = skipIndex < notIndex;
switch (frameworkType) {
case FrameworkType.Desktop:
@ -259,7 +263,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
return false;
}
static int GetHeaderSkipBytes(MethodDef method) {
static int GetHeaderSkipBytes(MethodDef method, out int index) {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 1; i++) {
var ldci4 = instrs[i];
@ -271,8 +275,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
var blt = instrs[i + 1];
if (blt.OpCode.Code != Code.Blt && blt.OpCode.Code != Code.Blt_S && blt.OpCode.Code != Code.Clt)
continue;
index = i;
return loopCount - 1;
}
index = 0;
return 0;
}
@ -312,15 +318,22 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
}
public byte[] Decrypt(Stream resourceStream) {
byte flags = (byte)resourceStream.ReadByte();
if (flipFlagsBits)
flags = (byte)~flags;
Stream sourceStream = resourceStream;
int sourceStreamOffset = 1;
bool didSomething = false;
if (skipBeforeFlag)
{
sourceStream.Position += skipBytes;
sourceStreamOffset += skipBytes;
}
byte flags = (byte)sourceStream.ReadByte();
if (flipFlagsBits)
flags = (byte)~flags;
if (!skipBeforeFlag) {
sourceStream.Position += skipBytes;
sourceStreamOffset += skipBytes;
}
byte allFlags = (byte)(desEncryptedFlag | deflatedFlag | bitwiseNotEncryptedFlag);
if ((flags & ~allFlags) != 0)