Add option to remove namespace if there's only one class in it
This commit is contained in:
parent
ff0c0cddbd
commit
c562c335e8
|
@ -30,6 +30,7 @@ namespace de4dot {
|
|||
Func<string, bool> IsValidName { get; }
|
||||
bool RenameResourcesInCode { get; }
|
||||
bool RenameSymbols { get; }
|
||||
bool RemoveNamespaceWithOneType { get; }
|
||||
|
||||
void deobfuscateBegin();
|
||||
void deobfuscate();
|
||||
|
|
|
@ -118,6 +118,10 @@ namespace de4dot {
|
|||
get { return options.RenameSymbols; }
|
||||
}
|
||||
|
||||
public bool RemoveNamespaceWithOneType {
|
||||
get { return (deob.RenamingOptions & RenamingOptions.RemoveNamespaceIfOneType) != 0; }
|
||||
}
|
||||
|
||||
public IDeobfuscator Deobfuscator {
|
||||
get { return deob; }
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace de4dot.deobfuscators {
|
|||
public IOperations Operations { get; set; }
|
||||
public IDeobfuscatedFile DeobfuscatedFile { get; set; }
|
||||
public virtual StringFeatures StringFeatures { get; set; }
|
||||
public virtual RenamingOptions RenamingOptions { get; set; }
|
||||
public DecrypterType DefaultDecrypterType { get; set; }
|
||||
|
||||
public abstract string Type { get; }
|
||||
|
|
|
@ -44,6 +44,11 @@ namespace de4dot.deobfuscators {
|
|||
AllowAll = AllowNoDecryption | AllowStaticDecryption | AllowDynamicDecryption,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum RenamingOptions {
|
||||
RemoveNamespaceIfOneType = 1,
|
||||
}
|
||||
|
||||
interface IDeobfuscator {
|
||||
string Type { get; }
|
||||
string Name { get; }
|
||||
|
@ -51,6 +56,7 @@ namespace de4dot.deobfuscators {
|
|||
IDeobfuscatorOptions TheOptions { get; }
|
||||
IOperations Operations { get; set; }
|
||||
StringFeatures StringFeatures { get; }
|
||||
RenamingOptions RenamingOptions { get; }
|
||||
DecrypterType DefaultDecrypterType { get; }
|
||||
|
||||
// This is non-null only in detect() and deobfuscateBegin().
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Mono.Cecil;
|
||||
using Mono.Cecil.Cil;
|
||||
|
@ -34,6 +35,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
|||
BoolOption removeInlinedMethods;
|
||||
BoolOption dumpEmbeddedAssemblies;
|
||||
BoolOption decryptResources;
|
||||
BoolOption removeNamespaces;
|
||||
|
||||
public DeobfuscatorInfo()
|
||||
: base(DEFAULT_REGEX) {
|
||||
|
@ -44,6 +46,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
|||
removeInlinedMethods = new BoolOption(null, makeArgName("remove-inlined"), "Remove inlined methods", true);
|
||||
dumpEmbeddedAssemblies = new BoolOption(null, makeArgName("embedded"), "Dump embedded assemblies", true);
|
||||
decryptResources = new BoolOption(null, makeArgName("rsrc"), "Decrypt resources", true);
|
||||
removeNamespaces = new BoolOption(null, makeArgName("ns1"), "Clear namespace if there's only one class in it", true);
|
||||
}
|
||||
|
||||
public override string Name {
|
||||
|
@ -64,6 +67,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
|||
RemoveInlinedMethods = removeInlinedMethods.get(),
|
||||
DumpEmbeddedAssemblies = dumpEmbeddedAssemblies.get(),
|
||||
DecryptResources = decryptResources.get(),
|
||||
RemoveNamespaces = removeNamespaces.get(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -76,6 +80,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
|||
removeInlinedMethods,
|
||||
dumpEmbeddedAssemblies,
|
||||
decryptResources,
|
||||
removeNamespaces,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +110,7 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
|||
public bool RemoveInlinedMethods { get; set; }
|
||||
public bool DumpEmbeddedAssemblies { get; set; }
|
||||
public bool DecryptResources { get; set; }
|
||||
public bool RemoveNamespaces { get; set; }
|
||||
}
|
||||
|
||||
public override string Type {
|
||||
|
@ -122,6 +128,11 @@ namespace de4dot.deobfuscators.dotNET_Reactor {
|
|||
public Deobfuscator(Options options)
|
||||
: base(options) {
|
||||
this.options = options;
|
||||
|
||||
if (options.RemoveNamespaces)
|
||||
this.RenamingOptions |= RenamingOptions.RemoveNamespaceIfOneType;
|
||||
else
|
||||
this.RenamingOptions &= ~RenamingOptions.RemoveNamespaceIfOneType;
|
||||
}
|
||||
|
||||
public override void init(ModuleDefinition module) {
|
||||
|
|
|
@ -210,6 +210,10 @@ namespace de4dot.renamer {
|
|||
|
||||
void renameTypeDefinitions() {
|
||||
Log.v("Renaming obfuscated type definitions");
|
||||
|
||||
foreach (var module in modules)
|
||||
module.onBeforeRenamingTypeDefinitions();
|
||||
|
||||
typeNameState = new TypeNameState();
|
||||
foreach (var typeDef in allTypes)
|
||||
typeNameState.currentNames.add(typeDef.OldName);
|
||||
|
|
|
@ -421,6 +421,11 @@ namespace de4dot.renamer {
|
|||
|
||||
bool IsDelegate { get; set; }
|
||||
|
||||
public string NewNamespace {
|
||||
get { return newNamespace; }
|
||||
set { newNamespace = value; }
|
||||
}
|
||||
|
||||
public TypeDef(TypeDefinition typeDefinition)
|
||||
: this(typeDefinition, null) {
|
||||
}
|
||||
|
@ -607,7 +612,7 @@ namespace de4dot.renamer {
|
|||
rename(nameCreator.newName(typeDefinition, newBaseType));
|
||||
}
|
||||
|
||||
if (typeDefinition.Namespace != "" && !typeNameState.isValidNamespace(typeDefinition.Namespace))
|
||||
if (newNamespace == null && typeDefinition.Namespace != "" && !typeNameState.isValidNamespace(typeDefinition.Namespace))
|
||||
newNamespace = typeNameState.newNamespace(typeDefinition.Namespace);
|
||||
|
||||
prepareRenameGenericParams(genericParams, typeNameState.IsValidName);
|
||||
|
|
|
@ -77,6 +77,37 @@ namespace de4dot.renamer {
|
|||
}
|
||||
}
|
||||
|
||||
public void onBeforeRenamingTypeDefinitions() {
|
||||
if (obfuscatedFile.RemoveNamespaceWithOneType)
|
||||
removeOneClassNamespaces();
|
||||
}
|
||||
|
||||
void removeOneClassNamespaces() {
|
||||
var nsToTypes = new Dictionary<string, List<TypeDef>>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var typeDef in allTypes.getAll()) {
|
||||
List<TypeDef> list;
|
||||
var ns = typeDef.TypeDefinition.Namespace;
|
||||
if (string.IsNullOrEmpty(ns))
|
||||
continue;
|
||||
if (IsValidName(ns))
|
||||
continue;
|
||||
if (!nsToTypes.TryGetValue(ns, out list))
|
||||
nsToTypes[ns] = list = new List<TypeDef>();
|
||||
list.Add(typeDef);
|
||||
}
|
||||
|
||||
foreach (var list in nsToTypes.Values) {
|
||||
const int maxClasses = 1;
|
||||
if (list.Count != maxClasses)
|
||||
continue;
|
||||
var ns = list[0].TypeDefinition.Namespace;
|
||||
Log.v("Removing namespace: {0}", ns);
|
||||
foreach (var type in list)
|
||||
type.NewNamespace = "";
|
||||
}
|
||||
}
|
||||
|
||||
static string renameResourceString(string s, string oldTypeName, string newTypeName) {
|
||||
if (!Utils.StartsWith(s, oldTypeName, StringComparison.Ordinal))
|
||||
return s;
|
||||
|
|
Loading…
Reference in New Issue
Block a user