Merge branch 'master' into dnr
This commit is contained in:
commit
75a464a7f4
|
@ -305,7 +305,7 @@ namespace de4dot.blocks {
|
||||||
public static bool isPinvokeMethod(MethodDefinition method, string dll, string funcName) {
|
public static bool isPinvokeMethod(MethodDefinition method, string dll, string funcName) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return false;
|
return false;
|
||||||
if (!method.HasPInvokeInfo || method.PInvokeInfo.EntryPoint != funcName)
|
if (method.PInvokeInfo == null || method.PInvokeInfo.EntryPoint != funcName)
|
||||||
return false;
|
return false;
|
||||||
return getDllName(dll).Equals(getDllName(method.PInvokeInfo.Module.Name), StringComparison.OrdinalIgnoreCase);
|
return getDllName(dll).Equals(getDllName(method.PInvokeInfo.Module.Name), StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,11 @@ namespace de4dot {
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(string newFilename) {
|
public void save(string newFilename, bool updateMaxStack) {
|
||||||
module.Write(newFilename);
|
var writerParams = new WriterParameters() {
|
||||||
|
UpdateMaxStack = updateMaxStack,
|
||||||
|
};
|
||||||
|
module.Write(newFilename, writerParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModuleDefinition reload(byte[] newModuleData, Dictionary<uint, DumpedMethod> dumpedMethods) {
|
public ModuleDefinition reload(byte[] newModuleData, Dictionary<uint, DumpedMethod> dumpedMethods) {
|
||||||
|
@ -63,7 +66,7 @@ namespace de4dot {
|
||||||
}
|
}
|
||||||
|
|
||||||
void readMethodsFile() {
|
void readMethodsFile() {
|
||||||
if (new FileInfo(methodsFilename).Exists) {
|
if (Utils.fileExists(methodsFilename)) {
|
||||||
using (var reader = new BinaryReader(File.Open(methodsFilename, FileMode.Open, FileAccess.Read, FileShare.Read))) {
|
using (var reader = new BinaryReader(File.Open(methodsFilename, FileMode.Open, FileAccess.Read, FileShare.Read))) {
|
||||||
dumpedMethods = new DumpedMethodsReader(reader).read();
|
dumpedMethods = new DumpedMethodsReader(reader).read();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
|
|
||||||
namespace de4dot {
|
namespace de4dot {
|
||||||
|
@ -31,6 +32,51 @@ namespace de4dot {
|
||||||
static AssemblyResolver() {
|
static AssemblyResolver() {
|
||||||
// Make sure there's only ONE assembly resolver
|
// Make sure there's only ONE assembly resolver
|
||||||
GlobalAssemblyResolver.Instance = Instance;
|
GlobalAssemblyResolver.Instance = Instance;
|
||||||
|
addOtherAssemblySearchPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addOtherAssemblySearchPaths() {
|
||||||
|
addOtherAssemblySearchPaths(Environment.GetEnvironmentVariable("ProgramFiles"));
|
||||||
|
addOtherAssemblySearchPaths(Environment.GetEnvironmentVariable("ProgramFiles(x86)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addOtherAssemblySearchPaths(string path) {
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
return;
|
||||||
|
addSilverlightDirs(Path.Combine(path, @"Microsoft Silverlight"));
|
||||||
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Client");
|
||||||
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v3.0\Libraries\Server");
|
||||||
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Client");
|
||||||
|
addIfExists(path, @"Microsoft SDKs\Silverlight\v4.0\Libraries\Server");
|
||||||
|
addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v3.0");
|
||||||
|
addIfExists(path, @"Reference Assemblies\Microsoft\Framework\Silverlight\v4.0");
|
||||||
|
addIfExists(path, @"Microsoft Visual Studio .NET\Common7\IDE\PublicAssemblies");
|
||||||
|
addIfExists(path, @"Microsoft Visual Studio 8.0\Common7\IDE\PublicAssemblies");
|
||||||
|
addIfExists(path, @"Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies");
|
||||||
|
addIfExists(path, @"Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies");
|
||||||
|
}
|
||||||
|
|
||||||
|
// basePath is eg. "C:\Program Files (x86)\Microsoft Silverlight"
|
||||||
|
static void addSilverlightDirs(string basePath) {
|
||||||
|
try {
|
||||||
|
var di = new DirectoryInfo(basePath);
|
||||||
|
foreach (var dir in di.GetDirectories()) {
|
||||||
|
if (Regex.IsMatch(dir.Name, @"^\d+(?:\.\d+){3}$"))
|
||||||
|
addIfExists(basePath, dir.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addIfExists(string basePath, string extraPath) {
|
||||||
|
try {
|
||||||
|
var path = Path.Combine(basePath, extraPath);
|
||||||
|
if (Utils.pathExists(path))
|
||||||
|
Instance.addSearchDirectory(path);
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSearchDirectory(string dir) {
|
public void addSearchDirectory(string dir) {
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace de4dot {
|
||||||
miscOptions.Add(new OneArgOption("r", null, "Scan for .NET files in all subdirs", "dir", (val) => {
|
miscOptions.Add(new OneArgOption("r", null, "Scan for .NET files in all subdirs", "dir", (val) => {
|
||||||
addSearchDir();
|
addSearchDir();
|
||||||
searchDir = new FilesDeobfuscator.SearchDir();
|
searchDir = new FilesDeobfuscator.SearchDir();
|
||||||
if (!new DirectoryInfo(val).Exists)
|
if (!Utils.pathExists(val))
|
||||||
exitError(string.Format("Directory {0} does not exist", val));
|
exitError(string.Format("Directory {0} does not exist", val));
|
||||||
searchDir.InputDirectory = val;
|
searchDir.InputDirectory = val;
|
||||||
}));
|
}));
|
||||||
|
@ -112,7 +112,7 @@ namespace de4dot {
|
||||||
miscOptions.Add(new NoArgOption("d", null, "Detect obfuscators and exit", () => {
|
miscOptions.Add(new NoArgOption("d", null, "Detect obfuscators and exit", () => {
|
||||||
filesOptions.DetectObfuscators = true;
|
filesOptions.DetectObfuscators = true;
|
||||||
}));
|
}));
|
||||||
miscOptions.Add(new OneArgOption(null, "asmpath", "Add an assembly search path", "path", (val) => {
|
miscOptions.Add(new OneArgOption(null, "asm-path", "Add an assembly search path", "path", (val) => {
|
||||||
AssemblyResolver.Instance.addSearchDirectory(val);
|
AssemblyResolver.Instance.addSearchDirectory(val);
|
||||||
}));
|
}));
|
||||||
miscOptions.Add(new NoArgOption(null, "dont-rename", "Don't rename classes, methods, etc.", () => {
|
miscOptions.Add(new NoArgOption(null, "dont-rename", "Don't rename classes, methods, etc.", () => {
|
||||||
|
@ -152,7 +152,7 @@ namespace de4dot {
|
||||||
|
|
||||||
defaultOption = new OneArgOption("f", null, "Name of .NET file", "file", (val) => {
|
defaultOption = new OneArgOption("f", null, "Name of .NET file", "file", (val) => {
|
||||||
addFile();
|
addFile();
|
||||||
if (!new FileInfo(val).Exists)
|
if (!Utils.fileExists(val))
|
||||||
exitError(string.Format("File \"{0}\" does not exist.", val));
|
exitError(string.Format("File \"{0}\" does not exist.", val));
|
||||||
newFileOptions = new ObfuscatedFile.Options {
|
newFileOptions = new ObfuscatedFile.Options {
|
||||||
Filename = val,
|
Filename = val,
|
||||||
|
@ -168,7 +168,7 @@ namespace de4dot {
|
||||||
fileOptions.Add(new OneArgOption("m", null, "Name of .methods file", "file", (val) => {
|
fileOptions.Add(new OneArgOption("m", null, "Name of .methods file", "file", (val) => {
|
||||||
if (newFileOptions == null)
|
if (newFileOptions == null)
|
||||||
exitError("Missing input file");
|
exitError("Missing input file");
|
||||||
if (!new FileInfo(val).Exists)
|
if (!Utils.fileExists(val))
|
||||||
exitError(string.Format("File \"{0}\" does not exist.", val));
|
exitError(string.Format("File \"{0}\" does not exist.", val));
|
||||||
newFileOptions.MethodsFilename = val;
|
newFileOptions.MethodsFilename = val;
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -198,6 +198,12 @@ namespace de4dot {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((file.ModuleDefinition.Attributes & ModuleAttributes.ILOnly) == 0) {
|
||||||
|
Log.w("Ignoring assembly with native code {0}", file.Filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var deob = file.Deobfuscator;
|
var deob = file.Deobfuscator;
|
||||||
if (skipUnknownObfuscator && deob is deobfuscators.Unknown.Deobfuscator) {
|
if (skipUnknownObfuscator && deob is deobfuscators.Unknown.Deobfuscator) {
|
||||||
Log.v("Skipping unknown obfuscator: {0}", file.Filename);
|
Log.v("Skipping unknown obfuscator: {0}", file.Filename);
|
||||||
|
@ -303,10 +309,16 @@ namespace de4dot {
|
||||||
void createDirectories(string path) {
|
void createDirectories(string path) {
|
||||||
if (string.IsNullOrEmpty(path))
|
if (string.IsNullOrEmpty(path))
|
||||||
return;
|
return;
|
||||||
|
try {
|
||||||
var di = new DirectoryInfo(path);
|
var di = new DirectoryInfo(path);
|
||||||
if (!di.Exists)
|
if (!di.Exists)
|
||||||
di.Create();
|
di.Create();
|
||||||
}
|
}
|
||||||
|
catch (System.Security.SecurityException) {
|
||||||
|
}
|
||||||
|
catch (ArgumentException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deobfuscateAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
void deobfuscateAllFiles(IEnumerable<IObfuscatedFile> allFiles) {
|
||||||
|
|
|
@ -258,7 +258,7 @@ namespace de4dot {
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
Log.n("Saving {0}", options.NewFilename);
|
Log.n("Saving {0}", options.NewFilename);
|
||||||
assemblyModule.save(options.NewFilename);
|
assemblyModule.save(options.NewFilename, options.ControlFlowDeobfuscation);
|
||||||
}
|
}
|
||||||
|
|
||||||
IList<MethodDefinition> getAllMethods() {
|
IList<MethodDefinition> getAllMethods() {
|
||||||
|
|
|
@ -198,5 +198,23 @@ namespace de4dot {
|
||||||
return name;
|
return name;
|
||||||
return name.Substring(0, i);
|
return name.Substring(0, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool pathExists(string path) {
|
||||||
|
try {
|
||||||
|
return new DirectoryInfo(path).Exists;
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool fileExists(string path) {
|
||||||
|
try {
|
||||||
|
return new FileInfo(path).Exists;
|
||||||
|
}
|
||||||
|
catch (Exception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@
|
||||||
<Compile Include="PE\DotNetStream.cs" />
|
<Compile Include="PE\DotNetStream.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="renamer\CurrentNames.cs" />
|
||||||
<Compile Include="renamer\DefinitionsRenamer.cs" />
|
<Compile Include="renamer\DefinitionsRenamer.cs" />
|
||||||
<Compile Include="renamer\ExternalAssemblies.cs" />
|
<Compile Include="renamer\ExternalAssemblies.cs" />
|
||||||
<Compile Include="renamer\MemberRefFinder.cs" />
|
<Compile Include="renamer\MemberRefFinder.cs" />
|
||||||
|
|
|
@ -290,8 +290,10 @@ namespace de4dot.deobfuscators.SmartAssembly {
|
||||||
|
|
||||||
public override void deobfuscateBegin() {
|
public override void deobfuscateBegin() {
|
||||||
base.deobfuscateBegin();
|
base.deobfuscateBegin();
|
||||||
if (options.RemoveMemoryManager)
|
if (options.RemoveMemoryManager) {
|
||||||
addModuleCctorInitCallToBeRemoved(memoryManagerInfo.CctorInitMethod);
|
addModuleCctorInitCallToBeRemoved(memoryManagerInfo.CctorInitMethod);
|
||||||
|
addCallToBeRemoved(module.EntryPoint, memoryManagerInfo.CctorInitMethod);
|
||||||
|
}
|
||||||
initDecrypters();
|
initDecrypters();
|
||||||
proxyDelegateFinder.find();
|
proxyDelegateFinder.find();
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,17 @@ namespace de4dot.deobfuscators.SmartAssembly {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool find() {
|
bool find() {
|
||||||
var cctor = DotNetUtils.getMethod(DotNetUtils.getModuleType(module), ".cctor");
|
if (checkCalledMethods(DotNetUtils.getMethod(DotNetUtils.getModuleType(module), ".cctor")))
|
||||||
if (cctor == null)
|
return true;
|
||||||
|
if (checkCalledMethods(module.EntryPoint))
|
||||||
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var tuple in DotNetUtils.getCalledMethods(module, cctor)) {
|
bool checkCalledMethods(MethodDefinition checkMethod) {
|
||||||
|
if (checkMethod == null)
|
||||||
|
return false;
|
||||||
|
foreach (var tuple in DotNetUtils.getCalledMethods(module, checkMethod)) {
|
||||||
var method = tuple.Item2;
|
var method = tuple.Item2;
|
||||||
if (method.Name == ".cctor" || method.Name == ".ctor")
|
if (method.Name == ".cctor" || method.Name == ".ctor")
|
||||||
continue;
|
continue;
|
||||||
|
|
62
de4dot.code/renamer/CurrentNames.cs
Normal file
62
de4dot.code/renamer/CurrentNames.cs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011 de4dot@gmail.com
|
||||||
|
|
||||||
|
This file is part of de4dot.
|
||||||
|
|
||||||
|
de4dot is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
de4dot is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace de4dot.renamer {
|
||||||
|
class CurrentNames {
|
||||||
|
Dictionary<string, bool> allNames = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||||
|
|
||||||
|
public void add(string name) {
|
||||||
|
allNames[name] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exists(string name) {
|
||||||
|
return allNames.ContainsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string newName(string oldName, INameCreator nameCreator) {
|
||||||
|
return newName(oldName, () => nameCreator.newName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string newName(string oldName, Func<string> createNewName) {
|
||||||
|
string prevName = null;
|
||||||
|
while (true) {
|
||||||
|
var name = createNewName();
|
||||||
|
if (name == prevName)
|
||||||
|
throw new ApplicationException(string.Format("Could not rename symbol to {0}", Utils.toCsharpString(name)));
|
||||||
|
|
||||||
|
if (!exists(name) || name == oldName) {
|
||||||
|
allNames[name] = true;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
prevName = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrentNames clone() {
|
||||||
|
var cn = new CurrentNames();
|
||||||
|
foreach (var key in allNames.Keys)
|
||||||
|
cn.allNames[key] = true;
|
||||||
|
return cn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -211,6 +211,8 @@ namespace de4dot.renamer {
|
||||||
void renameTypeDefinitions() {
|
void renameTypeDefinitions() {
|
||||||
Log.v("Renaming obfuscated type definitions");
|
Log.v("Renaming obfuscated type definitions");
|
||||||
typeNameState = new TypeNameState();
|
typeNameState = new TypeNameState();
|
||||||
|
foreach (var typeDef in allTypes)
|
||||||
|
typeNameState.currentNames.add(typeDef.OldName);
|
||||||
prepareRenameTypeDefinitions(baseTypes);
|
prepareRenameTypeDefinitions(baseTypes);
|
||||||
typeNameState = null;
|
typeNameState = null;
|
||||||
|
|
||||||
|
@ -504,7 +506,8 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
if (isAutoCreatedType(typeReference))
|
if (isAutoCreatedType(typeReference))
|
||||||
return null;
|
return null;
|
||||||
throw new ApplicationException(string.Format("Could not resolve TypeReference {0} ({1:X8})", typeReference, typeReference.MetadataToken.ToInt32()));
|
Log.e("Could not resolve TypeReference {0} ({1:X8})", typeReference, typeReference.MetadataToken.ToInt32());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef resolve(MethodReference methodReference) {
|
public MethodDef resolve(MethodReference methodReference) {
|
||||||
|
@ -520,7 +523,8 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
if (isAutoCreatedType(methodReference.DeclaringType))
|
if (isAutoCreatedType(methodReference.DeclaringType))
|
||||||
return null;
|
return null;
|
||||||
throw new ApplicationException(string.Format("Could not resolve MethodReference {0} ({1:X8})", methodReference, methodReference.MetadataToken.ToInt32()));
|
Log.e("Could not resolve MethodReference {0} ({1:X8})", methodReference, methodReference.MetadataToken.ToInt32());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldDef resolve(FieldReference fieldReference) {
|
public FieldDef resolve(FieldReference fieldReference) {
|
||||||
|
@ -536,7 +540,8 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
if (isAutoCreatedType(fieldReference.DeclaringType))
|
if (isAutoCreatedType(fieldReference.DeclaringType))
|
||||||
return null;
|
return null;
|
||||||
throw new ApplicationException(string.Format("Could not resolve FieldReference {0} ({1:X8})", fieldReference, fieldReference.MetadataToken.ToInt32()));
|
Log.e("Could not resolve FieldReference {0} ({1:X8})", fieldReference, fieldReference.MetadataToken.ToInt32());
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef findMethod(MethodReference methodReference) {
|
public MethodDef findMethod(MethodReference methodReference) {
|
||||||
|
|
|
@ -69,9 +69,20 @@ namespace de4dot.renamer {
|
||||||
Log.w("Could not load assembly {0}", asmFullName);
|
Log.w("Could not load assembly {0}", asmFullName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Log.v("Loaded assembly {0}", asmFullName);
|
if (assemblies.ContainsKey(asmDef.Name.FullName)) {
|
||||||
|
assemblies[asmFullName] = assemblies[asmDef.Name.FullName];
|
||||||
|
return assemblies[asmDef.Name.FullName];
|
||||||
|
}
|
||||||
|
|
||||||
return assemblies[asmFullName] = new ExternalAssembly(asmDef);
|
if (asmFullName == asmDef.Name.FullName)
|
||||||
|
Log.v("Loaded assembly {0}", asmFullName);
|
||||||
|
else
|
||||||
|
Log.v("Loaded assembly {0} (but wanted {1})", asmDef.Name.FullName, asmFullName);
|
||||||
|
|
||||||
|
asm = new ExternalAssembly(asmDef);
|
||||||
|
assemblies[asmFullName] = asm;
|
||||||
|
assemblies[asmDef.Name.FullName] = asm;
|
||||||
|
return asm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDefinition resolve(TypeReference type) {
|
public TypeDefinition resolve(TypeReference type) {
|
||||||
|
|
|
@ -91,13 +91,20 @@ namespace de4dot {
|
||||||
|
|
||||||
Dictionary<string, bool> exceptionMessages = new Dictionary<string, bool>(StringComparer.Ordinal);
|
Dictionary<string, bool> exceptionMessages = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||||
void access(Action action) {
|
void access(Action action) {
|
||||||
|
string exMessage = null;
|
||||||
try {
|
try {
|
||||||
action();
|
action();
|
||||||
}
|
}
|
||||||
|
catch (ResolutionException ex) {
|
||||||
|
exMessage = ex.Message;
|
||||||
|
}
|
||||||
catch (AssemblyResolutionException ex) {
|
catch (AssemblyResolutionException ex) {
|
||||||
if (!exceptionMessages.ContainsKey(ex.Message)) {
|
exMessage = ex.Message;
|
||||||
exceptionMessages[ex.Message] = true;
|
}
|
||||||
Log.w("Could not resolve a reference. ERROR: {0}", ex.Message);
|
if (exMessage != null) {
|
||||||
|
if (!exceptionMessages.ContainsKey(exMessage)) {
|
||||||
|
exceptionMessages[exMessage] = true;
|
||||||
|
Log.w("Could not resolve a reference. ERROR: {0}", exMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,7 +428,7 @@ namespace de4dot {
|
||||||
void addSecurityDeclaration(SecurityDeclaration decl) {
|
void addSecurityDeclaration(SecurityDeclaration decl) {
|
||||||
if (decl == null)
|
if (decl == null)
|
||||||
return;
|
return;
|
||||||
addSecurityAttributes(decl.SecurityAttributes);
|
access(() => addSecurityAttributes(decl.SecurityAttributes));
|
||||||
}
|
}
|
||||||
void addSecurityAttribute(SecurityAttribute attr) {
|
void addSecurityAttribute(SecurityAttribute attr) {
|
||||||
if (attr == null)
|
if (attr == null)
|
||||||
|
|
|
@ -21,6 +21,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
|
using Mono.Cecil.Cil;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.deobfuscators;
|
using de4dot.deobfuscators;
|
||||||
|
|
||||||
|
@ -286,6 +287,103 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeDef : Ref {
|
class TypeDef : Ref {
|
||||||
|
static Dictionary<string, bool> windowsFormsControlClasses = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||||
|
static TypeDef() {
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Control"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.AxHost"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ButtonBase"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Button"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.CheckBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.RadioButton"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DataGrid"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DataGridView"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DataVisualization.Charting.Chart"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DateTimePicker"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.GroupBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Integration.ElementHost"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Label"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.LinkLabel"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ListControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ComboBox"] = true;
|
||||||
|
windowsFormsControlClasses["Microsoft.VisualBasic.Compatibility.VB6.DriveListBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DataGridViewComboBoxEditingControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ListBox"] = true;
|
||||||
|
windowsFormsControlClasses["Microsoft.VisualBasic.Compatibility.VB6.DirListBox"] = true;
|
||||||
|
windowsFormsControlClasses["Microsoft.VisualBasic.Compatibility.VB6.FileListBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.CheckedListBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ListView"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.MdiClient"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.MonthCalendar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.PictureBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.PrintPreviewControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ProgressBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ScrollableControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ContainerControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Form"] = true;
|
||||||
|
windowsFormsControlClasses["System.ComponentModel.Design.CollectionEditor.CollectionForm"] = true;
|
||||||
|
windowsFormsControlClasses["System.Messaging.Design.QueuePathDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.ServiceProcess.Design.ServiceInstallerDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Web.UI.Design.WebControls.CalendarAutoFormatDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Web.UI.Design.WebControls.RegexEditorDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Design.ComponentEditorForm"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.PrintPreviewDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ThreadExceptionDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.Activities.Rules.Design.RuleConditionDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.Activities.Rules.Design.RuleSetDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.ComponentModel.Design.ThemeConfigurationDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.ComponentModel.Design.TypeBrowserDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.ComponentModel.Design.WorkflowPageSetupDialog"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.PropertyGrid"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.SplitContainer"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStripContainer"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStripPanel"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.UpDownBase"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DomainUpDown"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.NumericUpDown"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.UserControl"] = true;
|
||||||
|
windowsFormsControlClasses["Microsoft.VisualBasic.Compatibility.VB6.ADODC"] = true;
|
||||||
|
windowsFormsControlClasses["System.Web.UI.Design.WebControls.ParameterEditorUserControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.ComponentModel.Design.WorkflowOutline"] = true;
|
||||||
|
windowsFormsControlClasses["System.Workflow.ComponentModel.Design.WorkflowView"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Design.ComponentTray"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Panel"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Design.ComponentEditorPage"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.FlowLayoutPanel"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.SplitterPanel"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TableLayoutPanel"] = true;
|
||||||
|
windowsFormsControlClasses["System.ComponentModel.Design.ByteViewer"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TabPage"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStripContentPanel"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStrip"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.BindingNavigator"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.MenuStrip"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.StatusStrip"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStripDropDown"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStripDropDownMenu"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ContextMenuStrip"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolStripOverflow"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ScrollBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.HScrollBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.VScrollBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.Splitter"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.StatusBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TabControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TextBoxBase"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.MaskedTextBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.RichTextBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TextBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DataGridTextBox"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.DataGridViewTextBoxEditingControl"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.ToolBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TrackBar"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.TreeView"] = true;
|
||||||
|
windowsFormsControlClasses["System.ComponentModel.Design.ObjectSelectorEditor.Selector"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.WebBrowserBase"] = true;
|
||||||
|
windowsFormsControlClasses["System.Windows.Forms.WebBrowser"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<MethodDef, string> newMethodsNames = new Dictionary<MethodDef, string>();
|
||||||
|
|
||||||
public IDefFinder defFinder;
|
public IDefFinder defFinder;
|
||||||
public TypeInfo baseType = null;
|
public TypeInfo baseType = null;
|
||||||
public IList<TypeInfo> interfaces = new List<TypeInfo>(); // directly implemented interfaces
|
public IList<TypeInfo> interfaces = new List<TypeInfo>(); // directly implemented interfaces
|
||||||
|
@ -344,6 +442,23 @@ namespace de4dot.renamer {
|
||||||
get { return methods.getAll(); }
|
get { return methods.getAll(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool? isWindowsFormsControlDerivedClass_cached;
|
||||||
|
bool isWindowsFormsControlDerivedClass() {
|
||||||
|
if (!isWindowsFormsControlDerivedClass_cached.HasValue)
|
||||||
|
isWindowsFormsControlDerivedClass_cached = isWindowsFormsControlDerivedClassInternal();
|
||||||
|
return isWindowsFormsControlDerivedClass_cached.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWindowsFormsControlDerivedClassInternal() {
|
||||||
|
if (windowsFormsControlClasses.ContainsKey(OldFullName))
|
||||||
|
return true;
|
||||||
|
if (baseType != null)
|
||||||
|
return baseType.typeDef.isWindowsFormsControlDerivedClass();
|
||||||
|
if (TypeDefinition.BaseType != null)
|
||||||
|
return windowsFormsControlClasses.ContainsKey(TypeDefinition.BaseType.FullName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void addMembers() {
|
public void addMembers() {
|
||||||
var type = TypeDefinition;
|
var type = TypeDefinition;
|
||||||
|
|
||||||
|
@ -482,6 +597,12 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
if (OldFullName != "<Module>" && !typeNameState.IsValidName(OldName)) {
|
if (OldFullName != "<Module>" && !typeNameState.IsValidName(OldName)) {
|
||||||
var newBaseType = baseType != null && baseType.typeDef.Renamed ? baseType.typeDef.NewName : null;
|
var newBaseType = baseType != null && baseType.typeDef.Renamed ? baseType.typeDef.NewName : null;
|
||||||
|
string origClassName = null;
|
||||||
|
if (isWindowsFormsControlDerivedClass())
|
||||||
|
origClassName = findWindowsFormsClassName();
|
||||||
|
if (origClassName != null && typeNameState.IsValidName(origClassName))
|
||||||
|
rename(typeNameState.currentNames.newName(OldName, new NameCreator2(origClassName)));
|
||||||
|
else
|
||||||
rename(nameCreator.newName(typeDefinition, newBaseType));
|
rename(nameCreator.newName(typeDefinition, newBaseType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,6 +612,71 @@ namespace de4dot.renamer {
|
||||||
prepareRenameGenericParams(genericParams, typeNameState.IsValidName);
|
prepareRenameGenericParams(genericParams, typeNameState.IsValidName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string findWindowsFormsClassName() {
|
||||||
|
foreach (var methodDef in methods.getAll()) {
|
||||||
|
if (methodDef.MethodDefinition.Body == null)
|
||||||
|
continue;
|
||||||
|
if (methodDef.MethodDefinition.IsStatic || methodDef.MethodDefinition.IsVirtual)
|
||||||
|
continue;
|
||||||
|
var instructions = methodDef.MethodDefinition.Body.Instructions;
|
||||||
|
for (int i = 2; i < instructions.Count; i++) {
|
||||||
|
var call = instructions[i];
|
||||||
|
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
|
||||||
|
continue;
|
||||||
|
if (!isWindowsFormsSetNameMethod(call.Operand as MethodReference))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ldstr = instructions[i - 1];
|
||||||
|
if (ldstr.OpCode.Code != Code.Ldstr)
|
||||||
|
continue;
|
||||||
|
var className = ldstr.Operand as string;
|
||||||
|
if (className == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i - 2]) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
findInitializeComponentMethod(methodDef);
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findInitializeComponentMethod(MethodDef possibleInitMethod) {
|
||||||
|
foreach (var methodDef in methods.getAll()) {
|
||||||
|
if (methodDef.OldName != ".ctor")
|
||||||
|
continue;
|
||||||
|
if (methodDef.MethodDefinition.Body == null)
|
||||||
|
continue;
|
||||||
|
foreach (var instr in methodDef.MethodDefinition.Body.Instructions) {
|
||||||
|
if (instr.OpCode.Code != Code.Call)
|
||||||
|
continue;
|
||||||
|
if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(possibleInitMethod.MethodDefinition, instr.Operand as MethodReference))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
newMethodsNames[possibleInitMethod] = "InitializeComponent";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isWindowsFormsSetNameMethod(MethodReference method) {
|
||||||
|
if (method == null)
|
||||||
|
return false;
|
||||||
|
if (method.Name != "set_Name")
|
||||||
|
return false;
|
||||||
|
if (method.MethodReturnType.ReturnType.FullName != "System.Void")
|
||||||
|
return false;
|
||||||
|
if (method.Parameters.Count != 1)
|
||||||
|
return false;
|
||||||
|
if (method.Parameters[0].ParameterType.FullName != "System.String")
|
||||||
|
return false;
|
||||||
|
if (!method.DeclaringType.FullName.StartsWith("System.Windows.Forms.", StringComparison.Ordinal))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void rename() {
|
public void rename() {
|
||||||
var typeDefinition = TypeDefinition;
|
var typeDefinition = TypeDefinition;
|
||||||
|
|
||||||
|
@ -635,6 +821,13 @@ namespace de4dot.renamer {
|
||||||
if (MemberRenameState == null)
|
if (MemberRenameState == null)
|
||||||
MemberRenameState = baseType.typeDef.MemberRenameState.clone();
|
MemberRenameState = baseType.typeDef.MemberRenameState.clone();
|
||||||
|
|
||||||
|
if (IsRenamable) {
|
||||||
|
foreach (var fieldDef in fields.getAll())
|
||||||
|
MemberRenameState.variableNameState.addFieldName(fieldDef.OldName);
|
||||||
|
foreach (var methodDef in methods.getAll())
|
||||||
|
MemberRenameState.variableNameState.addMethodName(methodDef.OldName);
|
||||||
|
}
|
||||||
|
|
||||||
// For each base type and interface it implements, add all its virtual methods, props,
|
// For each base type and interface it implements, add all its virtual methods, props,
|
||||||
// and events if the type is a non-renamable type (eg. it's from mscorlib or some other
|
// and events if the type is a non-renamable type (eg. it's from mscorlib or some other
|
||||||
// non-deobfuscated assembly).
|
// non-deobfuscated assembly).
|
||||||
|
@ -657,6 +850,9 @@ namespace de4dot.renamer {
|
||||||
prepareRenameFields(); // must be first
|
prepareRenameFields(); // must be first
|
||||||
prepareRenameProperties();
|
prepareRenameProperties();
|
||||||
prepareRenameEvents();
|
prepareRenameEvents();
|
||||||
|
|
||||||
|
initializeEventHandlerNames();
|
||||||
|
|
||||||
prepareRenameMethods(); // must be last
|
prepareRenameMethods(); // must be last
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -726,6 +922,9 @@ namespace de4dot.renamer {
|
||||||
void prepareRenameFields() {
|
void prepareRenameFields() {
|
||||||
var variableNameState = MemberRenameState.variableNameState;
|
var variableNameState = MemberRenameState.variableNameState;
|
||||||
|
|
||||||
|
if (isWindowsFormsControlDerivedClass())
|
||||||
|
initializeWindowsFormsFields();
|
||||||
|
|
||||||
if (TypeDefinition.IsEnum) {
|
if (TypeDefinition.IsEnum) {
|
||||||
var instanceFields = new List<FieldDef>(getInstanceFields());
|
var instanceFields = new List<FieldDef>(getInstanceFields());
|
||||||
if (instanceFields.Count == 1) {
|
if (instanceFields.Count == 1) {
|
||||||
|
@ -739,6 +938,8 @@ namespace de4dot.renamer {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
string nameFormat = hasFlagsAttribute() ? "flag_{0}" : "const_{0}";
|
string nameFormat = hasFlagsAttribute() ? "flag_{0}" : "const_{0}";
|
||||||
foreach (var fieldDef in fields.getSorted()) {
|
foreach (var fieldDef in fields.getSorted()) {
|
||||||
|
if (fieldDef.Renamed)
|
||||||
|
continue;
|
||||||
if (!fieldDef.FieldDefinition.IsStatic || !fieldDef.FieldDefinition.IsLiteral)
|
if (!fieldDef.FieldDefinition.IsStatic || !fieldDef.FieldDefinition.IsLiteral)
|
||||||
continue;
|
continue;
|
||||||
if (!variableNameState.IsValidName(fieldDef.OldName))
|
if (!variableNameState.IsValidName(fieldDef.OldName))
|
||||||
|
@ -754,6 +955,134 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initializeWindowsFormsFields() {
|
||||||
|
var ourFields = new Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef>();
|
||||||
|
foreach (var fieldDef in fields.getAll())
|
||||||
|
ourFields[new FieldReferenceAndDeclaringTypeKey(fieldDef.FieldDefinition)] = fieldDef;
|
||||||
|
|
||||||
|
var variableNameState = MemberRenameState.variableNameState;
|
||||||
|
foreach (var methodDef in methods.getAll()) {
|
||||||
|
if (methodDef.MethodDefinition.Body == null)
|
||||||
|
continue;
|
||||||
|
if (methodDef.MethodDefinition.IsStatic || methodDef.MethodDefinition.IsVirtual)
|
||||||
|
continue;
|
||||||
|
var instructions = methodDef.MethodDefinition.Body.Instructions;
|
||||||
|
for (int i = 2; i < instructions.Count; i++) {
|
||||||
|
var call = instructions[i];
|
||||||
|
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
|
||||||
|
continue;
|
||||||
|
if (!isWindowsFormsSetNameMethod(call.Operand as MethodReference))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ldstr = instructions[i - 1];
|
||||||
|
if (ldstr.OpCode.Code != Code.Ldstr)
|
||||||
|
continue;
|
||||||
|
var fieldName = ldstr.Operand as string;
|
||||||
|
if (fieldName == null || !variableNameState.IsValidName(fieldName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ldfld = instructions[i - 2];
|
||||||
|
var fieldRef = ldfld.Operand as FieldReference;
|
||||||
|
if (fieldRef == null)
|
||||||
|
continue;
|
||||||
|
FieldDef fieldDef;
|
||||||
|
if (!ourFields.TryGetValue(new FieldReferenceAndDeclaringTypeKey(fieldRef), out fieldDef))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fieldDef.Renamed)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fieldDef.rename(variableNameState.getNewFieldName(fieldDef.OldName, new NameCreator2(fieldName)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initializeEventHandlerNames() {
|
||||||
|
var ourFields = new Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef>();
|
||||||
|
foreach (var fieldDef in fields.getAll())
|
||||||
|
ourFields[new FieldReferenceAndDeclaringTypeKey(fieldDef.FieldDefinition)] = fieldDef;
|
||||||
|
var ourMethods = new Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef>();
|
||||||
|
foreach (var methodDef in methods.getAll())
|
||||||
|
ourMethods[new MethodReferenceAndDeclaringTypeKey(methodDef.MethodDefinition)] = methodDef;
|
||||||
|
|
||||||
|
var variableNameState = MemberRenameState.variableNameState;
|
||||||
|
foreach (var methodDef in methods.getAll()) {
|
||||||
|
if (methodDef.MethodDefinition.Body == null)
|
||||||
|
continue;
|
||||||
|
if (methodDef.MethodDefinition.IsStatic)
|
||||||
|
continue;
|
||||||
|
var instructions = methodDef.MethodDefinition.Body.Instructions;
|
||||||
|
for (int i = 0; i < instructions.Count - 5; i++) {
|
||||||
|
// We're looking for this code pattern:
|
||||||
|
// ldarg.0
|
||||||
|
// ldfld field
|
||||||
|
// ldarg.0
|
||||||
|
// ldftn method
|
||||||
|
// newobj event_handler_ctor
|
||||||
|
// callvirt add_SomeEvent
|
||||||
|
|
||||||
|
if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i]) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ldfld = instructions[i + 1];
|
||||||
|
if (ldfld.OpCode.Code != Code.Ldfld)
|
||||||
|
continue;
|
||||||
|
var fieldRef = ldfld.Operand as FieldReference;
|
||||||
|
if (fieldRef == null)
|
||||||
|
continue;
|
||||||
|
FieldDef fieldDef;
|
||||||
|
if (!ourFields.TryGetValue(new FieldReferenceAndDeclaringTypeKey(fieldRef), out fieldDef))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i + 2]) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ldftn = instructions[i + 3];
|
||||||
|
if (ldftn.OpCode.Code != Code.Ldftn)
|
||||||
|
continue;
|
||||||
|
var methodRef = ldftn.Operand as MethodReference;
|
||||||
|
if (methodRef == null)
|
||||||
|
continue;
|
||||||
|
MethodDef handlerMethod;
|
||||||
|
if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(methodRef), out handlerMethod))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var newobj = instructions[i + 4];
|
||||||
|
if (newobj.OpCode.Code != Code.Newobj)
|
||||||
|
continue;
|
||||||
|
if (!isEventHandlerCtor(newobj.Operand as MethodReference))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var call = instructions[i + 5];
|
||||||
|
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
|
||||||
|
continue;
|
||||||
|
var addHandler = call.Operand as MethodReference;
|
||||||
|
if (addHandler == null)
|
||||||
|
continue;
|
||||||
|
if (!addHandler.Name.StartsWith("add_", StringComparison.Ordinal))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var eventName = addHandler.Name.Substring(4);
|
||||||
|
if (!MemberRenameState.variableNameState.IsValidName(eventName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
newMethodsNames[handlerMethod] = string.Format("{0}_{1}", fieldDef.NewName, eventName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isEventHandlerCtor(MethodReference method) {
|
||||||
|
if (method == null)
|
||||||
|
return false;
|
||||||
|
if (method.Name != ".ctor")
|
||||||
|
return false;
|
||||||
|
if (!DotNetUtils.isMethod(method, "System.Void", "(System.Object,System.IntPtr)"))
|
||||||
|
return false;
|
||||||
|
if (!method.DeclaringType.FullName.EndsWith("EventHandler", StringComparison.Ordinal))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static MethodReference getOverrideMethod(MethodDefinition meth) {
|
static MethodReference getOverrideMethod(MethodDefinition meth) {
|
||||||
if (meth == null || !meth.HasOverrides)
|
if (meth == null || !meth.HasOverrides)
|
||||||
return null;
|
return null;
|
||||||
|
@ -927,6 +1256,9 @@ namespace de4dot.renamer {
|
||||||
methodDef.Renamed = true;
|
methodDef.Renamed = true;
|
||||||
|
|
||||||
bool canRenameMethodName = true;
|
bool canRenameMethodName = true;
|
||||||
|
if (suggestedName == null)
|
||||||
|
newMethodsNames.TryGetValue(methodDef, out suggestedName);
|
||||||
|
|
||||||
if (IsDelegate && methodDef.isVirtual()) {
|
if (IsDelegate && methodDef.isVirtual()) {
|
||||||
switch (methodDef.MethodDefinition.Name) {
|
switch (methodDef.MethodDefinition.Name) {
|
||||||
case "BeginInvoke":
|
case "BeginInvoke":
|
||||||
|
@ -941,19 +1273,32 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
if (canRenameMethodName) {
|
if (canRenameMethodName) {
|
||||||
var nameCreator = getMethodNameCreator(methodDef, suggestedName);
|
var nameCreator = getMethodNameCreator(methodDef, suggestedName);
|
||||||
if (!methodDef.MethodDefinition.IsRuntimeSpecialName && !variableNameState.IsValidName(methodDef.OldName))
|
if (!methodDef.MethodDefinition.IsRuntimeSpecialName && !variableNameState.IsValidName(methodDef.OldName)) {
|
||||||
|
bool useNameCreator = methodDef.isVirtual() || methodDef.Property != null || methodDef.Event != null;
|
||||||
|
if (useNameCreator)
|
||||||
methodDef.NewName = nameCreator.newName();
|
methodDef.NewName = nameCreator.newName();
|
||||||
|
else
|
||||||
|
methodDef.NewName = variableNameState.getNewMethodName(methodDef.OldName, nameCreator);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodDef.ParamDefs.Count > 0) {
|
if (methodDef.ParamDefs.Count > 0) {
|
||||||
|
if (isEventHandler(methodDef)) {
|
||||||
|
methodDef.ParamDefs[0].NewName = "sender";
|
||||||
|
methodDef.ParamDefs[0].Renamed = true;
|
||||||
|
methodDef.ParamDefs[1].NewName = "e";
|
||||||
|
methodDef.ParamDefs[1].Renamed = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
var newVariableNameState = variableNameState.clone();
|
var newVariableNameState = variableNameState.clone();
|
||||||
foreach (var paramDef in methodDef.ParamDefs) {
|
foreach (var paramDef in methodDef.ParamDefs) {
|
||||||
if (!newVariableNameState.IsValidName(paramDef.OldName)) {
|
if (!newVariableNameState.IsValidName(paramDef.OldName)) {
|
||||||
paramDef.NewName = newVariableNameState.getNewParamName(paramDef.ParameterDefinition);
|
paramDef.NewName = newVariableNameState.getNewParamName(paramDef.OldName, paramDef.ParameterDefinition);
|
||||||
paramDef.Renamed = true;
|
paramDef.Renamed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prepareRenameGenericParams(methodDef.GenericParams, variableNameState.IsValidName, methodDef.Owner == null ? null : methodDef.Owner.genericParams);
|
prepareRenameGenericParams(methodDef.GenericParams, variableNameState.IsValidName, methodDef.Owner == null ? null : methodDef.Owner.genericParams);
|
||||||
|
|
||||||
|
@ -961,21 +1306,23 @@ namespace de4dot.renamer {
|
||||||
MemberRenameState.add(methodDef);
|
MemberRenameState.add(methodDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
string getPinvokeName(MethodDef methodDef) {
|
static bool isEventHandler(MethodDef methodDef) {
|
||||||
var methodNames = new Dictionary<string, bool>(StringComparer.Ordinal);
|
if (methodDef.MethodDefinition.Parameters.Count != 2)
|
||||||
foreach (var method in methods.getAll())
|
return false;
|
||||||
methodNames[method.NewName] = true;
|
if (methodDef.MethodDefinition.MethodReturnType.ReturnType.FullName != "System.Void")
|
||||||
|
return false;
|
||||||
|
if (methodDef.MethodDefinition.Parameters[0].ParameterType.FullName != "System.Object")
|
||||||
|
return false;
|
||||||
|
if (!methodDef.MethodDefinition.Parameters[1].ParameterType.FullName.Contains("EventArgs"))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (methodDef.MethodDefinition.PInvokeInfo == null)
|
string getPinvokeName(MethodDef methodDef) {
|
||||||
throw new ApplicationException(string.Format("PInvokeInfo is null: A type was probably removed but still referenced by the code."));
|
|
||||||
var entryPoint = methodDef.MethodDefinition.PInvokeInfo.EntryPoint;
|
var entryPoint = methodDef.MethodDefinition.PInvokeInfo.EntryPoint;
|
||||||
if (Regex.IsMatch(entryPoint, @"^#\d+$"))
|
if (Regex.IsMatch(entryPoint, @"^#\d+$"))
|
||||||
entryPoint = DotNetUtils.getDllName(methodDef.MethodDefinition.PInvokeInfo.Module.Name) + "_" + entryPoint.Substring(1);
|
entryPoint = DotNetUtils.getDllName(methodDef.MethodDefinition.PInvokeInfo.Module.Name) + "_" + entryPoint.Substring(1);
|
||||||
while (true) {
|
return entryPoint;
|
||||||
var newName = MemberRenameState.variableNameState.pinvokeNameCreator.newName(entryPoint);
|
|
||||||
if (!methodNames.ContainsKey(newName))
|
|
||||||
return newName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INameCreator getMethodNameCreator(MethodDef methodDef, string suggestedName) {
|
INameCreator getMethodNameCreator(MethodDef methodDef, string suggestedName) {
|
||||||
|
@ -983,7 +1330,7 @@ namespace de4dot.renamer {
|
||||||
INameCreator nameCreator = null;
|
INameCreator nameCreator = null;
|
||||||
string newName = null;
|
string newName = null;
|
||||||
|
|
||||||
if (methodDef.MethodDefinition.HasPInvokeInfo)
|
if (methodDef.MethodDefinition.PInvokeInfo != null)
|
||||||
newName = getPinvokeName(methodDef);
|
newName = getPinvokeName(methodDef);
|
||||||
else if (methodDef.MethodDefinition.IsStatic)
|
else if (methodDef.MethodDefinition.IsStatic)
|
||||||
nameCreator = variableNameState.staticMethodNameCreator;
|
nameCreator = variableNameState.staticMethodNameCreator;
|
||||||
|
@ -1007,8 +1354,12 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
if (newName == null)
|
if (newName == null)
|
||||||
newName = suggestedName;
|
newName = suggestedName;
|
||||||
if (newName != null)
|
if (newName != null) {
|
||||||
nameCreator = new OneNameCreator(newName);
|
if (methodDef.isVirtual())
|
||||||
|
nameCreator = new OneNameCreator(newName); // It must have this name
|
||||||
|
else
|
||||||
|
nameCreator = new NameCreator2(newName);
|
||||||
|
}
|
||||||
|
|
||||||
return nameCreator;
|
return nameCreator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,17 +125,6 @@ namespace de4dot.renamer {
|
||||||
string newName(TypeDefinition typeDefinition, string newBaseTypeName = null);
|
string newName(TypeDefinition typeDefinition, string newBaseTypeName = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PinvokeNameCreator {
|
|
||||||
Dictionary<string, NameCreator2> nameCreators = new Dictionary<string, NameCreator2>(StringComparer.Ordinal);
|
|
||||||
|
|
||||||
public string newName(string name) {
|
|
||||||
NameCreator2 nameCreator;
|
|
||||||
if (!nameCreators.TryGetValue(name, out nameCreator))
|
|
||||||
nameCreators[name] = nameCreator = new NameCreator2(name);
|
|
||||||
return nameCreator.newName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NameInfos {
|
class NameInfos {
|
||||||
IList<NameInfo> nameInfos = new List<NameInfo>();
|
IList<NameInfo> nameInfos = new List<NameInfo>();
|
||||||
|
|
||||||
|
@ -163,6 +152,7 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeNameCreator : ITypeNameCreator {
|
class TypeNameCreator : ITypeNameCreator {
|
||||||
|
CurrentNames currentNames;
|
||||||
INameCreator createUnknownTypeName;
|
INameCreator createUnknownTypeName;
|
||||||
INameCreator createEnumName;
|
INameCreator createEnumName;
|
||||||
INameCreator createStructName;
|
INameCreator createStructName;
|
||||||
|
@ -171,7 +161,8 @@ namespace de4dot.renamer {
|
||||||
INameCreator createInterfaceName;
|
INameCreator createInterfaceName;
|
||||||
NameInfos nameInfos = new NameInfos();
|
NameInfos nameInfos = new NameInfos();
|
||||||
|
|
||||||
public TypeNameCreator() {
|
public TypeNameCreator(CurrentNames currentNames) {
|
||||||
|
this.currentNames = currentNames;
|
||||||
createUnknownTypeName = createNameCreator("Type");
|
createUnknownTypeName = createNameCreator("Type");
|
||||||
createEnumName = createNameCreator("Enum");
|
createEnumName = createNameCreator("Enum");
|
||||||
createStructName = createNameCreator("Struct");
|
createStructName = createNameCreator("Struct");
|
||||||
|
@ -197,7 +188,7 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
public string newName(TypeDefinition typeDefinition, string newBaseTypeName = null) {
|
public string newName(TypeDefinition typeDefinition, string newBaseTypeName = null) {
|
||||||
var nameCreator = getNameCreator(typeDefinition, newBaseTypeName);
|
var nameCreator = getNameCreator(typeDefinition, newBaseTypeName);
|
||||||
return nameCreator.newName();
|
return currentNames.newName(typeDefinition.Name, nameCreator);
|
||||||
}
|
}
|
||||||
|
|
||||||
INameCreator getNameCreator(TypeDefinition typeDefinition, string newBaseTypeName) {
|
INameCreator getNameCreator(TypeDefinition typeDefinition, string newBaseTypeName) {
|
||||||
|
@ -228,6 +219,10 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
class GlobalTypeNameCreator : TypeNameCreator {
|
class GlobalTypeNameCreator : TypeNameCreator {
|
||||||
|
public GlobalTypeNameCreator(CurrentNames currentNames)
|
||||||
|
: base(currentNames) {
|
||||||
|
}
|
||||||
|
|
||||||
protected override INameCreator createNameCreator(string prefix) {
|
protected override INameCreator createNameCreator(string prefix) {
|
||||||
return new GlobalNameCreator(base.createNameCreator("G" + prefix));
|
return new GlobalNameCreator(base.createNameCreator("G" + prefix));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,11 @@ using de4dot.deobfuscators;
|
||||||
|
|
||||||
namespace de4dot.renamer {
|
namespace de4dot.renamer {
|
||||||
class TypeNameState {
|
class TypeNameState {
|
||||||
IDictionary<string, string> namespaceToNewName = new Dictionary<string, string>(StringComparer.Ordinal);
|
public CurrentNames currentNames;
|
||||||
INameCreator createNamespaceName = new GlobalNameCreator(new NameCreator("ns"));
|
IDictionary<string, string> namespaceToNewName;
|
||||||
public ITypeNameCreator globalTypeNameCreator = new GlobalTypeNameCreator();
|
INameCreator createNamespaceName;
|
||||||
public ITypeNameCreator internalTypeNameCreator = new TypeNameCreator();
|
public ITypeNameCreator globalTypeNameCreator;
|
||||||
|
public ITypeNameCreator internalTypeNameCreator;
|
||||||
Func<string, bool> isValidName;
|
Func<string, bool> isValidName;
|
||||||
|
|
||||||
public Func<string, bool> IsValidName {
|
public Func<string, bool> IsValidName {
|
||||||
|
@ -34,6 +35,14 @@ namespace de4dot.renamer {
|
||||||
set { isValidName = value; }
|
set { isValidName = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeNameState() {
|
||||||
|
currentNames = new CurrentNames();
|
||||||
|
namespaceToNewName = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
createNamespaceName = new GlobalNameCreator(new NameCreator("ns"));
|
||||||
|
globalTypeNameCreator = new GlobalTypeNameCreator(currentNames);
|
||||||
|
internalTypeNameCreator = new TypeNameCreator(currentNames);
|
||||||
|
}
|
||||||
|
|
||||||
public bool isValidNamespace(string ns) {
|
public bool isValidNamespace(string ns) {
|
||||||
foreach (var part in ns.Split(new char[] { '.' })) {
|
foreach (var part in ns.Split(new char[] { '.' })) {
|
||||||
if (!isValidName(part))
|
if (!isValidName(part))
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using de4dot.deobfuscators;
|
|
||||||
|
|
||||||
namespace de4dot.renamer {
|
namespace de4dot.renamer {
|
||||||
// State when renaming type members
|
// State when renaming type members
|
||||||
class VariableNameState {
|
class VariableNameState {
|
||||||
|
CurrentNames currentVariableNames = new CurrentNames();
|
||||||
|
CurrentNames currentMethodNames = new CurrentNames();
|
||||||
protected TypeNames variableNameCreator = new VariableNameCreator(); // For fields and method args
|
protected TypeNames variableNameCreator = new VariableNameCreator(); // For fields and method args
|
||||||
protected TypeNames propertyNameCreator = new PropertyNameCreator();
|
protected TypeNames propertyNameCreator = new PropertyNameCreator();
|
||||||
protected INameCreator eventNameCreator = new NameCreator("Event_");
|
protected INameCreator eventNameCreator = new NameCreator("Event_");
|
||||||
|
@ -30,7 +31,6 @@ namespace de4dot.renamer {
|
||||||
public INameCreator virtualMethodNameCreator = new NameCreator("vmethod_");
|
public INameCreator virtualMethodNameCreator = new NameCreator("vmethod_");
|
||||||
public INameCreator instanceMethodNameCreator = new NameCreator("method_");
|
public INameCreator instanceMethodNameCreator = new NameCreator("method_");
|
||||||
protected INameCreator genericPropertyNameCreator = new NameCreator("Prop_");
|
protected INameCreator genericPropertyNameCreator = new NameCreator("Prop_");
|
||||||
public PinvokeNameCreator pinvokeNameCreator = new PinvokeNameCreator();
|
|
||||||
Func<string, bool> isValidName;
|
Func<string, bool> isValidName;
|
||||||
|
|
||||||
public Func<string, bool> IsValidName {
|
public Func<string, bool> IsValidName {
|
||||||
|
@ -44,7 +44,17 @@ namespace de4dot.renamer {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addFieldName(string fieldName) {
|
||||||
|
currentVariableNames.add(fieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMethodName(string methodName) {
|
||||||
|
currentMethodNames.add(methodName);
|
||||||
|
}
|
||||||
|
|
||||||
protected void cloneInit(VariableNameState variableNameState) {
|
protected void cloneInit(VariableNameState variableNameState) {
|
||||||
|
variableNameState.currentVariableNames = new CurrentNames();
|
||||||
|
variableNameState.currentMethodNames = new CurrentNames();
|
||||||
variableNameState.variableNameCreator = variableNameCreator.clone();
|
variableNameState.variableNameCreator = variableNameCreator.clone();
|
||||||
variableNameState.propertyNameCreator = propertyNameCreator.clone();
|
variableNameState.propertyNameCreator = propertyNameCreator.clone();
|
||||||
variableNameState.eventNameCreator = eventNameCreator.clone();
|
variableNameState.eventNameCreator = eventNameCreator.clone();
|
||||||
|
@ -52,7 +62,6 @@ namespace de4dot.renamer {
|
||||||
variableNameState.virtualMethodNameCreator = virtualMethodNameCreator.clone();
|
variableNameState.virtualMethodNameCreator = virtualMethodNameCreator.clone();
|
||||||
variableNameState.instanceMethodNameCreator = instanceMethodNameCreator.clone();
|
variableNameState.instanceMethodNameCreator = instanceMethodNameCreator.clone();
|
||||||
variableNameState.genericPropertyNameCreator = genericPropertyNameCreator.clone();
|
variableNameState.genericPropertyNameCreator = genericPropertyNameCreator.clone();
|
||||||
variableNameState.pinvokeNameCreator = new PinvokeNameCreator();
|
|
||||||
variableNameState.isValidName = isValidName;
|
variableNameState.isValidName = isValidName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,11 +77,19 @@ namespace de4dot.renamer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public string getNewFieldName(FieldDefinition field) {
|
public string getNewFieldName(FieldDefinition field) {
|
||||||
return variableNameCreator.newName(field.FieldType);
|
return currentVariableNames.newName(field.Name, () => variableNameCreator.newName(field.FieldType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string getNewParamName(ParameterDefinition param) {
|
public string getNewFieldName(string oldName, INameCreator nameCreator) {
|
||||||
return variableNameCreator.newName(param.ParameterType);
|
return currentVariableNames.newName(oldName, () => nameCreator.newName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getNewParamName(string oldName, ParameterDefinition param) {
|
||||||
|
return currentVariableNames.newName(oldName, () => variableNameCreator.newName(param.ParameterType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getNewMethodName(string oldName, INameCreator nameCreator) {
|
||||||
|
return currentMethodNames.newName(oldName, nameCreator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user