Add code to dump DNR native methods to a file

This commit is contained in:
de4dot 2011-11-25 15:16:50 +01:00
parent b259991415
commit 900ec1bf07
3 changed files with 39 additions and 6 deletions

View File

@ -208,21 +208,28 @@ namespace de4dot {
class NoArgOption : Option {
Action action;
bool triggered;
public override bool NeedArgument {
get { return false; }
}
public NoArgOption(string shortName, string longName, string description, Action action)
public NoArgOption(string shortName, string longName, string description, Action action = null)
: base(shortName, longName, description) {
this.action = action;
}
public override bool set(string val, out string error) {
action();
triggered = true;
if (action != null)
action();
error = "";
return true;
}
public bool get() {
return triggered;
}
}
class OneArgOption : Option {

View File

@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using Mono.Cecil;
using Mono.Cecil.Cil;
@ -39,6 +40,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
BoolOption decryptResources;
BoolOption removeNamespaces;
BoolOption removeAntiStrongName;
NoArgOption dumpNativeMethods;
public DeobfuscatorInfo()
: base(DEFAULT_REGEX) {
@ -51,6 +53,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
decryptResources = new BoolOption(null, makeArgName("rsrc"), "Decrypt resources", true);
removeNamespaces = new BoolOption(null, makeArgName("ns1"), "Clear namespace if there's only one class in it", true);
removeAntiStrongName = new BoolOption(null, makeArgName("sn"), "Remove anti strong name code", true);
dumpNativeMethods = new NoArgOption(null, makeArgName("dump-native"), "Dump native methods to filename.dll.native");
}
public override string Name {
@ -73,6 +76,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
DecryptResources = decryptResources.get(),
RemoveNamespaces = removeNamespaces.get(),
RemoveAntiStrongName = removeAntiStrongName.get(),
DumpNativeMethods = dumpNativeMethods.get(),
});
}
@ -87,6 +91,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
decryptResources,
removeNamespaces,
removeAntiStrongName,
dumpNativeMethods,
};
}
}
@ -120,6 +125,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
public bool DecryptResources { get; set; }
public bool RemoveNamespaces { get; set; }
public bool RemoveAntiStrongName { get; set; }
public bool DumpNativeMethods { get; set; }
}
public override string Type {
@ -365,9 +371,25 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
if (!options.DecryptMethods)
return false;
if (!methodsDecrypter.decrypt(peImage, DeobfuscatedFile, ref dumpedMethods))
var tokenToNativeCode = new Dictionary<uint,byte[]>();
if (!methodsDecrypter.decrypt(peImage, DeobfuscatedFile, ref dumpedMethods, tokenToNativeCode))
return false;
if (options.DumpNativeMethods) {
using (var fileStream = new FileStream(module.FullyQualifiedName + ".native", FileMode.Create, FileAccess.Write, FileShare.Read)) {
var sortedTokens = new List<uint>(tokenToNativeCode.Keys);
sortedTokens.Sort();
var writer = new BinaryWriter(fileStream);
var nops = new byte[] { 0x90, 0x90, 0x90, 0x90 };
foreach (var token in sortedTokens) {
writer.Write((byte)0xB8);
writer.Write(token);
writer.Write(tokenToNativeCode[token]);
writer.Write(nops);
}
}
}
newFileData = fileData;
return true;
}

View File

@ -96,7 +96,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
static short[] nativeLdci4 = new short[] { 0x55, 0x8B, 0xEC, 0xB8, -1, -1, -1, -1, 0x5D, 0xC3 };
static short[] nativeLdci4_0 = new short[] { 0x55, 0x8B, 0xEC, 0x33, 0xC0, 0x5D, 0xC3 };
public bool decrypt(PE.PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator, ref Dictionary<uint, DumpedMethod> dumpedMethods) {
public bool decrypt(PE.PeImage peImage, ISimpleDeobfuscator simpleDeobfuscator, ref Dictionary<uint, DumpedMethod> dumpedMethods, Dictionary<uint,byte[]> tokenToNativeCode) {
if (encryptedResource.Method == null)
return false;
@ -188,6 +188,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
Log.w("Could not find method having code RVA {0:X8}", rva);
continue;
}
uint methodToken = 0x06000001 + (uint)methodIndex;
if (isNativeCode) {
if (!foundNativeCode) {
@ -195,7 +196,10 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
Log.w("Found native code. Assembly won't run.");
}
//TODO: Convert to CIL code
Log.v("Found native code. Ignoring it for now... Assembly won't run. token: {0:X8}", 0x06000001 + methodIndex);
Log.v("Found native code. Ignoring it for now... Assembly won't run. token: {0:X8}", methodToken);
if (tokenToNativeCode != null)
tokenToNativeCode[methodToken] = methodData;
// Convert return true / false methods. The others are converted to
// throw 0xDEADCODE.
@ -215,7 +219,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
}
var dm = new DumpedMethod();
dm.token = (uint)(0x06000001 + methodIndex);
dm.token = methodToken;
dm.code = methodData;
offset = methodDef.fileOffset + (uint)(methodIndex * methodDef.totalSize);