Rename types
This commit is contained in:
parent
b58c3843e3
commit
195c7194cb
|
@ -20,6 +20,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using de4dot.deobfuscators;
|
using de4dot.deobfuscators;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
|
using de4dot.renamer;
|
||||||
|
|
||||||
namespace de4dot {
|
namespace de4dot {
|
||||||
interface IObfuscatedFile {
|
interface IObfuscatedFile {
|
||||||
|
@ -27,7 +28,7 @@ namespace de4dot {
|
||||||
IDeobfuscator Deobfuscator { get; }
|
IDeobfuscator Deobfuscator { get; }
|
||||||
string Filename { get; }
|
string Filename { get; }
|
||||||
string NewFilename { get; }
|
string NewFilename { get; }
|
||||||
Func<string, bool> IsValidName { get; }
|
INameChecker NameChecker { get; }
|
||||||
bool RenameResourcesInCode { get; }
|
bool RenameResourcesInCode { get; }
|
||||||
bool RenameSymbols { get; }
|
bool RenameSymbols { get; }
|
||||||
bool RemoveNamespaceWithOneType { get; }
|
bool RemoveNamespaceWithOneType { get; }
|
||||||
|
|
|
@ -29,6 +29,7 @@ using de4dot.deobfuscators;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
using de4dot.blocks.cflow;
|
using de4dot.blocks.cflow;
|
||||||
using de4dot.AssemblyClient;
|
using de4dot.AssemblyClient;
|
||||||
|
using de4dot.renamer;
|
||||||
|
|
||||||
namespace de4dot {
|
namespace de4dot {
|
||||||
class ObfuscatedFile : IObfuscatedFile, IDeobfuscatedFile {
|
class ObfuscatedFile : IObfuscatedFile, IDeobfuscatedFile {
|
||||||
|
@ -106,8 +107,8 @@ namespace de4dot {
|
||||||
get { return module; }
|
get { return module; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<string, bool> IsValidName {
|
public INameChecker NameChecker {
|
||||||
get { return deob.IsValidName; }
|
get { return deob; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RenameResourcesInCode {
|
public bool RenameResourcesInCode {
|
||||||
|
|
|
@ -156,6 +156,7 @@
|
||||||
<Compile Include="renamer\asmmodules\EventDef.cs" />
|
<Compile Include="renamer\asmmodules\EventDef.cs" />
|
||||||
<Compile Include="renamer\asmmodules\ExternalAssemblies.cs" />
|
<Compile Include="renamer\asmmodules\ExternalAssemblies.cs" />
|
||||||
<Compile Include="renamer\asmmodules\FieldDef.cs" />
|
<Compile Include="renamer\asmmodules\FieldDef.cs" />
|
||||||
|
<Compile Include="renamer\asmmodules\GenericParamDef.cs" />
|
||||||
<Compile Include="renamer\asmmodules\IResolver.cs" />
|
<Compile Include="renamer\asmmodules\IResolver.cs" />
|
||||||
<Compile Include="renamer\asmmodules\MemberRefFinder.cs" />
|
<Compile Include="renamer\asmmodules\MemberRefFinder.cs" />
|
||||||
<Compile Include="renamer\asmmodules\MethodDef.cs" />
|
<Compile Include="renamer\asmmodules\MethodDef.cs" />
|
||||||
|
@ -166,7 +167,12 @@
|
||||||
<Compile Include="renamer\asmmodules\Ref.cs" />
|
<Compile Include="renamer\asmmodules\Ref.cs" />
|
||||||
<Compile Include="renamer\asmmodules\RefDict.cs" />
|
<Compile Include="renamer\asmmodules\RefDict.cs" />
|
||||||
<Compile Include="renamer\asmmodules\TypeDef.cs" />
|
<Compile Include="renamer\asmmodules\TypeDef.cs" />
|
||||||
|
<Compile Include="renamer\DerivedFrom.cs" />
|
||||||
|
<Compile Include="renamer\ExistingNames.cs" />
|
||||||
|
<Compile Include="renamer\INameChecker.cs" />
|
||||||
|
<Compile Include="renamer\NameCreators.cs" />
|
||||||
<Compile Include="renamer\Renamer.cs" />
|
<Compile Include="renamer\Renamer.cs" />
|
||||||
|
<Compile Include="renamer\TypeRenamerState.cs" />
|
||||||
<Compile Include="StringDecrypter.cs" />
|
<Compile Include="StringDecrypter.cs" />
|
||||||
<Compile Include="UserException.cs" />
|
<Compile Include="UserException.cs" />
|
||||||
<Compile Include="Utils.cs" />
|
<Compile Include="Utils.cs" />
|
||||||
|
|
|
@ -77,10 +77,6 @@ namespace de4dot.deobfuscators {
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Func<string, bool> IsValidName {
|
|
||||||
get { return (name) => checkValidName(name); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeobfuscatorBase(OptionsBase optionsBase) {
|
public DeobfuscatorBase(OptionsBase optionsBase) {
|
||||||
this.optionsBase = optionsBase;
|
this.optionsBase = optionsBase;
|
||||||
StringFeatures = StringFeatures.AllowAll;
|
StringFeatures = StringFeatures.AllowAll;
|
||||||
|
@ -502,5 +498,37 @@ namespace de4dot.deobfuscators {
|
||||||
var list = new List<CustomAttribute>(DotNetUtils.findAttributes(module.Assembly, attr));
|
var list = new List<CustomAttribute>(DotNetUtils.findAttributes(module.Assembly, attr));
|
||||||
return list.Count == 0 ? null : list[0];
|
return list.Count == 0 ? null : list[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool isValidNamespaceName(string ns) {
|
||||||
|
return checkValidName(ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidTypeName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidMethodName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidPropertyName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidEventName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidFieldName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidGenericParamName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isValidMethodArgName(string name) {
|
||||||
|
return checkValidName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using Mono.MyStuff;
|
using Mono.MyStuff;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
using de4dot.renamer;
|
||||||
|
|
||||||
namespace de4dot.deobfuscators {
|
namespace de4dot.deobfuscators {
|
||||||
interface IDeobfuscatorOptions {
|
interface IDeobfuscatorOptions {
|
||||||
|
@ -49,11 +50,10 @@ namespace de4dot.deobfuscators {
|
||||||
RemoveNamespaceIfOneType = 1,
|
RemoveNamespaceIfOneType = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IDeobfuscator {
|
interface IDeobfuscator : INameChecker {
|
||||||
string Type { get; }
|
string Type { get; }
|
||||||
string TypeLong { get; }
|
string TypeLong { get; }
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
Func<string, bool> IsValidName { get; }
|
|
||||||
IDeobfuscatorOptions TheOptions { get; }
|
IDeobfuscatorOptions TheOptions { get; }
|
||||||
IOperations Operations { get; set; }
|
IOperations Operations { get; set; }
|
||||||
StringFeatures StringFeatures { get; }
|
StringFeatures StringFeatures { get; }
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace de4dot.old_renamer {
|
||||||
List<MethodDefinition> allMethods;
|
List<MethodDefinition> allMethods;
|
||||||
|
|
||||||
public Func<string, bool> IsValidName {
|
public Func<string, bool> IsValidName {
|
||||||
get { return obfuscatedFile.IsValidName; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
class RefToDef<R, D> where R : MemberReference where D : R {
|
class RefToDef<R, D> where R : MemberReference where D : R {
|
||||||
|
|
62
de4dot.code/renamer/DerivedFrom.cs
Normal file
62
de4dot.code/renamer/DerivedFrom.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;
|
||||||
|
using de4dot.renamer.asmmodules;
|
||||||
|
|
||||||
|
namespace de4dot.renamer {
|
||||||
|
class DerivedFrom {
|
||||||
|
Dictionary<string, bool> classNames = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||||
|
Dictionary<TypeDef, bool> results = new Dictionary<TypeDef, bool>();
|
||||||
|
|
||||||
|
public DerivedFrom(string className) {
|
||||||
|
addName(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DerivedFrom(string[] classNames) {
|
||||||
|
foreach (var className in classNames)
|
||||||
|
addName(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addName(string className) {
|
||||||
|
classNames[className] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool check(TypeDef type) {
|
||||||
|
if (results.ContainsKey(type))
|
||||||
|
return results[type];
|
||||||
|
|
||||||
|
bool val;
|
||||||
|
if (classNames.ContainsKey(type.TypeDefinition.FullName))
|
||||||
|
val = true;
|
||||||
|
else if (type.baseType == null) {
|
||||||
|
if (type.TypeDefinition.BaseType != null)
|
||||||
|
val = classNames.ContainsKey(type.TypeDefinition.BaseType.FullName);
|
||||||
|
else
|
||||||
|
val = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val = check(type.baseType.typeDef);
|
||||||
|
|
||||||
|
results[type] = val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
de4dot.code/renamer/ExistingNames.cs
Normal file
62
de4dot.code/renamer/ExistingNames.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 ExistingNames {
|
||||||
|
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 getName(string oldName, INameCreator nameCreator) {
|
||||||
|
return getName(oldName, () => nameCreator.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getName(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 ExistingNames clone() {
|
||||||
|
var cn = new ExistingNames();
|
||||||
|
foreach (var key in allNames.Keys)
|
||||||
|
cn.allNames[key] = true;
|
||||||
|
return cn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
de4dot.code/renamer/INameChecker.cs
Normal file
31
de4dot.code/renamer/INameChecker.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace de4dot.renamer {
|
||||||
|
interface INameChecker {
|
||||||
|
bool isValidNamespaceName(string ns);
|
||||||
|
bool isValidTypeName(string name);
|
||||||
|
bool isValidMethodName(string name);
|
||||||
|
bool isValidPropertyName(string name);
|
||||||
|
bool isValidEventName(string name);
|
||||||
|
bool isValidFieldName(string name);
|
||||||
|
bool isValidGenericParamName(string name);
|
||||||
|
bool isValidMethodArgName(string name);
|
||||||
|
}
|
||||||
|
}
|
229
de4dot.code/renamer/NameCreators.cs
Normal file
229
de4dot.code/renamer/NameCreators.cs
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
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.Collections.Generic;
|
||||||
|
using Mono.Cecil;
|
||||||
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
namespace de4dot.renamer {
|
||||||
|
interface INameCreator {
|
||||||
|
INameCreator clone();
|
||||||
|
string create();
|
||||||
|
}
|
||||||
|
|
||||||
|
class OneNameCreator : INameCreator {
|
||||||
|
string name;
|
||||||
|
|
||||||
|
public OneNameCreator(string name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public INameCreator clone() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string create() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GlobalNameCreator : INameCreator {
|
||||||
|
INameCreator other;
|
||||||
|
|
||||||
|
public GlobalNameCreator(INameCreator other) {
|
||||||
|
this.other = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
public INameCreator clone() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string create() {
|
||||||
|
return other.create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenericParamNameCreator : INameCreator {
|
||||||
|
static string[] names = new string[] { "T", "U", "V", "W", "X", "Y", "Z" };
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
public string create() {
|
||||||
|
if (index < names.Length)
|
||||||
|
return names[index++];
|
||||||
|
return string.Format("T{0}", index++);
|
||||||
|
}
|
||||||
|
|
||||||
|
public INameCreator clone() {
|
||||||
|
var rv = new GenericParamNameCreator();
|
||||||
|
rv.index = index;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NameCreator : INameCreator {
|
||||||
|
string prefix;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
public NameCreator(string prefix, int num = 0) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.num = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public INameCreator clone() {
|
||||||
|
return new NameCreator(prefix, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string create() {
|
||||||
|
return prefix + num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Like NameCreator but don't add the counter the first time
|
||||||
|
class NameCreator2 : INameCreator {
|
||||||
|
string prefix;
|
||||||
|
int num;
|
||||||
|
const string separator = "_";
|
||||||
|
|
||||||
|
public NameCreator2(string prefix, int num = 0) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.num = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public INameCreator clone() {
|
||||||
|
return new NameCreator2(prefix, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string create() {
|
||||||
|
string rv;
|
||||||
|
if (num == 0)
|
||||||
|
rv = prefix;
|
||||||
|
else
|
||||||
|
rv = prefix + separator + num;
|
||||||
|
num++;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITypeNameCreator {
|
||||||
|
string create(TypeDefinition typeDefinition, string newBaseTypeName = null);
|
||||||
|
}
|
||||||
|
|
||||||
|
class NameInfos {
|
||||||
|
IList<NameInfo> nameInfos = new List<NameInfo>();
|
||||||
|
|
||||||
|
class NameInfo {
|
||||||
|
public string name;
|
||||||
|
public INameCreator nameCreator;
|
||||||
|
public NameInfo(string name, INameCreator nameCreator) {
|
||||||
|
this.name = name;
|
||||||
|
this.nameCreator = nameCreator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(string name, INameCreator nameCreator) {
|
||||||
|
nameInfos.Add(new NameInfo(name, nameCreator));
|
||||||
|
}
|
||||||
|
|
||||||
|
public INameCreator find(string typeName) {
|
||||||
|
foreach (var nameInfo in nameInfos) {
|
||||||
|
if (typeName.Contains(nameInfo.name))
|
||||||
|
return nameInfo.nameCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeNameCreator : ITypeNameCreator {
|
||||||
|
ExistingNames existingNames;
|
||||||
|
INameCreator createUnknownTypeName;
|
||||||
|
INameCreator createEnumName;
|
||||||
|
INameCreator createStructName;
|
||||||
|
INameCreator createDelegateName;
|
||||||
|
INameCreator createClassName;
|
||||||
|
INameCreator createInterfaceName;
|
||||||
|
NameInfos nameInfos = new NameInfos();
|
||||||
|
|
||||||
|
public TypeNameCreator(ExistingNames existingNames) {
|
||||||
|
this.existingNames = existingNames;
|
||||||
|
createUnknownTypeName = createNameCreator("Type");
|
||||||
|
createEnumName = createNameCreator("Enum");
|
||||||
|
createStructName = createNameCreator("Struct");
|
||||||
|
createDelegateName = createNameCreator("Delegate");
|
||||||
|
createClassName = createNameCreator("Class");
|
||||||
|
createInterfaceName = createNameCreator("Interface");
|
||||||
|
|
||||||
|
var names = new string[] {
|
||||||
|
"Exception",
|
||||||
|
"EventArgs",
|
||||||
|
"Attribute",
|
||||||
|
"Form",
|
||||||
|
"Dialog",
|
||||||
|
"Control",
|
||||||
|
};
|
||||||
|
foreach (var name in names)
|
||||||
|
nameInfos.add(name, createNameCreator(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual INameCreator createNameCreator(string prefix) {
|
||||||
|
return new NameCreator(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string create(TypeDefinition typeDefinition, string newBaseTypeName = null) {
|
||||||
|
var nameCreator = getNameCreator(typeDefinition, newBaseTypeName);
|
||||||
|
return existingNames.getName(typeDefinition.Name, nameCreator);
|
||||||
|
}
|
||||||
|
|
||||||
|
INameCreator getNameCreator(TypeDefinition typeDefinition, string newBaseTypeName) {
|
||||||
|
var nameCreator = createUnknownTypeName;
|
||||||
|
if (typeDefinition.IsEnum)
|
||||||
|
nameCreator = createEnumName;
|
||||||
|
else if (typeDefinition.IsValueType)
|
||||||
|
nameCreator = createStructName;
|
||||||
|
else if (typeDefinition.IsClass) {
|
||||||
|
if (typeDefinition.BaseType != null) {
|
||||||
|
if (MemberReferenceHelper.verifyType(typeDefinition.BaseType, "mscorlib", "System.Delegate"))
|
||||||
|
nameCreator = createDelegateName;
|
||||||
|
else if (MemberReferenceHelper.verifyType(typeDefinition.BaseType, "mscorlib", "System.MulticastDelegate"))
|
||||||
|
nameCreator = createDelegateName;
|
||||||
|
else {
|
||||||
|
nameCreator = nameInfos.find(newBaseTypeName ?? typeDefinition.BaseType.Name);
|
||||||
|
if (nameCreator == null)
|
||||||
|
nameCreator = createClassName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nameCreator = createClassName;
|
||||||
|
}
|
||||||
|
else if (typeDefinition.IsInterface)
|
||||||
|
nameCreator = createInterfaceName;
|
||||||
|
return nameCreator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GlobalTypeNameCreator : TypeNameCreator {
|
||||||
|
public GlobalTypeNameCreator(ExistingNames existingNames)
|
||||||
|
: base(existingNames) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override INameCreator createNameCreator(string prefix) {
|
||||||
|
return new GlobalNameCreator(base.createNameCreator("G" + prefix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,21 +17,177 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Mono.Cecil;
|
||||||
|
using Mono.Cecil.Cil;
|
||||||
|
using de4dot.blocks;
|
||||||
using de4dot.renamer.asmmodules;
|
using de4dot.renamer.asmmodules;
|
||||||
|
|
||||||
namespace de4dot.renamer {
|
namespace de4dot.renamer {
|
||||||
|
class MemberInfo {
|
||||||
|
Ref memberRef;
|
||||||
|
public string oldFullName;
|
||||||
|
public string oldName;
|
||||||
|
public string newName;
|
||||||
|
public bool renamed;
|
||||||
|
|
||||||
|
public MemberInfo(Ref memberRef) {
|
||||||
|
this.memberRef = memberRef;
|
||||||
|
oldFullName = memberRef.memberReference.FullName;
|
||||||
|
oldName = memberRef.memberReference.Name;
|
||||||
|
newName = memberRef.memberReference.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rename(string newTypeName) {
|
||||||
|
renamed = true;
|
||||||
|
newName = newTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool gotNewName() {
|
||||||
|
return oldName != newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeInfo : MemberInfo {
|
||||||
|
public string oldNamespace;
|
||||||
|
public string newNamespace;
|
||||||
|
|
||||||
|
public TypeInfo(TypeDef type)
|
||||||
|
: base(type) {
|
||||||
|
oldNamespace = type.TypeDefinition.Namespace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GenericParamInfo : MemberInfo {
|
||||||
|
public GenericParamInfo(GenericParamDef genericParamDef)
|
||||||
|
: base(genericParamDef) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Renamer {
|
class Renamer {
|
||||||
bool renameSymbols = true;
|
public bool RenameNamespaces { get; set; }
|
||||||
bool renameFields = true;
|
public bool RenameTypes { get; set; }
|
||||||
bool renameProperties = true;
|
public bool RenameProperties { get; set; }
|
||||||
bool renameEvents = true;
|
public bool RenameEvents { get; set; }
|
||||||
bool renameMethods = true;
|
public bool RenameFields { get; set; }
|
||||||
|
public bool RenameGenericParams { get; set; }
|
||||||
|
public bool RenameMethodArgs { get; set; }
|
||||||
Modules modules = new Modules();
|
Modules modules = new Modules();
|
||||||
|
DerivedFrom isWinFormsClass;
|
||||||
|
Dictionary<TypeDef, TypeInfo> allTypeInfos = new Dictionary<TypeDef, TypeInfo>();
|
||||||
|
Dictionary<GenericParamDef, GenericParamInfo> allGenericParamInfos = new Dictionary<GenericParamDef, GenericParamInfo>();
|
||||||
|
Dictionary<MethodDef, string> suggestedMethodNames = new Dictionary<MethodDef, string>();
|
||||||
|
|
||||||
|
static string[] WINFORMS_CLASSES = new string[] {
|
||||||
|
#region Win Forms class names
|
||||||
|
"System.Windows.Forms.Control",
|
||||||
|
"System.Windows.Forms.AxHost",
|
||||||
|
"System.Windows.Forms.ButtonBase",
|
||||||
|
"System.Windows.Forms.Button",
|
||||||
|
"System.Windows.Forms.CheckBox",
|
||||||
|
"System.Windows.Forms.RadioButton",
|
||||||
|
"System.Windows.Forms.DataGrid",
|
||||||
|
"System.Windows.Forms.DataGridView",
|
||||||
|
"System.Windows.Forms.DataVisualization.Charting.Chart",
|
||||||
|
"System.Windows.Forms.DateTimePicker",
|
||||||
|
"System.Windows.Forms.GroupBox",
|
||||||
|
"System.Windows.Forms.Integration.ElementHost",
|
||||||
|
"System.Windows.Forms.Label",
|
||||||
|
"System.Windows.Forms.LinkLabel",
|
||||||
|
"System.Windows.Forms.ListControl",
|
||||||
|
"System.Windows.Forms.ComboBox",
|
||||||
|
"Microsoft.VisualBasic.Compatibility.VB6.DriveListBox",
|
||||||
|
"System.Windows.Forms.DataGridViewComboBoxEditingControl",
|
||||||
|
"System.Windows.Forms.ListBox",
|
||||||
|
"Microsoft.VisualBasic.Compatibility.VB6.DirListBox",
|
||||||
|
"Microsoft.VisualBasic.Compatibility.VB6.FileListBox",
|
||||||
|
"System.Windows.Forms.CheckedListBox",
|
||||||
|
"System.Windows.Forms.ListView",
|
||||||
|
"System.Windows.Forms.MdiClient",
|
||||||
|
"System.Windows.Forms.MonthCalendar",
|
||||||
|
"System.Windows.Forms.PictureBox",
|
||||||
|
"System.Windows.Forms.PrintPreviewControl",
|
||||||
|
"System.Windows.Forms.ProgressBar",
|
||||||
|
"System.Windows.Forms.ScrollableControl",
|
||||||
|
"System.Windows.Forms.ContainerControl",
|
||||||
|
"System.Windows.Forms.Form",
|
||||||
|
"System.ComponentModel.Design.CollectionEditor.CollectionForm",
|
||||||
|
"System.Messaging.Design.QueuePathDialog",
|
||||||
|
"System.ServiceProcess.Design.ServiceInstallerDialog",
|
||||||
|
"System.Web.UI.Design.WebControls.CalendarAutoFormatDialog",
|
||||||
|
"System.Web.UI.Design.WebControls.RegexEditorDialog",
|
||||||
|
"System.Windows.Forms.Design.ComponentEditorForm",
|
||||||
|
"System.Windows.Forms.PrintPreviewDialog",
|
||||||
|
"System.Windows.Forms.ThreadExceptionDialog",
|
||||||
|
"System.Workflow.Activities.Rules.Design.RuleConditionDialog",
|
||||||
|
"System.Workflow.Activities.Rules.Design.RuleSetDialog",
|
||||||
|
"System.Workflow.ComponentModel.Design.ThemeConfigurationDialog",
|
||||||
|
"System.Workflow.ComponentModel.Design.TypeBrowserDialog",
|
||||||
|
"System.Workflow.ComponentModel.Design.WorkflowPageSetupDialog",
|
||||||
|
"System.Windows.Forms.PropertyGrid",
|
||||||
|
"System.Windows.Forms.SplitContainer",
|
||||||
|
"System.Windows.Forms.ToolStripContainer",
|
||||||
|
"System.Windows.Forms.ToolStripPanel",
|
||||||
|
"System.Windows.Forms.UpDownBase",
|
||||||
|
"System.Windows.Forms.DomainUpDown",
|
||||||
|
"System.Windows.Forms.NumericUpDown",
|
||||||
|
"System.Windows.Forms.UserControl",
|
||||||
|
"Microsoft.VisualBasic.Compatibility.VB6.ADODC",
|
||||||
|
"System.Web.UI.Design.WebControls.ParameterEditorUserControl",
|
||||||
|
"System.Workflow.ComponentModel.Design.WorkflowOutline",
|
||||||
|
"System.Workflow.ComponentModel.Design.WorkflowView",
|
||||||
|
"System.Windows.Forms.Design.ComponentTray",
|
||||||
|
"System.Windows.Forms.Panel",
|
||||||
|
"System.Windows.Forms.Design.ComponentEditorPage",
|
||||||
|
"System.Windows.Forms.FlowLayoutPanel",
|
||||||
|
"System.Windows.Forms.SplitterPanel",
|
||||||
|
"System.Windows.Forms.TableLayoutPanel",
|
||||||
|
"System.ComponentModel.Design.ByteViewer",
|
||||||
|
"System.Windows.Forms.TabPage",
|
||||||
|
"System.Windows.Forms.ToolStripContentPanel",
|
||||||
|
"System.Windows.Forms.ToolStrip",
|
||||||
|
"System.Windows.Forms.BindingNavigator",
|
||||||
|
"System.Windows.Forms.MenuStrip",
|
||||||
|
"System.Windows.Forms.StatusStrip",
|
||||||
|
"System.Windows.Forms.ToolStripDropDown",
|
||||||
|
"System.Windows.Forms.ToolStripDropDownMenu",
|
||||||
|
"System.Windows.Forms.ContextMenuStrip",
|
||||||
|
"System.Windows.Forms.ToolStripOverflow",
|
||||||
|
"System.Windows.Forms.ScrollBar",
|
||||||
|
"System.Windows.Forms.HScrollBar",
|
||||||
|
"System.Windows.Forms.VScrollBar",
|
||||||
|
"System.Windows.Forms.Splitter",
|
||||||
|
"System.Windows.Forms.StatusBar",
|
||||||
|
"System.Windows.Forms.TabControl",
|
||||||
|
"System.Windows.Forms.TextBoxBase",
|
||||||
|
"System.Windows.Forms.MaskedTextBox",
|
||||||
|
"System.Windows.Forms.RichTextBox",
|
||||||
|
"System.Windows.Forms.TextBox",
|
||||||
|
"System.Windows.Forms.DataGridTextBox",
|
||||||
|
"System.Windows.Forms.DataGridViewTextBoxEditingControl",
|
||||||
|
"System.Windows.Forms.ToolBar",
|
||||||
|
"System.Windows.Forms.TrackBar",
|
||||||
|
"System.Windows.Forms.TreeView",
|
||||||
|
"System.ComponentModel.Design.ObjectSelectorEditor.Selector",
|
||||||
|
"System.Windows.Forms.WebBrowserBase",
|
||||||
|
"System.Windows.Forms.WebBrowser",
|
||||||
|
#endregion
|
||||||
|
};
|
||||||
|
|
||||||
public Renamer(IEnumerable<IObfuscatedFile> files) {
|
public Renamer(IEnumerable<IObfuscatedFile> files) {
|
||||||
|
RenameNamespaces = true;
|
||||||
|
RenameTypes = true;
|
||||||
|
RenameProperties = true;
|
||||||
|
RenameEvents = true;
|
||||||
|
RenameFields = true;
|
||||||
|
RenameGenericParams = true;
|
||||||
|
RenameMethodArgs = true;
|
||||||
|
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
modules.add(new Module(file));
|
modules.add(new Module(file));
|
||||||
|
|
||||||
|
isWinFormsClass = new DerivedFrom(WINFORMS_CLASSES);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rename() {
|
public void rename() {
|
||||||
|
@ -41,7 +197,224 @@ namespace de4dot.renamer {
|
||||||
|
|
||||||
modules.initialize();
|
modules.initialize();
|
||||||
modules.initializeVirtualMembers();
|
modules.initializeVirtualMembers();
|
||||||
|
renameTypeDefinitions();
|
||||||
modules.cleanUp();
|
modules.cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renameTypeDefinitions() {
|
||||||
|
Log.v("Renaming obfuscated type definitions");
|
||||||
|
|
||||||
|
prepareRenameTypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareRenameTypes() {
|
||||||
|
foreach (var type in modules.AllTypes)
|
||||||
|
allTypeInfos[type] = new TypeInfo(type);
|
||||||
|
|
||||||
|
var state = new TypeRenamerState();
|
||||||
|
prepareRenameTypes(modules.BaseTypes, state);
|
||||||
|
fixClsTypeNames();
|
||||||
|
renameTypeDefinitions(modules.NonNestedTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renameTypeDefinitions(IEnumerable<TypeDef> typeDefs) {
|
||||||
|
Log.indent();
|
||||||
|
foreach (var typeDef in typeDefs) {
|
||||||
|
rename(typeDef);
|
||||||
|
renameTypeDefinitions(typeDef.NestedTypes);
|
||||||
|
}
|
||||||
|
Log.deIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void rename(TypeDef type) {
|
||||||
|
var typeDefinition = type.TypeDefinition;
|
||||||
|
var info = allTypeInfos[type];
|
||||||
|
|
||||||
|
Log.v("Type: {0} ({1:X8})", typeDefinition.FullName, typeDefinition.MetadataToken.ToUInt32());
|
||||||
|
Log.indent();
|
||||||
|
|
||||||
|
renameGenericParams(type.GenericParams);
|
||||||
|
|
||||||
|
if (RenameTypes && info.gotNewName()) {
|
||||||
|
var old = typeDefinition.Name;
|
||||||
|
typeDefinition.Name = info.newName;
|
||||||
|
Log.v("Name: {0} => {1}", old, typeDefinition.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RenameNamespaces && info.newNamespace != null) {
|
||||||
|
var old = typeDefinition.Namespace;
|
||||||
|
typeDefinition.Namespace = info.newNamespace;
|
||||||
|
Log.v("Namespace: {0} => {1}", old, typeDefinition.Namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.deIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void renameGenericParams(IEnumerable<GenericParamDef> genericParams) {
|
||||||
|
if (!RenameGenericParams)
|
||||||
|
return;
|
||||||
|
foreach (var param in genericParams) {
|
||||||
|
var info = allGenericParamInfos[param];
|
||||||
|
if (!info.gotNewName())
|
||||||
|
continue;
|
||||||
|
param.GenericParameter.Name = info.newName;
|
||||||
|
Log.v("GenParam: {0} => {1}", info.oldFullName, param.GenericParameter.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the renamed types are using valid CLS names. That means renaming all
|
||||||
|
// generic types from eg. Class1 to Class1`2. If we don't do this, some decompilers
|
||||||
|
// (eg. ILSpy v1.0) won't produce correct output.
|
||||||
|
void fixClsTypeNames() {
|
||||||
|
foreach (var type in modules.NonNestedTypes)
|
||||||
|
fixClsTypeNames(null, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixClsTypeNames(TypeDef nesting, TypeDef nested) {
|
||||||
|
int nestingCount = nesting == null ? 0 : nesting.GenericParams.Count;
|
||||||
|
int arity = nested.GenericParams.Count - nestingCount;
|
||||||
|
var nestedInfo = allTypeInfos[nested];
|
||||||
|
if (nestedInfo.renamed && arity > 0)
|
||||||
|
nestedInfo.newName += "`" + arity;
|
||||||
|
foreach (var nestedType in nested.NestedTypes)
|
||||||
|
fixClsTypeNames(nested, nestedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareRenameTypes(IEnumerable<TypeDef> types, TypeRenamerState state) {
|
||||||
|
foreach (var typeDef in types) {
|
||||||
|
prepareRenameTypes(typeDef, state);
|
||||||
|
prepareRenameTypes(typeDef.derivedTypes, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareRenameTypes(TypeDef type, TypeRenamerState state) {
|
||||||
|
var info = allTypeInfos[type];
|
||||||
|
var checker = type.Module.ObfuscatedFile.NameChecker;
|
||||||
|
|
||||||
|
if (RenameNamespaces) {
|
||||||
|
if (info.newNamespace == null && info.oldNamespace != "") {
|
||||||
|
if (!checker.isValidNamespaceName(info.oldNamespace)) {
|
||||||
|
info.newNamespace = state.createNamespace(info.oldNamespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RenameTypes) {
|
||||||
|
if (info.oldFullName != "<Module>" && !checker.isValidTypeName(info.oldName)) {
|
||||||
|
string origClassName = null;
|
||||||
|
if (isWinFormsClass.check(type))
|
||||||
|
origClassName = findWindowsFormsClassName(type);
|
||||||
|
if (origClassName != null && checker.isValidTypeName(origClassName))
|
||||||
|
info.rename(state.getTypeName(info.oldName, origClassName));
|
||||||
|
else {
|
||||||
|
ITypeNameCreator nameCreator = type.isGlobalType() ?
|
||||||
|
state.globalTypeNameCreator :
|
||||||
|
state.internalTypeNameCreator;
|
||||||
|
string newBaseType = null;
|
||||||
|
TypeInfo baseInfo;
|
||||||
|
if (type.baseType != null && allTypeInfos.TryGetValue(type.baseType.typeDef, out baseInfo)) {
|
||||||
|
if (baseInfo.renamed)
|
||||||
|
newBaseType = baseInfo.newName;
|
||||||
|
}
|
||||||
|
info.rename(nameCreator.create(type.TypeDefinition, newBaseType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RenameGenericParams)
|
||||||
|
prepareRenameGenericParams(type.GenericParams, checker);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareRenameGenericParams(IEnumerable<GenericParamDef> genericParams, INameChecker checker, IEnumerable<GenericParamDef> otherGenericParams = null) {
|
||||||
|
var usedNames = new Dictionary<string, bool>(StringComparer.Ordinal);
|
||||||
|
var nameCreator = new GenericParamNameCreator();
|
||||||
|
|
||||||
|
foreach (var gp in genericParams)
|
||||||
|
allGenericParamInfos[gp] = new GenericParamInfo(gp);
|
||||||
|
|
||||||
|
if (otherGenericParams != null) {
|
||||||
|
foreach (var param in otherGenericParams) {
|
||||||
|
var gpInfo = allGenericParamInfos[param];
|
||||||
|
usedNames[gpInfo.newName] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var param in genericParams) {
|
||||||
|
var gpInfo = allGenericParamInfos[param];
|
||||||
|
if (!checker.isValidGenericParamName(gpInfo.oldName) || usedNames.ContainsKey(gpInfo.oldName)) {
|
||||||
|
string newName;
|
||||||
|
do {
|
||||||
|
newName = nameCreator.create();
|
||||||
|
} while (usedNames.ContainsKey(newName));
|
||||||
|
usedNames[newName] = true;
|
||||||
|
gpInfo.rename(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string findWindowsFormsClassName(TypeDef type) {
|
||||||
|
foreach (var methodDef in type.getAllMethods()) {
|
||||||
|
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(type, methodDef);
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findInitializeComponentMethod(TypeDef type, MethodDef possibleInitMethod) {
|
||||||
|
foreach (var methodDef in type.getAllMethods()) {
|
||||||
|
if (methodDef.MethodDefinition.Name != ".ctor")
|
||||||
|
continue;
|
||||||
|
if (methodDef.MethodDefinition.Body == null)
|
||||||
|
continue;
|
||||||
|
foreach (var instr in methodDef.MethodDefinition.Body.Instructions) {
|
||||||
|
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
||||||
|
continue;
|
||||||
|
if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(possibleInitMethod.MethodDefinition, instr.Operand as MethodReference))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
suggestedMethodNames[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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
50
de4dot.code/renamer/TypeRenamerState.cs
Normal file
50
de4dot.code/renamer/TypeRenamerState.cs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
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 TypeRenamerState {
|
||||||
|
ExistingNames existingNames;
|
||||||
|
Dictionary<string, string> namespaceToNewName;
|
||||||
|
INameCreator createNamespaceName;
|
||||||
|
public ITypeNameCreator globalTypeNameCreator;
|
||||||
|
public ITypeNameCreator internalTypeNameCreator;
|
||||||
|
|
||||||
|
public TypeRenamerState() {
|
||||||
|
existingNames = new ExistingNames();
|
||||||
|
namespaceToNewName = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||||
|
createNamespaceName = new GlobalNameCreator(new NameCreator("ns"));
|
||||||
|
globalTypeNameCreator = new GlobalTypeNameCreator(existingNames);
|
||||||
|
internalTypeNameCreator = new TypeNameCreator(existingNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getTypeName(string oldName, string newName) {
|
||||||
|
return existingNames.getName(oldName, new NameCreator2(newName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string createNamespace(string ns) {
|
||||||
|
string newName;
|
||||||
|
if (namespaceToNewName.TryGetValue(ns, out newName))
|
||||||
|
return newName;
|
||||||
|
return namespaceToNewName[ns] = createNamespaceName.create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
de4dot.code/renamer/asmmodules/GenericParamDef.cs
Normal file
43
de4dot.code/renamer/asmmodules/GenericParamDef.cs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
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.Collections.Generic;
|
||||||
|
using Mono.Cecil;
|
||||||
|
|
||||||
|
namespace de4dot.renamer.asmmodules {
|
||||||
|
class GenericParamDef : Ref {
|
||||||
|
public GenericParameter GenericParameter {
|
||||||
|
get { return (GenericParameter)memberReference; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public GenericParamDef(GenericParameter genericParameter, int index)
|
||||||
|
: base(genericParameter, null, index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<GenericParamDef> createGenericParamDefList(IEnumerable<GenericParameter> parameters) {
|
||||||
|
var list = new List<GenericParamDef>();
|
||||||
|
if (parameters == null)
|
||||||
|
return list;
|
||||||
|
int i = 0;
|
||||||
|
foreach (var param in parameters)
|
||||||
|
list.Add(new GenericParamDef(param, i++));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,16 +17,20 @@
|
||||||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
|
|
||||||
namespace de4dot.renamer.asmmodules {
|
namespace de4dot.renamer.asmmodules {
|
||||||
class MethodDef : Ref {
|
class MethodDef : Ref {
|
||||||
|
IList<GenericParamDef> genericParams;
|
||||||
|
|
||||||
public MethodDefinition MethodDefinition {
|
public MethodDefinition MethodDefinition {
|
||||||
get { return (MethodDefinition)memberReference; }
|
get { return (MethodDefinition)memberReference; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef(MethodDefinition methodDefinition, TypeDef owner, int index)
|
public MethodDef(MethodDefinition methodDefinition, TypeDef owner, int index)
|
||||||
: base(methodDefinition, owner, index) {
|
: base(methodDefinition, owner, index) {
|
||||||
|
genericParams = GenericParamDef.createGenericParamDefList(MethodDefinition.GenericParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool isPublic() {
|
public bool isPublic() {
|
||||||
|
|
|
@ -40,6 +40,10 @@ namespace de4dot.renamer.asmmodules {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IObfuscatedFile ObfuscatedFile {
|
||||||
|
get { return obfuscatedFile; }
|
||||||
|
}
|
||||||
|
|
||||||
public string Filename {
|
public string Filename {
|
||||||
get { return obfuscatedFile.Filename; }
|
get { return obfuscatedFile.Filename; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,20 @@ namespace de4dot.renamer.asmmodules {
|
||||||
AssemblyHash assemblyHash = new AssemblyHash();
|
AssemblyHash assemblyHash = new AssemblyHash();
|
||||||
|
|
||||||
List<TypeDef> allTypes = new List<TypeDef>();
|
List<TypeDef> allTypes = new List<TypeDef>();
|
||||||
List<TypeDef> baseTypes = new List<TypeDef>(); //TODO: Do we need this?
|
List<TypeDef> baseTypes = new List<TypeDef>();
|
||||||
List<TypeDef> nonNestedTypes; //TODO: Do we need this?
|
List<TypeDef> nonNestedTypes;
|
||||||
|
|
||||||
|
public IEnumerable<TypeDef> AllTypes {
|
||||||
|
get { return allTypes; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<TypeDef> BaseTypes {
|
||||||
|
get { return baseTypes; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TypeDef> NonNestedTypes {
|
||||||
|
get { return nonNestedTypes; }
|
||||||
|
}
|
||||||
|
|
||||||
class AssemblyHash {
|
class AssemblyHash {
|
||||||
IDictionary<string, ModuleHash> assemblyHash = new Dictionary<string, ModuleHash>(StringComparer.Ordinal);
|
IDictionary<string, ModuleHash> assemblyHash = new Dictionary<string, ModuleHash>(StringComparer.Ordinal);
|
||||||
|
|
|
@ -21,7 +21,7 @@ using Mono.Cecil;
|
||||||
|
|
||||||
namespace de4dot.renamer.asmmodules {
|
namespace de4dot.renamer.asmmodules {
|
||||||
abstract class Ref {
|
abstract class Ref {
|
||||||
protected readonly MemberReference memberReference;
|
public readonly MemberReference memberReference;
|
||||||
public int Index { get; set; }
|
public int Index { get; set; }
|
||||||
public TypeDef Owner { get; set; }
|
public TypeDef Owner { get; set; }
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,7 @@ namespace de4dot.renamer.asmmodules {
|
||||||
MethodDefDict methods = new MethodDefDict();
|
MethodDefDict methods = new MethodDefDict();
|
||||||
PropertyDefDict properties = new PropertyDefDict();
|
PropertyDefDict properties = new PropertyDefDict();
|
||||||
TypeDefDict types = new TypeDefDict();
|
TypeDefDict types = new TypeDefDict();
|
||||||
|
List<GenericParamDef> genericParams;
|
||||||
internal TypeInfo baseType = null;
|
internal TypeInfo baseType = null;
|
||||||
internal IList<TypeInfo> interfaces = new List<TypeInfo>(); // directly implemented interfaces
|
internal IList<TypeInfo> interfaces = new List<TypeInfo>(); // directly implemented interfaces
|
||||||
internal IList<TypeDef> derivedTypes = new List<TypeDef>();
|
internal IList<TypeDef> derivedTypes = new List<TypeDef>();
|
||||||
|
@ -214,10 +215,18 @@ namespace de4dot.renamer.asmmodules {
|
||||||
Dictionary<TypeInfo, bool> allImplementedInterfaces = new Dictionary<TypeInfo, bool>();
|
Dictionary<TypeInfo, bool> allImplementedInterfaces = new Dictionary<TypeInfo, bool>();
|
||||||
InterfaceMethodInfos interfaceMethodInfos = new InterfaceMethodInfos();
|
InterfaceMethodInfos interfaceMethodInfos = new InterfaceMethodInfos();
|
||||||
|
|
||||||
|
public Module Module {
|
||||||
|
get { return module; }
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasModule {
|
public bool HasModule {
|
||||||
get { return module != null; }
|
get { return module != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IList<GenericParamDef> GenericParams {
|
||||||
|
get { return genericParams; }
|
||||||
|
}
|
||||||
|
|
||||||
public IEnumerable<TypeDef> NestedTypes {
|
public IEnumerable<TypeDef> NestedTypes {
|
||||||
get { return types.getSorted(); }
|
get { return types.getSorted(); }
|
||||||
}
|
}
|
||||||
|
@ -231,6 +240,7 @@ namespace de4dot.renamer.asmmodules {
|
||||||
public TypeDef(TypeDefinition typeDefinition, Module module, int index)
|
public TypeDef(TypeDefinition typeDefinition, Module module, int index)
|
||||||
: base(typeDefinition, null, index) {
|
: base(typeDefinition, null, index) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
|
genericParams = GenericParamDef.createGenericParamDefList(TypeDefinition.GenericParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInterface(TypeDef ifaceDef, TypeReference iface) {
|
public void addInterface(TypeDef ifaceDef, TypeReference iface) {
|
||||||
|
@ -290,6 +300,28 @@ namespace de4dot.renamer.asmmodules {
|
||||||
add(new PropertyDef(type.Properties[i], this, i));
|
add(new PropertyDef(type.Properties[i], this, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool isNested() {
|
||||||
|
return NestingType != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool isGlobalType() {
|
||||||
|
if (!isNested())
|
||||||
|
return TypeDefinition.IsPublic;
|
||||||
|
var mask = TypeDefinition.Attributes & TypeAttributes.VisibilityMask;
|
||||||
|
switch (mask) {
|
||||||
|
case TypeAttributes.NestedPrivate:
|
||||||
|
case TypeAttributes.NestedAssembly:
|
||||||
|
case TypeAttributes.NestedFamANDAssem:
|
||||||
|
return false;
|
||||||
|
case TypeAttributes.NestedPublic:
|
||||||
|
case TypeAttributes.NestedFamily:
|
||||||
|
case TypeAttributes.NestedFamORAssem:
|
||||||
|
return NestingType.isGlobalType();
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void initializeVirtualMembers(MethodNameScopes scopes, IResolver resolver) {
|
public void initializeVirtualMembers(MethodNameScopes scopes, IResolver resolver) {
|
||||||
if (initializeVirtualMembersCalled)
|
if (initializeVirtualMembersCalled)
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user