Add options to preserve rids, heaps

This commit is contained in:
de4dot 2012-12-01 03:24:12 +01:00
parent dcdbe25a0f
commit 643e155cf8
7 changed files with 82 additions and 19 deletions

View File

@ -51,17 +51,7 @@ namespace de4dot.code {
return module;
}
public void save(string newFilename, bool preserveTokens, bool updateMaxStack, IModuleWriterListener writerListener) {
MetaDataFlags mdFlags = 0;
if (!updateMaxStack)
mdFlags |= MetaDataFlags.KeepOldMaxStack;
if (preserveTokens) {
mdFlags |= MetaDataFlags.PreserveRids |
MetaDataFlags.PreserveUSOffsets |
MetaDataFlags.PreserveBlobOffsets |
MetaDataFlags.PreserveExtraSignatureData;
}
public void save(string newFilename, MetaDataFlags mdFlags, IModuleWriterListener writerListener) {
if (module.IsILOnly) {
var writerOptions = new ModuleWriterOptions(module, writerListener);
writerOptions.MetaDataOptions.Flags |= mdFlags;

View File

@ -88,6 +88,8 @@ namespace de4dot.code {
public List<string> StringDecrypterMethods { get; private set; }
public bool ControlFlowDeobfuscation { get; set; }
public bool KeepObfuscatorTypes { get; set; }
public bool PreserveTokens { get; set; }
public MetaDataFlags MetaDataFlags { get; set; }
public Options() {
StringDecrypterType = DecrypterType.Default;
@ -251,6 +253,7 @@ namespace de4dot.code {
}
op.KeepObfuscatorTypes = options.KeepObfuscatorTypes;
op.MetaDataFlags = options.MetaDataFlags;
return op;
}
@ -322,13 +325,26 @@ namespace de4dot.code {
return detected;
}
bool ShouldPreserveTokens() {
return options.KeepObfuscatorTypes || deob.Type == "un";
MetaDataFlags getMetaDataFlags() {
var mdFlags = options.MetaDataFlags | deob.MetaDataFlags;
// Always preserve tokens if it's an unknown obfuscator
if (deob.Type == "un") {
mdFlags |= MetaDataFlags.PreserveRids |
MetaDataFlags.PreserveUSOffsets |
MetaDataFlags.PreserveBlobOffsets |
MetaDataFlags.PreserveExtraSignatureData;
}
return mdFlags;
}
public void save() {
Logger.n("Saving {0}", options.NewFilename);
assemblyModule.save(options.NewFilename, ShouldPreserveTokens(), options.ControlFlowDeobfuscation, deob as IModuleWriterListener);
var mdFlags = getMetaDataFlags();
if (!options.ControlFlowDeobfuscation)
mdFlags |= MetaDataFlags.KeepOldMaxStack;
assemblyModule.save(options.NewFilename, mdFlags, deob as IModuleWriterListener);
}
IList<MethodDef> getAllMethods() {
@ -556,7 +572,7 @@ namespace de4dot.code {
deob.DeobfuscatedFile = null;
if (!options.ControlFlowDeobfuscation) {
if (ShouldPreserveTokens())
if (options.KeepObfuscatorTypes || deob.Type == "un")
return;
}
@ -611,6 +627,11 @@ namespace de4dot.code {
}
}
bool CanOptimizeLocals() {
// Don't remove any locals if we must preserve StandAloneSig table
return (getMetaDataFlags() & MetaDataFlags.PreserveStandAloneSigRids) == 0;
}
void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter, bool isVerbose, bool isVV) {
if (!hasNonEmptyBody(method))
return;
@ -629,9 +650,7 @@ namespace de4dot.code {
cflowDeobfuscator.deobfuscate();
if (options.ControlFlowDeobfuscation) {
// Don't remove any locals if we should preserve tokens or we won't be able
// to always preserve StandAloneSig tokens.
if (!ShouldPreserveTokens())
if (CanOptimizeLocals())
numRemovedLocals = blocks.optimizeLocals();
blocks.repartitionBlocks();
}

View File

@ -77,6 +77,10 @@ namespace de4dot.code.deobfuscators {
public virtual RenamingOptions RenamingOptions { get; set; }
public DecrypterType DefaultDecrypterType { get; set; }
public virtual MetaDataFlags MetaDataFlags {
get { return Operations.MetaDataFlags; }
}
public abstract string Type { get; }
public abstract string TypeLong { get; }
public abstract string Name { get; }

View File

@ -19,8 +19,9 @@
using System;
using System.Collections.Generic;
using dot10.DotNet;
using dot10.PE;
using dot10.DotNet;
using dot10.DotNet.Writer;
using de4dot.blocks;
using de4dot.blocks.cflow;
using de4dot.code.renamer;
@ -58,6 +59,7 @@ namespace de4dot.code.deobfuscators {
string Name { get; }
IDeobfuscatorOptions TheOptions { get; }
IOperations Operations { get; set; }
MetaDataFlags MetaDataFlags { get; }
StringFeatures StringFeatures { get; }
RenamingOptions RenamingOptions { get; }
DecrypterType DefaultDecrypterType { get; }

View File

@ -17,6 +17,8 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using dot10.DotNet.Writer;
namespace de4dot.code.deobfuscators {
public enum OpDecryptString {
None,
@ -26,11 +28,13 @@ namespace de4dot.code.deobfuscators {
public interface IOperations {
bool KeepObfuscatorTypes { get; }
MetaDataFlags MetaDataFlags { get; }
OpDecryptString DecryptStrings { get; }
}
class Operations : IOperations {
public bool KeepObfuscatorTypes { get; set; }
public MetaDataFlags MetaDataFlags { get; set; }
public OpDecryptString DecryptStrings { get; set; }
}
}

View File

@ -21,6 +21,7 @@ using System;
using System.IO;
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Writer;
using de4dot.code;
using de4dot.code.deobfuscators;
using de4dot.code.AssemblyClient;
@ -159,6 +160,43 @@ namespace de4dot.cui {
miscOptions.Add(new NoArgOption(null, "keep-types", "Keep obfuscator types, fields, methods", () => {
filesOptions.KeepObfuscatorTypes = true;
}));
miscOptions.Add(new NoArgOption(null, "preserve-tokens", "Preserve important tokens, #US, #Blob, extra sig data", () => {
filesOptions.MetaDataFlags |= MetaDataFlags.PreserveRids |
MetaDataFlags.PreserveUSOffsets |
MetaDataFlags.PreserveBlobOffsets |
MetaDataFlags.PreserveExtraSignatureData;
}));
miscOptions.Add(new OneArgOption(null, "preserve-table", "Preserve rids in table: tr (TypeRef), td (TypeDef), fd (Field), md (Method), pd (Param), mr (MemberRef), s (StandAloneSig), ed (Event), pr (Property), ts (TypeSpec), ms (MethodSpec). Can be combined: ed,fd,md", "flags", (val) => {
foreach (var s in val.Split(',')) {
switch (s.Trim()) {
case "": break;
case "tr": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveTypeRefRids; break;
case "td": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveTypeDefRids; break;
case "fd": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveFieldRids; break;
case "md": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveMethodRids; break;
case "pd": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveParamRids; break;
case "mr": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveMemberRefRids; break;
case "s": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveStandAloneSigRids; break;
case "ed": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveEventRids; break;
case "pr": filesOptions.MetaDataFlags |= MetaDataFlags.PreservePropertyRids; break;
case "ts": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveTypeSpecRids; break;
case "ms": filesOptions.MetaDataFlags |= MetaDataFlags.PreserveMethodSpecRids; break;
default: throw new UserException(string.Format("Invalid --preserve-table option: {0}", s));
}
}
}));
miscOptions.Add(new NoArgOption(null, "preserve-strings", "Preserve #Strings heap offsets", () => {
filesOptions.MetaDataFlags |= MetaDataFlags.PreserveStringsOffsets;
}));
miscOptions.Add(new NoArgOption(null, "preserve-us", "Preserve #US heap offsets", () => {
filesOptions.MetaDataFlags |= MetaDataFlags.PreserveUSOffsets;
}));
miscOptions.Add(new NoArgOption(null, "preserve-blob", "Preserve #Blob heap offsets", () => {
filesOptions.MetaDataFlags |= MetaDataFlags.PreserveBlobOffsets;
}));
miscOptions.Add(new NoArgOption(null, "preserve-sig-data", "Preserve extra data at the end of signatures", () => {
filesOptions.MetaDataFlags |= MetaDataFlags.PreserveExtraSignatureData;
}));
miscOptions.Add(new NoArgOption(null, "one-file", "Deobfuscate one file at a time", () => {
filesOptions.OneFileAtATime = true;
}));
@ -183,6 +221,7 @@ namespace de4dot.cui {
Filename = val,
ControlFlowDeobfuscation = filesOptions.ControlFlowDeobfuscation,
KeepObfuscatorTypes = filesOptions.KeepObfuscatorTypes,
MetaDataFlags = filesOptions.MetaDataFlags,
};
if (defaultStringDecrypterType != null)
newFileOptions.StringDecrypterType = defaultStringDecrypterType.Value;

View File

@ -21,6 +21,7 @@ using System;
using System.IO;
using System.Collections.Generic;
using dot10.DotNet;
using dot10.DotNet.Writer;
using de4dot.blocks;
using de4dot.code;
using de4dot.code.renamer;
@ -37,6 +38,7 @@ namespace de4dot.cui {
public IList<IDeobfuscatorInfo> DeobfuscatorInfos { get; set; }
public IList<IObfuscatedFile> Files { get; set; }
public IList<SearchDir> SearchDirs { get; set; }
public MetaDataFlags MetaDataFlags { get; set; }
public bool DetectObfuscators { get; set; }
public bool DontCreateNewParamDefs { get; set; }
public bool RenameNamespaces { get; set; }
@ -163,6 +165,7 @@ namespace de4dot.cui {
DeobfuscatorContext = deobfuscatorContext,
ControlFlowDeobfuscation = options.ControlFlowDeobfuscation,
KeepObfuscatorTypes = options.KeepObfuscatorTypes,
MetaDataFlags = options.MetaDataFlags,
CreateDestinationDir = !onlyScan,
});
@ -186,6 +189,7 @@ namespace de4dot.cui {
public IDeobfuscatorContext DeobfuscatorContext { get; set; }
public bool ControlFlowDeobfuscation { get; set; }
public bool KeepObfuscatorTypes { get; set; }
public MetaDataFlags MetaDataFlags { get; set; }
public bool CreateDestinationDir { get; set; }
}
@ -312,6 +316,7 @@ namespace de4dot.cui {
Filename = Utils.getFullPath(filename),
ControlFlowDeobfuscation = options.ControlFlowDeobfuscation,
KeepObfuscatorTypes = options.KeepObfuscatorTypes,
MetaDataFlags = options.MetaDataFlags,
};
if (options.DefaultStringDecrypterType != null)
fileOptions.StringDecrypterType = options.DefaultStringDecrypterType.Value;