Add more renamer code

This commit is contained in:
de4dot 2011-11-18 16:55:54 +01:00
parent ed3ee45064
commit 1b0fbfc681
12 changed files with 1327 additions and 283 deletions

View File

@ -163,6 +163,7 @@
<Compile Include="renamer\asmmodules\MethodNameScopes.cs" />
<Compile Include="renamer\asmmodules\Module.cs" />
<Compile Include="renamer\asmmodules\Modules.cs" />
<Compile Include="renamer\asmmodules\ParamDef.cs" />
<Compile Include="renamer\asmmodules\PropertyDef.cs" />
<Compile Include="renamer\asmmodules\Ref.cs" />
<Compile Include="renamer\asmmodules\RefDict.cs" />
@ -170,9 +171,13 @@
<Compile Include="renamer\DerivedFrom.cs" />
<Compile Include="renamer\ExistingNames.cs" />
<Compile Include="renamer\INameChecker.cs" />
<Compile Include="renamer\MemberInfos.cs" />
<Compile Include="renamer\NameCreators.cs" />
<Compile Include="renamer\Renamer.cs" />
<Compile Include="renamer\TypeInfo.cs" />
<Compile Include="renamer\TypeNames.cs" />
<Compile Include="renamer\TypeRenamerState.cs" />
<Compile Include="renamer\VariableNameState.cs" />
<Compile Include="StringDecrypter.cs" />
<Compile Include="UserException.cs" />
<Compile Include="Utils.cs" />

View File

@ -0,0 +1,267 @@
/*
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 de4dot.renamer.asmmodules;
namespace de4dot.renamer {
class MemberInfo {
Ref memberRef;
public string oldFullName;
public string oldName;
public string newName;
public bool renamed;
public string suggestedName;
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 GenericParamInfo : MemberInfo {
public GenericParamInfo(GenericParamDef genericParamDef)
: base(genericParamDef) {
}
}
class PropertyInfo : MemberInfo {
public PropertyInfo(PropertyDef propertyDef)
: base(propertyDef) {
}
}
class EventInfo : MemberInfo {
public EventInfo(EventDef eventDef)
: base(eventDef) {
}
}
class FieldInfo : MemberInfo {
public FieldInfo(FieldDef fieldDef)
: base(fieldDef) {
}
}
class MethodInfo : MemberInfo {
public MethodInfo(MethodDef methodDef)
: base(methodDef) {
}
}
class ParamInfo {
ParamDef paramDef;
public string oldName;
public string newName;
public ParamInfo(ParamDef paramDef) {
this.paramDef = paramDef;
this.oldName = paramDef.ParameterDefinition.Name;
this.newName = paramDef.ParameterDefinition.Name;
}
public bool gotNewName() {
return oldName != newName;
}
}
class MemberInfos {
Dictionary<TypeDef, TypeInfo> allTypeInfos = new Dictionary<TypeDef, TypeInfo>();
Dictionary<PropertyDef, PropertyInfo> allPropertyInfos = new Dictionary<PropertyDef, PropertyInfo>();
Dictionary<EventDef, EventInfo> allEventInfos = new Dictionary<EventDef, EventInfo>();
Dictionary<FieldDef, FieldInfo> allFieldInfos = new Dictionary<FieldDef, FieldInfo>();
Dictionary<MethodDef, MethodInfo> allMethodInfos = new Dictionary<MethodDef, MethodInfo>();
Dictionary<GenericParamDef, GenericParamInfo> allGenericParamInfos = new Dictionary<GenericParamDef, GenericParamInfo>();
Dictionary<ParamDef, ParamInfo> allParamInfos = new Dictionary<ParamDef, ParamInfo>();
DerivedFrom checkWinFormsClass;
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 MemberInfos() {
checkWinFormsClass = new DerivedFrom(WINFORMS_CLASSES);
}
public bool isWinFormsClass(TypeDef type) {
return checkWinFormsClass.check(type);
}
public TypeInfo type(TypeDef t) {
return allTypeInfos[t];
}
public bool tryGetType(TypeDef t, out TypeInfo info) {
return allTypeInfos.TryGetValue(t, out info);
}
public PropertyInfo prop(PropertyDef prop) {
return allPropertyInfos[prop];
}
public EventInfo evt(EventDef evt) {
return allEventInfos[evt];
}
public FieldInfo field(FieldDef field) {
return allFieldInfos[field];
}
public MethodInfo method(MethodDef method) {
return allMethodInfos[method];
}
public GenericParamInfo gparam(GenericParamDef gparam) {
return allGenericParamInfos[gparam];
}
public ParamInfo param(ParamDef param) {
return allParamInfos[param];
}
public void initialize(Modules modules) {
foreach (var type in modules.AllTypes) {
allTypeInfos[type] = new TypeInfo(type, this);
foreach (var gp in type.GenericParams)
allGenericParamInfos[gp] = new GenericParamInfo(gp);
foreach (var field in type.AllFields)
allFieldInfos[field] = new FieldInfo(field);
foreach (var evt in type.AllEvents)
allEventInfos[evt] = new EventInfo(evt);
foreach (var prop in type.AllProperties)
allPropertyInfos[prop] = new PropertyInfo(prop);
foreach (var method in type.AllMethods) {
allMethodInfos[method] = new MethodInfo(method);
foreach (var gp in method.GenericParams)
allGenericParamInfos[gp] = new GenericParamInfo(gp);
foreach (var param in method.ParamDefs)
allParamInfos[param] = new ParamInfo(param);
}
}
}
}
}

View File

@ -17,163 +17,21 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using Mono.Cecil;
using Mono.Cecil.Cil;
using de4dot.blocks;
using de4dot.renamer.asmmodules;
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 {
public bool RenameNamespaces { get; set; }
public bool RenameTypes { get; set; }
public bool RenameGenericParams { get; set; }
public bool RenameProperties { get; set; }
public bool RenameEvents { get; set; }
public bool RenameFields { get; set; }
public bool RenameGenericParams { get; set; }
public bool RenameMethods { get; set; }
public bool RenameMethodArgs { get; set; }
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
};
MemberInfos memberInfos = new MemberInfos();
public Renamer(IEnumerable<IObfuscatedFile> files) {
RenameNamespaces = true;
@ -186,8 +44,6 @@ namespace de4dot.renamer {
foreach (var file in files)
modules.add(new Module(file));
isWinFormsClass = new DerivedFrom(WINFORMS_CLASSES);
}
public void rename() {
@ -197,22 +53,18 @@ namespace de4dot.renamer {
modules.initialize();
modules.initializeVirtualMembers();
memberInfos.initialize(modules);
renameTypeDefinitions();
renameTypeReferences();
modules.onTypesRenamed();
prepareRenameMemberDefinitions();
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);
prepareRenameTypes(modules.BaseTypes, new TypeRenamerState());
fixClsTypeNames();
renameTypeDefinitions(modules.NonNestedTypes);
}
@ -228,7 +80,7 @@ namespace de4dot.renamer {
void rename(TypeDef type) {
var typeDefinition = type.TypeDefinition;
var info = allTypeInfos[type];
var info = memberInfos.type(type);
Log.v("Type: {0} ({1:X8})", typeDefinition.FullName, typeDefinition.MetadataToken.ToUInt32());
Log.indent();
@ -254,7 +106,7 @@ namespace de4dot.renamer {
if (!RenameGenericParams)
return;
foreach (var param in genericParams) {
var info = allGenericParamInfos[param];
var info = memberInfos.gparam(param);
if (!info.gotNewName())
continue;
param.GenericParameter.Name = info.newName;
@ -273,7 +125,7 @@ namespace de4dot.renamer {
void fixClsTypeNames(TypeDef nesting, TypeDef nested) {
int nestingCount = nesting == null ? 0 : nesting.GenericParams.Count;
int arity = nested.GenericParams.Count - nestingCount;
var nestedInfo = allTypeInfos[nested];
var nestedInfo = memberInfos.type(nested);
if (nestedInfo.renamed && arity > 0)
nestedInfo.newName += "`" + arity;
foreach (var nestedType in nested.NestedTypes)
@ -282,139 +134,74 @@ namespace de4dot.renamer {
void prepareRenameTypes(IEnumerable<TypeDef> types, TypeRenamerState state) {
foreach (var typeDef in types) {
prepareRenameTypes(typeDef, state);
memberInfos.type(typeDef).prepareRenameTypes(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);
void renameTypeReferences() {
Log.v("Renaming references to type definitions");
var theModules = modules.TheModules;
foreach (var module in theModules) {
if (theModules.Count > 1)
Log.v("Renaming references to type definitions ({0})", module.Filename);
Log.indent();
foreach (var refToDef in module.TypeRefsToRename) {
refToDef.reference.Name = refToDef.definition.Name;
refToDef.reference.Namespace = refToDef.definition.Namespace;
}
Log.deIndent();
}
}
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;
void prepareRenameMemberDefinitions() {
Log.v("Renaming member definitions #1");
var ldstr = instructions[i - 1];
if (ldstr.OpCode.Code != Code.Ldstr)
continue;
var className = ldstr.Operand as string;
if (className == null)
continue;
prepareRenameEntryPoints();
if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i - 2]) != 0)
continue;
foreach (var typeDef in modules.BaseTypes)
memberInfos.type(typeDef).variableNameState = new VariableNameState();
findInitializeComponentMethod(type, methodDef);
return className;
}
}
return null;
foreach (var typeDef in modules.AllTypes)
prepareRenameMembers(typeDef);
}
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;
Dictionary<TypeDef, bool> prepareRenameMembersCalled = new Dictionary<TypeDef, bool>();
void prepareRenameMembers(TypeDef type) {
if (prepareRenameMembersCalled.ContainsKey(type))
return;
prepareRenameMembersCalled[type] = true;
suggestedMethodNames[possibleInitMethod] = "InitializeComponent";
return;
}
}
foreach (var ifaceInfo in type.interfaces)
prepareRenameMembers(ifaceInfo.typeDef);
if (type.baseType != null)
prepareRenameMembers(type.baseType.typeDef);
TypeInfo info;
if (memberInfos.tryGetType(type, out info))
info.prepareRenameMembers();
}
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 (!Utils.StartsWith(method.DeclaringType.FullName, "System.Windows.Forms.", StringComparison.Ordinal))
return false;
return true;
void prepareRenameEntryPoints() {
foreach (var module in modules.TheModules) {
var entryPoint = module.ModuleDefinition.EntryPoint;
if (entryPoint == null)
continue;
var methodDef = modules.resolve(entryPoint);
if (methodDef == null) {
Log.w(string.Format("Could not find entry point. Module: {0}, Method: {1}", module.ModuleDefinition.FullyQualifiedName, entryPoint));
continue;
}
if (!methodDef.isStatic())
continue;
memberInfos.method(methodDef).suggestedName = "Main";
if (methodDef.ParamDefs.Count == 1) {
var paramDef = methodDef.ParamDefs[0];
var type = paramDef.ParameterDefinition.ParameterType;
if (type.FullName == "System.String[]")
memberInfos.param(paramDef).newName = "args";
}
}
}
}
}

View File

@ -0,0 +1,664 @@
/*
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 Mono.Cecil;
using Mono.Cecil.Cil;
using de4dot.renamer.asmmodules;
using de4dot.blocks;
namespace de4dot.renamer {
class TypeInfo : MemberInfo {
public string oldNamespace;
public string newNamespace;
public VariableNameState variableNameState;
TypeDef type;
MemberInfos memberInfos;
public TypeInfo(TypeDef typeDef, MemberInfos memberInfos)
: base(typeDef) {
this.type = typeDef;
this.memberInfos = memberInfos;
oldNamespace = typeDef.TypeDefinition.Namespace;
}
bool isWinFormsClass() {
return memberInfos.isWinFormsClass(type);
}
public PropertyInfo prop(PropertyDef prop) {
return memberInfos.prop(prop);
}
public EventInfo evt(EventDef evt) {
return memberInfos.evt(evt);
}
public FieldInfo field(FieldDef field) {
return memberInfos.field(field);
}
public MethodInfo method(MethodDef method) {
return memberInfos.method(method);
}
public GenericParamInfo gparam(GenericParamDef gparam) {
return memberInfos.gparam(gparam);
}
public ParamInfo param(ParamDef param) {
return memberInfos.param(param);
}
TypeInfo getBase() {
if (type.baseType == null)
return null;
TypeInfo baseInfo;
memberInfos.tryGetType(type.baseType.typeDef, out baseInfo);
return baseInfo;
}
public void prepareRenameTypes(TypeRenamerState state) {
var checker = type.Module.ObfuscatedFile.NameChecker;
if (newNamespace == null && oldNamespace != "") {
if (!checker.isValidNamespaceName(oldNamespace)) {
newNamespace = state.createNamespace(oldNamespace);
}
}
if (oldFullName != "<Module>" && !checker.isValidTypeName(oldName)) {
string origClassName = null;
if (isWinFormsClass())
origClassName = findWindowsFormsClassName(type);
if (origClassName != null && checker.isValidTypeName(origClassName))
rename(state.getTypeName(oldName, origClassName));
else {
ITypeNameCreator nameCreator = type.isGlobalType() ?
state.globalTypeNameCreator :
state.internalTypeNameCreator;
string newBaseType = null;
TypeInfo baseInfo = getBase();
if (baseInfo != null && baseInfo.renamed)
newBaseType = baseInfo.newName;
rename(nameCreator.create(type.TypeDefinition, newBaseType));
}
}
prepareRenameGenericParams(type.GenericParams, checker);
}
public void prepareRenameMembers() {
if (variableNameState == null)
variableNameState = memberInfos.type(type.baseType.typeDef).variableNameState.clone();
if (isWinFormsClass())
initializeWindowsFormsFieldsAndProps();
prepareRenameFields();
prepareRenameProperties();
prepareRenameEvents();
initializeEventHandlerNames();
prepareRenameMethods();
}
void prepareRenameFields() {
var checker = type.Module.ObfuscatedFile.NameChecker;
if (type.TypeDefinition.IsEnum) {
var instanceFields = getInstanceFields();
if (instanceFields.Count == 1) {
var fieldDef = instanceFields[0];
rename("value__");
fieldDef.FieldDefinition.IsRuntimeSpecialName = true;
fieldDef.FieldDefinition.IsSpecialName = true;
}
int i = 0;
string nameFormat = hasFlagsAttribute() ? "flag_{0}" : "const_{0}";
foreach (var fieldDef in type.AllFieldsSorted) {
if (renamed)
continue;
if (!fieldDef.FieldDefinition.IsStatic || !fieldDef.FieldDefinition.IsLiteral)
continue;
if (!checker.isValidFieldName(oldName))
rename(string.Format(nameFormat, i));
i++;
}
}
foreach (var fieldDef in type.AllFieldsSorted) {
if (renamed)
continue;
if (!checker.isValidFieldName(oldName))
rename(variableNameState.getNewFieldName(fieldDef.FieldDefinition));
}
}
List<FieldDef> getInstanceFields() {
var fields = new List<FieldDef>();
foreach (var fieldDef in type.AllFields) {
if (!fieldDef.FieldDefinition.IsStatic)
fields.Add(fieldDef);
}
return fields;
}
bool hasFlagsAttribute() {
foreach (var attr in type.TypeDefinition.CustomAttributes) {
if (attr.AttributeType.FullName == "System.FlagsAttribute")
return true;
}
return false;
}
void prepareRenameProperties() {
//TODO:
}
void prepareRenameEvents() {
//TODO:
}
void prepareRenameMethods() {
//TODO:
}
void prepareRenameGenericParams(IEnumerable<GenericParamDef> genericParams, INameChecker checker, IEnumerable<GenericParamDef> otherGenericParams = null) {
var usedNames = new Dictionary<string, bool>(StringComparer.Ordinal);
var nameCreator = new GenericParamNameCreator();
if (otherGenericParams != null) {
foreach (var param in otherGenericParams) {
var gpInfo = memberInfos.gparam(param);
usedNames[gpInfo.newName] = true;
}
}
foreach (var param in genericParams) {
var gpInfo = memberInfos.gparam(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);
}
}
}
void initializeWindowsFormsFieldsAndProps() {
var checker = type.Module.ObfuscatedFile.NameChecker;
var ourFields = new Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef>();
foreach (var fieldDef in type.AllFields)
ourFields[new FieldReferenceAndDeclaringTypeKey(fieldDef.FieldDefinition)] = fieldDef;
var ourMethods = new Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef>();
foreach (var methodDef in type.AllMethods)
ourMethods[new MethodReferenceAndDeclaringTypeKey(methodDef.MethodDefinition)] = methodDef;
foreach (var methodDef in type.AllMethods) {
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 || !checker.isValidFieldName(fieldName))
continue;
var instr = instructions[i - 2];
FieldReference fieldRef = null;
if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) {
var calledMethod = instr.Operand as MethodReference;
if (calledMethod == null)
continue;
MethodDef calledMethodDef;
if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(calledMethod), out calledMethodDef))
continue;
fieldRef = getFieldReference(calledMethodDef.MethodDefinition);
if (fieldRef == null)
continue;
var propDef = calledMethodDef.Property;
if (propDef == null)
continue;
memberInfos.prop(propDef).suggestedName = fieldName;
fieldName = "_" + fieldName;
}
else if (instr.OpCode.Code == Code.Ldfld) {
fieldRef = instr.Operand as FieldReference;
}
if (fieldRef == null)
continue;
FieldDef fieldDef;
if (!ourFields.TryGetValue(new FieldReferenceAndDeclaringTypeKey(fieldRef), out fieldDef))
continue;
var fieldInfo = memberInfos.field(fieldDef);
if (fieldInfo.renamed)
continue;
fieldInfo.rename(variableNameState.getNewFieldName(fieldInfo.oldName, new NameCreator2(fieldName)));
}
}
}
static FieldReference getFieldReference(MethodDefinition method) {
if (method == null || method.Body == null)
return null;
var instructions = method.Body.Instructions;
int index = 0;
var ldarg0 = DotNetUtils.getInstruction(instructions, ref index);
if (ldarg0 == null || DotNetUtils.getArgIndex(method, ldarg0) != 0)
return null;
var ldfld = DotNetUtils.getInstruction(instructions, ref index);
if (ldfld == null || ldfld.OpCode.Code != Code.Ldfld)
return null;
var ret = DotNetUtils.getInstruction(instructions, ref index);
if (ret == null || ret.OpCode.Code != Code.Ret)
return null;
return ldfld.Operand as FieldReference;
}
void initializeEventHandlerNames() {
var ourFields = new Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef>();
foreach (var fieldDef in type.AllFields)
ourFields[new FieldReferenceAndDeclaringTypeKey(fieldDef.FieldDefinition)] = fieldDef;
var ourMethods = new Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef>();
foreach (var methodDef in type.AllMethods)
ourMethods[new MethodReferenceAndDeclaringTypeKey(methodDef.MethodDefinition)] = methodDef;
initVbEventHandlers(ourFields, ourMethods);
initFieldEventHandlers(ourFields, ourMethods);
initTypeEventHandlers(ourFields, ourMethods);
}
// VB initializes the handlers in the property setter, where it first removes the handler
// from the previous control, and then adds the handler to the new control.
void initVbEventHandlers(Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef> ourFields, Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef> ourMethods) {
var checker = type.Module.ObfuscatedFile.NameChecker;
foreach (var propDef in type.AllProperties) {
var setter = propDef.PropertyDefinition.SetMethod;
if (setter == null)
continue;
var setterDef = type.find(setter);
if (setterDef == null)
continue;
string eventName;
var handler = getVbHandler(setterDef.MethodDefinition, out eventName);
if (handler == null)
continue;
MethodDef handlerDef;
if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(handler), out handlerDef))
continue;
if (!checker.isValidEventName(eventName))
continue;
memberInfos.method(handlerDef).suggestedName = string.Format("{0}_{1}", newName, eventName);
}
}
static MethodReference getVbHandler(MethodDefinition method, out string eventName) {
eventName = null;
if (method.Body == null)
return null;
if (method.MethodReturnType.ReturnType.FullName != "System.Void")
return null;
if (method.Parameters.Count != 1)
return null;
if (method.Body.Variables.Count != 1)
return null;
if (!isEventHandlerType(method.Body.Variables[0].VariableType))
return null;
var instructions = method.Body.Instructions;
int index = 0;
int newobjIndex = findInstruction(instructions, index, Code.Newobj);
if (newobjIndex == -1 || findInstruction(instructions, newobjIndex + 1, Code.Newobj) != -1)
return null;
if (!isEventHandlerCtor(instructions[newobjIndex].Operand as MethodReference))
return null;
if (newobjIndex < 1)
return null;
var ldvirtftn = instructions[newobjIndex - 1];
if (ldvirtftn.OpCode.Code != Code.Ldvirtftn && ldvirtftn.OpCode.Code != Code.Ldftn)
return null;
var handlerMethod = ldvirtftn.Operand as MethodReference;
if (handlerMethod == null)
return null;
if (!MemberReferenceHelper.compareTypes(method.DeclaringType, handlerMethod.DeclaringType))
return null;
index = newobjIndex;
FieldReference addField, removeField;
MethodReference addMethod, removeMethod;
if (!findEventCall(instructions, ref index, out removeField, out removeMethod))
return null;
if (!findEventCall(instructions, ref index, out addField, out addMethod))
return null;
if (findInstruction(instructions, index, Code.Callvirt) != -1)
return null;
if (!MemberReferenceHelper.compareFieldReference(addField, removeField))
return null;
if (!MemberReferenceHelper.compareTypes(method.DeclaringType, addField.DeclaringType))
return null;
if (!MemberReferenceHelper.compareTypes(addMethod.DeclaringType, removeMethod.DeclaringType))
return null;
if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal))
return null;
if (!Utils.StartsWith(removeMethod.Name, "remove_", StringComparison.Ordinal))
return null;
eventName = addMethod.Name.Substring(4);
if (eventName != removeMethod.Name.Substring(7))
return null;
if (eventName == "")
return null;
return handlerMethod;
}
static bool findEventCall(IList<Instruction> instructions, ref int index, out FieldReference field, out MethodReference calledMethod) {
field = null;
calledMethod = null;
int callvirt = findInstruction(instructions, index, Code.Callvirt);
if (callvirt < 2)
return false;
index = callvirt + 1;
var ldloc = instructions[callvirt - 1];
if (ldloc.OpCode.Code != Code.Ldloc_0)
return false;
var ldfld = instructions[callvirt - 2];
if (ldfld.OpCode.Code != Code.Ldfld)
return false;
field = ldfld.Operand as FieldReference;
calledMethod = instructions[callvirt].Operand as MethodReference;
return field != null && calledMethod != null;
}
static int findInstruction(IList<Instruction> instructions, int index, Code code) {
for (int i = index; i < instructions.Count; i++) {
if (instructions[i].OpCode.Code == code)
return i;
}
return -1;
}
void initFieldEventHandlers(Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef> ourFields, Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef> ourMethods) {
var checker = type.Module.ObfuscatedFile.NameChecker;
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDefinition.Body == null)
continue;
if (methodDef.MethodDefinition.IsStatic)
continue;
var instructions = methodDef.MethodDefinition.Body.Instructions;
for (int i = 0; i < instructions.Count - 6; i++) {
// We're looking for this code pattern:
// ldarg.0
// ldfld field
// ldarg.0
// ldftn method / ldarg.0 + ldvirtftn
// newobj event_handler_ctor
// callvirt add_SomeEvent
if (DotNetUtils.getArgIndex(methodDef.MethodDefinition, instructions[i]) != 0)
continue;
int index = i + 1;
var ldfld = instructions[index++];
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[index++]) != 0)
continue;
MethodReference methodRef;
var instr = instructions[index + 1];
if (instr.OpCode.Code == Code.Ldvirtftn) {
if (!isThisOrDup(methodDef.MethodDefinition, instructions[index++]))
continue;
var ldvirtftn = instructions[index++];
methodRef = ldvirtftn.Operand as MethodReference;
}
else {
var ldftn = instructions[index++];
if (ldftn.OpCode.Code != Code.Ldftn)
continue;
methodRef = ldftn.Operand as MethodReference;
}
if (methodRef == null)
continue;
MethodDef handlerMethod;
if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(methodRef), out handlerMethod))
continue;
var newobj = instructions[index++];
if (newobj.OpCode.Code != Code.Newobj)
continue;
if (!isEventHandlerCtor(newobj.Operand as MethodReference))
continue;
var call = instructions[index++];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
var addHandler = call.Operand as MethodReference;
if (addHandler == null)
continue;
if (!Utils.StartsWith(addHandler.Name, "add_", StringComparison.Ordinal))
continue;
var eventName = addHandler.Name.Substring(4);
if (!checker.isValidEventName(eventName))
continue;
memberInfos.method(handlerMethod).suggestedName = string.Format("{0}_{1}", newName, eventName);
}
}
}
void initTypeEventHandlers(Dictionary<FieldReferenceAndDeclaringTypeKey, FieldDef> ourFields, Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef> ourMethods) {
var checker = type.Module.ObfuscatedFile.NameChecker;
foreach (var methodDef in type.AllMethods) {
if (methodDef.MethodDefinition.Body == null)
continue;
if (methodDef.MethodDefinition.IsStatic)
continue;
var method = methodDef.MethodDefinition;
var instructions = method.Body.Instructions;
for (int i = 0; i < instructions.Count - 5; i++) {
// ldarg.0
// ldarg.0 / dup
// ldarg.0 / dup
// ldvirtftn handler
// newobj event handler ctor
// call add_Xyz
if (DotNetUtils.getArgIndex(method, instructions[i]) != 0)
continue;
int index = i + 1;
if (!isThisOrDup(method, instructions[index++]))
continue;
MethodReference handler;
if (instructions[index].OpCode.Code == Code.Ldftn) {
handler = instructions[index++].Operand as MethodReference;
}
else {
if (!isThisOrDup(method, instructions[index++]))
continue;
var instr = instructions[index++];
if (instr.OpCode.Code != Code.Ldvirtftn)
continue;
handler = instr.Operand as MethodReference;
}
if (handler == null)
continue;
MethodDef handlerDef;
if (!ourMethods.TryGetValue(new MethodReferenceAndDeclaringTypeKey(handler), out handlerDef))
continue;
var newobj = instructions[index++];
if (newobj.OpCode.Code != Code.Newobj)
continue;
if (!isEventHandlerCtor(newobj.Operand as MethodReference))
continue;
var call = instructions[index++];
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
continue;
var addMethod = call.Operand as MethodReference;
if (addMethod == null)
continue;
if (!Utils.StartsWith(addMethod.Name, "add_", StringComparison.Ordinal))
continue;
var eventName = addMethod.Name.Substring(4);
if (!checker.isValidEventName(eventName))
continue;
memberInfos.method(handlerDef).suggestedName = string.Format("{0}_{1}", newName, eventName);
}
}
}
static bool isThisOrDup(MethodReference method, Instruction instr) {
return DotNetUtils.getArgIndex(method, instr) == 0 || instr.OpCode.Code == Code.Dup;
}
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 (!isEventHandlerType(method.DeclaringType))
return false;
return true;
}
static bool isEventHandlerType(TypeReference type) {
return type.FullName.EndsWith("EventHandler", StringComparison.Ordinal);
}
static MethodReference getOverrideMethod(MethodDefinition meth) {
if (meth == null || !meth.HasOverrides)
return null;
return meth.Overrides[0];
}
string findWindowsFormsClassName(TypeDef type) {
foreach (var methodDef in type.AllMethods) {
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.AllMethods) {
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;
memberInfos.method(possibleInitMethod).suggestedName = "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 (!Utils.StartsWith(method.DeclaringType.FullName, "System.Windows.Forms.", StringComparison.Ordinal))
return false;
return true;
}
}
}

View File

@ -0,0 +1,123 @@
/*
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 Mono.Cecil;
namespace de4dot.renamer {
abstract class TypeNames {
protected IDictionary<string, INameCreator> typeNames = new Dictionary<string, INameCreator>(StringComparer.Ordinal);
protected INameCreator genericParamNameCreator = new NameCreator("gparam_");
public TypeNames() {
addTypeName("System.Boolean", "bool");
addTypeName("System.Byte", "byte");
addTypeName("System.Char", "char");
addTypeName("System.Double", "double");
addTypeName("System.Int16", "short");
addTypeName("System.Int32", "int");
addTypeName("System.Int64", "long");
addTypeName("System.IntPtr", "intptr");
addTypeName("System.SByte", "sbyte");
addTypeName("System.Single", "float");
addTypeName("System.String", "string");
addTypeName("System.UInt16", "ushort");
addTypeName("System.UInt32", "uint");
addTypeName("System.UInt64", "ulong");
addTypeName("System.UIntPtr", "uintptr");
addTypeName("System.Decimal", "decimal");
}
public string create(TypeReference typeRef) {
var elementType = typeRef.GetElementType();
if (elementType is GenericParameter)
return genericParamNameCreator.create();
var name = elementType.FullName;
INameCreator nc;
if (typeNames.TryGetValue(name, out nc))
return nc.create();
var parts = name.Replace('/', '.').Split(new char[] { '.' });
var newName = parts[parts.Length - 1];
int tickIndex = newName.LastIndexOf('`');
if (tickIndex > 0)
newName = newName.Substring(0, tickIndex);
return addTypeName(name, newName).create();
}
INameCreator addTypeName(string fullName, string newName) {
newName = fixName(newName);
var name2 = " " + newName;
INameCreator nc;
if (!typeNames.TryGetValue(name2, out nc))
typeNames[name2] = nc = new NameCreator(newName + "_");
typeNames[fullName] = nc;
return nc;
}
protected abstract string fixName(string name);
public abstract TypeNames clone();
protected IDictionary<string, INameCreator> cloneDict() {
var rv = new Dictionary<string, INameCreator>(StringComparer.Ordinal);
foreach (var key in typeNames.Keys)
rv[key] = typeNames[key].clone();
return rv;
}
}
class VariableNameCreator : TypeNames {
protected override string fixName(string name) {
// Make all leading upper case chars lower case
var s = "";
for (int i = 0; i < name.Length; i++) {
char c = char.ToLowerInvariant(name[i]);
if (c == name[i])
return s + name.Substring(i);
s += c;
}
return s;
}
public override TypeNames clone() {
var rv = new VariableNameCreator();
rv.typeNames = cloneDict();
rv.genericParamNameCreator = genericParamNameCreator.clone();
return rv;
}
}
class PropertyNameCreator : TypeNames {
protected override string fixName(string name) {
return name.Substring(0, 1).ToUpperInvariant() + name.Substring(1);
}
public override TypeNames clone() {
var rv = new PropertyNameCreator();
rv.typeNames = cloneDict();
rv.genericParamNameCreator = genericParamNameCreator.clone();
return rv;
}
}
}

View 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 Mono.Cecil;
namespace de4dot.renamer {
class VariableNameState {
ExistingNames existingVariableNames = new ExistingNames();
TypeNames variableNameCreator = new VariableNameCreator(); // For fields and method args
public virtual VariableNameState clone() {
var rv = new VariableNameState();
cloneInit(rv);
return rv;
}
void cloneInit(VariableNameState variableNameState) {
variableNameState.existingVariableNames = new ExistingNames();
variableNameState.variableNameCreator = variableNameCreator.clone();
}
public void addFieldName(string fieldName) {
existingVariableNames.add(fieldName);
}
public string getNewFieldName(FieldDefinition field) {
return existingVariableNames.getName(field.Name, () => variableNameCreator.create(field.FieldType));
}
public string getNewFieldName(string oldName, INameCreator nameCreator) {
return existingVariableNames.getName(oldName, () => nameCreator.create());
}
}
}

View File

@ -23,6 +23,18 @@ using Mono.Cecil;
namespace de4dot.renamer.asmmodules {
class MethodDef : Ref {
IList<GenericParamDef> genericParams;
IList<ParamDef> paramDefs = new List<ParamDef>();
public PropertyDef Property { get; set; }
public EventDef Event { get; set; }
public IList<ParamDef> ParamDefs {
get { return paramDefs; }
}
public IList<GenericParamDef> GenericParams {
get { return genericParams; }
}
public MethodDefinition MethodDefinition {
get { return (MethodDefinition)memberReference; }
@ -31,6 +43,10 @@ namespace de4dot.renamer.asmmodules {
public MethodDef(MethodDefinition methodDefinition, TypeDef owner, int index)
: base(methodDefinition, owner, index) {
genericParams = GenericParamDef.createGenericParamDefList(MethodDefinition.GenericParameters);
for (int i = 0; i < methodDefinition.Parameters.Count; i++) {
var param = methodDefinition.Parameters[i];
paramDefs.Add(new ParamDef(param, i));
}
}
public bool isPublic() {
@ -44,5 +60,9 @@ namespace de4dot.renamer.asmmodules {
public bool isNewSlot() {
return MethodDefinition.IsNewSlot;
}
public bool isStatic() {
return MethodDefinition.IsStatic;
}
}
}

View File

@ -41,6 +41,10 @@ namespace de4dot.renamer.asmmodules {
return;
methods.AddRange(other.methods);
}
public override string ToString() {
return string.Format("{0} -- {1}", methods.Count, methods.Count > 0 ? methods[0].ToString() : "");
}
}
class MethodNameScopes {
@ -78,5 +82,9 @@ namespace de4dot.renamer.asmmodules {
foreach (var methodDef in b.Methods)
methodScopes[methodDef] = a;
}
public IEnumerable<MethodNameScope> getAllScopes() {
return Utils.unique(methodScopes.Values);
}
}
}

View File

@ -31,7 +31,7 @@ namespace de4dot.renamer.asmmodules {
IList<RefToDef<MethodReference, MethodDefinition>> methodRefsToRename = new List<RefToDef<MethodReference, MethodDefinition>>();
IList<RefToDef<FieldReference, FieldDefinition>> fieldRefsToRename = new List<RefToDef<FieldReference, FieldDefinition>>();
class RefToDef<R, D> where R : MemberReference where D : R {
public class RefToDef<R, D> where R : MemberReference where D : R {
public R reference;
public D definition;
public RefToDef(R reference, D definition) {
@ -40,6 +40,18 @@ namespace de4dot.renamer.asmmodules {
}
}
public IEnumerable<RefToDef<TypeReference, TypeDefinition>> TypeRefsToRename {
get { return typeRefsToRename; }
}
public IEnumerable<RefToDef<MethodReference, MethodDefinition>> MethodRefsToRename {
get { return methodRefsToRename; }
}
public IEnumerable<RefToDef<FieldReference, FieldDefinition>> FieldRefsToRename {
get { return fieldRefsToRename; }
}
public IObfuscatedFile ObfuscatedFile {
get { return obfuscatedFile; }
}
@ -111,6 +123,15 @@ namespace de4dot.renamer.asmmodules {
}
}
public void onTypesRenamed() {
var newTypes = new TypeDefDict();
foreach (var typeDef in types.getAll()) {
typeDef.onTypesRenamed();
newTypes.add(typeDef);
}
types = newTypes;
}
static TypeReference getNonGenericTypeReference(TypeReference typeReference) {
if (typeReference == null)
return null;

View File

@ -33,6 +33,10 @@ namespace de4dot.renamer.asmmodules {
List<TypeDef> baseTypes = new List<TypeDef>();
List<TypeDef> nonNestedTypes;
public IList<Module> TheModules {
get { return modules; }
}
public IEnumerable<TypeDef> AllTypes {
get { return allTypes; }
}
@ -258,6 +262,11 @@ namespace de4dot.renamer.asmmodules {
typeDef.initializeVirtualMembers(scopes, this);
}
public void onTypesRenamed() {
foreach (var module in modules)
module.onTypesRenamed();
}
public void cleanUp() {
externalAssemblies.unloadAll();
foreach (var module in DotNetUtils.typeCaches.invalidateAll())

View File

@ -0,0 +1,32 @@
/*
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 Mono.Cecil;
namespace de4dot.renamer.asmmodules {
class ParamDef {
public ParameterDefinition ParameterDefinition { get; set; }
public int Index { get; private set; }
public ParamDef(ParameterDefinition parameterDefinition, int index) {
this.ParameterDefinition = parameterDefinition;
Index = index;
}
}
}

View File

@ -114,7 +114,7 @@ namespace de4dot.renamer.asmmodules {
public InterfaceMethodInfo(TypeInfo iface) {
this.iface = iface;
foreach (var methodDef in iface.typeDef.getAllMethods())
foreach (var methodDef in iface.typeDef.AllMethods)
ifaceMethodToClassMethod[methodDef] = null;
}
@ -237,6 +237,38 @@ namespace de4dot.renamer.asmmodules {
get { return (TypeDefinition)memberReference; }
}
public IEnumerable<EventDef> AllEvents {
get { return events.getAll(); }
}
public IEnumerable<FieldDef> AllFields {
get { return fields.getAll(); }
}
public IEnumerable<MethodDef> AllMethods {
get { return methods.getAll(); }
}
public IEnumerable<PropertyDef> AllProperties {
get { return properties.getAll(); }
}
public IEnumerable<EventDef> AllEventsSorted {
get { return events.getSorted(); }
}
public IEnumerable<FieldDef> AllFieldsSorted {
get { return fields.getSorted(); }
}
public IEnumerable<MethodDef> AllMethodsSorted {
get { return methods.getSorted(); }
}
public IEnumerable<PropertyDef> AllPropertiesSorted {
get { return properties.getSorted(); }
}
public TypeDef(TypeDefinition typeDefinition, Module module, int index)
: base(typeDefinition, null, index) {
this.module = module;
@ -283,10 +315,6 @@ namespace de4dot.renamer.asmmodules {
return fields.find(fr);
}
public IEnumerable<MethodDef> getAllMethods() {
return methods.getAll();
}
public void addMembers() {
var type = TypeDefinition;
@ -298,6 +326,31 @@ namespace de4dot.renamer.asmmodules {
add(new MethodDef(type.Methods[i], this, i));
for (int i = 0; i < type.Properties.Count; i++)
add(new PropertyDef(type.Properties[i], this, i));
foreach (var propDef in properties.getAll()) {
foreach (var method in propDef.methodDefinitions()) {
var methodDef = find(method);
if (methodDef == null)
throw new ApplicationException("Could not find property method");
methodDef.Property = propDef;
}
}
foreach (var eventDef in events.getAll()) {
foreach (var method in eventDef.methodDefinitions()) {
var methodDef = find(method);
if (methodDef == null)
throw new ApplicationException("Could not find event method");
methodDef.Event = eventDef;
}
}
}
public void onTypesRenamed() {
events.onTypesRenamed();
fields.onTypesRenamed();
methods.onTypesRenamed();
types.onTypesRenamed();
}
public bool isNested() {
@ -361,7 +414,13 @@ namespace de4dot.renamer.asmmodules {
}
}
Dictionary<MethodDef, bool> overrideMethods;
void initializeInterfaceMethods(MethodNameScopes scopes) {
if (baseType != null)
overrideMethods = new Dictionary<MethodDef, bool>(baseType.typeDef.overrideMethods);
else
overrideMethods = new Dictionary<MethodDef, bool>();
initializeAllInterfaces();
if (TypeDefinition.IsInterface)
@ -448,7 +507,6 @@ namespace de4dot.renamer.asmmodules {
//--- inherited or chosen by name matching.
methodsDict.Clear();
var ifaceMethodsDict = new Dictionary<MethodReferenceAndDeclaringTypeKey, MethodDef>();
var overrideMethods = new Dictionary<MethodDef, bool>();
foreach (var ifaceInfo in allImplementedInterfaces.Keys) {
var git = ifaceInfo.typeReference as GenericInstanceType;
foreach (var ifaceMethod in ifaceInfo.typeDef.methods.getAll()) {