2012-04-29 06:01:50 +08:00
|
|
|
|
/*
|
|
|
|
|
Copyright (C) 2011-2012 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;
|
2012-11-01 21:39:39 +08:00
|
|
|
|
using dot10.DotNet;
|
|
|
|
|
using dot10.DotNet.MD;
|
2012-04-29 06:01:50 +08:00
|
|
|
|
using de4dot.blocks;
|
|
|
|
|
|
|
|
|
|
namespace de4dot.code.deobfuscators {
|
2012-11-02 04:09:09 +08:00
|
|
|
|
class MemberReferenceBuilder {
|
2012-11-01 21:39:39 +08:00
|
|
|
|
ModuleDefMD module;
|
|
|
|
|
Dictionary<TypeSig, TypeSig> createdTypes = new Dictionary<TypeSig, TypeSig>(TypeEqualityComparer.Instance);
|
2012-04-29 06:01:50 +08:00
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public MemberReferenceBuilder(ModuleDefMD module) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
this.module = module;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public AssemblyRef CorLib {
|
|
|
|
|
get { return module.CorLibTypes.AssemblyRef; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Object {
|
|
|
|
|
get { return module.CorLibTypes.Object; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Void {
|
|
|
|
|
get { return module.CorLibTypes.Void; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Boolean {
|
|
|
|
|
get { return module.CorLibTypes.Boolean; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Char {
|
|
|
|
|
get { return module.CorLibTypes.Char; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig SByte {
|
|
|
|
|
get { return module.CorLibTypes.SByte; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Byte {
|
|
|
|
|
get { return module.CorLibTypes.Byte; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Int16 {
|
|
|
|
|
get { return module.CorLibTypes.Int16; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig UInt16 {
|
|
|
|
|
get { return module.CorLibTypes.UInt16; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Int32 {
|
|
|
|
|
get { return module.CorLibTypes.Int32; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig UInt32 {
|
|
|
|
|
get { return module.CorLibTypes.UInt32; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Int64 {
|
|
|
|
|
get { return module.CorLibTypes.Int64; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig UInt64 {
|
|
|
|
|
get { return module.CorLibTypes.UInt64; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Single {
|
|
|
|
|
get { return module.CorLibTypes.Single; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig Double {
|
|
|
|
|
get { return module.CorLibTypes.Double; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig IntPtr {
|
|
|
|
|
get { return module.CorLibTypes.IntPtr; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig UIntPtr {
|
|
|
|
|
get { return module.CorLibTypes.UIntPtr; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig String {
|
|
|
|
|
get { return module.CorLibTypes.String; }
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public CorLibTypeSig TypedReference {
|
|
|
|
|
get { return module.CorLibTypes.TypedReference; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ClassSig type(string ns, string name, string asmSimpleName) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return type(ns, name, findAssemblyReference(asmSimpleName));
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ClassSig type(string ns, string name) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return type(ns, name, CorLib);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ClassSig type(string ns, string name, AssemblyRef asmRef) {
|
|
|
|
|
return (ClassSig)type(false, ns, name, asmRef);
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ValueTypeSig valueType(string ns, string name, string asmSimpleName) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return valueType(ns, name, findAssemblyReference(asmSimpleName));
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ValueTypeSig valueType(string ns, string name) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return valueType(ns, name, CorLib);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ValueTypeSig valueType(string ns, string name, AssemblyRef asmRef) {
|
|
|
|
|
return (ValueTypeSig)type(true, ns, name, asmRef);
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ClassOrValueTypeSig type(bool isValueType, string ns, string name, IResolutionScope resolutionScope) {
|
|
|
|
|
var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, resolutionScope));
|
|
|
|
|
ClassOrValueTypeSig type;
|
|
|
|
|
if (isValueType)
|
|
|
|
|
type = new ValueTypeSig(typeRef);
|
|
|
|
|
else
|
|
|
|
|
type = new ClassSig(typeRef);
|
|
|
|
|
return (ClassOrValueTypeSig)add(type);
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public ArraySig array(TypeSig typeRef) {
|
|
|
|
|
return (ArraySig)add(new ArraySig(typeRef));
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
TypeSig add(TypeSig typeRef) {
|
|
|
|
|
TypeSig createdTypeRef;
|
|
|
|
|
if (createdTypes.TryGetValue(typeRef, out createdTypeRef)) {
|
|
|
|
|
if (createdTypeRef.ElementType != typeRef.ElementType)
|
2012-04-29 06:01:50 +08:00
|
|
|
|
throw new ApplicationException(string.Format("Type {0}'s IsValueType is not correct", createdTypeRef));
|
|
|
|
|
return createdTypeRef;
|
|
|
|
|
}
|
2012-11-01 21:39:39 +08:00
|
|
|
|
createdTypes[typeRef] = typeRef;
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return typeRef;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public MemberRef instanceMethod(string name, IMemberRefParent declaringType, TypeSig returnType, params TypeSig[] args) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return method(true, name, declaringType, returnType, args);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public MemberRef staticMethod(string name, IMemberRefParent declaringType, TypeSig returnType, params TypeSig[] args) {
|
2012-04-29 06:01:50 +08:00
|
|
|
|
return method(false, name, declaringType, returnType, args);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
public MemberRef method(bool isInstance, string name, IMemberRefParent declaringType, TypeSig returnType, params TypeSig[] args) {
|
|
|
|
|
MethodSig sig;
|
|
|
|
|
if (isInstance)
|
|
|
|
|
sig = MethodSig.CreateInstance(returnType, args);
|
|
|
|
|
else
|
|
|
|
|
sig = MethodSig.CreateStatic(returnType, args);
|
|
|
|
|
return module.UpdateRowId(new MemberRefUser(module, name, sig, declaringType));
|
2012-04-29 06:01:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
AssemblyRef findAssemblyReference(string asmSimpleName) {
|
|
|
|
|
AssemblyRef asmRef = null;
|
2012-04-29 06:01:50 +08:00
|
|
|
|
foreach (var asmRef2 in findAssemblyReferences(asmSimpleName)) {
|
|
|
|
|
if (asmRef == null || asmRef.Version == null || (asmRef2.Version != null && asmRef2.Version > asmRef.Version))
|
|
|
|
|
asmRef = asmRef2;
|
|
|
|
|
}
|
|
|
|
|
if (asmRef == null)
|
|
|
|
|
throw new ApplicationException(string.Format("Could not find assembly {0} in assembly references", asmSimpleName));
|
|
|
|
|
return asmRef;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-01 21:39:39 +08:00
|
|
|
|
List<AssemblyRef> findAssemblyReferences(string asmSimpleName) {
|
|
|
|
|
var asmRefs = new List<AssemblyRef>();
|
|
|
|
|
var name = new UTF8String(asmSimpleName);
|
|
|
|
|
foreach (var asmRef in module.GetAssemblyRefs()) {
|
|
|
|
|
if (UTF8String.Equals(asmRef.Name, name))
|
2012-04-29 06:01:50 +08:00
|
|
|
|
asmRefs.Add(asmRef);
|
|
|
|
|
}
|
|
|
|
|
return asmRefs;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|