2012-01-08 03:27:07 +08:00
|
|
|
|
/*
|
2012-01-10 06:04:52 +08:00
|
|
|
|
Copyright (C) 2011-2012 de4dot@gmail.com
|
2012-01-08 03:27:07 +08:00
|
|
|
|
|
|
|
|
|
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 Mono.Cecil;
|
|
|
|
|
using de4dot.blocks;
|
|
|
|
|
|
|
|
|
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
|
|
|
|
class TypeReferenceConverter : TypeReferenceUpdaterBase {
|
|
|
|
|
MemberReferenceConverter memberReferenceConverter;
|
|
|
|
|
|
|
|
|
|
ModuleDefinition Module {
|
|
|
|
|
get { return memberReferenceConverter.Module; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TypeReferenceConverter(MemberReferenceConverter memberReferenceConverter) {
|
|
|
|
|
this.memberReferenceConverter = memberReferenceConverter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TypeReference convert(TypeReference a) {
|
|
|
|
|
var newOne = update(a);
|
|
|
|
|
if (!(a is GenericParameter) && !MemberReferenceHelper.compareTypes(newOne, a))
|
|
|
|
|
throw new ApplicationException("Could not convert type reference");
|
|
|
|
|
return newOne;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override TypeReference updateTypeReference(TypeReference a) {
|
|
|
|
|
if (a.Module == Module)
|
|
|
|
|
return a;
|
|
|
|
|
|
|
|
|
|
var newTypeRef = new TypeReference(a.Namespace, a.Name, Module, memberReferenceConverter.convert(a.Scope), a.IsValueType);
|
|
|
|
|
foreach (var gp in a.GenericParameters)
|
|
|
|
|
newTypeRef.GenericParameters.Add(new GenericParameter(gp.Name, newTypeRef));
|
|
|
|
|
newTypeRef.DeclaringType = update(a.DeclaringType);
|
|
|
|
|
newTypeRef.UpdateElementType();
|
|
|
|
|
return newTypeRef;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Converts type references/definitions in one module to this module
|
|
|
|
|
class MemberReferenceConverter {
|
|
|
|
|
ModuleDefinition module;
|
|
|
|
|
|
|
|
|
|
public ModuleDefinition Module {
|
|
|
|
|
get { return module; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MemberReferenceConverter(ModuleDefinition module) {
|
|
|
|
|
this.module = module;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isInOurModule(MemberReference memberRef) {
|
|
|
|
|
return memberRef.Module == module;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TypeReference convert(TypeReference typeRef) {
|
|
|
|
|
if (typeRef == null)
|
|
|
|
|
return null;
|
|
|
|
|
typeRef = new TypeReferenceConverter(this).convert(typeRef);
|
|
|
|
|
return tryGetTypeDefinition(typeRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FieldReference convert(FieldReference fieldRef) {
|
|
|
|
|
if (isInOurModule(fieldRef))
|
|
|
|
|
return tryGetFieldDefinition(fieldRef);
|
|
|
|
|
|
|
|
|
|
return new FieldReference(fieldRef.Name, convert(fieldRef.FieldType), convert(fieldRef.DeclaringType));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MethodReference convert(MethodReference methodRef) {
|
|
|
|
|
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDefinition))
|
|
|
|
|
throw new ApplicationException("Invalid method reference type");
|
|
|
|
|
if (isInOurModule(methodRef))
|
|
|
|
|
return tryGetMethodDefinition(methodRef);
|
|
|
|
|
|
|
|
|
|
return copy(methodRef);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MethodReference copy(MethodReference methodRef) {
|
|
|
|
|
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDefinition))
|
|
|
|
|
throw new ApplicationException("Invalid method reference type");
|
|
|
|
|
|
|
|
|
|
var newMethodRef = new MethodReference(methodRef.Name, convert(methodRef.MethodReturnType.ReturnType), convert(methodRef.DeclaringType));
|
|
|
|
|
newMethodRef.HasThis = methodRef.HasThis;
|
|
|
|
|
newMethodRef.ExplicitThis = methodRef.ExplicitThis;
|
|
|
|
|
newMethodRef.CallingConvention = methodRef.CallingConvention;
|
|
|
|
|
foreach (var param in methodRef.Parameters)
|
|
|
|
|
newMethodRef.Parameters.Add(new ParameterDefinition(param.Name, param.Attributes, convert(param.ParameterType)));
|
|
|
|
|
foreach (var gp in methodRef.GenericParameters)
|
|
|
|
|
newMethodRef.GenericParameters.Add(new GenericParameter(gp.Name, newMethodRef));
|
|
|
|
|
return newMethodRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public IMetadataScope convert(IMetadataScope scope) {
|
|
|
|
|
switch (scope.MetadataScopeType) {
|
|
|
|
|
case MetadataScopeType.AssemblyNameReference:
|
|
|
|
|
return convert((AssemblyNameReference)scope);
|
|
|
|
|
|
|
|
|
|
case MetadataScopeType.ModuleDefinition:
|
|
|
|
|
var mod = (ModuleDefinition)scope;
|
|
|
|
|
if (mod.Assembly != null)
|
|
|
|
|
return convert((AssemblyNameReference)mod.Assembly.Name);
|
|
|
|
|
return convert((ModuleReference)scope);
|
|
|
|
|
|
|
|
|
|
case MetadataScopeType.ModuleReference:
|
|
|
|
|
return convert((ModuleReference)scope);
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
throw new ApplicationException("Unknown MetadataScopeType");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AssemblyNameReference convert(AssemblyNameReference asmRef) {
|
|
|
|
|
foreach (var modAsmRef in module.AssemblyReferences) {
|
|
|
|
|
if (modAsmRef.FullName == asmRef.FullName)
|
|
|
|
|
return modAsmRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var newAsmRef = AssemblyNameReference.Parse(asmRef.FullName);
|
|
|
|
|
module.AssemblyReferences.Add(newAsmRef);
|
|
|
|
|
return newAsmRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ModuleReference convert(ModuleReference modRef) {
|
|
|
|
|
foreach (var modModRef in module.ModuleReferences) {
|
|
|
|
|
if (modModRef.Name == modRef.Name)
|
|
|
|
|
return modModRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var newModRef = new ModuleReference(modRef.Name);
|
|
|
|
|
module.ModuleReferences.Add(newModRef);
|
|
|
|
|
return newModRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public TypeReference tryGetTypeDefinition(TypeReference typeRef) {
|
|
|
|
|
return DotNetUtils.getType(module, typeRef) ?? typeRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FieldReference tryGetFieldDefinition(FieldReference fieldRef) {
|
|
|
|
|
var fieldDef = fieldRef as FieldDefinition;
|
|
|
|
|
if (fieldDef != null)
|
|
|
|
|
return fieldDef;
|
|
|
|
|
|
|
|
|
|
var declaringType = DotNetUtils.getType(module, fieldRef.DeclaringType);
|
|
|
|
|
if (declaringType == null)
|
|
|
|
|
return fieldRef;
|
2012-01-14 18:53:38 +08:00
|
|
|
|
return DotNetUtils.getField(declaringType, fieldRef);
|
2012-01-08 03:27:07 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MethodReference tryGetMethodDefinition(MethodReference methodRef) {
|
|
|
|
|
var methodDef = methodRef as MethodDefinition;
|
|
|
|
|
if (methodDef != null)
|
|
|
|
|
return methodDef;
|
|
|
|
|
|
|
|
|
|
var declaringType = DotNetUtils.getType(module, methodRef.DeclaringType);
|
|
|
|
|
if (declaringType == null)
|
|
|
|
|
return methodRef;
|
2012-01-14 18:53:38 +08:00
|
|
|
|
return DotNetUtils.getMethod(declaringType, methodRef);
|
2012-01-08 03:27:07 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|