Merge pull request #111 from angelsl/master
CryptoObfuscator: Detect if decrypter should skip before reading flag or vice versa
This commit is contained in:
commit
21318d2161
|
@ -38,6 +38,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
byte bitwiseNotEncryptedFlag;
|
byte bitwiseNotEncryptedFlag;
|
||||||
FrameworkType frameworkType;
|
FrameworkType frameworkType;
|
||||||
bool flipFlagsBits;
|
bool flipFlagsBits;
|
||||||
|
bool skipBeforeFlag;
|
||||||
int skipBytes;
|
int skipBytes;
|
||||||
|
|
||||||
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
|
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
|
@ -179,21 +180,22 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
bitwiseNotEncryptedFlag = 4;
|
bitwiseNotEncryptedFlag = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CheckFlipBits(MethodDef method) {
|
static bool CheckFlipBits(MethodDef method, out int index) {
|
||||||
int nots = 0;
|
int nots = 0, i;
|
||||||
var instrs = method.Body.Instructions;
|
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];
|
var ldloc = instrs[i];
|
||||||
if (!ldloc.IsLdloc())
|
if (!ldloc.IsLdloc())
|
||||||
continue;
|
continue;
|
||||||
var local = ldloc.GetLocal(method.Body.Variables);
|
var local = ldloc.GetLocal(method.Body.Variables);
|
||||||
if (local == null || local.Type.GetElementType().GetPrimitiveSize() < 0)
|
if (local == null || local.Type.GetElementType().GetPrimitiveSize() < 0)
|
||||||
continue;
|
continue;
|
||||||
|
if (instrs[i + 1].OpCode.Code == Code.Not) {
|
||||||
if (instrs[i + 1].OpCode.Code == Code.Not)
|
|
||||||
nots++;
|
nots++;
|
||||||
|
index = i + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (nots & 1) == 1;
|
return (nots & 1) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,8 +225,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
constants.Add(flagValue);
|
constants.Add(flagValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
flipFlagsBits = CheckFlipBits(method);
|
int notIndex, skipIndex;
|
||||||
skipBytes = GetHeaderSkipBytes(method);
|
flipFlagsBits = CheckFlipBits(method, out notIndex);
|
||||||
|
skipBytes = GetHeaderSkipBytes(method, out skipIndex);
|
||||||
|
skipBeforeFlag = skipIndex < notIndex;
|
||||||
|
|
||||||
switch (frameworkType) {
|
switch (frameworkType) {
|
||||||
case FrameworkType.Desktop:
|
case FrameworkType.Desktop:
|
||||||
|
@ -259,7 +263,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetHeaderSkipBytes(MethodDef method) {
|
static int GetHeaderSkipBytes(MethodDef method, out int index) {
|
||||||
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 ldci4 = instrs[i];
|
var ldci4 = instrs[i];
|
||||||
|
@ -271,8 +275,10 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
var blt = instrs[i + 1];
|
var blt = instrs[i + 1];
|
||||||
if (blt.OpCode.Code != Code.Blt && blt.OpCode.Code != Code.Blt_S && blt.OpCode.Code != Code.Clt)
|
if (blt.OpCode.Code != Code.Blt && blt.OpCode.Code != Code.Blt_S && blt.OpCode.Code != Code.Clt)
|
||||||
continue;
|
continue;
|
||||||
|
index = i;
|
||||||
return loopCount - 1;
|
return loopCount - 1;
|
||||||
}
|
}
|
||||||
|
index = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,15 +318,22 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] Decrypt(Stream resourceStream) {
|
public byte[] Decrypt(Stream resourceStream) {
|
||||||
byte flags = (byte)resourceStream.ReadByte();
|
|
||||||
if (flipFlagsBits)
|
|
||||||
flags = (byte)~flags;
|
|
||||||
Stream sourceStream = resourceStream;
|
Stream sourceStream = resourceStream;
|
||||||
int sourceStreamOffset = 1;
|
int sourceStreamOffset = 1;
|
||||||
bool didSomething = false;
|
bool didSomething = false;
|
||||||
|
|
||||||
|
if (skipBeforeFlag)
|
||||||
|
{
|
||||||
sourceStream.Position += skipBytes;
|
sourceStream.Position += skipBytes;
|
||||||
sourceStreamOffset += 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);
|
byte allFlags = (byte)(desEncryptedFlag | deflatedFlag | bitwiseNotEncryptedFlag);
|
||||||
if ((flags & ~allFlags) != 0)
|
if ((flags & ~allFlags) != 0)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user