Port Babel.NET deobfuscator

This commit is contained in:
de4dot 2012-11-08 07:06:46 +01:00
parent ce6659510e
commit f699017197
19 changed files with 376 additions and 439 deletions

View File

@ -404,19 +404,17 @@ namespace de4dot.blocks {
return (FieldDefinition)field;
return getField(getType(module, field.DeclaringType), field);
}
#endif
public static FieldDefinition getField(TypeDefinition type, FieldReference fieldReference) {
public static FieldDef getField(TypeDef type, IField fieldReference) {
if (type == null || fieldReference == null)
return null;
if (fieldReference is FieldDefinition)
return (FieldDefinition)fieldReference;
foreach (var field in type.Fields) {
if (MemberReferenceHelper.compareFieldReference(field, fieldReference))
return field;
}
return null;
if (fieldReference is FieldDef)
return (FieldDef)fieldReference;
return type.FindField(fieldReference.Name, fieldReference.FieldSig);
}
#if PORT
public static FieldDefinition getField(TypeDefinition type, string typeFullName) {
if (type == null)
return null;
@ -778,7 +776,6 @@ namespace de4dot.blocks {
}
}
#if PORT
public static IList<Instruction> getInstructions(IList<Instruction> instructions, int i, params OpCode[] opcodes) {
if (i + opcodes.Length > instructions.Count)
return null;
@ -797,6 +794,7 @@ namespace de4dot.blocks {
return list;
}
#if PORT
public static bool hasReturnValue(IMethodSignature method) {
var type = method.MethodReturnType.ReturnType;
while (type.IsOptionalModifier || type.IsRequiredModifier)

View File

@ -76,22 +76,22 @@
<Compile Include="deobfuscators\Agile_NET\vm\UnknownHandlerInfo.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\VmOpCodeHandlerDetector.cs" />
<Compile Include="deobfuscators\Agile_NET\vm\VmOperands.cs" />
<None Include="deobfuscators\Babel_NET\AssemblyResolver.cs" />
<None Include="deobfuscators\Babel_NET\BabelInflater.cs" />
<None Include="deobfuscators\Babel_NET\BabelMethodCallInliner.cs" />
<None Include="deobfuscators\Babel_NET\BabelUtils.cs" />
<None Include="deobfuscators\Babel_NET\ConstantsDecrypter.cs" />
<None Include="deobfuscators\Babel_NET\Deobfuscator.cs" />
<None Include="deobfuscators\Babel_NET\ImageReader.cs" />
<None Include="deobfuscators\Babel_NET\InflaterCreator.cs" />
<None Include="deobfuscators\Babel_NET\MemberReferenceConverter.cs" />
<None Include="deobfuscators\Babel_NET\MethodBodyReader.cs" />
<None Include="deobfuscators\Babel_NET\MethodReferenceReader.cs" />
<None Include="deobfuscators\Babel_NET\MethodsDecrypter.cs" />
<None Include="deobfuscators\Babel_NET\ProxyCallFixer.cs" />
<None Include="deobfuscators\Babel_NET\ResourceDecrypter.cs" />
<None Include="deobfuscators\Babel_NET\ResourceResolver.cs" />
<None Include="deobfuscators\Babel_NET\StringDecrypter.cs" />
<Compile Include="deobfuscators\Babel_NET\AssemblyResolver.cs" />
<Compile Include="deobfuscators\Babel_NET\BabelInflater.cs" />
<Compile Include="deobfuscators\Babel_NET\BabelMethodCallInliner.cs" />
<Compile Include="deobfuscators\Babel_NET\BabelUtils.cs" />
<Compile Include="deobfuscators\Babel_NET\ConstantsDecrypter.cs" />
<Compile Include="deobfuscators\Babel_NET\Deobfuscator.cs" />
<Compile Include="deobfuscators\Babel_NET\ImageReader.cs" />
<Compile Include="deobfuscators\Babel_NET\InflaterCreator.cs" />
<Compile Include="deobfuscators\Babel_NET\MemberReferenceConverter.cs" />
<Compile Include="deobfuscators\Babel_NET\MethodBodyReader.cs" />
<Compile Include="deobfuscators\Babel_NET\MethodReferenceReader.cs" />
<Compile Include="deobfuscators\Babel_NET\MethodsDecrypter.cs" />
<Compile Include="deobfuscators\Babel_NET\ProxyCallFixer.cs" />
<Compile Include="deobfuscators\Babel_NET\ResourceDecrypter.cs" />
<Compile Include="deobfuscators\Babel_NET\ResourceResolver.cs" />
<Compile Include="deobfuscators\Babel_NET\StringDecrypter.cs" />
<Compile Include="deobfuscators\Blowfish.cs" />
<None Include="deobfuscators\CodeFort\AssemblyData.cs" />
<None Include="deobfuscators\CodeFort\AssemblyDecrypter.cs" />

View File

@ -19,12 +19,13 @@
using System;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
class AssemblyResolver {
ModuleDefinition module;
ModuleDefMD module;
ResourceDecrypter resourceDecrypter;
TypeDef resolverType;
MethodDef registerMethod;
@ -63,7 +64,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return embeddedAssemblyInfos; }
}
public AssemblyResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter) {
public AssemblyResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter) {
this.module = module;
this.resourceDecrypter = resourceDecrypter;
}
@ -114,14 +115,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return;
}
var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData());
var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes());
var reader = new BinaryReader(new MemoryStream(decrypted));
int numAssemblies = reader.ReadInt32();
embeddedAssemblyInfos = new EmbeddedAssemblyInfo[numAssemblies];
for (int i = 0; i < numAssemblies; i++) {
string name = reader.ReadString();
var data = reader.ReadBytes(reader.ReadInt32());
var mod = ModuleDefinition.ReadModule(new MemoryStream(data));
var mod = ModuleDefMD.Load(data);
embeddedAssemblyInfos[i] = new EmbeddedAssemblyInfo(name, DeobUtils.getExtension(mod.Kind), data);
}
}

View File

@ -35,7 +35,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
branchEmulator = new BranchEmulator(emulator, this);
}
public static List<MethodDef> find(ModuleDefinition module, IEnumerable<MethodDef> notInlinedMethods) {
public static List<MethodDef> find(ModuleDefMD module, IEnumerable<MethodDef> notInlinedMethods) {
var notInlinedMethodsDict = new Dictionary<MethodDef, bool>();
foreach (var method in notInlinedMethods)
notInlinedMethodsDict[method] = true;
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return false;
if (!method.IsAssembly)
return false;
if (method.GenericParameters.Count > 0)
if (method.MethodSig.GetGenParamCount() > 0)
return false;
return method.IsStatic;
@ -233,8 +233,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
protected override bool isCompatibleType(int paramIndex, TypeReference origType, TypeReference newType) {
if (MemberReferenceHelper.compareTypes(origType, newType))
protected override bool isCompatibleType(int paramIndex, IType origType, IType newType) {
if (new SigComparer().Equals(origType, newType))
return true;
if (newType.IsValueType || origType.IsValueType)
return false;

View File

@ -25,18 +25,18 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
static class BabelUtils {
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType) {
public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType) {
return findEmbeddedResource(module, decrypterType, (method) => { });
}
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType, ISimpleDeobfuscator simpleDeobfuscator, IDeobfuscator deob) {
return findEmbeddedResource(module, decrypterType, (method) => {
simpleDeobfuscator.deobfuscate(method);
simpleDeobfuscator.decryptStrings(method, deob);
});
}
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType, Action<MethodDef> fixMethod) {
public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType, Action<MethodDef> fixMethod) {
foreach (var method in decrypterType.Methods) {
if (!DotNetUtils.isMethod(method, "System.String", "()"))
continue;
@ -50,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return null;
}
static EmbeddedResource findEmbeddedResource1(ModuleDefinition module, MethodDef method) {
static EmbeddedResource findEmbeddedResource1(ModuleDefMD module, MethodDef method) {
foreach (var s in DotNetUtils.getCodeStrings(method)) {
var resource = DotNetUtils.getResource(module, s) as EmbeddedResource;
if (resource != null)
@ -59,7 +59,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return null;
}
static EmbeddedResource findEmbeddedResource2(ModuleDefinition module, MethodDef method) {
static EmbeddedResource findEmbeddedResource2(ModuleDefMD module, MethodDef method) {
var strings = new List<string>(DotNetUtils.getCodeStrings(method));
if (strings.Count != 1)
return null;
@ -83,13 +83,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
continue;
var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (instrs[i + 2].OpCode.Code != Code.Xor)
continue;
xorKey = DotNetUtils.getLdcI4Value(ldci4);
xorKey = ldci4.GetLdcI4Value();
return true;
}
@ -107,12 +107,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Ldftn)
continue;
var handlerRef = instr.Operand as MethodReference;
var handlerRef = instr.Operand as IMethod;
if (handlerRef == null)
continue;
if (!DotNetUtils.isMethod(handlerRef, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
continue;
if (!MemberReferenceHelper.compareTypes(type, handlerRef.DeclaringType))
if (!new SigComparer().Equals(type, handlerRef.DeclaringType))
continue;
handler = DotNetUtils.getMethod(type, handlerRef);
if (handler == null)

View File

@ -21,13 +21,14 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
class ConstantsDecrypter {
ModuleDefinition module;
ModuleDefMD module;
ResourceDecrypter resourceDecrypter;
InitializedDataCreator initializedDataCreator;
TypeDef decrypterType;
@ -78,7 +79,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return arrayDecrypter; }
}
public ConstantsDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter, InitializedDataCreator initializedDataCreator) {
public ConstantsDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter, InitializedDataCreator initializedDataCreator) {
this.module = module;
this.resourceDecrypter = resourceDecrypter;
this.initializedDataCreator = initializedDataCreator;
@ -109,7 +110,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (!checkNestedFields(nested))
return false;
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor"));
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor"));
if (DotNetUtils.getMethod(type, "System.Int32", "(System.Int32)") == null)
return false;
@ -135,7 +136,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (!new FieldTypes(nested).all(requiredTypes))
return false;
foreach (var field in nested.Fields) {
if (MemberReferenceHelper.compareTypes(nested, field.FieldType))
if (new SigComparer().Equals(nested, field.FieldSig.GetFieldType()))
return true;
}
return false;
@ -151,7 +152,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return;
}
var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData());
var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes());
var reader = new BinaryReader(new MemoryStream(decrypted));
int count;
@ -194,10 +195,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
struct ArrayInfo {
public FieldDef encryptedField;
public ArrayType arrayType;
public SZArraySig arrayType;
public int start, len;
public ArrayInfo(int start, int len, FieldDef encryptedField, ArrayType arrayType) {
public ArrayInfo(int start, int len, FieldDef encryptedField, SZArraySig arrayType) {
this.start = start;
this.len = len;
this.encryptedField = encryptedField;
@ -239,23 +240,23 @@ namespace de4dot.code.deobfuscators.Babel_NET {
var call1 = instrs[index++];
if (call1.OpCode.Code != Code.Call && call1.OpCode.Code != Code.Callvirt)
continue;
if (!DotNetUtils.isMethod(call1.Operand as MethodReference, "System.Void", "(System.Array,System.RuntimeFieldHandle)"))
if (!DotNetUtils.isMethod(call1.Operand as IMethod, "System.Void", "(System.Array,System.RuntimeFieldHandle)"))
continue;
var call2 = instrs[index++];
if (call2.OpCode.Code != Code.Call && call2.OpCode.Code != Code.Callvirt)
continue;
if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(call2.Operand as MethodReference, arrayDecrypter))
if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(call2.Operand as IMethod, arrayDecrypter))
continue;
var castclass = instrs[index++];
if (castclass.OpCode.Code != Code.Castclass)
continue;
var arrayType = castclass.Operand as ArrayType;
var arrayType = (castclass.Operand as ITypeDefOrRef).ToSZArraySig();
if (arrayType == null)
continue;
if (arrayType.ElementType.GetPrimitiveSize() == -1) {
Log.w("Can't decrypt non-primitive type array in method {0}", blocks.Method.MDToken.ToInt32());
if (arrayType.Next.ElementType.GetPrimitiveSize() == -1) {
Log.w("Can't decrypt non-primitive type array in method {0:X8}", blocks.Method.MDToken.ToInt32());
continue;
}
@ -264,11 +265,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
infos.Reverse();
foreach (var info in infos) {
var elemSize = info.arrayType.ElementType.GetPrimitiveSize();
var elemSize = info.arrayType.Next.ElementType.GetPrimitiveSize();
var decrypted = decryptArray(info.encryptedField.InitialValue, elemSize);
initializedDataCreator.addInitializeArrayCode(block, info.start, info.len, info.arrayType.ElementType, decrypted);
Log.v("Decrypted {0} array: {1} elements", info.arrayType.ElementType.ToString(), decrypted.Length / elemSize);
initializedDataCreator.addInitializeArrayCode(block, info.start, info.len, info.arrayType.Next.ToTypeDefOrRef(), decrypted);
Log.v("Decrypted {0} array: {1} elements", info.arrayType.Next.ToString(), decrypted.Length / elemSize);
}
}
}

View File

@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
this.options = options;
}
public override void init(ModuleDefinition module) {
public override void init(ModuleDefMD module) {
base.init(module);
}
@ -183,9 +183,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
void checkVersion(TypeDef attr) {
var versionField = DotNetUtils.getFieldByName(attr, "Version");
if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant is string) {
var val = Regex.Match((string)versionField.Constant, @"^(\d+\.\d+\.\d+\.\d+)$");
var versionField = attr.FindField("Version");
if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant.Value is string) {
var val = Regex.Match((string)versionField.Constant.Value, @"^(\d+\.\d+\.\d+\.\d+)$");
if (val.Groups.Count < 2)
return;
obfuscatorName = string.Format("{0} {1}", DeobfuscatorInfo.THE_NAME, val.Groups[1].ToString());

View File

@ -22,10 +22,14 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
using CR = System.Runtime.InteropServices;
using DR = dot10.DotNet;
namespace de4dot.code.deobfuscators.Babel_NET {
class ImageReader {
static int METHODS_SIG = 0x0000BEBA;
@ -43,19 +47,19 @@ namespace de4dot.code.deobfuscators.Babel_NET {
ByRef = 4,
}
ModuleDefinition module;
BinaryReader reader;
ModuleDefMD module;
IBinaryReader reader;
string[] strings;
AssemblyNameReference[] assemblyNames;
AssemblyRef[] assemblyNames;
Dictionary<string, int> methodOffsets;
List<TypeReference> typeReferences;
List<TypeSig> typeReferences;
MemberReferenceConverter memberReferenceConverter;
IDeobfuscatorContext deobfuscatorContext;
public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefinition module, byte[] data) {
public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, byte[] data) {
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
this.reader = new BinaryReader(new MemoryStream(data));
this.reader = MemoryImageStream.Create(data);
this.memberReferenceConverter = new MemberReferenceConverter(module);
}
@ -67,14 +71,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (metadataOffset < 0)
return false;
long pos = metadataOffset + 4;
reader.BaseStream.Position = pos;
reader.Position = pos;
int version = reader.ReadInt16(); // major, minor
if (version == 0x0001) {
initializeV10();
return true;
}
reader.BaseStream.Position = pos;
reader.Position = pos;
initializeV55();
return true;
}
@ -108,18 +112,18 @@ namespace de4dot.code.deobfuscators.Babel_NET {
var babelMethod = getMethod(name);
var body = method.Body;
body.MaxStackSize = babelMethod.MaxStack;
body.MaxStack = babelMethod.MaxStack;
body.InitLocals = babelMethod.InitLocals;
body.Variables.Clear();
body.LocalList.Clear();
foreach (var local in babelMethod.Locals)
body.Variables.Add(local);
body.LocalList.Add(local);
var toNewOperand = new Dictionary<object, object>();
if (babelMethod.ThisParameter != null)
toNewOperand[babelMethod.ThisParameter] = body.ThisParameter;
for (int i = 0; i < method.Parameters.Count; i++)
toNewOperand[babelMethod.Parameters[i]] = method.Parameters[i];
toNewOperand[babelMethod.ThisParameter] = method.Parameters[0];
for (int i = 0; i < babelMethod.Parameters.Length; i++)
toNewOperand[babelMethod.Parameters[i]] = method.Parameters[i + method.Parameters.MethodSigIndexBase];
body.Instructions.Clear();
foreach (var instr in babelMethod.Instructions) {
@ -137,7 +141,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
BabelMethodDefinition getMethod(string name) {
int offset = methodOffsets[name];
methodOffsets.Remove(name);
reader.BaseStream.Position = offset;
reader.Position = offset;
return new MethodDefinitionReader(this, reader).read();
}
@ -145,20 +149,20 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return strings[readVariableLengthInt32()];
}
public TypeReference readTypeReference() {
public TypeSig readTypeSig() {
return typeReferences[readVariableLengthInt32()];
}
public TypeReference[] readTypeReferences() {
var refs = new TypeReference[readVariableLengthInt32()];
public TypeSig[] readTypeSigs() {
var refs = new TypeSig[readVariableLengthInt32()];
for (int i = 0; i < refs.Length; i++)
refs[i] = readTypeReference();
refs[i] = readTypeSig();
return refs;
}
public FieldReference readFieldReference() {
public IField readFieldReference() {
var name = readString();
var declaringType = readTypeReference();
var declaringType = readTypeSig();
var fields = getFields(resolve(declaringType), name);
if (fields == null || fields.Count != 1) {
@ -173,15 +177,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
static List<FieldDef> getFields(TypeDef type, string name) {
if (type == null)
return null;
var fields = new List<FieldDef>();
foreach (var field in type.Fields) {
if (field.Name == name)
fields.Add(field);
}
return fields;
return new List<FieldDef>(type.FindFields(name));
}
public MethodReference readMethodReference() {
public IMethod readMethodReference() {
var babelMethodRef = new MethodReferenceReader(this, reader).read();
var method = getMethodReference(babelMethodRef);
@ -191,16 +190,15 @@ namespace de4dot.code.deobfuscators.Babel_NET {
Utils.removeNewlines(babelMethodRef.DeclaringType)));
}
var git = babelMethodRef.DeclaringType as GenericInstanceType;
var git = babelMethodRef.DeclaringType.ToGenericInstSig();
if (git == null)
return method;
var newMethod = memberReferenceConverter.copy(method);
newMethod.DeclaringType = babelMethodRef.DeclaringType;
return newMethod;
var mr = new MemberRefUser(module, method.Name, method.MethodSig.Clone(), babelMethodRef.DeclaringType.ToTypeDefOrRef());
return module.UpdateRowId(mr);
}
MethodReference getMethodReference(BabelMethodreference babelMethodRef) {
IMethod getMethodReference(BabelMethodreference babelMethodRef) {
var declaringType = resolve(babelMethodRef.DeclaringType);
if (declaringType == null)
return null;
@ -215,20 +213,19 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return methods[0];
}
List<MethodReference> getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) {
var methods = new List<MethodReference>();
List<IMethod> getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) {
var methods = new List<IMethod>();
var git = babelMethodRef.DeclaringType as GenericInstanceType;
IGenericInstance gim = babelMethodRef.IsGenericMethod ? babelMethodRef : null;
var gis = babelMethodRef.DeclaringType as GenericInstSig;
var gim = babelMethodRef.GenericArguments;
foreach (var method in declaringType.Methods) {
if (compareMethod(MethodReferenceInstance.make(method, git, gim), babelMethodRef)) {
if (compareMethod(GenericArgsSubstitutor.create(method, gis, gim), babelMethodRef)) {
if (!babelMethodRef.IsGenericMethod)
methods.Add(memberReferenceConverter.convert(method));
else {
var gim2 = new GenericInstanceMethod(memberReferenceConverter.convert(method));
foreach (var arg in babelMethodRef.GenericArguments)
gim2.GenericArguments.Add(arg);
methods.Add(gim2);
var gim2 = new GenericInstMethodSig(babelMethodRef.GenericArguments);
var ms = module.UpdateRowId(new MethodSpecUser(memberReferenceConverter.convert(method), gim2));
methods.Add(ms);
}
}
}
@ -236,66 +233,71 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return methods;
}
bool compareMethod(MethodReference method, BabelMethodreference babelMethodRef) {
if (method.Parameters.Count != babelMethodRef.Parameters.Length)
bool compareMethod(IMethod method, BabelMethodreference babelMethodRef) {
var sig = method.MethodSig;
if (sig.Params.Count != babelMethodRef.Parameters.Length)
return false;
if (method.Name != babelMethodRef.Name)
return false;
if (method.HasThis != babelMethodRef.HasThis)
if (sig.HasThis != babelMethodRef.HasThis)
return false;
if (method.GenericParameters.Count != babelMethodRef.GenericArguments.Length)
if (sig.GenParamCount != babelMethodRef.GenericArguments.Length)
return false;
if (!MemberReferenceHelper.compareTypes(method.MethodReturnType.ReturnType, babelMethodRef.ReturnType))
if (!new SigComparer().Equals(sig.RetType, babelMethodRef.ReturnType))
return false;
for (int i = 0; i < babelMethodRef.Parameters.Length; i++) {
if (!MemberReferenceHelper.compareTypes(method.Parameters[i].ParameterType, babelMethodRef.Parameters[i].ParameterType))
if (!new SigComparer().Equals(sig.Params[i], babelMethodRef.Parameters[i].Type))
return false;
}
return true;
}
TypeDef resolve(TypeReference type) {
if (type is TypeDef)
return (TypeDef)type;
TypeDef resolve(TypeSig type) {
type = type.RemovePinnedAndModifiers();
if (type.IsGenericInstance)
type = ((GenericInstanceType)type).ElementType;
var gis = type as GenericInstSig;
if (gis != null)
type = gis.GenericType;
if (type.Module == module && isModuleAssembly(type.Scope))
return DotNetUtils.getType(module, type);
var tdrs = type as TypeDefOrRefSig;
if (tdrs == null)
return null;
return deobfuscatorContext.resolve(type);
var td = tdrs.TypeDef;
if (td != null)
return td;
var tr = tdrs.TypeRef;
if (tr != null)
return tr.Resolve();
return null;
}
public CallSite readCallSite() {
var returnType = readTypeReference();
var paramTypes = readTypeReferences();
var callingConvention = (CallingConvention)reader.ReadInt32();
public MethodSig readCallSite() {
var returnType = readTypeSig();
var paramTypes = readTypeSigs();
var callingConvention = (CR.CallingConvention)reader.ReadInt32();
var cs = new CallSite(returnType);
foreach (var paramType in paramTypes)
cs.Parameters.Add(new ParameterDefinition(paramType));
cs.CallingConvention = convertCallingConvention(callingConvention);
return cs;
return new MethodSig(convertCallingConvention(callingConvention), 0, returnType, paramTypes);
}
static MethodCallingConvention convertCallingConvention(CallingConvention callingConvention) {
static DR.CallingConvention convertCallingConvention(CR.CallingConvention callingConvention) {
switch (callingConvention) {
case CallingConvention.Winapi: return MethodCallingConvention.Default;
case CallingConvention.Cdecl: return MethodCallingConvention.C;
case CallingConvention.StdCall: return MethodCallingConvention.StdCall;
case CallingConvention.ThisCall: return MethodCallingConvention.ThisCall;
case CallingConvention.FastCall: return MethodCallingConvention.FastCall;
case CR.CallingConvention.Winapi: return DR.CallingConvention.Default;
case CR.CallingConvention.Cdecl: return DR.CallingConvention.C;
case CR.CallingConvention.StdCall: return DR.CallingConvention.StdCall;
case CR.CallingConvention.ThisCall: return DR.CallingConvention.ThisCall;
case CR.CallingConvention.FastCall: return DR.CallingConvention.FastCall;
default: throw new ApplicationException(string.Format("Unknown CallingConvention {0}", callingConvention));
}
}
void initializeStrings(int headerOffset) {
reader.BaseStream.Position = headerOffset;
reader.Position = headerOffset;
if (reader.ReadInt32() != STRINGS_SIG)
throw new ApplicationException("Invalid strings sig");
@ -305,27 +307,17 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
void initializeAssemblyNames(int headerOffset) {
reader.BaseStream.Position = headerOffset;
reader.Position = headerOffset;
if (reader.ReadInt32() != ASSEMBLY_NAMES_SIG)
throw new ApplicationException("Invalid assembly names sig");
assemblyNames = new AssemblyNameReference[readVariableLengthInt32()];
assemblyNames = new AssemblyRef[readVariableLengthInt32()];
for (int i = 0; i < assemblyNames.Length; i++)
assemblyNames[i] = getModuleAssemblyReference(AssemblyNameReference.Parse(readString()));
}
bool isModuleAssembly(IMetadataScope scope) {
return DotNetUtils.isReferenceToModule(module, scope);
}
AssemblyNameReference getModuleAssemblyReference(AssemblyNameReference asmRef) {
if (isModuleAssembly(asmRef))
return module.Assembly.Name;
return memberReferenceConverter.convert(asmRef);
assemblyNames[i] = module.UpdateRowId(new AssemblyRefUser(new AssemblyNameInfo(readString())));
}
void initializeMethodNames(int headerOffset) {
reader.BaseStream.Position = headerOffset;
reader.Position = headerOffset;
if (reader.ReadInt32() != METHOD_NAMES_SIG)
throw new ApplicationException("Invalid methods sig");
@ -338,14 +330,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
void initializeTypeReferences(int headerOffset) {
reader.BaseStream.Position = headerOffset;
reader.Position = headerOffset;
if (reader.ReadInt32() != TYPEREFS_SIG)
throw new ApplicationException("Invalid typerefs sig");
int numTypeRefs = reader.ReadInt32();
typeReferences = new List<TypeReference>(numTypeRefs + 1);
typeReferences = new List<TypeSig>(numTypeRefs + 1);
typeReferences.Add(null);
var genericArgFixes = new Dictionary<GenericInstanceType, List<int>>();
var genericArgFixes = new Dictionary<GenericInstSig, List<int>>();
for (int i = 0; i < numTypeRefs; i++) {
TypeId typeId = (TypeId)reader.ReadByte();
switch (typeId) {
@ -384,35 +376,30 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
TypeReference readTypeRef() {
TypeSig readTypeRef() {
string ns, name;
parseReflectionTypeName(readString(), out ns, out name);
var asmRef = assemblyNames[readVariableLengthInt32()];
var declaringType = readTypeReference();
var typeReference = new TypeReference(ns, name, module, asmRef) {
DeclaringType = declaringType,
};
typeReference.UpdateElementType();
var declaringType = readTypeSig();
var typeReference = new TypeRefUser(module, ns, name);
if (declaringType != null)
typeReference.ResolutionScope = getTypeRef(declaringType);
else
typeReference.ResolutionScope = asmRef;
typeReference = memberReferenceConverter.convert(typeReference);
typeReference.IsValueType = isValueType(typeReference);
return typeReference;
return memberReferenceConverter.convert(typeReference);
}
bool isValueType(TypeReference typeRef) {
var typeDef = typeRef as TypeDef;
if (typeDef != null)
return typeDef.IsValueType;
if (typeRef.Module == module && isModuleAssembly(typeRef.Scope))
typeDef = DotNetUtils.getType(module, typeRef);
else
typeDef = resolve(typeRef);
if (typeDef != null)
return typeDef.IsValueType;
Log.w("Could not determine whether type '{0}' is a value type", Utils.removeNewlines(typeRef));
return false; // Assume it's a reference type
TypeRef getTypeRef(TypeSig type) {
var tdr = type as TypeDefOrRefSig;
if (tdr == null)
throw new ApplicationException("Not a type ref");
if (tdr.TypeRef != null)
return tdr.TypeRef;
var td = tdr.TypeDef;
if (td != null)
return new Importer(module).Import(td) as TypeRef;
throw new ApplicationException("Not a type ref");
}
static void parseReflectionTypeName(string fullName, out string ns, out string name) {
@ -461,8 +448,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return sb.ToString();
}
GenericInstanceType readGenericInstanceType(out List<int> genericArgs) {
var git = new GenericInstanceType(readTypeReference());
GenericInstSig readGenericInstanceType(out List<int> genericArgs) {
var git = new GenericInstSig(readTypeSig() as ClassOrValueTypeSig);
int numArgs = readVariableLengthInt32();
genericArgs = new List<int>(numArgs);
for (int i = 0; i < numArgs; i++)
@ -470,28 +457,40 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return git;
}
PointerType readPointerType() {
return new PointerType(readTypeReference());
PtrSig readPointerType() {
return new PtrSig(readTypeSig());
}
ArrayType readArrayType() {
return new ArrayType(readTypeReference(), readVariableLengthInt32());
TypeSig readArrayType() {
var typeSig = readTypeSig();
int rank = readVariableLengthInt32();
if (rank == 1)
return new SZArraySig(typeSig);
return new ArraySig(typeSig, rank);
}
ByReferenceType readByReferenceType() {
return new ByReferenceType(readTypeReference());
ByRefSig readByReferenceType() {
return new ByRefSig(readTypeSig());
}
public uint readVariableLengthUInt32() {
uint val;
reader.ReadCompressedUInt32(out val);
return val;
}
public int readVariableLengthInt32() {
return DeobUtils.readVariableLengthInt32(reader);
uint val;
reader.ReadCompressedUInt32(out val);
return (int)val;
}
int getMetadataOffset() {
reader.BaseStream.Position = reader.BaseStream.Length - 4;
reader.Position = reader.Length - 4;
for (int i = 0; i < 30; i++) {
if (reader.ReadInt32() == METADATA_SIG)
return (int)reader.BaseStream.Position - 4;
reader.BaseStream.Position -= 8;
return (int)reader.Position - 4;
reader.Position -= 8;
}
return -1;
}

View File

@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
var type = calledMethod.DeclaringType;
foreach (var nested in type.NestedTypes) {
if (DeobUtils.hasInteger(DotNetUtils.getMethod(nested, ".ctor"), 0x8001))
if (DeobUtils.hasInteger(nested.FindMethod(".ctor"), 0x8001))
return type;
}
}
@ -98,7 +98,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
var instrs = method.Body.Instructions;
for (int i = 0; i < instrs.Count - 3; i++) {
var ldci4_1 = instrs[i];
if (!DotNetUtils.isLdcI4(ldci4_1) || DotNetUtils.getLdcI4Value(ldci4_1) != 16)
if (!ldci4_1.IsLdcI4() || ldci4_1.GetLdcI4Value() != 16)
continue;
var callvirt = instrs[i + 1];
@ -106,13 +106,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
continue;
var ldci4_2 = instrs[i + 2];
if (!DotNetUtils.isLdcI4(ldci4_2))
if (!ldci4_2.IsLdcI4())
continue;
if (instrs[i + 3].OpCode.Code != Code.Xor)
continue;
return DotNetUtils.getLdcI4Value(ldci4_2);
return ldci4_2.GetLdcI4Value();
}
return null;

View File

@ -22,123 +22,57 @@ using dot10.DotNet;
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 GenericParam) && !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 GenericParam(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;
ModuleDefMD module;
public ModuleDefinition Module {
public ModuleDefMD Module {
get { return module; }
}
public MemberReferenceConverter(ModuleDefinition module) {
public MemberReferenceConverter(ModuleDefMD module) {
this.module = module;
}
bool isInOurModule(MemberReference memberRef) {
return memberRef.Module == module;
bool isInOurModule(IMemberRef memberRef) {
return memberRef.OwnerModule == module;
}
public TypeReference convert(TypeReference typeRef) {
if (typeRef == null)
return null;
typeRef = new TypeReferenceConverter(this).convert(typeRef);
return tryGetTypeDefinition(typeRef);
Importer createImporter() {
return new Importer(module, ImporterOptions.TryToUseTypeDefs);
}
public FieldReference convert(FieldReference fieldRef) {
public TypeSig convert(TypeRef typeRef) {
return createImporter().Import(typeRef).ToTypeSig();
}
ITypeDefOrRef convert(ITypeDefOrRef tdr) {
return (ITypeDefOrRef)createImporter().Import(tdr);
}
TypeSig convert2(TypeSig ts) {
return createImporter().Import(ts);
}
public TypeSig convert(TypeSig ts) {
return createImporter().Import(ts);
}
public IField convert(IField fieldRef) {
if (isInOurModule(fieldRef))
return tryGetFieldDefinition(fieldRef);
return new FieldReference(fieldRef.Name, convert(fieldRef.FieldType), convert(fieldRef.DeclaringType));
return createImporter().Import(fieldRef);
}
public MethodReference convert(MethodReference methodRef) {
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef))
public IMethodDefOrRef convert(IMethod methodRef) {
if (!(methodRef is MemberRef || methodRef is MethodDef) || methodRef.MethodSig == null)
throw new ApplicationException("Invalid method reference type");
if (isInOurModule(methodRef))
return tryGetMethodDefinition(methodRef);
return copy(methodRef);
return (IMethodDefOrRef)tryGetMethodDefinition(methodRef);
return (IMethodDefOrRef)createImporter().Import(methodRef);
}
public MethodReference copy(MethodReference methodRef) {
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef))
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 GenericParam(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) {
return DotNetUtils.addAssemblyReference(module, asmRef);
}
public ModuleReference convert(ModuleReference modRef) {
return DotNetUtils.addModuleReference(module, modRef);
}
public TypeReference tryGetTypeDefinition(TypeReference typeRef) {
return DotNetUtils.getType(module, typeRef) ?? typeRef;
}
public FieldReference tryGetFieldDefinition(FieldReference fieldRef) {
public IField tryGetFieldDefinition(IField fieldRef) {
var fieldDef = fieldRef as FieldDef;
if (fieldDef != null)
return fieldDef;
@ -149,7 +83,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return DotNetUtils.getField(declaringType, fieldRef);
}
public MethodReference tryGetMethodDefinition(MethodReference methodRef) {
public IMethod tryGetMethodDefinition(IMethod methodRef) {
var methodDef = methodRef as MethodDef;
if (methodDef != null)
return methodDef;

View File

@ -18,7 +18,9 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
@ -26,67 +28,73 @@ namespace de4dot.code.deobfuscators.Babel_NET {
class MethodBodyReader : MethodBodyReaderBase {
ImageReader imageReader;
public int Flags2 { get; set; }
public short MaxStack { get; set; }
public ushort MaxStack { get; set; }
public MethodBodyReader(ImageReader imageReader, BinaryReader reader)
public MethodBodyReader(ImageReader imageReader, IBinaryReader reader)
: base(reader) {
this.imageReader = imageReader;
}
public void read(ParameterDefinition[] parameters) {
public void read(IList<Parameter> parameters) {
this.parameters = parameters;
Flags2 = reader.ReadInt16();
MaxStack = reader.ReadInt16();
setLocals(imageReader.readTypeReferences());
readInstructions(imageReader.readVariableLengthInt32());
MaxStack = reader.ReadUInt16();
SetLocals(imageReader.readTypeSigs());
ReadInstructions(imageReader.readVariableLengthInt32());
readExceptionHandlers(imageReader.readVariableLengthInt32());
}
protected override FieldReference readInlineField(Instruction instr) {
protected override IField ReadInlineField(Instruction instr) {
return imageReader.readFieldReference();
}
protected override MethodReference readInlineMethod(Instruction instr) {
protected override IMethod ReadInlineMethod(Instruction instr) {
return imageReader.readMethodReference();
}
protected override CallSite readInlineSig(Instruction instr) {
protected override MethodSig ReadInlineSig(Instruction instr) {
return imageReader.readCallSite();
}
protected override string readInlineString(Instruction instr) {
protected override string ReadInlineString(Instruction instr) {
return imageReader.readString();
}
protected override MemberReference readInlineTok(Instruction instr) {
protected override ITokenOperand ReadInlineTok(Instruction instr) {
switch (reader.ReadByte()) {
case 0: return imageReader.readTypeReference();
case 0: return imageReader.readTypeSig().ToTypeDefOrRef();
case 1: return imageReader.readFieldReference();
case 2: return imageReader.readMethodReference();
default: throw new ApplicationException("Unknown token type");
}
}
protected override TypeReference readInlineType(Instruction instr) {
return imageReader.readTypeReference();
protected override ITypeDefOrRef ReadInlineType(Instruction instr) {
return imageReader.readTypeSig().ToTypeDefOrRef();
}
protected override ExceptionHandler readExceptionHandler() {
void readExceptionHandlers(int numExceptionHandlers) {
exceptionHandlers = new List<ExceptionHandler>(numExceptionHandlers);
for (int i = 0; i < numExceptionHandlers; i++)
Add(readExceptionHandler());
}
ExceptionHandler readExceptionHandler() {
var ehType = (ExceptionHandlerType)reader.ReadByte();
int tryOffset = imageReader.readVariableLengthInt32();
int tryLength = imageReader.readVariableLengthInt32();
int handlerOffset = imageReader.readVariableLengthInt32();
int handlerLength = imageReader.readVariableLengthInt32();
var catchType = imageReader.readTypeReference();
int filterOffset = imageReader.readVariableLengthInt32();
uint tryOffset = imageReader.readVariableLengthUInt32();
uint tryLength = imageReader.readVariableLengthUInt32();
uint handlerOffset = imageReader.readVariableLengthUInt32();
uint handlerLength = imageReader.readVariableLengthUInt32();
var catchType = imageReader.readTypeSig().ToTypeDefOrRef();
uint filterOffset = imageReader.readVariableLengthUInt32();
var eh = new ExceptionHandler(ehType);
eh.TryStart = getInstruction(tryOffset);
eh.TryEnd = getInstructionOrNull(tryOffset + tryLength);
eh.TryStart = GetInstructionThrow(tryOffset);
eh.TryEnd = GetInstruction(tryOffset + tryLength);
if (ehType == ExceptionHandlerType.Filter)
eh.FilterStart = getInstruction(filterOffset);
eh.HandlerStart = getInstruction(handlerOffset);
eh.HandlerEnd = getInstructionOrNull(handlerOffset + handlerLength);
eh.FilterStart = GetInstructionThrow(filterOffset);
eh.HandlerStart = GetInstructionThrow(handlerOffset);
eh.HandlerEnd = GetInstruction(handlerOffset + handlerLength);
eh.CatchType = catchType;
return eh;
}

View File

@ -20,17 +20,17 @@
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using Mono.Collections.Generic;
namespace de4dot.code.deobfuscators.Babel_NET {
class BabelMethodreference : IGenericInstance {
class BabelMethodreference {
public string Name { get; set; }
public TypeReference DeclaringType { get; set; }
public TypeReference ReturnType { get; set; }
public ParameterDefinition[] Parameters { get; set; }
public TypeReference[] GenericArguments { get; set; }
public TypeSig DeclaringType { get; set; }
public TypeSig ReturnType { get; set; }
public Parameter[] Parameters { get; set; }
public TypeSig[] GenericArguments { get; set; }
public int Flags { get; set; }
public bool HasThis {
@ -40,27 +40,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
public bool IsGenericMethod {
get { return (Flags & 2) != 0; }
}
bool IGenericInstance.HasGenericArguments {
get { return IsGenericMethod; }
}
Collection<TypeReference> IGenericInstance.GenericArguments {
get { return new Collection<TypeReference>(GenericArguments); }
}
MetadataToken IMetadataTokenProvider.MDToken {
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
class BabelMethodDefinition : BabelMethodreference {
ParameterDefinition thisParameter;
Parameter thisParameter;
public int Flags2 { get; set; }
public short MaxStack { get; set; }
public IList<VariableDefinition> Locals { get; set; }
public ushort MaxStack { get; set; }
public IList<Local> Locals { get; set; }
public IList<Instruction> Instructions { get; set; }
public IList<ExceptionHandler> ExceptionHandlers { get; set; }
@ -80,13 +67,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return (Flags2 & 0x80) != 0; }
}
public ParameterDefinition ThisParameter {
public Parameter ThisParameter {
get {
if (!HasThis)
return null;
if (thisParameter != null)
return thisParameter;
return thisParameter = new ParameterDefinition(DeclaringType);
return thisParameter = new Parameter(0, Parameter.HIDDEN_THIS_METHOD_SIG_INDEX, DeclaringType);
}
}
@ -98,10 +85,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
ExceptionHandlers = mbr.ExceptionHandlers;
}
public ParameterDefinition[] getRealParameters() {
public IList<Parameter> getRealParameters() {
if (ThisParameter == null)
return Parameters;
var parameters = new ParameterDefinition[Parameters.Length + 1];
var parameters = new Parameter[Parameters.Length + 1];
parameters[0] = ThisParameter;
Array.Copy(Parameters, 0, parameters, 1, Parameters.Length);
return parameters;
@ -110,14 +97,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
class MethodReferenceReader {
ImageReader imageReader;
BinaryReader reader;
IBinaryReader reader;
BabelMethodreference bmr;
public MethodReferenceReader(ImageReader imageReader, BinaryReader reader)
public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader)
: this(imageReader, reader, new BabelMethodreference()) {
}
public MethodReferenceReader(ImageReader imageReader, BinaryReader reader, BabelMethodreference bmr) {
public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader, BabelMethodreference bmr) {
this.imageReader = imageReader;
this.reader = reader;
this.bmr = bmr;
@ -125,23 +112,24 @@ namespace de4dot.code.deobfuscators.Babel_NET {
public BabelMethodreference read() {
bmr.Name = imageReader.readString();
bmr.DeclaringType = imageReader.readTypeReference();
bmr.ReturnType = imageReader.readTypeReference();
bmr.Parameters = readParameters();
bmr.DeclaringType = imageReader.readTypeSig();
bmr.ReturnType = imageReader.readTypeSig();
var argTypes = imageReader.readTypeSigs();
bmr.Flags = reader.ReadByte();
if (bmr.IsGenericMethod)
bmr.GenericArguments = imageReader.readTypeReferences();
bmr.GenericArguments = imageReader.readTypeSigs();
else
bmr.GenericArguments = new TypeReference[0];
bmr.GenericArguments = new TypeSig[0];
bmr.Parameters = readParameters(argTypes, bmr.HasThis);
return bmr;
}
ParameterDefinition[] readParameters() {
var typeReferences = imageReader.readTypeReferences();
var parameters = new ParameterDefinition[typeReferences.Length];
for (int i = 0; i < parameters.Length; i++)
parameters[i] = new ParameterDefinition(typeReferences[i]);
return parameters;
Parameter[] readParameters(IList<TypeSig> argTypes, bool hasThis) {
var ps = new Parameter[argTypes.Count];
int bi = hasThis ? 1 : 0;
for (int i = 0; i < ps.Length; i++)
ps[i] = new Parameter(bi + i, i, argTypes[i]);
return ps;
}
}
@ -150,7 +138,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
MethodBodyReader methodBodyReader;
BabelMethodDefinition bmd;
public MethodDefinitionReader(ImageReader imageReader, BinaryReader reader) {
public MethodDefinitionReader(ImageReader imageReader, IBinaryReader reader) {
this.bmd = new BabelMethodDefinition();
this.methodReferenceReader = new MethodReferenceReader(imageReader, reader, bmd);
this.methodBodyReader = new MethodBodyReader(imageReader, reader);

View File

@ -20,13 +20,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
class MethodsDecrypter {
ModuleDefinition module;
ModuleDefMD module;
ResourceDecrypter resourceDecrypter;
IDeobfuscatorContext deobfuscatorContext;
Dictionary<string, ImageReader> imageReaders = new Dictionary<string, ImageReader>(StringComparer.Ordinal);
@ -39,7 +40,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return methodsDecrypterCreator != null; }
}
public MethodsDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter, IDeobfuscatorContext deobfuscatorContext) {
public MethodsDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter, IDeobfuscatorContext deobfuscatorContext) {
this.module = module;
this.resourceDecrypter = resourceDecrypter;
this.deobfuscatorContext = deobfuscatorContext;
@ -54,7 +55,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
var fieldTypes = new FieldTypes(type);
if (!fieldTypes.all(requiredFields))
continue;
if (DotNetUtils.getMethod(type, "Finalize") == null)
if (type.FindMethod("Finalize") == null)
continue;
var executeMethod = DotNetUtils.getMethod(type, "System.Object", "(System.String,System.Object[])");
if (executeMethod == null || !executeMethod.IsStatic || executeMethod.Body == null)
@ -84,10 +85,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
TypeDef findMethodsDecrypterType(TypeDef type) {
foreach (var field in type.Fields) {
var fieldType = DotNetUtils.getType(module, field.FieldType);
var fieldType = DotNetUtils.getType(module, field.FieldSig.GetFieldType());
if (fieldType == null)
continue;
if (DotNetUtils.getMethod(fieldType, "Finalize") == null)
if (fieldType.FindMethod("Finalize") == null)
continue;
if (!new FieldTypes(fieldType).exists("System.Collections.Hashtable"))
continue;
@ -106,7 +107,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
encryptedResource = BabelUtils.findEmbeddedResource(module, methodsDecrypter, simpleDeobfuscator, deob);
if (encryptedResource != null)
addImageReader("", resourceDecrypter.decrypt(encryptedResource.GetResourceData()));
addImageReader("", resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes()));
}
ImageReader addImageReader(string name, byte[] data) {
@ -178,7 +179,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return null;
try {
var encrypted = File.ReadAllBytes(getFile(Path.GetDirectoryName(module.FullyQualifiedName), feature));
var encrypted = File.ReadAllBytes(getFile(Path.GetDirectoryName(module.Location), feature));
var decrypted = resourceDecrypter.decrypt(encrypted);
return addImageReader(feature, decrypted);
}
@ -241,7 +242,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
continue;
if (MemberReferenceHelper.compareMethodReferenceAndDeclaringType(decryptExecuteMethod, instr.Operand as MethodReference))
if (MethodEqualityComparer.CompareDeclaringTypes.Equals(decryptExecuteMethod, instr.Operand as IMethod))
return true;
}
return false;

View File

@ -27,7 +27,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
class ProxyCallFixer : ProxyCallFixer2 {
MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType> methodToType = new MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType>();
public ProxyCallFixer(ModuleDefinition module)
public ProxyCallFixer(ModuleDefMD module)
: base(module) {
}
@ -38,11 +38,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
class Context {
public TypeReference delegateType;
public ITypeDefOrRef delegateType;
public int methodToken;
public int declaringTypeToken;
public ProxyCreatorType proxyCreatorType;
public Context(TypeReference delegateType, int methodToken, int declaringTypeToken, ProxyCreatorType proxyCreatorType) {
public Context(ITypeDefOrRef delegateType, int methodToken, int declaringTypeToken, ProxyCreatorType proxyCreatorType) {
this.delegateType = delegateType;
this.methodToken = methodToken;
this.declaringTypeToken = declaringTypeToken;
@ -57,24 +57,24 @@ namespace de4dot.code.deobfuscators.Babel_NET {
protected override object checkCctor(TypeDef type, MethodDef cctor) {
var instructions = cctor.Body.Instructions;
for (int i = 0; i < instructions.Count; i++) {
TypeReference delegateType;
FieldReference delegateField;
MethodReference createMethod;
ITypeDefOrRef delegateType;
IField delegateField;
IMethod createMethod;
int methodToken, declaringTypeToken;
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call);
if (instrs != null) {
delegateType = instrs[0].Operand as TypeReference;
methodToken = DotNetUtils.getLdcI4Value(instrs[1]);
declaringTypeToken = DotNetUtils.getLdcI4Value(instrs[2]);
delegateField = instrs[3].Operand as FieldReference;
createMethod = instrs[4].Operand as MethodReference;
delegateType = instrs[0].Operand as ITypeDefOrRef;
methodToken = instrs[1].GetLdcI4Value();
declaringTypeToken = instrs[2].GetLdcI4Value();
delegateField = instrs[3].Operand as IField;
createMethod = instrs[4].Operand as IMethod;
}
else if ((instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call)) != null) {
delegateType = instrs[0].Operand as TypeReference;
methodToken = DotNetUtils.getLdcI4Value(instrs[1]);
delegateType = instrs[0].Operand as ITypeDefOrRef;
methodToken = instrs[1].GetLdcI4Value();
declaringTypeToken = -1;
delegateField = instrs[2].Operand as FieldReference;
createMethod = instrs[3].Operand as MethodReference;
delegateField = instrs[2].Operand as IField;
createMethod = instrs[3].Operand as IMethod;
}
else
continue;
@ -95,7 +95,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return null;
}
protected override void getCallInfo(object context, FieldDef field, out MethodReference calledMethod, out OpCode callOpcode) {
protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
var ctx = (Context)context;
switch (ctx.proxyCreatorType) {
@ -109,7 +109,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
throw new ApplicationException(string.Format("Invalid proxy creator type: {0}", ctx.proxyCreatorType));
}
calledMethod = module.LookupToken(ctx.methodToken) as MethodReference;
var method = module.ResolveToken(ctx.methodToken) as IMethod;
if (method.MethodSig == null)
method = null;
calledMethod = method;
}
public void findDelegateCreator() {
@ -145,7 +148,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, methodToCheck)) {
if (!calledMethod.IsStatic || calledMethod.Body == null)
continue;
if (!MemberReferenceHelper.compareTypes(methodToCheck.DeclaringType, calledMethod.DeclaringType))
if (!new SigComparer().Equals(methodToCheck.DeclaringType, calledMethod.DeclaringType))
continue;
if (DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Reflection.FieldInfo,System.Type,System.Reflection.MethodInfo)"))
return ProxyCreatorType.CallOrCallvirt;

View File

@ -26,10 +26,10 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
class ResourceDecrypterCreator {
ModuleDefinition module;
ModuleDefMD module;
ISimpleDeobfuscator simpleDeobfuscator;
public ResourceDecrypterCreator(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
public ResourceDecrypterCreator(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
this.module = module;
this.simpleDeobfuscator = simpleDeobfuscator;
}
@ -40,12 +40,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
class ResourceDecrypter {
ModuleDefinition module;
ModuleDefMD module;
ISimpleDeobfuscator simpleDeobfuscator;
MethodDef decryptMethod;
IDecrypter decrypter;
public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
this.module = module;
this.simpleDeobfuscator = simpleDeobfuscator;
}
@ -56,9 +56,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
// v3.0
class Decrypter1 : IDecrypter {
ModuleDefinition module;
ModuleDefMD module;
public Decrypter1(ModuleDefinition module) {
public Decrypter1(ModuleDefMD module) {
this.module = module;
}
@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
key = reader.ReadBytes(reader.ReadByte());
else {
key = new byte[reader.ReadByte()];
Array.Copy(module.Assembly.Name.PublicKey, 0, key, 0, key.Length);
Array.Copy(module.Assembly.PublicKey.Data, 0, key, 0, key.Length);
}
reader.ReadBytes(reader.ReadInt32()); // hash
@ -92,9 +92,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
// v3.5+
class Decrypter2 : IDecrypter {
ModuleDefinition module;
ModuleDefMD module;
public Decrypter2(ModuleDefinition module) {
public Decrypter2(ModuleDefMD module) {
this.module = module;
}
@ -143,7 +143,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
key = reader.ReadBytes(reader.ReadByte());
else {
key = new byte[reader.ReadByte()];
Array.Copy(module.Assembly.Name.PublicKey, 12, key, 0, key.Length);
Array.Copy(module.Assembly.PublicKey.Data, 12, key, 0, key.Length);
key[5] |= 0x80;
}
return isCompressed;
@ -152,10 +152,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
// v5.0+ retail
class Decrypter3 : IDecrypter {
ModuleDefinition module;
ModuleDefMD module;
Inflater inflater;
public Decrypter3(ModuleDefinition module, MethodDef decryptMethod) {
public Decrypter3(ModuleDefMD module, MethodDef decryptMethod) {
this.module = module;
this.inflater = InflaterCreator.create(decryptMethod, true);
}
@ -201,7 +201,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
key = reader.ReadBytes(reader.ReadByte());
else {
key = new byte[reader.ReadByte()];
Array.Copy(module.Assembly.Name.PublicKey, 12, key, 0, key.Length);
Array.Copy(module.Assembly.PublicKey.Data, 12, key, 0, key.Length);
key[5] |= 0x80;
}
return isCompressed;

View File

@ -20,13 +20,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
class ResourceResolver {
ModuleDefinition module;
ModuleDefMD module;
ResourceDecrypter resourceDecrypter;
ISimpleDeobfuscator simpleDeobfuscator;
TypeDef resolverType;
@ -47,7 +48,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return registerMethod; }
}
public ResourceResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) {
public ResourceResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) {
this.module = module;
this.resourceDecrypter = resourceDecrypter;
this.simpleDeobfuscator = simpleDeobfuscator;
@ -104,20 +105,20 @@ namespace de4dot.code.deobfuscators.Babel_NET {
var callvirt = instrs[i];
if (callvirt.OpCode.Code != Code.Callvirt)
continue;
var calledMethod = callvirt.Operand as MethodReference;
var calledMethod = callvirt.Operand as IMethod;
if (calledMethod == null)
continue;
if (calledMethod.FullName != "System.Int32 System.IO.BinaryReader::ReadInt32()")
continue;
var ldci4 = instrs[i + 1];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
if (instrs[i + 2].OpCode.Code != Code.Xor)
continue;
ints.Add(DotNetUtils.getLdcI4Value(ldci4));
ints.Add(ldci4.GetLdcI4Value());
}
if (ints.Count == 2) {
@ -130,14 +131,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
public EmbeddedResource mergeResources() {
if (encryptedResource == null)
return null;
DeobUtils.decryptAndAddResources(module, encryptedResource.Name, () => decryptResourceAssembly());
DeobUtils.decryptAndAddResources(module, encryptedResource.Name.String, () => decryptResourceAssembly());
var result = encryptedResource;
encryptedResource = null;
return result;
}
byte[] decryptResourceAssembly() {
var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData());
var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes());
var reader = new BinaryReader(new MemoryStream(decrypted));
int numResources = reader.ReadInt32() ^ xorKey1;

View File

@ -21,6 +21,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
@ -28,7 +29,7 @@ using de4dot.blocks.cflow;
namespace de4dot.code.deobfuscators.Babel_NET {
class StringDecrypter {
ModuleDefinition module;
ModuleDefMD module;
ResourceDecrypter resourceDecrypter;
ISimpleDeobfuscator simpleDeobfuscator;
TypeDef decrypterType;
@ -38,7 +39,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
interface IDecrypterInfo {
MethodDef Decrypter { get; }
bool NeedsResource { get; }
void initialize(ModuleDefinition module, EmbeddedResource resource);
void initialize(ModuleDefMD module, EmbeddedResource resource);
string decrypt(object[] args);
}
@ -49,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return false; }
}
public void initialize(ModuleDefinition module, EmbeddedResource resource) {
public void initialize(ModuleDefMD module, EmbeddedResource resource) {
}
public string decrypt(object[] args) {
@ -72,8 +73,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return true; }
}
public void initialize(ModuleDefinition module, EmbeddedResource resource) {
key = resource.GetResourceData();
public void initialize(ModuleDefMD module, EmbeddedResource resource) {
key = resource.Data.ReadAllBytes();
if (key.Length != 0x100)
throw new ApplicationException(string.Format("Unknown key length: {0}", key.Length));
}
@ -106,8 +107,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
this.resourceDecrypter = resourceDecrypter;
}
public void initialize(ModuleDefinition module, EmbeddedResource resource) {
var decrypted = resourceDecrypter.decrypt(resource.GetResourceData());
public void initialize(ModuleDefMD module, EmbeddedResource resource) {
var decrypted = resourceDecrypter.decrypt(resource.Data.ReadAllBytes());
var reader = new BinaryReader(new MemoryStream(decrypted));
while (reader.BaseStream.Position < reader.BaseStream.Length)
offsetToString[getOffset((int)reader.BaseStream.Position)] = reader.ReadString();
@ -118,8 +119,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0)
return offset;
if (dummyMethod == null) {
dummyMethod = new MethodDef("", 0, new TypeReference("", "", null, null));
dummyMethod.Body = new MethodBody(dummyMethod);
dummyMethod = new MethodDefUser();
dummyMethod.Body = new CilBody();
}
emulator.init(dummyMethod);
emulator.push(new Int32Value(offset));
@ -153,7 +154,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return encryptedResource; }
}
public StringDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter) {
public StringDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter) {
this.module = module;
this.resourceDecrypter = resourceDecrypter;
}
@ -212,7 +213,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
int stringLength = 0, stringToCharArray = 0, stringCtor = 0;
foreach (var instr in method.Body.Instructions) {
var calledMethod = instr.Operand as MethodReference;
var calledMethod = instr.Operand as IMethod;
if (calledMethod == null)
continue;
@ -246,7 +247,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (nested.HasProperties || nested.HasEvents)
return null;
if (DotNetUtils.getMethod(nested, ".ctor") == null)
if (nested.FindMethod(".ctor") == null)
return null;
if (nested.Fields.Count == 1 || nested.Fields.Count == 3) {
@ -259,7 +260,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (decrypterBuilderMethod == null)
return null;
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor"));
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor"));
var nestedDecrypter = DotNetUtils.getMethod(nested, "System.String", "(System.Int32)");
if (nestedDecrypter == null || nestedDecrypter.IsStatic)
@ -286,7 +287,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (decrypter == null || !decrypter.IsStatic)
return null;
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor"));
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor"));
return new DecrypterInfoV3(resourceDecrypter) { Decrypter = decrypter };
}
@ -346,7 +347,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return true;
case Code.Newarr:
var arrayType = (TypeReference)instr.Operand;
var arrayType = (ITypeDefOrRef)instr.Operand;
int arrayCount = ((Int32Value)emulator.pop()).value;
if (arrayType.FullName == "System.Char")
emulator.push(new UserValue(new char[arrayCount]));
@ -396,7 +397,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
break;
case Code.Ldsfld:
emulator.push(new UserValue((FieldReference)instr.Operand));
emulator.push(new UserValue((IField)instr.Operand));
break;
default:
@ -409,30 +410,32 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
bool doCall(Instruction instr) {
var calledMethod = (MethodReference)instr.Operand;
if (calledMethod.FullName == "System.Byte[] System.Convert::FromBase64String(System.String)") {
var calledMethod = (IMethod)instr.Operand;
var sig = calledMethod.MethodSig;
var fn = calledMethod.FullName;
if (fn == "System.Byte[] System.Convert::FromBase64String(System.String)") {
emulator.push(new UserValue(Convert.FromBase64String(((StringValue)emulator.pop()).value)));
return true;
}
else if (calledMethod.FullName == "System.String System.Text.Encoding::GetString(System.Byte[])") {
else if (fn == "System.String System.Text.Encoding::GetString(System.Byte[])") {
emulator.push(new StringValue(Encoding.UTF8.GetString((byte[])((UserValue)emulator.pop()).obj)));
return true;
}
else if (calledMethod.FullName == "System.Int32 System.Int32::Parse(System.String)") {
else if (fn == "System.Int32 System.Int32::Parse(System.String)") {
emulator.push(new Int32Value(int.Parse(((StringValue)emulator.pop()).value)));
return true;
}
else if (calledMethod.FullName == "System.String[] System.String::Split(System.Char[])") {
else if (fn == "System.String[] System.String::Split(System.Char[])") {
var ary = (char[])((UserValue)emulator.pop()).obj;
var s = ((StringValue)emulator.pop()).value;
emulator.push(new UserValue(s.Split(ary)));
return true;
}
else if (calledMethod.HasThis && calledMethod.DeclaringType.FullName == "System.Reflection.Emit.ILGenerator" && calledMethod.Name == "Emit") {
else if (sig != null && sig.HasThis && calledMethod.DeclaringType.FullName == "System.Reflection.Emit.ILGenerator" && calledMethod.Name == "Emit") {
Value operand = null;
if (calledMethod.Parameters.Count == 2)
if (calledMethod.MethodSig.GetParamCount() == 2)
operand = emulator.pop();
var opcode = reflectionToCecilOpCode((FieldReference)((UserValue)emulator.pop()).obj);
var opcode = reflectionToOpCode((IField)((UserValue)emulator.pop()).obj);
emulator.pop(); // the this ptr
addInstruction(new Instruction {
OpCode = opcode,
@ -458,8 +461,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
instructions.Add(instr);
}
static OpCode reflectionToCecilOpCode(FieldReference reflectionField) {
var field = typeof(OpCodes).GetField(reflectionField.Name);
static OpCode reflectionToOpCode(IField reflectionField) {
var field = typeof(OpCodes).GetField(reflectionField.Name.String);
if (field == null || field.FieldType != typeof(OpCode))
return null;
return (OpCode)field.GetValue(null);
@ -499,9 +502,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return -1;
}
static bool hasFieldType(IEnumerable<FieldDef> fields, TypeReference fieldType) {
static bool hasFieldType(IEnumerable<FieldDef> fields, TypeDef fieldType) {
foreach (var field in fields) {
if (MemberReferenceHelper.compareTypes(field.FieldType, fieldType))
if (new SigComparer().Equals(field.FieldSig.GetFieldType(), fieldType))
return true;
}
return false;
@ -517,32 +520,32 @@ namespace de4dot.code.deobfuscators.Babel_NET {
continue;
var ldci4 = instrs[index++];
if (!DotNetUtils.isLdcI4(ldci4))
if (!ldci4.IsLdcI4())
continue;
var callvirt = instrs[index++];
if (callvirt.OpCode.Code != Code.Callvirt)
continue;
var calledMethod = callvirt.Operand as MethodReference;
var calledMethod = callvirt.Operand as IMethod;
if (calledMethod == null)
continue;
if (calledMethod.FullName != "System.Void System.Reflection.Emit.ILGenerator::Emit(System.Reflection.Emit.OpCode,System.Int32)")
continue;
if (!DotNetUtils.isLdloc(instrs[index++]))
if (!instrs[index++].IsLdloc())
continue;
var ldsfld2 = instrs[index++];
if (ldsfld2.OpCode.Code != Code.Ldsfld)
continue;
var field = ldsfld2.Operand as FieldReference;
var field = ldsfld2.Operand as IField;
if (field == null)
continue;
if (field.FullName != "System.Reflection.Emit.OpCode System.Reflection.Emit.OpCodes::Xor")
continue;
// Here if Babel.NET 5.5
return DotNetUtils.getLdcI4Value(ldci4);
return ldci4.GetLdcI4Value();
}
// Here if Babel.NET <= 5.0
@ -552,11 +555,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
bool checkFields(TypeDef type, string fieldType1, TypeDef fieldType2) {
if (type.Fields.Count != 2)
return false;
if (type.Fields[0].FieldType.FullName != fieldType1 &&
type.Fields[1].FieldType.FullName != fieldType1)
if (type.Fields[0].FieldSig.GetFieldType().GetFullName() != fieldType1 &&
type.Fields[1].FieldSig.GetFieldType().GetFullName() != fieldType1)
return false;
if (!MemberReferenceHelper.compareTypes(type.Fields[0].FieldType, fieldType2) &&
!MemberReferenceHelper.compareTypes(type.Fields[1].FieldType, fieldType2))
if (!new SigComparer().Equals(type.Fields[0].FieldSig.GetFieldType(), fieldType2) &&
!new SigComparer().Equals(type.Fields[1].FieldSig.GetFieldType(), fieldType2))
return false;
return true;
}

View File

@ -38,8 +38,8 @@ namespace de4dot.cui {
return new List<IDeobfuscatorInfo> {
new de4dot.code.deobfuscators.Unknown.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(),
#if PORT
new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),

2
dot10

@ -1 +1 @@
Subproject commit cdf5619a39c2caf03b35569ef42383ca31971166
Subproject commit 5844915b880f422af17a3bcd234829ba32dcb6e5