Port Babel.NET deobfuscator
This commit is contained in:
parent
ce6659510e
commit
f699017197
|
@ -404,19 +404,17 @@ namespace de4dot.blocks {
|
||||||
return (FieldDefinition)field;
|
return (FieldDefinition)field;
|
||||||
return getField(getType(module, field.DeclaringType), 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)
|
if (type == null || fieldReference == null)
|
||||||
return null;
|
return null;
|
||||||
if (fieldReference is FieldDefinition)
|
if (fieldReference is FieldDef)
|
||||||
return (FieldDefinition)fieldReference;
|
return (FieldDef)fieldReference;
|
||||||
foreach (var field in type.Fields) {
|
return type.FindField(fieldReference.Name, fieldReference.FieldSig);
|
||||||
if (MemberReferenceHelper.compareFieldReference(field, fieldReference))
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PORT
|
||||||
public static FieldDefinition getField(TypeDefinition type, string typeFullName) {
|
public static FieldDefinition getField(TypeDefinition type, string typeFullName) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return 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) {
|
public static IList<Instruction> getInstructions(IList<Instruction> instructions, int i, params OpCode[] opcodes) {
|
||||||
if (i + opcodes.Length > instructions.Count)
|
if (i + opcodes.Length > instructions.Count)
|
||||||
return null;
|
return null;
|
||||||
|
@ -797,6 +794,7 @@ namespace de4dot.blocks {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if PORT
|
||||||
public static bool hasReturnValue(IMethodSignature method) {
|
public static bool hasReturnValue(IMethodSignature method) {
|
||||||
var type = method.MethodReturnType.ReturnType;
|
var type = method.MethodReturnType.ReturnType;
|
||||||
while (type.IsOptionalModifier || type.IsRequiredModifier)
|
while (type.IsOptionalModifier || type.IsRequiredModifier)
|
||||||
|
|
|
@ -76,22 +76,22 @@
|
||||||
<Compile Include="deobfuscators\Agile_NET\vm\UnknownHandlerInfo.cs" />
|
<Compile Include="deobfuscators\Agile_NET\vm\UnknownHandlerInfo.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\vm\VmOpCodeHandlerDetector.cs" />
|
<Compile Include="deobfuscators\Agile_NET\vm\VmOpCodeHandlerDetector.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\vm\VmOperands.cs" />
|
<Compile Include="deobfuscators\Agile_NET\vm\VmOperands.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\AssemblyResolver.cs" />
|
<Compile Include="deobfuscators\Babel_NET\AssemblyResolver.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\BabelInflater.cs" />
|
<Compile Include="deobfuscators\Babel_NET\BabelInflater.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\BabelMethodCallInliner.cs" />
|
<Compile Include="deobfuscators\Babel_NET\BabelMethodCallInliner.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\BabelUtils.cs" />
|
<Compile Include="deobfuscators\Babel_NET\BabelUtils.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\ConstantsDecrypter.cs" />
|
<Compile Include="deobfuscators\Babel_NET\ConstantsDecrypter.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\Deobfuscator.cs" />
|
<Compile Include="deobfuscators\Babel_NET\Deobfuscator.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\ImageReader.cs" />
|
<Compile Include="deobfuscators\Babel_NET\ImageReader.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\InflaterCreator.cs" />
|
<Compile Include="deobfuscators\Babel_NET\InflaterCreator.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\MemberReferenceConverter.cs" />
|
<Compile Include="deobfuscators\Babel_NET\MemberReferenceConverter.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\MethodBodyReader.cs" />
|
<Compile Include="deobfuscators\Babel_NET\MethodBodyReader.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\MethodReferenceReader.cs" />
|
<Compile Include="deobfuscators\Babel_NET\MethodReferenceReader.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\MethodsDecrypter.cs" />
|
<Compile Include="deobfuscators\Babel_NET\MethodsDecrypter.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\ProxyCallFixer.cs" />
|
<Compile Include="deobfuscators\Babel_NET\ProxyCallFixer.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\ResourceDecrypter.cs" />
|
<Compile Include="deobfuscators\Babel_NET\ResourceDecrypter.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\ResourceResolver.cs" />
|
<Compile Include="deobfuscators\Babel_NET\ResourceResolver.cs" />
|
||||||
<None Include="deobfuscators\Babel_NET\StringDecrypter.cs" />
|
<Compile Include="deobfuscators\Babel_NET\StringDecrypter.cs" />
|
||||||
<Compile Include="deobfuscators\Blowfish.cs" />
|
<Compile Include="deobfuscators\Blowfish.cs" />
|
||||||
<None Include="deobfuscators\CodeFort\AssemblyData.cs" />
|
<None Include="deobfuscators\CodeFort\AssemblyData.cs" />
|
||||||
<None Include="deobfuscators\CodeFort\AssemblyDecrypter.cs" />
|
<None Include="deobfuscators\CodeFort\AssemblyDecrypter.cs" />
|
||||||
|
|
|
@ -19,12 +19,13 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class AssemblyResolver {
|
class AssemblyResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
TypeDef resolverType;
|
TypeDef resolverType;
|
||||||
MethodDef registerMethod;
|
MethodDef registerMethod;
|
||||||
|
@ -63,7 +64,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return embeddedAssemblyInfos; }
|
get { return embeddedAssemblyInfos; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssemblyResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter) {
|
public AssemblyResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.resourceDecrypter = resourceDecrypter;
|
this.resourceDecrypter = resourceDecrypter;
|
||||||
}
|
}
|
||||||
|
@ -114,14 +115,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData());
|
var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes());
|
||||||
var reader = new BinaryReader(new MemoryStream(decrypted));
|
var reader = new BinaryReader(new MemoryStream(decrypted));
|
||||||
int numAssemblies = reader.ReadInt32();
|
int numAssemblies = reader.ReadInt32();
|
||||||
embeddedAssemblyInfos = new EmbeddedAssemblyInfo[numAssemblies];
|
embeddedAssemblyInfos = new EmbeddedAssemblyInfo[numAssemblies];
|
||||||
for (int i = 0; i < numAssemblies; i++) {
|
for (int i = 0; i < numAssemblies; i++) {
|
||||||
string name = reader.ReadString();
|
string name = reader.ReadString();
|
||||||
var data = reader.ReadBytes(reader.ReadInt32());
|
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);
|
embeddedAssemblyInfos[i] = new EmbeddedAssemblyInfo(name, DeobUtils.getExtension(mod.Kind), data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
branchEmulator = new BranchEmulator(emulator, this);
|
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>();
|
var notInlinedMethodsDict = new Dictionary<MethodDef, bool>();
|
||||||
foreach (var method in notInlinedMethods)
|
foreach (var method in notInlinedMethods)
|
||||||
notInlinedMethodsDict[method] = true;
|
notInlinedMethodsDict[method] = true;
|
||||||
|
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return false;
|
return false;
|
||||||
if (!method.IsAssembly)
|
if (!method.IsAssembly)
|
||||||
return false;
|
return false;
|
||||||
if (method.GenericParameters.Count > 0)
|
if (method.MethodSig.GetGenParamCount() > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return method.IsStatic;
|
return method.IsStatic;
|
||||||
|
@ -233,8 +233,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool isCompatibleType(int paramIndex, TypeReference origType, TypeReference newType) {
|
protected override bool isCompatibleType(int paramIndex, IType origType, IType newType) {
|
||||||
if (MemberReferenceHelper.compareTypes(origType, newType))
|
if (new SigComparer().Equals(origType, newType))
|
||||||
return true;
|
return true;
|
||||||
if (newType.IsValueType || origType.IsValueType)
|
if (newType.IsValueType || origType.IsValueType)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,18 +25,18 @@ using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
static class BabelUtils {
|
static class BabelUtils {
|
||||||
public static EmbeddedResource findEmbeddedResource(ModuleDefinition module, TypeDef decrypterType) {
|
public static EmbeddedResource findEmbeddedResource(ModuleDefMD module, TypeDef decrypterType) {
|
||||||
return findEmbeddedResource(module, decrypterType, (method) => { });
|
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) => {
|
return findEmbeddedResource(module, decrypterType, (method) => {
|
||||||
simpleDeobfuscator.deobfuscate(method);
|
simpleDeobfuscator.deobfuscate(method);
|
||||||
simpleDeobfuscator.decryptStrings(method, deob);
|
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) {
|
foreach (var method in decrypterType.Methods) {
|
||||||
if (!DotNetUtils.isMethod(method, "System.String", "()"))
|
if (!DotNetUtils.isMethod(method, "System.String", "()"))
|
||||||
continue;
|
continue;
|
||||||
|
@ -50,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EmbeddedResource findEmbeddedResource1(ModuleDefinition module, MethodDef method) {
|
static EmbeddedResource findEmbeddedResource1(ModuleDefMD module, MethodDef method) {
|
||||||
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
foreach (var s in DotNetUtils.getCodeStrings(method)) {
|
||||||
var resource = DotNetUtils.getResource(module, s) as EmbeddedResource;
|
var resource = DotNetUtils.getResource(module, s) as EmbeddedResource;
|
||||||
if (resource != null)
|
if (resource != null)
|
||||||
|
@ -59,7 +59,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static EmbeddedResource findEmbeddedResource2(ModuleDefinition module, MethodDef method) {
|
static EmbeddedResource findEmbeddedResource2(ModuleDefMD module, MethodDef method) {
|
||||||
var strings = new List<string>(DotNetUtils.getCodeStrings(method));
|
var strings = new List<string>(DotNetUtils.getCodeStrings(method));
|
||||||
if (strings.Count != 1)
|
if (strings.Count != 1)
|
||||||
return null;
|
return null;
|
||||||
|
@ -83,13 +83,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var ldci4 = instrs[i + 1];
|
var ldci4 = instrs[i + 1];
|
||||||
if (!DotNetUtils.isLdcI4(ldci4))
|
if (!ldci4.IsLdcI4())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xorKey = DotNetUtils.getLdcI4Value(ldci4);
|
xorKey = ldci4.GetLdcI4Value();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +107,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Ldftn)
|
if (instr.OpCode.Code != Code.Ldftn)
|
||||||
continue;
|
continue;
|
||||||
var handlerRef = instr.Operand as MethodReference;
|
var handlerRef = instr.Operand as IMethod;
|
||||||
if (handlerRef == null)
|
if (handlerRef == null)
|
||||||
continue;
|
continue;
|
||||||
if (!DotNetUtils.isMethod(handlerRef, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
|
if (!DotNetUtils.isMethod(handlerRef, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)"))
|
||||||
continue;
|
continue;
|
||||||
if (!MemberReferenceHelper.compareTypes(type, handlerRef.DeclaringType))
|
if (!new SigComparer().Equals(type, handlerRef.DeclaringType))
|
||||||
continue;
|
continue;
|
||||||
handler = DotNetUtils.getMethod(type, handlerRef);
|
handler = DotNetUtils.getMethod(type, handlerRef);
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
|
|
|
@ -21,13 +21,14 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class ConstantsDecrypter {
|
class ConstantsDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
InitializedDataCreator initializedDataCreator;
|
InitializedDataCreator initializedDataCreator;
|
||||||
TypeDef decrypterType;
|
TypeDef decrypterType;
|
||||||
|
@ -78,7 +79,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return arrayDecrypter; }
|
get { return arrayDecrypter; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantsDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter, InitializedDataCreator initializedDataCreator) {
|
public ConstantsDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter, InitializedDataCreator initializedDataCreator) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.resourceDecrypter = resourceDecrypter;
|
this.resourceDecrypter = resourceDecrypter;
|
||||||
this.initializedDataCreator = initializedDataCreator;
|
this.initializedDataCreator = initializedDataCreator;
|
||||||
|
@ -109,7 +110,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (!checkNestedFields(nested))
|
if (!checkNestedFields(nested))
|
||||||
return false;
|
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)
|
if (DotNetUtils.getMethod(type, "System.Int32", "(System.Int32)") == null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -135,7 +136,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (!new FieldTypes(nested).all(requiredTypes))
|
if (!new FieldTypes(nested).all(requiredTypes))
|
||||||
return false;
|
return false;
|
||||||
foreach (var field in nested.Fields) {
|
foreach (var field in nested.Fields) {
|
||||||
if (MemberReferenceHelper.compareTypes(nested, field.FieldType))
|
if (new SigComparer().Equals(nested, field.FieldSig.GetFieldType()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -151,7 +152,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData());
|
var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes());
|
||||||
var reader = new BinaryReader(new MemoryStream(decrypted));
|
var reader = new BinaryReader(new MemoryStream(decrypted));
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
@ -194,10 +195,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
struct ArrayInfo {
|
struct ArrayInfo {
|
||||||
public FieldDef encryptedField;
|
public FieldDef encryptedField;
|
||||||
public ArrayType arrayType;
|
public SZArraySig arrayType;
|
||||||
public int start, len;
|
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.start = start;
|
||||||
this.len = len;
|
this.len = len;
|
||||||
this.encryptedField = encryptedField;
|
this.encryptedField = encryptedField;
|
||||||
|
@ -239,23 +240,23 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var call1 = instrs[index++];
|
var call1 = instrs[index++];
|
||||||
if (call1.OpCode.Code != Code.Call && call1.OpCode.Code != Code.Callvirt)
|
if (call1.OpCode.Code != Code.Call && call1.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
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;
|
continue;
|
||||||
|
|
||||||
var call2 = instrs[index++];
|
var call2 = instrs[index++];
|
||||||
if (call2.OpCode.Code != Code.Call && call2.OpCode.Code != Code.Callvirt)
|
if (call2.OpCode.Code != Code.Call && call2.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
continue;
|
||||||
if (!MemberReferenceHelper.compareMethodReferenceAndDeclaringType(call2.Operand as MethodReference, arrayDecrypter))
|
if (!MethodEqualityComparer.CompareDeclaringTypes.Equals(call2.Operand as IMethod, arrayDecrypter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var castclass = instrs[index++];
|
var castclass = instrs[index++];
|
||||||
if (castclass.OpCode.Code != Code.Castclass)
|
if (castclass.OpCode.Code != Code.Castclass)
|
||||||
continue;
|
continue;
|
||||||
var arrayType = castclass.Operand as ArrayType;
|
var arrayType = (castclass.Operand as ITypeDefOrRef).ToSZArraySig();
|
||||||
if (arrayType == null)
|
if (arrayType == null)
|
||||||
continue;
|
continue;
|
||||||
if (arrayType.ElementType.GetPrimitiveSize() == -1) {
|
if (arrayType.Next.ElementType.GetPrimitiveSize() == -1) {
|
||||||
Log.w("Can't decrypt non-primitive type array in method {0}", blocks.Method.MDToken.ToInt32());
|
Log.w("Can't decrypt non-primitive type array in method {0:X8}", blocks.Method.MDToken.ToInt32());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,11 +265,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
infos.Reverse();
|
infos.Reverse();
|
||||||
foreach (var info in infos) {
|
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);
|
var decrypted = decryptArray(info.encryptedField.InitialValue, elemSize);
|
||||||
|
|
||||||
initializedDataCreator.addInitializeArrayCode(block, info.start, info.len, info.arrayType.ElementType, decrypted);
|
initializedDataCreator.addInitializeArrayCode(block, info.start, info.len, info.arrayType.Next.ToTypeDefOrRef(), decrypted);
|
||||||
Log.v("Decrypted {0} array: {1} elements", info.arrayType.ElementType.ToString(), decrypted.Length / elemSize);
|
Log.v("Decrypted {0} array: {1} elements", info.arrayType.Next.ToString(), decrypted.Length / elemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void init(ModuleDefinition module) {
|
public override void init(ModuleDefMD module) {
|
||||||
base.init(module);
|
base.init(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,9 +183,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkVersion(TypeDef attr) {
|
void checkVersion(TypeDef attr) {
|
||||||
var versionField = DotNetUtils.getFieldByName(attr, "Version");
|
var versionField = attr.FindField("Version");
|
||||||
if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant is string) {
|
if (versionField != null && versionField.IsLiteral && versionField.Constant != null && versionField.Constant.Value is string) {
|
||||||
var val = Regex.Match((string)versionField.Constant, @"^(\d+\.\d+\.\d+\.\d+)$");
|
var val = Regex.Match((string)versionField.Constant.Value, @"^(\d+\.\d+\.\d+\.\d+)$");
|
||||||
if (val.Groups.Count < 2)
|
if (val.Groups.Count < 2)
|
||||||
return;
|
return;
|
||||||
obfuscatorName = string.Format("{0} {1}", DeobfuscatorInfo.THE_NAME, val.Groups[1].ToString());
|
obfuscatorName = string.Format("{0} {1}", DeobfuscatorInfo.THE_NAME, val.Groups[1].ToString());
|
||||||
|
|
|
@ -22,10 +22,14 @@ using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
|
using CR = System.Runtime.InteropServices;
|
||||||
|
using DR = dot10.DotNet;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class ImageReader {
|
class ImageReader {
|
||||||
static int METHODS_SIG = 0x0000BEBA;
|
static int METHODS_SIG = 0x0000BEBA;
|
||||||
|
@ -43,19 +47,19 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
ByRef = 4,
|
ByRef = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
BinaryReader reader;
|
IBinaryReader reader;
|
||||||
string[] strings;
|
string[] strings;
|
||||||
AssemblyNameReference[] assemblyNames;
|
AssemblyRef[] assemblyNames;
|
||||||
Dictionary<string, int> methodOffsets;
|
Dictionary<string, int> methodOffsets;
|
||||||
List<TypeReference> typeReferences;
|
List<TypeSig> typeReferences;
|
||||||
MemberReferenceConverter memberReferenceConverter;
|
MemberReferenceConverter memberReferenceConverter;
|
||||||
IDeobfuscatorContext deobfuscatorContext;
|
IDeobfuscatorContext deobfuscatorContext;
|
||||||
|
|
||||||
public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefinition module, byte[] data) {
|
public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, byte[] data) {
|
||||||
this.deobfuscatorContext = deobfuscatorContext;
|
this.deobfuscatorContext = deobfuscatorContext;
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.reader = new BinaryReader(new MemoryStream(data));
|
this.reader = MemoryImageStream.Create(data);
|
||||||
this.memberReferenceConverter = new MemberReferenceConverter(module);
|
this.memberReferenceConverter = new MemberReferenceConverter(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,14 +71,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (metadataOffset < 0)
|
if (metadataOffset < 0)
|
||||||
return false;
|
return false;
|
||||||
long pos = metadataOffset + 4;
|
long pos = metadataOffset + 4;
|
||||||
reader.BaseStream.Position = pos;
|
reader.Position = pos;
|
||||||
int version = reader.ReadInt16(); // major, minor
|
int version = reader.ReadInt16(); // major, minor
|
||||||
if (version == 0x0001) {
|
if (version == 0x0001) {
|
||||||
initializeV10();
|
initializeV10();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.BaseStream.Position = pos;
|
reader.Position = pos;
|
||||||
initializeV55();
|
initializeV55();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -108,18 +112,18 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var babelMethod = getMethod(name);
|
var babelMethod = getMethod(name);
|
||||||
var body = method.Body;
|
var body = method.Body;
|
||||||
|
|
||||||
body.MaxStackSize = babelMethod.MaxStack;
|
body.MaxStack = babelMethod.MaxStack;
|
||||||
body.InitLocals = babelMethod.InitLocals;
|
body.InitLocals = babelMethod.InitLocals;
|
||||||
|
|
||||||
body.Variables.Clear();
|
body.LocalList.Clear();
|
||||||
foreach (var local in babelMethod.Locals)
|
foreach (var local in babelMethod.Locals)
|
||||||
body.Variables.Add(local);
|
body.LocalList.Add(local);
|
||||||
|
|
||||||
var toNewOperand = new Dictionary<object, object>();
|
var toNewOperand = new Dictionary<object, object>();
|
||||||
if (babelMethod.ThisParameter != null)
|
if (babelMethod.ThisParameter != null)
|
||||||
toNewOperand[babelMethod.ThisParameter] = body.ThisParameter;
|
toNewOperand[babelMethod.ThisParameter] = method.Parameters[0];
|
||||||
for (int i = 0; i < method.Parameters.Count; i++)
|
for (int i = 0; i < babelMethod.Parameters.Length; i++)
|
||||||
toNewOperand[babelMethod.Parameters[i]] = method.Parameters[i];
|
toNewOperand[babelMethod.Parameters[i]] = method.Parameters[i + method.Parameters.MethodSigIndexBase];
|
||||||
|
|
||||||
body.Instructions.Clear();
|
body.Instructions.Clear();
|
||||||
foreach (var instr in babelMethod.Instructions) {
|
foreach (var instr in babelMethod.Instructions) {
|
||||||
|
@ -137,7 +141,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
BabelMethodDefinition getMethod(string name) {
|
BabelMethodDefinition getMethod(string name) {
|
||||||
int offset = methodOffsets[name];
|
int offset = methodOffsets[name];
|
||||||
methodOffsets.Remove(name);
|
methodOffsets.Remove(name);
|
||||||
reader.BaseStream.Position = offset;
|
reader.Position = offset;
|
||||||
return new MethodDefinitionReader(this, reader).read();
|
return new MethodDefinitionReader(this, reader).read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,20 +149,20 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return strings[readVariableLengthInt32()];
|
return strings[readVariableLengthInt32()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeReference readTypeReference() {
|
public TypeSig readTypeSig() {
|
||||||
return typeReferences[readVariableLengthInt32()];
|
return typeReferences[readVariableLengthInt32()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeReference[] readTypeReferences() {
|
public TypeSig[] readTypeSigs() {
|
||||||
var refs = new TypeReference[readVariableLengthInt32()];
|
var refs = new TypeSig[readVariableLengthInt32()];
|
||||||
for (int i = 0; i < refs.Length; i++)
|
for (int i = 0; i < refs.Length; i++)
|
||||||
refs[i] = readTypeReference();
|
refs[i] = readTypeSig();
|
||||||
return refs;
|
return refs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldReference readFieldReference() {
|
public IField readFieldReference() {
|
||||||
var name = readString();
|
var name = readString();
|
||||||
var declaringType = readTypeReference();
|
var declaringType = readTypeSig();
|
||||||
|
|
||||||
var fields = getFields(resolve(declaringType), name);
|
var fields = getFields(resolve(declaringType), name);
|
||||||
if (fields == null || fields.Count != 1) {
|
if (fields == null || fields.Count != 1) {
|
||||||
|
@ -173,15 +177,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
static List<FieldDef> getFields(TypeDef type, string name) {
|
static List<FieldDef> getFields(TypeDef type, string name) {
|
||||||
if (type == null)
|
if (type == null)
|
||||||
return null;
|
return null;
|
||||||
var fields = new List<FieldDef>();
|
return new List<FieldDef>(type.FindFields(name));
|
||||||
foreach (var field in type.Fields) {
|
|
||||||
if (field.Name == name)
|
|
||||||
fields.Add(field);
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference readMethodReference() {
|
public IMethod readMethodReference() {
|
||||||
var babelMethodRef = new MethodReferenceReader(this, reader).read();
|
var babelMethodRef = new MethodReferenceReader(this, reader).read();
|
||||||
|
|
||||||
var method = getMethodReference(babelMethodRef);
|
var method = getMethodReference(babelMethodRef);
|
||||||
|
@ -191,16 +190,15 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
Utils.removeNewlines(babelMethodRef.DeclaringType)));
|
Utils.removeNewlines(babelMethodRef.DeclaringType)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var git = babelMethodRef.DeclaringType as GenericInstanceType;
|
var git = babelMethodRef.DeclaringType.ToGenericInstSig();
|
||||||
if (git == null)
|
if (git == null)
|
||||||
return method;
|
return method;
|
||||||
|
|
||||||
var newMethod = memberReferenceConverter.copy(method);
|
var mr = new MemberRefUser(module, method.Name, method.MethodSig.Clone(), babelMethodRef.DeclaringType.ToTypeDefOrRef());
|
||||||
newMethod.DeclaringType = babelMethodRef.DeclaringType;
|
return module.UpdateRowId(mr);
|
||||||
return newMethod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodReference getMethodReference(BabelMethodreference babelMethodRef) {
|
IMethod getMethodReference(BabelMethodreference babelMethodRef) {
|
||||||
var declaringType = resolve(babelMethodRef.DeclaringType);
|
var declaringType = resolve(babelMethodRef.DeclaringType);
|
||||||
if (declaringType == null)
|
if (declaringType == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -215,20 +213,19 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return methods[0];
|
return methods[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MethodReference> getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) {
|
List<IMethod> getMethods(TypeDef declaringType, BabelMethodreference babelMethodRef) {
|
||||||
var methods = new List<MethodReference>();
|
var methods = new List<IMethod>();
|
||||||
|
|
||||||
var git = babelMethodRef.DeclaringType as GenericInstanceType;
|
var gis = babelMethodRef.DeclaringType as GenericInstSig;
|
||||||
IGenericInstance gim = babelMethodRef.IsGenericMethod ? babelMethodRef : null;
|
var gim = babelMethodRef.GenericArguments;
|
||||||
foreach (var method in declaringType.Methods) {
|
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)
|
if (!babelMethodRef.IsGenericMethod)
|
||||||
methods.Add(memberReferenceConverter.convert(method));
|
methods.Add(memberReferenceConverter.convert(method));
|
||||||
else {
|
else {
|
||||||
var gim2 = new GenericInstanceMethod(memberReferenceConverter.convert(method));
|
var gim2 = new GenericInstMethodSig(babelMethodRef.GenericArguments);
|
||||||
foreach (var arg in babelMethodRef.GenericArguments)
|
var ms = module.UpdateRowId(new MethodSpecUser(memberReferenceConverter.convert(method), gim2));
|
||||||
gim2.GenericArguments.Add(arg);
|
methods.Add(ms);
|
||||||
methods.Add(gim2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,66 +233,71 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return methods;
|
return methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool compareMethod(MethodReference method, BabelMethodreference babelMethodRef) {
|
bool compareMethod(IMethod method, BabelMethodreference babelMethodRef) {
|
||||||
if (method.Parameters.Count != babelMethodRef.Parameters.Length)
|
var sig = method.MethodSig;
|
||||||
|
if (sig.Params.Count != babelMethodRef.Parameters.Length)
|
||||||
return false;
|
return false;
|
||||||
if (method.Name != babelMethodRef.Name)
|
if (method.Name != babelMethodRef.Name)
|
||||||
return false;
|
return false;
|
||||||
if (method.HasThis != babelMethodRef.HasThis)
|
if (sig.HasThis != babelMethodRef.HasThis)
|
||||||
return false;
|
return false;
|
||||||
if (method.GenericParameters.Count != babelMethodRef.GenericArguments.Length)
|
if (sig.GenParamCount != babelMethodRef.GenericArguments.Length)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!MemberReferenceHelper.compareTypes(method.MethodReturnType.ReturnType, babelMethodRef.ReturnType))
|
if (!new SigComparer().Equals(sig.RetType, babelMethodRef.ReturnType))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int i = 0; i < babelMethodRef.Parameters.Length; i++) {
|
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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeDef resolve(TypeReference type) {
|
TypeDef resolve(TypeSig type) {
|
||||||
if (type is TypeDef)
|
type = type.RemovePinnedAndModifiers();
|
||||||
return (TypeDef)type;
|
|
||||||
|
|
||||||
if (type.IsGenericInstance)
|
var gis = type as GenericInstSig;
|
||||||
type = ((GenericInstanceType)type).ElementType;
|
if (gis != null)
|
||||||
|
type = gis.GenericType;
|
||||||
|
|
||||||
if (type.Module == module && isModuleAssembly(type.Scope))
|
var tdrs = type as TypeDefOrRefSig;
|
||||||
return DotNetUtils.getType(module, type);
|
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() {
|
public MethodSig readCallSite() {
|
||||||
var returnType = readTypeReference();
|
var returnType = readTypeSig();
|
||||||
var paramTypes = readTypeReferences();
|
var paramTypes = readTypeSigs();
|
||||||
var callingConvention = (CallingConvention)reader.ReadInt32();
|
var callingConvention = (CR.CallingConvention)reader.ReadInt32();
|
||||||
|
|
||||||
var cs = new CallSite(returnType);
|
return new MethodSig(convertCallingConvention(callingConvention), 0, returnType, paramTypes);
|
||||||
foreach (var paramType in paramTypes)
|
|
||||||
cs.Parameters.Add(new ParameterDefinition(paramType));
|
|
||||||
cs.CallingConvention = convertCallingConvention(callingConvention);
|
|
||||||
|
|
||||||
return cs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MethodCallingConvention convertCallingConvention(CallingConvention callingConvention) {
|
static DR.CallingConvention convertCallingConvention(CR.CallingConvention callingConvention) {
|
||||||
switch (callingConvention) {
|
switch (callingConvention) {
|
||||||
case CallingConvention.Winapi: return MethodCallingConvention.Default;
|
case CR.CallingConvention.Winapi: return DR.CallingConvention.Default;
|
||||||
case CallingConvention.Cdecl: return MethodCallingConvention.C;
|
case CR.CallingConvention.Cdecl: return DR.CallingConvention.C;
|
||||||
case CallingConvention.StdCall: return MethodCallingConvention.StdCall;
|
case CR.CallingConvention.StdCall: return DR.CallingConvention.StdCall;
|
||||||
case CallingConvention.ThisCall: return MethodCallingConvention.ThisCall;
|
case CR.CallingConvention.ThisCall: return DR.CallingConvention.ThisCall;
|
||||||
case CallingConvention.FastCall: return MethodCallingConvention.FastCall;
|
case CR.CallingConvention.FastCall: return DR.CallingConvention.FastCall;
|
||||||
default: throw new ApplicationException(string.Format("Unknown CallingConvention {0}", callingConvention));
|
default: throw new ApplicationException(string.Format("Unknown CallingConvention {0}", callingConvention));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeStrings(int headerOffset) {
|
void initializeStrings(int headerOffset) {
|
||||||
reader.BaseStream.Position = headerOffset;
|
reader.Position = headerOffset;
|
||||||
if (reader.ReadInt32() != STRINGS_SIG)
|
if (reader.ReadInt32() != STRINGS_SIG)
|
||||||
throw new ApplicationException("Invalid strings sig");
|
throw new ApplicationException("Invalid strings sig");
|
||||||
|
|
||||||
|
@ -305,27 +307,17 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeAssemblyNames(int headerOffset) {
|
void initializeAssemblyNames(int headerOffset) {
|
||||||
reader.BaseStream.Position = headerOffset;
|
reader.Position = headerOffset;
|
||||||
if (reader.ReadInt32() != ASSEMBLY_NAMES_SIG)
|
if (reader.ReadInt32() != ASSEMBLY_NAMES_SIG)
|
||||||
throw new ApplicationException("Invalid 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++)
|
for (int i = 0; i < assemblyNames.Length; i++)
|
||||||
assemblyNames[i] = getModuleAssemblyReference(AssemblyNameReference.Parse(readString()));
|
assemblyNames[i] = module.UpdateRowId(new AssemblyRefUser(new AssemblyNameInfo(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeMethodNames(int headerOffset) {
|
void initializeMethodNames(int headerOffset) {
|
||||||
reader.BaseStream.Position = headerOffset;
|
reader.Position = headerOffset;
|
||||||
if (reader.ReadInt32() != METHOD_NAMES_SIG)
|
if (reader.ReadInt32() != METHOD_NAMES_SIG)
|
||||||
throw new ApplicationException("Invalid methods sig");
|
throw new ApplicationException("Invalid methods sig");
|
||||||
|
|
||||||
|
@ -338,14 +330,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeTypeReferences(int headerOffset) {
|
void initializeTypeReferences(int headerOffset) {
|
||||||
reader.BaseStream.Position = headerOffset;
|
reader.Position = headerOffset;
|
||||||
if (reader.ReadInt32() != TYPEREFS_SIG)
|
if (reader.ReadInt32() != TYPEREFS_SIG)
|
||||||
throw new ApplicationException("Invalid typerefs sig");
|
throw new ApplicationException("Invalid typerefs sig");
|
||||||
|
|
||||||
int numTypeRefs = reader.ReadInt32();
|
int numTypeRefs = reader.ReadInt32();
|
||||||
typeReferences = new List<TypeReference>(numTypeRefs + 1);
|
typeReferences = new List<TypeSig>(numTypeRefs + 1);
|
||||||
typeReferences.Add(null);
|
typeReferences.Add(null);
|
||||||
var genericArgFixes = new Dictionary<GenericInstanceType, List<int>>();
|
var genericArgFixes = new Dictionary<GenericInstSig, List<int>>();
|
||||||
for (int i = 0; i < numTypeRefs; i++) {
|
for (int i = 0; i < numTypeRefs; i++) {
|
||||||
TypeId typeId = (TypeId)reader.ReadByte();
|
TypeId typeId = (TypeId)reader.ReadByte();
|
||||||
switch (typeId) {
|
switch (typeId) {
|
||||||
|
@ -384,35 +376,30 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeReference readTypeRef() {
|
TypeSig readTypeRef() {
|
||||||
string ns, name;
|
string ns, name;
|
||||||
parseReflectionTypeName(readString(), out ns, out name);
|
parseReflectionTypeName(readString(), out ns, out name);
|
||||||
var asmRef = assemblyNames[readVariableLengthInt32()];
|
var asmRef = assemblyNames[readVariableLengthInt32()];
|
||||||
var declaringType = readTypeReference();
|
var declaringType = readTypeSig();
|
||||||
var typeReference = new TypeReference(ns, name, module, asmRef) {
|
var typeReference = new TypeRefUser(module, ns, name);
|
||||||
DeclaringType = declaringType,
|
if (declaringType != null)
|
||||||
};
|
typeReference.ResolutionScope = getTypeRef(declaringType);
|
||||||
typeReference.UpdateElementType();
|
else
|
||||||
|
typeReference.ResolutionScope = asmRef;
|
||||||
|
|
||||||
typeReference = memberReferenceConverter.convert(typeReference);
|
return memberReferenceConverter.convert(typeReference);
|
||||||
typeReference.IsValueType = isValueType(typeReference);
|
|
||||||
return typeReference;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValueType(TypeReference typeRef) {
|
TypeRef getTypeRef(TypeSig type) {
|
||||||
var typeDef = typeRef as TypeDef;
|
var tdr = type as TypeDefOrRefSig;
|
||||||
if (typeDef != null)
|
if (tdr == null)
|
||||||
return typeDef.IsValueType;
|
throw new ApplicationException("Not a type ref");
|
||||||
|
if (tdr.TypeRef != null)
|
||||||
if (typeRef.Module == module && isModuleAssembly(typeRef.Scope))
|
return tdr.TypeRef;
|
||||||
typeDef = DotNetUtils.getType(module, typeRef);
|
var td = tdr.TypeDef;
|
||||||
else
|
if (td != null)
|
||||||
typeDef = resolve(typeRef);
|
return new Importer(module).Import(td) as TypeRef;
|
||||||
if (typeDef != null)
|
throw new ApplicationException("Not a type ref");
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parseReflectionTypeName(string fullName, out string ns, out string name) {
|
static void parseReflectionTypeName(string fullName, out string ns, out string name) {
|
||||||
|
@ -461,8 +448,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericInstanceType readGenericInstanceType(out List<int> genericArgs) {
|
GenericInstSig readGenericInstanceType(out List<int> genericArgs) {
|
||||||
var git = new GenericInstanceType(readTypeReference());
|
var git = new GenericInstSig(readTypeSig() as ClassOrValueTypeSig);
|
||||||
int numArgs = readVariableLengthInt32();
|
int numArgs = readVariableLengthInt32();
|
||||||
genericArgs = new List<int>(numArgs);
|
genericArgs = new List<int>(numArgs);
|
||||||
for (int i = 0; i < numArgs; i++)
|
for (int i = 0; i < numArgs; i++)
|
||||||
|
@ -470,28 +457,40 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return git;
|
return git;
|
||||||
}
|
}
|
||||||
|
|
||||||
PointerType readPointerType() {
|
PtrSig readPointerType() {
|
||||||
return new PointerType(readTypeReference());
|
return new PtrSig(readTypeSig());
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayType readArrayType() {
|
TypeSig readArrayType() {
|
||||||
return new ArrayType(readTypeReference(), readVariableLengthInt32());
|
var typeSig = readTypeSig();
|
||||||
|
int rank = readVariableLengthInt32();
|
||||||
|
if (rank == 1)
|
||||||
|
return new SZArraySig(typeSig);
|
||||||
|
return new ArraySig(typeSig, rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByReferenceType readByReferenceType() {
|
ByRefSig readByReferenceType() {
|
||||||
return new ByReferenceType(readTypeReference());
|
return new ByRefSig(readTypeSig());
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint readVariableLengthUInt32() {
|
||||||
|
uint val;
|
||||||
|
reader.ReadCompressedUInt32(out val);
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int readVariableLengthInt32() {
|
public int readVariableLengthInt32() {
|
||||||
return DeobUtils.readVariableLengthInt32(reader);
|
uint val;
|
||||||
|
reader.ReadCompressedUInt32(out val);
|
||||||
|
return (int)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMetadataOffset() {
|
int getMetadataOffset() {
|
||||||
reader.BaseStream.Position = reader.BaseStream.Length - 4;
|
reader.Position = reader.Length - 4;
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
if (reader.ReadInt32() == METADATA_SIG)
|
if (reader.ReadInt32() == METADATA_SIG)
|
||||||
return (int)reader.BaseStream.Position - 4;
|
return (int)reader.Position - 4;
|
||||||
reader.BaseStream.Position -= 8;
|
reader.Position -= 8;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
var type = calledMethod.DeclaringType;
|
var type = calledMethod.DeclaringType;
|
||||||
foreach (var nested in type.NestedTypes) {
|
foreach (var nested in type.NestedTypes) {
|
||||||
if (DeobUtils.hasInteger(DotNetUtils.getMethod(nested, ".ctor"), 0x8001))
|
if (DeobUtils.hasInteger(nested.FindMethod(".ctor"), 0x8001))
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var instrs = method.Body.Instructions;
|
var instrs = method.Body.Instructions;
|
||||||
for (int i = 0; i < instrs.Count - 3; i++) {
|
for (int i = 0; i < instrs.Count - 3; i++) {
|
||||||
var ldci4_1 = instrs[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;
|
continue;
|
||||||
|
|
||||||
var callvirt = instrs[i + 1];
|
var callvirt = instrs[i + 1];
|
||||||
|
@ -106,13 +106,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var ldci4_2 = instrs[i + 2];
|
var ldci4_2 = instrs[i + 2];
|
||||||
if (!DotNetUtils.isLdcI4(ldci4_2))
|
if (!ldci4_2.IsLdcI4())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (instrs[i + 3].OpCode.Code != Code.Xor)
|
if (instrs[i + 3].OpCode.Code != Code.Xor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return DotNetUtils.getLdcI4Value(ldci4_2);
|
return ldci4_2.GetLdcI4Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -22,123 +22,57 @@ using dot10.DotNet;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
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
|
// Converts type references/definitions in one module to this module
|
||||||
class MemberReferenceConverter {
|
class MemberReferenceConverter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
|
|
||||||
public ModuleDefinition Module {
|
public ModuleDefMD Module {
|
||||||
get { return module; }
|
get { return module; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemberReferenceConverter(ModuleDefinition module) {
|
public MemberReferenceConverter(ModuleDefMD module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInOurModule(MemberReference memberRef) {
|
bool isInOurModule(IMemberRef memberRef) {
|
||||||
return memberRef.Module == module;
|
return memberRef.OwnerModule == module;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeReference convert(TypeReference typeRef) {
|
Importer createImporter() {
|
||||||
if (typeRef == null)
|
return new Importer(module, ImporterOptions.TryToUseTypeDefs);
|
||||||
return null;
|
|
||||||
typeRef = new TypeReferenceConverter(this).convert(typeRef);
|
|
||||||
return tryGetTypeDefinition(typeRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
if (isInOurModule(fieldRef))
|
||||||
return tryGetFieldDefinition(fieldRef);
|
return tryGetFieldDefinition(fieldRef);
|
||||||
|
return createImporter().Import(fieldRef);
|
||||||
return new FieldReference(fieldRef.Name, convert(fieldRef.FieldType), convert(fieldRef.DeclaringType));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference convert(MethodReference methodRef) {
|
public IMethodDefOrRef convert(IMethod methodRef) {
|
||||||
if (methodRef.GetType() != typeof(MethodReference) && methodRef.GetType() != typeof(MethodDef))
|
if (!(methodRef is MemberRef || methodRef is MethodDef) || methodRef.MethodSig == null)
|
||||||
throw new ApplicationException("Invalid method reference type");
|
throw new ApplicationException("Invalid method reference type");
|
||||||
if (isInOurModule(methodRef))
|
if (isInOurModule(methodRef))
|
||||||
return tryGetMethodDefinition(methodRef);
|
return (IMethodDefOrRef)tryGetMethodDefinition(methodRef);
|
||||||
|
return (IMethodDefOrRef)createImporter().Import(methodRef);
|
||||||
return copy(methodRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference copy(MethodReference methodRef) {
|
public IField tryGetFieldDefinition(IField fieldRef) {
|
||||||
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) {
|
|
||||||
var fieldDef = fieldRef as FieldDef;
|
var fieldDef = fieldRef as FieldDef;
|
||||||
if (fieldDef != null)
|
if (fieldDef != null)
|
||||||
return fieldDef;
|
return fieldDef;
|
||||||
|
@ -149,7 +83,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return DotNetUtils.getField(declaringType, fieldRef);
|
return DotNetUtils.getField(declaringType, fieldRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodReference tryGetMethodDefinition(MethodReference methodRef) {
|
public IMethod tryGetMethodDefinition(IMethod methodRef) {
|
||||||
var methodDef = methodRef as MethodDef;
|
var methodDef = methodRef as MethodDef;
|
||||||
if (methodDef != null)
|
if (methodDef != null)
|
||||||
return methodDef;
|
return methodDef;
|
||||||
|
|
|
@ -18,7 +18,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
|
|
||||||
|
@ -26,67 +28,73 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class MethodBodyReader : MethodBodyReaderBase {
|
class MethodBodyReader : MethodBodyReaderBase {
|
||||||
ImageReader imageReader;
|
ImageReader imageReader;
|
||||||
public int Flags2 { get; set; }
|
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) {
|
: base(reader) {
|
||||||
this.imageReader = imageReader;
|
this.imageReader = imageReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(ParameterDefinition[] parameters) {
|
public void read(IList<Parameter> parameters) {
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
Flags2 = reader.ReadInt16();
|
Flags2 = reader.ReadInt16();
|
||||||
MaxStack = reader.ReadInt16();
|
MaxStack = reader.ReadUInt16();
|
||||||
setLocals(imageReader.readTypeReferences());
|
SetLocals(imageReader.readTypeSigs());
|
||||||
readInstructions(imageReader.readVariableLengthInt32());
|
ReadInstructions(imageReader.readVariableLengthInt32());
|
||||||
readExceptionHandlers(imageReader.readVariableLengthInt32());
|
readExceptionHandlers(imageReader.readVariableLengthInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override FieldReference readInlineField(Instruction instr) {
|
protected override IField ReadInlineField(Instruction instr) {
|
||||||
return imageReader.readFieldReference();
|
return imageReader.readFieldReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override MethodReference readInlineMethod(Instruction instr) {
|
protected override IMethod ReadInlineMethod(Instruction instr) {
|
||||||
return imageReader.readMethodReference();
|
return imageReader.readMethodReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CallSite readInlineSig(Instruction instr) {
|
protected override MethodSig ReadInlineSig(Instruction instr) {
|
||||||
return imageReader.readCallSite();
|
return imageReader.readCallSite();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string readInlineString(Instruction instr) {
|
protected override string ReadInlineString(Instruction instr) {
|
||||||
return imageReader.readString();
|
return imageReader.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override MemberReference readInlineTok(Instruction instr) {
|
protected override ITokenOperand ReadInlineTok(Instruction instr) {
|
||||||
switch (reader.ReadByte()) {
|
switch (reader.ReadByte()) {
|
||||||
case 0: return imageReader.readTypeReference();
|
case 0: return imageReader.readTypeSig().ToTypeDefOrRef();
|
||||||
case 1: return imageReader.readFieldReference();
|
case 1: return imageReader.readFieldReference();
|
||||||
case 2: return imageReader.readMethodReference();
|
case 2: return imageReader.readMethodReference();
|
||||||
default: throw new ApplicationException("Unknown token type");
|
default: throw new ApplicationException("Unknown token type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TypeReference readInlineType(Instruction instr) {
|
protected override ITypeDefOrRef ReadInlineType(Instruction instr) {
|
||||||
return imageReader.readTypeReference();
|
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();
|
var ehType = (ExceptionHandlerType)reader.ReadByte();
|
||||||
int tryOffset = imageReader.readVariableLengthInt32();
|
uint tryOffset = imageReader.readVariableLengthUInt32();
|
||||||
int tryLength = imageReader.readVariableLengthInt32();
|
uint tryLength = imageReader.readVariableLengthUInt32();
|
||||||
int handlerOffset = imageReader.readVariableLengthInt32();
|
uint handlerOffset = imageReader.readVariableLengthUInt32();
|
||||||
int handlerLength = imageReader.readVariableLengthInt32();
|
uint handlerLength = imageReader.readVariableLengthUInt32();
|
||||||
var catchType = imageReader.readTypeReference();
|
var catchType = imageReader.readTypeSig().ToTypeDefOrRef();
|
||||||
int filterOffset = imageReader.readVariableLengthInt32();
|
uint filterOffset = imageReader.readVariableLengthUInt32();
|
||||||
|
|
||||||
var eh = new ExceptionHandler(ehType);
|
var eh = new ExceptionHandler(ehType);
|
||||||
eh.TryStart = getInstruction(tryOffset);
|
eh.TryStart = GetInstructionThrow(tryOffset);
|
||||||
eh.TryEnd = getInstructionOrNull(tryOffset + tryLength);
|
eh.TryEnd = GetInstruction(tryOffset + tryLength);
|
||||||
if (ehType == ExceptionHandlerType.Filter)
|
if (ehType == ExceptionHandlerType.Filter)
|
||||||
eh.FilterStart = getInstruction(filterOffset);
|
eh.FilterStart = GetInstructionThrow(filterOffset);
|
||||||
eh.HandlerStart = getInstruction(handlerOffset);
|
eh.HandlerStart = GetInstructionThrow(handlerOffset);
|
||||||
eh.HandlerEnd = getInstructionOrNull(handlerOffset + handlerLength);
|
eh.HandlerEnd = GetInstruction(handlerOffset + handlerLength);
|
||||||
eh.CatchType = catchType;
|
eh.CatchType = catchType;
|
||||||
return eh;
|
return eh;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,17 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using Mono.Collections.Generic;
|
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class BabelMethodreference : IGenericInstance {
|
class BabelMethodreference {
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public TypeReference DeclaringType { get; set; }
|
public TypeSig DeclaringType { get; set; }
|
||||||
public TypeReference ReturnType { get; set; }
|
public TypeSig ReturnType { get; set; }
|
||||||
public ParameterDefinition[] Parameters { get; set; }
|
public Parameter[] Parameters { get; set; }
|
||||||
public TypeReference[] GenericArguments { get; set; }
|
public TypeSig[] GenericArguments { get; set; }
|
||||||
public int Flags { get; set; }
|
public int Flags { get; set; }
|
||||||
|
|
||||||
public bool HasThis {
|
public bool HasThis {
|
||||||
|
@ -40,27 +40,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
public bool IsGenericMethod {
|
public bool IsGenericMethod {
|
||||||
get { return (Flags & 2) != 0; }
|
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 {
|
class BabelMethodDefinition : BabelMethodreference {
|
||||||
ParameterDefinition thisParameter;
|
Parameter thisParameter;
|
||||||
|
|
||||||
public int Flags2 { get; set; }
|
public int Flags2 { get; set; }
|
||||||
public short MaxStack { get; set; }
|
public ushort MaxStack { get; set; }
|
||||||
public IList<VariableDefinition> Locals { get; set; }
|
public IList<Local> Locals { get; set; }
|
||||||
public IList<Instruction> Instructions { get; set; }
|
public IList<Instruction> Instructions { get; set; }
|
||||||
public IList<ExceptionHandler> ExceptionHandlers { get; set; }
|
public IList<ExceptionHandler> ExceptionHandlers { get; set; }
|
||||||
|
|
||||||
|
@ -80,13 +67,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return (Flags2 & 0x80) != 0; }
|
get { return (Flags2 & 0x80) != 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParameterDefinition ThisParameter {
|
public Parameter ThisParameter {
|
||||||
get {
|
get {
|
||||||
if (!HasThis)
|
if (!HasThis)
|
||||||
return null;
|
return null;
|
||||||
if (thisParameter != null)
|
if (thisParameter != null)
|
||||||
return thisParameter;
|
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;
|
ExceptionHandlers = mbr.ExceptionHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParameterDefinition[] getRealParameters() {
|
public IList<Parameter> getRealParameters() {
|
||||||
if (ThisParameter == null)
|
if (ThisParameter == null)
|
||||||
return Parameters;
|
return Parameters;
|
||||||
var parameters = new ParameterDefinition[Parameters.Length + 1];
|
var parameters = new Parameter[Parameters.Length + 1];
|
||||||
parameters[0] = ThisParameter;
|
parameters[0] = ThisParameter;
|
||||||
Array.Copy(Parameters, 0, parameters, 1, Parameters.Length);
|
Array.Copy(Parameters, 0, parameters, 1, Parameters.Length);
|
||||||
return parameters;
|
return parameters;
|
||||||
|
@ -110,14 +97,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
class MethodReferenceReader {
|
class MethodReferenceReader {
|
||||||
ImageReader imageReader;
|
ImageReader imageReader;
|
||||||
BinaryReader reader;
|
IBinaryReader reader;
|
||||||
BabelMethodreference bmr;
|
BabelMethodreference bmr;
|
||||||
|
|
||||||
public MethodReferenceReader(ImageReader imageReader, BinaryReader reader)
|
public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader)
|
||||||
: this(imageReader, reader, new BabelMethodreference()) {
|
: 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.imageReader = imageReader;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
this.bmr = bmr;
|
this.bmr = bmr;
|
||||||
|
@ -125,23 +112,24 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
public BabelMethodreference read() {
|
public BabelMethodreference read() {
|
||||||
bmr.Name = imageReader.readString();
|
bmr.Name = imageReader.readString();
|
||||||
bmr.DeclaringType = imageReader.readTypeReference();
|
bmr.DeclaringType = imageReader.readTypeSig();
|
||||||
bmr.ReturnType = imageReader.readTypeReference();
|
bmr.ReturnType = imageReader.readTypeSig();
|
||||||
bmr.Parameters = readParameters();
|
var argTypes = imageReader.readTypeSigs();
|
||||||
bmr.Flags = reader.ReadByte();
|
bmr.Flags = reader.ReadByte();
|
||||||
if (bmr.IsGenericMethod)
|
if (bmr.IsGenericMethod)
|
||||||
bmr.GenericArguments = imageReader.readTypeReferences();
|
bmr.GenericArguments = imageReader.readTypeSigs();
|
||||||
else
|
else
|
||||||
bmr.GenericArguments = new TypeReference[0];
|
bmr.GenericArguments = new TypeSig[0];
|
||||||
|
bmr.Parameters = readParameters(argTypes, bmr.HasThis);
|
||||||
return bmr;
|
return bmr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParameterDefinition[] readParameters() {
|
Parameter[] readParameters(IList<TypeSig> argTypes, bool hasThis) {
|
||||||
var typeReferences = imageReader.readTypeReferences();
|
var ps = new Parameter[argTypes.Count];
|
||||||
var parameters = new ParameterDefinition[typeReferences.Length];
|
int bi = hasThis ? 1 : 0;
|
||||||
for (int i = 0; i < parameters.Length; i++)
|
for (int i = 0; i < ps.Length; i++)
|
||||||
parameters[i] = new ParameterDefinition(typeReferences[i]);
|
ps[i] = new Parameter(bi + i, i, argTypes[i]);
|
||||||
return parameters;
|
return ps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +138,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
MethodBodyReader methodBodyReader;
|
MethodBodyReader methodBodyReader;
|
||||||
BabelMethodDefinition bmd;
|
BabelMethodDefinition bmd;
|
||||||
|
|
||||||
public MethodDefinitionReader(ImageReader imageReader, BinaryReader reader) {
|
public MethodDefinitionReader(ImageReader imageReader, IBinaryReader reader) {
|
||||||
this.bmd = new BabelMethodDefinition();
|
this.bmd = new BabelMethodDefinition();
|
||||||
this.methodReferenceReader = new MethodReferenceReader(imageReader, reader, bmd);
|
this.methodReferenceReader = new MethodReferenceReader(imageReader, reader, bmd);
|
||||||
this.methodBodyReader = new MethodBodyReader(imageReader, reader);
|
this.methodBodyReader = new MethodBodyReader(imageReader, reader);
|
||||||
|
|
|
@ -20,13 +20,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class MethodsDecrypter {
|
class MethodsDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
IDeobfuscatorContext deobfuscatorContext;
|
IDeobfuscatorContext deobfuscatorContext;
|
||||||
Dictionary<string, ImageReader> imageReaders = new Dictionary<string, ImageReader>(StringComparer.Ordinal);
|
Dictionary<string, ImageReader> imageReaders = new Dictionary<string, ImageReader>(StringComparer.Ordinal);
|
||||||
|
@ -39,7 +40,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return methodsDecrypterCreator != null; }
|
get { return methodsDecrypterCreator != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodsDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter, IDeobfuscatorContext deobfuscatorContext) {
|
public MethodsDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter, IDeobfuscatorContext deobfuscatorContext) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.resourceDecrypter = resourceDecrypter;
|
this.resourceDecrypter = resourceDecrypter;
|
||||||
this.deobfuscatorContext = deobfuscatorContext;
|
this.deobfuscatorContext = deobfuscatorContext;
|
||||||
|
@ -54,7 +55,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var fieldTypes = new FieldTypes(type);
|
var fieldTypes = new FieldTypes(type);
|
||||||
if (!fieldTypes.all(requiredFields))
|
if (!fieldTypes.all(requiredFields))
|
||||||
continue;
|
continue;
|
||||||
if (DotNetUtils.getMethod(type, "Finalize") == null)
|
if (type.FindMethod("Finalize") == null)
|
||||||
continue;
|
continue;
|
||||||
var executeMethod = DotNetUtils.getMethod(type, "System.Object", "(System.String,System.Object[])");
|
var executeMethod = DotNetUtils.getMethod(type, "System.Object", "(System.String,System.Object[])");
|
||||||
if (executeMethod == null || !executeMethod.IsStatic || executeMethod.Body == null)
|
if (executeMethod == null || !executeMethod.IsStatic || executeMethod.Body == null)
|
||||||
|
@ -84,10 +85,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
TypeDef findMethodsDecrypterType(TypeDef type) {
|
TypeDef findMethodsDecrypterType(TypeDef type) {
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
var fieldType = DotNetUtils.getType(module, field.FieldType);
|
var fieldType = DotNetUtils.getType(module, field.FieldSig.GetFieldType());
|
||||||
if (fieldType == null)
|
if (fieldType == null)
|
||||||
continue;
|
continue;
|
||||||
if (DotNetUtils.getMethod(fieldType, "Finalize") == null)
|
if (fieldType.FindMethod("Finalize") == null)
|
||||||
continue;
|
continue;
|
||||||
if (!new FieldTypes(fieldType).exists("System.Collections.Hashtable"))
|
if (!new FieldTypes(fieldType).exists("System.Collections.Hashtable"))
|
||||||
continue;
|
continue;
|
||||||
|
@ -106,7 +107,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
encryptedResource = BabelUtils.findEmbeddedResource(module, methodsDecrypter, simpleDeobfuscator, deob);
|
encryptedResource = BabelUtils.findEmbeddedResource(module, methodsDecrypter, simpleDeobfuscator, deob);
|
||||||
if (encryptedResource != null)
|
if (encryptedResource != null)
|
||||||
addImageReader("", resourceDecrypter.decrypt(encryptedResource.GetResourceData()));
|
addImageReader("", resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageReader addImageReader(string name, byte[] data) {
|
ImageReader addImageReader(string name, byte[] data) {
|
||||||
|
@ -178,7 +179,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
try {
|
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);
|
var decrypted = resourceDecrypter.decrypt(encrypted);
|
||||||
return addImageReader(feature, decrypted);
|
return addImageReader(feature, decrypted);
|
||||||
}
|
}
|
||||||
|
@ -241,7 +242,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
continue;
|
||||||
if (MemberReferenceHelper.compareMethodReferenceAndDeclaringType(decryptExecuteMethod, instr.Operand as MethodReference))
|
if (MethodEqualityComparer.CompareDeclaringTypes.Equals(decryptExecuteMethod, instr.Operand as IMethod))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -27,7 +27,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class ProxyCallFixer : ProxyCallFixer2 {
|
class ProxyCallFixer : ProxyCallFixer2 {
|
||||||
MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType> methodToType = new MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType>();
|
MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType> methodToType = new MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType>();
|
||||||
|
|
||||||
public ProxyCallFixer(ModuleDefinition module)
|
public ProxyCallFixer(ModuleDefMD module)
|
||||||
: base(module) {
|
: base(module) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,11 +38,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
public TypeReference delegateType;
|
public ITypeDefOrRef delegateType;
|
||||||
public int methodToken;
|
public int methodToken;
|
||||||
public int declaringTypeToken;
|
public int declaringTypeToken;
|
||||||
public ProxyCreatorType proxyCreatorType;
|
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.delegateType = delegateType;
|
||||||
this.methodToken = methodToken;
|
this.methodToken = methodToken;
|
||||||
this.declaringTypeToken = declaringTypeToken;
|
this.declaringTypeToken = declaringTypeToken;
|
||||||
|
@ -57,24 +57,24 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
protected override object checkCctor(TypeDef type, MethodDef cctor) {
|
||||||
var instructions = cctor.Body.Instructions;
|
var instructions = cctor.Body.Instructions;
|
||||||
for (int i = 0; i < instructions.Count; i++) {
|
for (int i = 0; i < instructions.Count; i++) {
|
||||||
TypeReference delegateType;
|
ITypeDefOrRef delegateType;
|
||||||
FieldReference delegateField;
|
IField delegateField;
|
||||||
MethodReference createMethod;
|
IMethod createMethod;
|
||||||
int methodToken, declaringTypeToken;
|
int methodToken, declaringTypeToken;
|
||||||
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call);
|
var instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call);
|
||||||
if (instrs != null) {
|
if (instrs != null) {
|
||||||
delegateType = instrs[0].Operand as TypeReference;
|
delegateType = instrs[0].Operand as ITypeDefOrRef;
|
||||||
methodToken = DotNetUtils.getLdcI4Value(instrs[1]);
|
methodToken = instrs[1].GetLdcI4Value();
|
||||||
declaringTypeToken = DotNetUtils.getLdcI4Value(instrs[2]);
|
declaringTypeToken = instrs[2].GetLdcI4Value();
|
||||||
delegateField = instrs[3].Operand as FieldReference;
|
delegateField = instrs[3].Operand as IField;
|
||||||
createMethod = instrs[4].Operand as MethodReference;
|
createMethod = instrs[4].Operand as IMethod;
|
||||||
}
|
}
|
||||||
else if ((instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call)) != null) {
|
else if ((instrs = DotNetUtils.getInstructions(instructions, i, OpCodes.Ldtoken, OpCodes.Ldc_I4, OpCodes.Ldtoken, OpCodes.Call)) != null) {
|
||||||
delegateType = instrs[0].Operand as TypeReference;
|
delegateType = instrs[0].Operand as ITypeDefOrRef;
|
||||||
methodToken = DotNetUtils.getLdcI4Value(instrs[1]);
|
methodToken = instrs[1].GetLdcI4Value();
|
||||||
declaringTypeToken = -1;
|
declaringTypeToken = -1;
|
||||||
delegateField = instrs[2].Operand as FieldReference;
|
delegateField = instrs[2].Operand as IField;
|
||||||
createMethod = instrs[3].Operand as MethodReference;
|
createMethod = instrs[3].Operand as IMethod;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
@ -95,7 +95,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return null;
|
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;
|
var ctx = (Context)context;
|
||||||
|
|
||||||
switch (ctx.proxyCreatorType) {
|
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));
|
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() {
|
public void findDelegateCreator() {
|
||||||
|
@ -145,7 +148,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, methodToCheck)) {
|
||||||
if (!calledMethod.IsStatic || calledMethod.Body == null)
|
if (!calledMethod.IsStatic || calledMethod.Body == null)
|
||||||
continue;
|
continue;
|
||||||
if (!MemberReferenceHelper.compareTypes(methodToCheck.DeclaringType, calledMethod.DeclaringType))
|
if (!new SigComparer().Equals(methodToCheck.DeclaringType, calledMethod.DeclaringType))
|
||||||
continue;
|
continue;
|
||||||
if (DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Reflection.FieldInfo,System.Type,System.Reflection.MethodInfo)"))
|
if (DotNetUtils.isMethod(calledMethod, "System.Void", "(System.Reflection.FieldInfo,System.Type,System.Reflection.MethodInfo)"))
|
||||||
return ProxyCreatorType.CallOrCallvirt;
|
return ProxyCreatorType.CallOrCallvirt;
|
||||||
|
|
|
@ -26,10 +26,10 @@ using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class ResourceDecrypterCreator {
|
class ResourceDecrypterCreator {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
|
|
||||||
public ResourceDecrypterCreator(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
public ResourceDecrypterCreator(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,12 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResourceDecrypter {
|
class ResourceDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
MethodDef decryptMethod;
|
MethodDef decryptMethod;
|
||||||
IDecrypter decrypter;
|
IDecrypter decrypter;
|
||||||
|
|
||||||
public ResourceDecrypter(ModuleDefinition module, ISimpleDeobfuscator simpleDeobfuscator) {
|
public ResourceDecrypter(ModuleDefMD module, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||||
}
|
}
|
||||||
|
@ -56,9 +56,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
// v3.0
|
// v3.0
|
||||||
class Decrypter1 : IDecrypter {
|
class Decrypter1 : IDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
|
|
||||||
public Decrypter1(ModuleDefinition module) {
|
public Decrypter1(ModuleDefMD module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
key = reader.ReadBytes(reader.ReadByte());
|
key = reader.ReadBytes(reader.ReadByte());
|
||||||
else {
|
else {
|
||||||
key = new byte[reader.ReadByte()];
|
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
|
reader.ReadBytes(reader.ReadInt32()); // hash
|
||||||
|
@ -92,9 +92,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
// v3.5+
|
// v3.5+
|
||||||
class Decrypter2 : IDecrypter {
|
class Decrypter2 : IDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
|
|
||||||
public Decrypter2(ModuleDefinition module) {
|
public Decrypter2(ModuleDefMD module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
key = reader.ReadBytes(reader.ReadByte());
|
key = reader.ReadBytes(reader.ReadByte());
|
||||||
else {
|
else {
|
||||||
key = new byte[reader.ReadByte()];
|
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;
|
key[5] |= 0x80;
|
||||||
}
|
}
|
||||||
return isCompressed;
|
return isCompressed;
|
||||||
|
@ -152,10 +152,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
// v5.0+ retail
|
// v5.0+ retail
|
||||||
class Decrypter3 : IDecrypter {
|
class Decrypter3 : IDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
Inflater inflater;
|
Inflater inflater;
|
||||||
|
|
||||||
public Decrypter3(ModuleDefinition module, MethodDef decryptMethod) {
|
public Decrypter3(ModuleDefMD module, MethodDef decryptMethod) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.inflater = InflaterCreator.create(decryptMethod, true);
|
this.inflater = InflaterCreator.create(decryptMethod, true);
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
key = reader.ReadBytes(reader.ReadByte());
|
key = reader.ReadBytes(reader.ReadByte());
|
||||||
else {
|
else {
|
||||||
key = new byte[reader.ReadByte()];
|
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;
|
key[5] |= 0x80;
|
||||||
}
|
}
|
||||||
return isCompressed;
|
return isCompressed;
|
||||||
|
|
|
@ -20,13 +20,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class ResourceResolver {
|
class ResourceResolver {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
TypeDef resolverType;
|
TypeDef resolverType;
|
||||||
|
@ -47,7 +48,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return registerMethod; }
|
get { return registerMethod; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceResolver(ModuleDefinition module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) {
|
public ResourceResolver(ModuleDefMD module, ResourceDecrypter resourceDecrypter, ISimpleDeobfuscator simpleDeobfuscator) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.resourceDecrypter = resourceDecrypter;
|
this.resourceDecrypter = resourceDecrypter;
|
||||||
this.simpleDeobfuscator = simpleDeobfuscator;
|
this.simpleDeobfuscator = simpleDeobfuscator;
|
||||||
|
@ -104,20 +105,20 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
var callvirt = instrs[i];
|
var callvirt = instrs[i];
|
||||||
if (callvirt.OpCode.Code != Code.Callvirt)
|
if (callvirt.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = callvirt.Operand as MethodReference;
|
var calledMethod = callvirt.Operand as IMethod;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (calledMethod.FullName != "System.Int32 System.IO.BinaryReader::ReadInt32()")
|
if (calledMethod.FullName != "System.Int32 System.IO.BinaryReader::ReadInt32()")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var ldci4 = instrs[i + 1];
|
var ldci4 = instrs[i + 1];
|
||||||
if (!DotNetUtils.isLdcI4(ldci4))
|
if (!ldci4.IsLdcI4())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
if (instrs[i + 2].OpCode.Code != Code.Xor)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ints.Add(DotNetUtils.getLdcI4Value(ldci4));
|
ints.Add(ldci4.GetLdcI4Value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ints.Count == 2) {
|
if (ints.Count == 2) {
|
||||||
|
@ -130,14 +131,14 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
public EmbeddedResource mergeResources() {
|
public EmbeddedResource mergeResources() {
|
||||||
if (encryptedResource == null)
|
if (encryptedResource == null)
|
||||||
return null;
|
return null;
|
||||||
DeobUtils.decryptAndAddResources(module, encryptedResource.Name, () => decryptResourceAssembly());
|
DeobUtils.decryptAndAddResources(module, encryptedResource.Name.String, () => decryptResourceAssembly());
|
||||||
var result = encryptedResource;
|
var result = encryptedResource;
|
||||||
encryptedResource = null;
|
encryptedResource = null;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] decryptResourceAssembly() {
|
byte[] decryptResourceAssembly() {
|
||||||
var decrypted = resourceDecrypter.decrypt(encryptedResource.GetResourceData());
|
var decrypted = resourceDecrypter.decrypt(encryptedResource.Data.ReadAllBytes());
|
||||||
var reader = new BinaryReader(new MemoryStream(decrypted));
|
var reader = new BinaryReader(new MemoryStream(decrypted));
|
||||||
|
|
||||||
int numResources = reader.ReadInt32() ^ xorKey1;
|
int numResources = reader.ReadInt32() ^ xorKey1;
|
||||||
|
|
|
@ -21,6 +21,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using dot10.IO;
|
||||||
using dot10.DotNet;
|
using dot10.DotNet;
|
||||||
using dot10.DotNet.Emit;
|
using dot10.DotNet.Emit;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
@ -28,7 +29,7 @@ using de4dot.blocks.cflow;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Babel_NET {
|
namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefinition module;
|
ModuleDefMD module;
|
||||||
ResourceDecrypter resourceDecrypter;
|
ResourceDecrypter resourceDecrypter;
|
||||||
ISimpleDeobfuscator simpleDeobfuscator;
|
ISimpleDeobfuscator simpleDeobfuscator;
|
||||||
TypeDef decrypterType;
|
TypeDef decrypterType;
|
||||||
|
@ -38,7 +39,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
interface IDecrypterInfo {
|
interface IDecrypterInfo {
|
||||||
MethodDef Decrypter { get; }
|
MethodDef Decrypter { get; }
|
||||||
bool NeedsResource { get; }
|
bool NeedsResource { get; }
|
||||||
void initialize(ModuleDefinition module, EmbeddedResource resource);
|
void initialize(ModuleDefMD module, EmbeddedResource resource);
|
||||||
string decrypt(object[] args);
|
string decrypt(object[] args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return false; }
|
get { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(ModuleDefinition module, EmbeddedResource resource) {
|
public void initialize(ModuleDefMD module, EmbeddedResource resource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public string decrypt(object[] args) {
|
public string decrypt(object[] args) {
|
||||||
|
@ -72,8 +73,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return true; }
|
get { return true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(ModuleDefinition module, EmbeddedResource resource) {
|
public void initialize(ModuleDefMD module, EmbeddedResource resource) {
|
||||||
key = resource.GetResourceData();
|
key = resource.Data.ReadAllBytes();
|
||||||
if (key.Length != 0x100)
|
if (key.Length != 0x100)
|
||||||
throw new ApplicationException(string.Format("Unknown key length: {0}", key.Length));
|
throw new ApplicationException(string.Format("Unknown key length: {0}", key.Length));
|
||||||
}
|
}
|
||||||
|
@ -106,8 +107,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
this.resourceDecrypter = resourceDecrypter;
|
this.resourceDecrypter = resourceDecrypter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(ModuleDefinition module, EmbeddedResource resource) {
|
public void initialize(ModuleDefMD module, EmbeddedResource resource) {
|
||||||
var decrypted = resourceDecrypter.decrypt(resource.GetResourceData());
|
var decrypted = resourceDecrypter.decrypt(resource.Data.ReadAllBytes());
|
||||||
var reader = new BinaryReader(new MemoryStream(decrypted));
|
var reader = new BinaryReader(new MemoryStream(decrypted));
|
||||||
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
while (reader.BaseStream.Position < reader.BaseStream.Length)
|
||||||
offsetToString[getOffset((int)reader.BaseStream.Position)] = reader.ReadString();
|
offsetToString[getOffset((int)reader.BaseStream.Position)] = reader.ReadString();
|
||||||
|
@ -118,8 +119,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0)
|
if (OffsetCalcInstructions == null || OffsetCalcInstructions.Count == 0)
|
||||||
return offset;
|
return offset;
|
||||||
if (dummyMethod == null) {
|
if (dummyMethod == null) {
|
||||||
dummyMethod = new MethodDef("", 0, new TypeReference("", "", null, null));
|
dummyMethod = new MethodDefUser();
|
||||||
dummyMethod.Body = new MethodBody(dummyMethod);
|
dummyMethod.Body = new CilBody();
|
||||||
}
|
}
|
||||||
emulator.init(dummyMethod);
|
emulator.init(dummyMethod);
|
||||||
emulator.push(new Int32Value(offset));
|
emulator.push(new Int32Value(offset));
|
||||||
|
@ -153,7 +154,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
get { return encryptedResource; }
|
get { return encryptedResource; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringDecrypter(ModuleDefinition module, ResourceDecrypter resourceDecrypter) {
|
public StringDecrypter(ModuleDefMD module, ResourceDecrypter resourceDecrypter) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.resourceDecrypter = resourceDecrypter;
|
this.resourceDecrypter = resourceDecrypter;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +213,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
|
|
||||||
int stringLength = 0, stringToCharArray = 0, stringCtor = 0;
|
int stringLength = 0, stringToCharArray = 0, stringCtor = 0;
|
||||||
foreach (var instr in method.Body.Instructions) {
|
foreach (var instr in method.Body.Instructions) {
|
||||||
var calledMethod = instr.Operand as MethodReference;
|
var calledMethod = instr.Operand as IMethod;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -246,7 +247,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (nested.HasProperties || nested.HasEvents)
|
if (nested.HasProperties || nested.HasEvents)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (DotNetUtils.getMethod(nested, ".ctor") == null)
|
if (nested.FindMethod(".ctor") == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (nested.Fields.Count == 1 || nested.Fields.Count == 3) {
|
if (nested.Fields.Count == 1 || nested.Fields.Count == 3) {
|
||||||
|
@ -259,7 +260,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (decrypterBuilderMethod == null)
|
if (decrypterBuilderMethod == null)
|
||||||
return 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)");
|
var nestedDecrypter = DotNetUtils.getMethod(nested, "System.String", "(System.Int32)");
|
||||||
if (nestedDecrypter == null || nestedDecrypter.IsStatic)
|
if (nestedDecrypter == null || nestedDecrypter.IsStatic)
|
||||||
|
@ -286,7 +287,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (decrypter == null || !decrypter.IsStatic)
|
if (decrypter == null || !decrypter.IsStatic)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(DotNetUtils.getMethod(nested, ".ctor"));
|
resourceDecrypter.DecryptMethod = ResourceDecrypter.findDecrypterMethod(nested.FindMethod(".ctor"));
|
||||||
|
|
||||||
return new DecrypterInfoV3(resourceDecrypter) { Decrypter = decrypter };
|
return new DecrypterInfoV3(resourceDecrypter) { Decrypter = decrypter };
|
||||||
}
|
}
|
||||||
|
@ -346,7 +347,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Code.Newarr:
|
case Code.Newarr:
|
||||||
var arrayType = (TypeReference)instr.Operand;
|
var arrayType = (ITypeDefOrRef)instr.Operand;
|
||||||
int arrayCount = ((Int32Value)emulator.pop()).value;
|
int arrayCount = ((Int32Value)emulator.pop()).value;
|
||||||
if (arrayType.FullName == "System.Char")
|
if (arrayType.FullName == "System.Char")
|
||||||
emulator.push(new UserValue(new char[arrayCount]));
|
emulator.push(new UserValue(new char[arrayCount]));
|
||||||
|
@ -396,7 +397,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Code.Ldsfld:
|
case Code.Ldsfld:
|
||||||
emulator.push(new UserValue((FieldReference)instr.Operand));
|
emulator.push(new UserValue((IField)instr.Operand));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -409,30 +410,32 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool doCall(Instruction instr) {
|
bool doCall(Instruction instr) {
|
||||||
var calledMethod = (MethodReference)instr.Operand;
|
var calledMethod = (IMethod)instr.Operand;
|
||||||
if (calledMethod.FullName == "System.Byte[] System.Convert::FromBase64String(System.String)") {
|
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)));
|
emulator.push(new UserValue(Convert.FromBase64String(((StringValue)emulator.pop()).value)));
|
||||||
return true;
|
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)));
|
emulator.push(new StringValue(Encoding.UTF8.GetString((byte[])((UserValue)emulator.pop()).obj)));
|
||||||
return true;
|
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)));
|
emulator.push(new Int32Value(int.Parse(((StringValue)emulator.pop()).value)));
|
||||||
return true;
|
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 ary = (char[])((UserValue)emulator.pop()).obj;
|
||||||
var s = ((StringValue)emulator.pop()).value;
|
var s = ((StringValue)emulator.pop()).value;
|
||||||
emulator.push(new UserValue(s.Split(ary)));
|
emulator.push(new UserValue(s.Split(ary)));
|
||||||
return true;
|
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;
|
Value operand = null;
|
||||||
if (calledMethod.Parameters.Count == 2)
|
if (calledMethod.MethodSig.GetParamCount() == 2)
|
||||||
operand = emulator.pop();
|
operand = emulator.pop();
|
||||||
var opcode = reflectionToCecilOpCode((FieldReference)((UserValue)emulator.pop()).obj);
|
var opcode = reflectionToOpCode((IField)((UserValue)emulator.pop()).obj);
|
||||||
emulator.pop(); // the this ptr
|
emulator.pop(); // the this ptr
|
||||||
addInstruction(new Instruction {
|
addInstruction(new Instruction {
|
||||||
OpCode = opcode,
|
OpCode = opcode,
|
||||||
|
@ -458,8 +461,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
instructions.Add(instr);
|
instructions.Add(instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static OpCode reflectionToCecilOpCode(FieldReference reflectionField) {
|
static OpCode reflectionToOpCode(IField reflectionField) {
|
||||||
var field = typeof(OpCodes).GetField(reflectionField.Name);
|
var field = typeof(OpCodes).GetField(reflectionField.Name.String);
|
||||||
if (field == null || field.FieldType != typeof(OpCode))
|
if (field == null || field.FieldType != typeof(OpCode))
|
||||||
return null;
|
return null;
|
||||||
return (OpCode)field.GetValue(null);
|
return (OpCode)field.GetValue(null);
|
||||||
|
@ -499,9 +502,9 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hasFieldType(IEnumerable<FieldDef> fields, TypeReference fieldType) {
|
static bool hasFieldType(IEnumerable<FieldDef> fields, TypeDef fieldType) {
|
||||||
foreach (var field in fields) {
|
foreach (var field in fields) {
|
||||||
if (MemberReferenceHelper.compareTypes(field.FieldType, fieldType))
|
if (new SigComparer().Equals(field.FieldSig.GetFieldType(), fieldType))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -517,32 +520,32 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var ldci4 = instrs[index++];
|
var ldci4 = instrs[index++];
|
||||||
if (!DotNetUtils.isLdcI4(ldci4))
|
if (!ldci4.IsLdcI4())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var callvirt = instrs[index++];
|
var callvirt = instrs[index++];
|
||||||
if (callvirt.OpCode.Code != Code.Callvirt)
|
if (callvirt.OpCode.Code != Code.Callvirt)
|
||||||
continue;
|
continue;
|
||||||
var calledMethod = callvirt.Operand as MethodReference;
|
var calledMethod = callvirt.Operand as IMethod;
|
||||||
if (calledMethod == null)
|
if (calledMethod == null)
|
||||||
continue;
|
continue;
|
||||||
if (calledMethod.FullName != "System.Void System.Reflection.Emit.ILGenerator::Emit(System.Reflection.Emit.OpCode,System.Int32)")
|
if (calledMethod.FullName != "System.Void System.Reflection.Emit.ILGenerator::Emit(System.Reflection.Emit.OpCode,System.Int32)")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!DotNetUtils.isLdloc(instrs[index++]))
|
if (!instrs[index++].IsLdloc())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var ldsfld2 = instrs[index++];
|
var ldsfld2 = instrs[index++];
|
||||||
if (ldsfld2.OpCode.Code != Code.Ldsfld)
|
if (ldsfld2.OpCode.Code != Code.Ldsfld)
|
||||||
continue;
|
continue;
|
||||||
var field = ldsfld2.Operand as FieldReference;
|
var field = ldsfld2.Operand as IField;
|
||||||
if (field == null)
|
if (field == null)
|
||||||
continue;
|
continue;
|
||||||
if (field.FullName != "System.Reflection.Emit.OpCode System.Reflection.Emit.OpCodes::Xor")
|
if (field.FullName != "System.Reflection.Emit.OpCode System.Reflection.Emit.OpCodes::Xor")
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Here if Babel.NET 5.5
|
// Here if Babel.NET 5.5
|
||||||
return DotNetUtils.getLdcI4Value(ldci4);
|
return ldci4.GetLdcI4Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here if Babel.NET <= 5.0
|
// Here if Babel.NET <= 5.0
|
||||||
|
@ -552,11 +555,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
bool checkFields(TypeDef type, string fieldType1, TypeDef fieldType2) {
|
bool checkFields(TypeDef type, string fieldType1, TypeDef fieldType2) {
|
||||||
if (type.Fields.Count != 2)
|
if (type.Fields.Count != 2)
|
||||||
return false;
|
return false;
|
||||||
if (type.Fields[0].FieldType.FullName != fieldType1 &&
|
if (type.Fields[0].FieldSig.GetFieldType().GetFullName() != fieldType1 &&
|
||||||
type.Fields[1].FieldType.FullName != fieldType1)
|
type.Fields[1].FieldSig.GetFieldType().GetFullName() != fieldType1)
|
||||||
return false;
|
return false;
|
||||||
if (!MemberReferenceHelper.compareTypes(type.Fields[0].FieldType, fieldType2) &&
|
if (!new SigComparer().Equals(type.Fields[0].FieldSig.GetFieldType(), fieldType2) &&
|
||||||
!MemberReferenceHelper.compareTypes(type.Fields[1].FieldType, fieldType2))
|
!new SigComparer().Equals(type.Fields[1].FieldSig.GetFieldType(), fieldType2))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,8 +38,8 @@ namespace de4dot.cui {
|
||||||
return new List<IDeobfuscatorInfo> {
|
return new List<IDeobfuscatorInfo> {
|
||||||
new de4dot.code.deobfuscators.Unknown.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.Unknown.DeobfuscatorInfo(),
|
||||||
new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.Agile_NET.DeobfuscatorInfo(),
|
||||||
#if PORT
|
|
||||||
new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.Babel_NET.DeobfuscatorInfo(),
|
||||||
|
#if PORT
|
||||||
new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.CodeFort.DeobfuscatorInfo(),
|
||||||
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.CodeVeil.DeobfuscatorInfo(),
|
||||||
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),
|
new de4dot.code.deobfuscators.CodeWall.DeobfuscatorInfo(),
|
||||||
|
|
2
dot10
2
dot10
|
@ -1 +1 @@
|
||||||
Subproject commit cdf5619a39c2caf03b35569ef42383ca31971166
|
Subproject commit 5844915b880f422af17a3bcd234829ba32dcb6e5
|
Loading…
Reference in New Issue
Block a user