Support older string decrypter method and detect older methods decrypter

This commit is contained in:
de4dot 2011-10-28 01:33:05 +02:00
parent eb002895e1
commit 699ac4378d
3 changed files with 43 additions and 10 deletions

View File

@ -147,7 +147,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
public override void deobfuscateBegin() {
base.deobfuscateBegin();
stringDecrypter.init(peImage, DeobfuscatedFile);
stringDecrypter.init(peImage, fileData, DeobfuscatedFile);
booleanDecrypter.init(fileData, DeobfuscatedFile);
boolValueInliner = new BoolValueInliner();

View File

@ -55,7 +55,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
public void find() {
var additionalTypes = new string[] {
"System.Diagnostics.StackFrame",
// "System.Diagnostics.StackFrame", //TODO: Not in DNR <= 3.7.0.3
"System.IntPtr",
"System.Reflection.Assembly",
};
@ -73,14 +73,17 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
var method = info.Item2;
var key = new MethodReferenceAndDeclaringTypeKey(method);
if (!checkedMethods.ContainsKey(key)) {
checkedMethods[key] = true;
checkedMethods[key] = false;
if (info.Item1.BaseType == null || info.Item1.BaseType.FullName != "System.Object")
continue;
if (!DotNetUtils.isMethod(method, "System.Void", "()"))
continue;
if (!encryptedResource.couldBeResourceDecrypter(method, additionalTypes))
continue;
checkedMethods[key] = true;
}
else if (!checkedMethods[key])
continue;
callCounter.add(method);
}
}
@ -116,7 +119,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
int tmp = methodsDataReader.ReadInt32();
methodsDataReader.BaseStream.Position -= 4;
if ((tmp & 0xFF000000) == 0x06000000) {
// It's method token + rva. DNR <= 3.9.0.1 ???
// It's method token + rva. DNR 3.7.0.3 - 3.9.0.1
methodsDataReader.BaseStream.Position += 8 * patchCount;
patchCount = methodsDataReader.ReadInt32();
mode = methodsDataReader.ReadInt32();

View File

@ -33,6 +33,14 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
MethodDefinition otherStringDecrypter;
byte[] decryptedData;
PE.PeImage peImage;
byte[] fileData;
StringDecrypterVersion stringDecrypterVersion;
enum StringDecrypterVersion {
UNKNOWN = 0,
VER_37, // 3.7-
VER_38, // 3.8+
}
public class DecrypterInfo {
public MethodDefinition method;
@ -69,6 +77,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
public StringDecrypter(ModuleDefinition module, StringDecrypter oldOne) {
this.module = module;
this.stringDecrypterVersion = oldOne.stringDecrypterVersion;
this.encryptedResource = new EncryptedResource(module, oldOne.encryptedResource);
foreach (var oldInfo in oldOne.decrypterInfos) {
var method = module.LookupToken(oldInfo.method.MetadataToken.ToInt32()) as MethodDefinition;
@ -134,10 +143,11 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
}
}
public void init(PE.PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator) {
public void init(PE.PeImage peImage, byte[] fileData, ISimpleDeobfuscator simpleDeobfuscator) {
if (encryptedResource.ResourceDecrypterMethod == null)
return;
this.peImage = peImage;
this.fileData = fileData;
foreach (var info in decrypterInfos) {
simpleDeobfuscator.deobfuscate(info.method);
@ -187,12 +197,21 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
if (newKey == null || newIv == null)
continue;
initializeStringDecrypterVersion(method);
key = newKey;
iv = newIv;
return;
}
}
void initializeStringDecrypterVersion(MethodDefinition method) {
var localTypes = new LocalTypes(method);
if (localTypes.exists("System.IntPtr"))
stringDecrypterVersion = StringDecrypterVersion.VER_38;
else
stringDecrypterVersion = StringDecrypterVersion.VER_37;
}
DecrypterInfo getDecrypterInfo(MethodDefinition method) {
foreach (var info in decrypterInfos) {
if (info.method == method)
@ -209,9 +228,21 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
return Encoding.Unicode.GetString(decryptedData, offset + 4, length);
}
else {
uint rva = BitConverter.ToUInt32(decryptedData, offset);
int length = peImage.readInt32(rva);
var encryptedStringData = peImage.readBytes(rva + 4, length);
byte[] encryptedStringData;
if (stringDecrypterVersion == StringDecrypterVersion.VER_37) {
int fileOffset = BitConverter.ToInt32(decryptedData, offset);
int length = BitConverter.ToInt32(fileData, fileOffset);
encryptedStringData = new byte[length];
Array.Copy(fileData, fileOffset + 4, encryptedStringData, 0, length);
}
else if (stringDecrypterVersion == StringDecrypterVersion.VER_38) {
uint rva = BitConverter.ToUInt32(decryptedData, offset);
int length = peImage.readInt32(rva);
encryptedStringData = peImage.readBytes(rva + 4, length);
}
else
throw new ApplicationException("Unknown string decrypter version");
byte[] decryptedStringData;
using (var aes = new RijndaelManaged()) {
aes.Mode = CipherMode.CBC;
@ -224,8 +255,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
}
public string decrypt(string s) {
var data = Convert.FromBase64String(s);
return Encoding.Unicode.GetString(data, 0, data.Length);
return Encoding.Unicode.GetString(Convert.FromBase64String(s));
}
}
}