Use standard .NET naming convention

This commit is contained in:
de4dot 2013-01-19 13:03:57 +01:00
parent fa6c10b8c0
commit 211d1b67f6
319 changed files with 10050 additions and 10050 deletions

View File

@ -30,17 +30,17 @@ namespace AssemblyData {
List<string> assemblySearchPaths = new List<string>();
public AssemblyResolver() {
AppDomain.CurrentDomain.AssemblyResolve += assemblyResolve;
AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
}
void addAssemblySearchPath(string path) {
void AddAssemblySearchPath(string path) {
if (assemblySearchPathsDict.ContainsKey(path))
return;
assemblySearchPathsDict[path] = true;
assemblySearchPaths.Add(path);
}
Assembly get(string assemblyFullName) {
Assembly Get(string assemblyFullName) {
var asmName = new AssemblyName(assemblyFullName);
Assembly assembly;
@ -53,8 +53,8 @@ namespace AssemblyData {
}
static string[] assemblyExtensions = new string[] { ".dll", ".exe" };
Assembly assemblyResolve(object sender, ResolveEventArgs args) {
var assembly = get(args.Name);
Assembly AssemblyResolve(object sender, ResolveEventArgs args) {
var assembly = Get(args.Name);
if (assembly != null)
return assembly;
@ -65,8 +65,8 @@ namespace AssemblyData {
var filename = Path.Combine(path, asmName.Name + ext);
if (!new FileInfo(filename).Exists)
continue;
addConfigFile(filename + ".config");
return addAssembly(Assembly.LoadFile(filename));
AddConfigFile(filename + ".config");
return AddAssembly(Assembly.LoadFile(filename));
}
catch (IOException) {
}
@ -86,12 +86,12 @@ namespace AssemblyData {
return null;
}
public Assembly load(string filename) {
addConfigFile(filename + ".config");
return addAssembly(loadFile(filename));
public Assembly Load(string filename) {
AddConfigFile(filename + ".config");
return AddAssembly(LoadFile(filename));
}
Assembly loadFile(string filename) {
Assembly LoadFile(string filename) {
try {
return Assembly.LoadFrom(filename);
}
@ -101,16 +101,16 @@ namespace AssemblyData {
}
}
Assembly addAssembly(Assembly assembly) {
Assembly AddAssembly(Assembly assembly) {
var asmName = assembly.GetName();
assemblies[asmName.FullName] = assembly;
assemblies[asmName.Name] = assembly;
return assembly;
}
void addConfigFile(string configFilename) {
var dirName = Utils.getDirName(Utils.getFullPath(configFilename));
addAssemblySearchPath(dirName);
void AddConfigFile(string configFilename) {
var dirName = Utils.GetDirName(Utils.GetFullPath(configFilename));
AddAssemblySearchPath(dirName);
try {
using (var xmlStream = new FileStream(configFilename, FileMode.Open, FileAccess.Read, FileShare.Read)) {
@ -124,7 +124,7 @@ namespace AssemblyData {
if (string.IsNullOrEmpty(privatePath))
continue;
foreach (var path in privatePath.Split(';'))
addAssemblySearchPath(Path.Combine(dirName, path));
AddAssemblySearchPath(Path.Combine(dirName, path));
}
}
}

View File

@ -26,19 +26,19 @@ using AssemblyData;
namespace AssemblyServer {
public static class Start {
public static int main(string[] args) {
public static int Main2(string[] args) {
if (args.Length != 2)
Environment.Exit(1);
var channelName = args[0];
var uri = args[1];
var service = new AssemblyService();
startServer(service, channelName, uri);
service.waitExit();
StartServer(service, channelName, uri);
service.WaitExit();
return 0;
}
static void startServer(AssemblyService service, string name, string uri) {
static void StartServer(AssemblyService service, string name, string uri) {
var props = new Hashtable();
props["portName"] = name;
var provider = new BinaryServerFormatterSinkProvider();

View File

@ -33,14 +33,14 @@ namespace AssemblyData {
AssemblyResolver assemblyResolver = new AssemblyResolver();
bool installCompileMethodCalled = false;
public void doNothing() {
public void DoNothing() {
}
public void exit() {
public void Exit() {
exitEvent.Set();
}
public void waitExit() {
public void WaitExit() {
exitEvent.WaitOne();
}
@ -48,28 +48,28 @@ namespace AssemblyData {
return null;
}
void checkStringDecrypter() {
void CheckStringDecrypter() {
if (stringDecrypter == null)
throw new ApplicationException("setStringDecrypterType() hasn't been called yet.");
}
void checkAssembly() {
void CheckAssembly() {
if (assembly == null)
throw new ApplicationException("loadAssembly() hasn't been called yet.");
}
public void loadAssembly(string filename) {
public void LoadAssembly(string filename) {
if (assembly != null)
throw new ApplicationException("Only one assembly can be explicitly loaded");
try {
assembly = assemblyResolver.load(filename);
assembly = assemblyResolver.Load(filename);
}
catch (BadImageFormatException) {
throw new ApplicationException(string.Format("Could not load assembly {0}. Maybe it's 32-bit or 64-bit only?", filename));
}
}
public void setStringDecrypterType(StringDecrypterType type) {
public void SetStringDecrypterType(StringDecrypterType type) {
if (stringDecrypter != null)
throw new ApplicationException("StringDecrypterType already set");
@ -87,25 +87,25 @@ namespace AssemblyData {
}
}
public int defineStringDecrypter(int methodToken) {
checkStringDecrypter();
var methodInfo = findMethod(methodToken);
public int DefineStringDecrypter(int methodToken) {
CheckStringDecrypter();
var methodInfo = FindMethod(methodToken);
if (methodInfo == null)
throw new ApplicationException(string.Format("Could not find method {0:X8}", methodToken));
if (methodInfo.ReturnType != typeof(string) && methodInfo.ReturnType != typeof(object))
throw new ApplicationException(string.Format("Method return type must be string or object: {0}", methodInfo));
return stringDecrypter.defineStringDecrypter(methodInfo);
return stringDecrypter.DefineStringDecrypter(methodInfo);
}
public object[] decryptStrings(int stringDecrypterMethod, object[] args, int callerToken) {
checkStringDecrypter();
var caller = getCaller(callerToken);
public object[] DecryptStrings(int stringDecrypterMethod, object[] args, int callerToken) {
CheckStringDecrypter();
var caller = GetCaller(callerToken);
foreach (var arg in args)
SimpleData.unpack((object[])arg);
return SimpleData.pack(stringDecrypter.decryptStrings(stringDecrypterMethod, args, caller));
SimpleData.Unpack((object[])arg);
return SimpleData.Pack(stringDecrypter.DecryptStrings(stringDecrypterMethod, args, caller));
}
MethodBase getCaller(int callerToken) {
MethodBase GetCaller(int callerToken) {
try {
return assembly.GetModules()[0].ResolveMethod(callerToken);
}
@ -114,8 +114,8 @@ namespace AssemblyData {
}
}
MethodInfo findMethod(int methodToken) {
checkAssembly();
MethodInfo FindMethod(int methodToken) {
CheckAssembly();
foreach (var module in assembly.GetModules()) {
var method = module.ResolveMethod(methodToken) as MethodInfo;
@ -126,28 +126,28 @@ namespace AssemblyData {
return null;
}
public void installCompileMethod(DecryptMethodsInfo decryptMethodsInfo) {
public void InstallCompileMethod(DecryptMethodsInfo decryptMethodsInfo) {
if (installCompileMethodCalled)
throw new ApplicationException("installCompileMethod() has already been called");
installCompileMethodCalled = true;
DynamicMethodsDecrypter.Instance.DecryptMethodsInfo = decryptMethodsInfo;
DynamicMethodsDecrypter.Instance.installCompileMethod();
DynamicMethodsDecrypter.Instance.InstallCompileMethod();
}
public void loadObfuscator(string filename) {
loadAssembly(filename);
public void LoadObfuscator(string filename) {
LoadAssembly(filename);
DynamicMethodsDecrypter.Instance.Module = assembly.ManifestModule;
DynamicMethodsDecrypter.Instance.loadObfuscator();
DynamicMethodsDecrypter.Instance.LoadObfuscator();
}
public bool canDecryptMethods() {
checkAssembly();
return DynamicMethodsDecrypter.Instance.canDecryptMethods();
public bool CanDecryptMethods() {
CheckAssembly();
return DynamicMethodsDecrypter.Instance.CanDecryptMethods();
}
public DumpedMethods decryptMethods() {
checkAssembly();
return DynamicMethodsDecrypter.Instance.decryptMethods();
public DumpedMethods DecryptMethods() {
CheckAssembly();
return DynamicMethodsDecrypter.Instance.DecryptMethods();
}
}
}

View File

@ -27,12 +27,12 @@ namespace AssemblyData {
delegate string DecryptString(object[] args);
List<DecryptString> stringDecryptMethods = new List<DecryptString>();
public int defineStringDecrypter(MethodInfo method) {
stringDecryptMethods.Add(buildDynamicMethod(method));
public int DefineStringDecrypter(MethodInfo method) {
stringDecryptMethods.Add(BuildDynamicMethod(method));
return stringDecryptMethods.Count - 1;
}
public object[] decryptStrings(int stringDecrypterMethod, object[] args, MethodBase caller) {
public object[] DecryptStrings(int stringDecrypterMethod, object[] args, MethodBase caller) {
if (stringDecrypterMethod > stringDecryptMethods.Count)
throw new ApplicationException("Invalid string decrypter method");
@ -43,9 +43,9 @@ namespace AssemblyData {
return rv;
}
DecryptString buildDynamicMethod(MethodInfo method) {
DecryptString BuildDynamicMethod(MethodInfo method) {
var dm = new DynamicMethod("", typeof(string), new Type[] { typeof(object[]) }, typeof(DelegateStringDecrypter), true);
Utils.addCallStringDecrypterMethodInstructions(method, dm.GetILGenerator());
Utils.AddCallStringDecrypterMethodInstructions(method, dm.GetILGenerator());
return (DecryptString)dm.CreateDelegate(typeof(DecryptString));
}
}

View File

@ -36,26 +36,26 @@ namespace AssemblyData {
}
}
public int defineStringDecrypter(MethodInfo method) {
public int DefineStringDecrypter(MethodInfo method) {
decryptInfos.Add(new DecryptInfo(method));
return decryptInfos.Count - 1;
}
public object[] decryptStrings(int stringDecrypterMethod, object[] args, MethodBase caller) {
public object[] DecryptStrings(int stringDecrypterMethod, object[] args, MethodBase caller) {
var decryptInfo = decryptInfos[stringDecrypterMethod];
if (decryptInfo.decryptString == null)
decryptInfo.decryptString = createDecryptString(decryptInfo.method);
decryptInfo.decryptString = CreateDecryptString(decryptInfo.method);
methodsRewriter.setCaller(decryptInfo.decryptString, caller);
methodsRewriter.SetCaller(decryptInfo.decryptString, caller);
var result = new object[args.Length];
for (int i = 0; i < args.Length; i++)
result[i] = decryptInfo.decryptString((object[])args[i]);
return result;
}
RewrittenMethod createDecryptString(MethodInfo method) {
methodsRewriter.createMethod(method);
return methodsRewriter.createDelegate(method);
RewrittenMethod CreateDecryptString(MethodInfo method) {
methodsRewriter.CreateMethod(method);
return methodsRewriter.CreateDelegate(method);
}
}
}

View File

@ -28,18 +28,18 @@ namespace AssemblyData {
}
public interface IAssemblyService {
void doNothing();
void exit();
void DoNothing();
void Exit();
void loadAssembly(string filename);
void LoadAssembly(string filename);
void setStringDecrypterType(StringDecrypterType type);
int defineStringDecrypter(int methodToken);
object[] decryptStrings(int stringDecrypterMethod, object[] args, int callerToken);
void SetStringDecrypterType(StringDecrypterType type);
int DefineStringDecrypter(int methodToken);
object[] DecryptStrings(int stringDecrypterMethod, object[] args, int callerToken);
void installCompileMethod(DecryptMethodsInfo decryptMethodsInfo);
void loadObfuscator(string filename);
bool canDecryptMethods();
DumpedMethods decryptMethods();
void InstallCompileMethod(DecryptMethodsInfo decryptMethodsInfo);
void LoadObfuscator(string filename);
bool CanDecryptMethods();
DumpedMethods DecryptMethods();
}
}

View File

@ -21,7 +21,7 @@ using System.Reflection;
namespace AssemblyData {
interface IStringDecrypter {
int defineStringDecrypter(MethodInfo method);
object[] decryptStrings(int stringDecrypterMethod, object[] args, MethodBase caller);
int DefineStringDecrypter(MethodInfo method);
object[] DecryptStrings(int stringDecrypterMethod, object[] args, MethodBase caller);
}
}

View File

@ -51,7 +51,7 @@ namespace AssemblyData {
}
public static class SimpleData {
public static object[] pack(object[] args) {
public static object[] Pack(object[] args) {
for (int i = 0; i < args.Length; i++) {
var s = args[i] as string;
if (s != null)
@ -60,7 +60,7 @@ namespace AssemblyData {
return args;
}
public static object[] unpack(object[] args) {
public static object[] Unpack(object[] args) {
for (int i = 0; i < args.Length; i++) {
var s = args[i] as MyString;
if (s != null)

View File

@ -68,11 +68,11 @@ namespace AssemblyData {
static class Utils {
static Random random = new Random();
public static uint getRandomUint() {
public static uint GetRandomUint() {
return (uint)(random.NextDouble() * uint.MaxValue);
}
public static Type getDelegateType(Type returnType, Type[] args) {
public static Type GetDelegateType(Type returnType, Type[] args) {
Type[] types;
if (returnType == typeof(void)) {
types = args;
@ -133,7 +133,7 @@ namespace AssemblyData {
}
}
public static string randomName(int min, int max) {
public static string RandomName(int min, int max) {
int numChars = random.Next(min, max + 1);
var sb = new StringBuilder(numChars);
int numLower = 0;
@ -153,7 +153,7 @@ namespace AssemblyData {
return sb.ToString();
}
public static void addCallStringDecrypterMethodInstructions(MethodInfo method, ILGenerator ilg) {
public static void AddCallStringDecrypterMethodInstructions(MethodInfo method, ILGenerator ilg) {
var args = method.GetParameters();
for (int i = 0; i < args.Length; i++) {
var arg = args[i].ParameterType;
@ -171,7 +171,7 @@ namespace AssemblyData {
ilg.Emit(OpCodes.Ret);
}
public static string getFullPath(string path) {
public static string GetFullPath(string path) {
try {
return Path.GetFullPath(path);
}
@ -180,7 +180,7 @@ namespace AssemblyData {
}
}
public static string getDirName(string name) {
public static string GetDirName(string name) {
return Path.GetDirectoryName(name);
}
}

View File

@ -35,10 +35,10 @@ namespace AssemblyData.methodsrewriter {
public AssemblyResolver(string asmName) {
assembly = Assembly.Load(new AssemblyName(asmName));
initTypes();
InitTypes();
}
void initTypes() {
void InitTypes() {
foreach (var type in assembly.GetTypes()) {
string key = (type.Namespace ?? "") + "." + type.Name;
List<TypeResolver> list;
@ -48,7 +48,7 @@ namespace AssemblyData.methodsrewriter {
}
}
TypeResolver getTypeResolver(ITypeDefOrRef typeRef) {
TypeResolver GetTypeResolver(ITypeDefOrRef typeRef) {
if (typeRef == null)
return null;
var scopeType = typeRef.ScopeType;
@ -65,30 +65,30 @@ namespace AssemblyData.methodsrewriter {
}
foreach (var resolver in list) {
if (ResolverUtils.compareTypes(resolver.type, scopeType))
if (ResolverUtils.CompareTypes(resolver.type, scopeType))
return resolver;
}
return null;
}
public FieldInfo resolve(IField fieldRef) {
var resolver = getTypeResolver(fieldRef.DeclaringType);
public FieldInfo Resolve(IField fieldRef) {
var resolver = GetTypeResolver(fieldRef.DeclaringType);
if (resolver != null)
return resolver.resolve(fieldRef);
return resolveGlobalField(fieldRef);
return resolver.Resolve(fieldRef);
return ResolveGlobalField(fieldRef);
}
FieldInfo resolveGlobalField(IField fieldRef) {
initGlobalFields();
FieldInfo ResolveGlobalField(IField fieldRef) {
InitGlobalFields();
foreach (var globalField in globalFields) {
if (ResolverUtils.compareFields(globalField, fieldRef))
if (ResolverUtils.CompareFields(globalField, fieldRef))
return globalField;
}
return null;
}
void initGlobalFields() {
void InitGlobalFields() {
if (globalFields != null)
return;
globalFields = new List<FieldInfo>();
@ -100,23 +100,23 @@ namespace AssemblyData.methodsrewriter {
}
}
public MethodBase resolve(IMethod methodRef) {
var resolver = getTypeResolver(methodRef.DeclaringType);
public MethodBase Resolve(IMethod methodRef) {
var resolver = GetTypeResolver(methodRef.DeclaringType);
if (resolver != null)
return resolver.resolve(methodRef);
return resolveGlobalMethod(methodRef);
return resolver.Resolve(methodRef);
return ResolveGlobalMethod(methodRef);
}
MethodBase resolveGlobalMethod(IMethod methodRef) {
initGlobalMethods();
MethodBase ResolveGlobalMethod(IMethod methodRef) {
InitGlobalMethods();
foreach (var globalMethod in globalMethods) {
if (ResolverUtils.compareMethods(globalMethod, methodRef))
if (ResolverUtils.CompareMethods(globalMethod, methodRef))
return globalMethod;
}
return null;
}
void initGlobalMethods() {
void InitGlobalMethods() {
if (globalMethods != null)
return;
globalMethods = new List<MethodBase>();
@ -128,8 +128,8 @@ namespace AssemblyData.methodsrewriter {
}
}
public Type resolve(ITypeDefOrRef typeRef) {
var resolver = getTypeResolver(typeRef);
public Type Resolve(ITypeDefOrRef typeRef) {
var resolver = GetTypeResolver(typeRef);
if (resolver != null)
return resolver.type;

View File

@ -81,14 +81,14 @@ namespace AssemblyData.methodsrewriter {
this.methodName = methodName;
}
public void setMethodInfo(MMethod methodInfo) {
public void SetMethodInfo(MMethod methodInfo) {
this.methodInfo = methodInfo;
methodReturnType = ResolverUtils.getReturnType(methodInfo.methodBase);
methodParameters = getMethodParameterTypes(methodInfo.methodBase);
delegateType = Utils.getDelegateType(methodReturnType, methodParameters);
methodReturnType = ResolverUtils.GetReturnType(methodInfo.methodBase);
methodParameters = GetMethodParameterTypes(methodInfo.methodBase);
delegateType = Utils.GetDelegateType(methodReturnType, methodParameters);
}
public Delegate generate(IList<Instruction> allInstructions, IList<ExceptionHandler> allExceptionHandlers) {
public Delegate Generate(IList<Instruction> allInstructions, IList<ExceptionHandler> allExceptionHandlers) {
this.allInstructions = allInstructions;
this.allExceptionHandlers = allExceptionHandlers;
@ -96,37 +96,37 @@ namespace AssemblyData.methodsrewriter {
var lastInstr = allInstructions[allInstructions.Count - 1];
ilg = dm.GetILGenerator((int)lastInstr.Offset + lastInstr.GetSize());
initInstrToIndex();
initLocals();
initLabels();
InitInstrToIndex();
InitLocals();
InitLabels();
exceptionHandlersStack = new Stack<ExceptionHandler>();
for (int i = 0; i < allInstructions.Count; i++) {
updateExceptionHandlers(i);
UpdateExceptionHandlers(i);
var instr = allInstructions[i];
ilg.MarkLabel(labels[i]);
if (instr.Operand is Operand)
writeSpecialInstr(instr, (Operand)instr.Operand);
WriteSpecialInstr(instr, (Operand)instr.Operand);
else
writeInstr(instr);
WriteInstr(instr);
}
updateExceptionHandlers(-1);
UpdateExceptionHandlers(-1);
return dm.CreateDelegate(delegateType);
}
Instruction getExceptionInstruction(int instructionIndex) {
Instruction GetExceptionInstruction(int instructionIndex) {
return instructionIndex < 0 ? null : allInstructions[instructionIndex];
}
void updateExceptionHandlers(int instructionIndex) {
var instr = getExceptionInstruction(instructionIndex);
updateExceptionHandlers(instr);
if (addTryStart(instr))
updateExceptionHandlers(instr);
void UpdateExceptionHandlers(int instructionIndex) {
var instr = GetExceptionInstruction(instructionIndex);
UpdateExceptionHandlers(instr);
if (AddTryStart(instr))
UpdateExceptionHandlers(instr);
}
void updateExceptionHandlers(Instruction instr) {
void UpdateExceptionHandlers(Instruction instr) {
while (exceptionHandlersStack.Count > 0) {
var ex = exceptionHandlersStack.Peek();
if (ex.TryEnd == instr) {
@ -137,11 +137,11 @@ namespace AssemblyData.methodsrewriter {
if (ex.HandlerType == ExceptionHandlerType.Finally)
ilg.BeginFinallyBlock();
else
ilg.BeginCatchBlock(Resolver.getRtType(ex.CatchType));
ilg.BeginCatchBlock(Resolver.GetRtType(ex.CatchType));
}
if (ex.HandlerEnd == instr) {
exceptionHandlersStack.Pop();
if (exceptionHandlersStack.Count == 0 || !isSameTryBlock(ex, exceptionHandlersStack.Peek()))
if (exceptionHandlersStack.Count == 0 || !IsSameTryBlock(ex, exceptionHandlersStack.Peek()))
ilg.EndExceptionBlock();
}
else
@ -149,7 +149,7 @@ namespace AssemblyData.methodsrewriter {
}
}
bool addTryStart(Instruction instr) {
bool AddTryStart(Instruction instr) {
var list = new List<ExceptionHandler>();
foreach (var ex in allExceptionHandlers) {
if (ex.TryStart == instr)
@ -158,7 +158,7 @@ namespace AssemblyData.methodsrewriter {
list.Reverse();
foreach (var ex in list) {
if (exceptionHandlersStack.Count == 0 || !isSameTryBlock(ex, exceptionHandlersStack.Peek()))
if (exceptionHandlersStack.Count == 0 || !IsSameTryBlock(ex, exceptionHandlersStack.Peek()))
ilg.BeginExceptionBlock();
exceptionHandlersStack.Push(ex);
}
@ -166,33 +166,33 @@ namespace AssemblyData.methodsrewriter {
return list.Count > 0;
}
static bool isSameTryBlock(ExceptionHandler ex1, ExceptionHandler ex2) {
static bool IsSameTryBlock(ExceptionHandler ex1, ExceptionHandler ex2) {
return ex1.TryStart == ex2.TryStart && ex1.TryEnd == ex2.TryEnd;
}
void initInstrToIndex() {
void InitInstrToIndex() {
instrToIndex = new Dictionary<Instruction, int>(allInstructions.Count);
for (int i = 0; i < allInstructions.Count; i++)
instrToIndex[allInstructions[i]] = i;
}
void initLocals() {
void InitLocals() {
locals = new List<LocalBuilder>();
foreach (var local in methodInfo.methodDef.Body.Variables)
locals.Add(ilg.DeclareLocal(Resolver.getRtType(local.Type), local.Type.RemoveModifiers().IsPinned));
locals.Add(ilg.DeclareLocal(Resolver.GetRtType(local.Type), local.Type.RemoveModifiers().IsPinned));
tempObjLocal = ilg.DeclareLocal(typeof(object));
tempObjArrayLocal = ilg.DeclareLocal(typeof(object[]));
}
void initLabels() {
void InitLabels() {
labels = new List<Label>(allInstructions.Count);
for (int i = 0; i < allInstructions.Count; i++)
labels.Add(ilg.DefineLabel());
}
Type[] getMethodParameterTypes(MethodBase method) {
Type[] GetMethodParameterTypes(MethodBase method) {
var list = new List<Type>();
if (ResolverUtils.hasThis(method))
if (ResolverUtils.HasThis(method))
list.Add(method.DeclaringType);
foreach (var param in method.GetParameters())
@ -204,19 +204,19 @@ namespace AssemblyData.methodsrewriter {
return list.ToArray();
}
void writeSpecialInstr(Instruction instr, Operand operand) {
void WriteSpecialInstr(Instruction instr, Operand operand) {
BindingFlags flags;
switch (operand.type) {
case Operand.Type.ThisArg:
ilg.Emit(convertOpCode(instr.OpCode), (short)thisArgIndex);
ilg.Emit(ConvertOpCode(instr.OpCode), (short)thisArgIndex);
break;
case Operand.Type.TempObj:
ilg.Emit(convertOpCode(instr.OpCode), tempObjLocal);
ilg.Emit(ConvertOpCode(instr.OpCode), tempObjLocal);
break;
case Operand.Type.TempObjArray:
ilg.Emit(convertOpCode(instr.OpCode), tempObjArrayLocal);
ilg.Emit(ConvertOpCode(instr.OpCode), tempObjArrayLocal);
break;
case Operand.Type.OurMethod:
@ -225,19 +225,19 @@ namespace AssemblyData.methodsrewriter {
var ourMethod = methodsRewriter.GetType().GetMethod(methodName, flags);
if (ourMethod == null)
throw new ApplicationException(string.Format("Could not find method {0}", methodName));
ilg.Emit(convertOpCode(instr.OpCode), ourMethod);
ilg.Emit(ConvertOpCode(instr.OpCode), ourMethod);
break;
case Operand.Type.NewMethod:
var methodBase = (MethodBase)operand.data;
var delegateType = methodsRewriter.getDelegateType(methodBase);
var delegateType = methodsRewriter.GetDelegateType(methodBase);
flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance;
var invokeMethod = delegateType.GetMethod("Invoke", flags);
ilg.Emit(convertOpCode(instr.OpCode), invokeMethod);
ilg.Emit(ConvertOpCode(instr.OpCode), invokeMethod);
break;
case Operand.Type.ReflectionType:
ilg.Emit(convertOpCode(instr.OpCode), (Type)operand.data);
ilg.Emit(ConvertOpCode(instr.OpCode), (Type)operand.data);
break;
default:
@ -245,19 +245,19 @@ namespace AssemblyData.methodsrewriter {
}
}
Label getLabel(Instruction target) {
Label GetLabel(Instruction target) {
return labels[instrToIndex[target]];
}
Label[] getLabels(Instruction[] targets) {
Label[] GetLabels(Instruction[] targets) {
var labels = new Label[targets.Length];
for (int i = 0; i < labels.Length; i++)
labels[i] = getLabel(targets[i]);
labels[i] = GetLabel(targets[i]);
return labels;
}
void writeInstr(Instruction instr) {
var opcode = convertOpCode(instr.OpCode);
void WriteInstr(Instruction instr) {
var opcode = ConvertOpCode(instr.OpCode);
switch (instr.OpCode.OperandType) {
case OperandType.InlineNone:
ilg.Emit(opcode);
@ -265,11 +265,11 @@ namespace AssemblyData.methodsrewriter {
case OperandType.InlineBrTarget:
case OperandType.ShortInlineBrTarget:
ilg.Emit(opcode, getLabel((Instruction)instr.Operand));
ilg.Emit(opcode, GetLabel((Instruction)instr.Operand));
break;
case OperandType.InlineSwitch:
ilg.Emit(opcode, getLabels((Instruction[])instr.Operand));
ilg.Emit(opcode, GetLabels((Instruction[])instr.Operand));
break;
case OperandType.ShortInlineI:
@ -303,7 +303,7 @@ namespace AssemblyData.methodsrewriter {
case OperandType.InlineType:
case OperandType.InlineMethod:
case OperandType.InlineField:
var obj = Resolver.getRtObject((ITokenOperand)instr.Operand);
var obj = Resolver.GetRtObject((ITokenOperand)instr.Operand);
if (obj is ConstructorInfo)
ilg.Emit(opcode, (ConstructorInfo)obj);
else if (obj is MethodInfo)
@ -330,7 +330,7 @@ namespace AssemblyData.methodsrewriter {
}
}
ROpCode convertOpCode(OpCode opcode) {
ROpCode ConvertOpCode(OpCode opcode) {
ROpCode ropcode;
if (dnlibToReflection.TryGetValue(opcode, out ropcode))
return ropcode;

View File

@ -22,6 +22,6 @@ using System.Reflection;
namespace AssemblyData.methodsrewriter {
interface IMethodsRewriter {
Type getDelegateType(MethodBase methodBase);
Type GetDelegateType(MethodBase methodBase);
}
}

View File

@ -29,7 +29,7 @@ namespace AssemblyData.methodsrewriter {
this.methodDef = methodDef;
}
public bool hasInstructions() {
public bool HasInstructions() {
return methodDef.Body != null && methodDef.Body.Instructions.Count != 0;
}

View File

@ -36,10 +36,10 @@ namespace AssemblyData.methodsrewriter {
public MModule(Module module, ModuleDefMD moduleDef) {
this.module = module;
this.moduleDef = moduleDef;
initTokenToType();
InitTokenToType();
}
void initTokenToType() {
void InitTokenToType() {
moduleType = moduleDef.Types[0];
foreach (var typeDef in moduleDef.GetTypes()) {
int token = (int)typeDef.MDToken.Raw;
@ -49,27 +49,27 @@ namespace AssemblyData.methodsrewriter {
}
catch {
tokenToType[token] = null;
typeRefToType.add(typeDef, null);
typeRefToType.Add(typeDef, null);
continue;
}
var mtype = new MType(type, typeDef);
tokenToType[token] = mtype;
typeRefToType.add(typeDef, mtype);
typeRefToType.Add(typeDef, mtype);
}
}
public MType getType(IType typeRef) {
return typeRefToType.find(typeRef);
public MType GetType(IType typeRef) {
return typeRefToType.Find(typeRef);
}
public MMethod getMethod(IMethod methodRef) {
var type = getType(methodRef.DeclaringType);
public MMethod GetMethod(IMethod methodRef) {
var type = GetType(methodRef.DeclaringType);
if (type != null)
return type.getMethod(methodRef);
return type.GetMethod(methodRef);
if (!new SigComparer().Equals(moduleType, methodRef.DeclaringType))
return null;
initGlobalMethods();
InitGlobalMethods();
foreach (var method in tokenToGlobalMethod.Values) {
if (new SigComparer().Equals(methodRef, method.methodDef))
return method;
@ -78,14 +78,14 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public MField getField(IField fieldRef) {
var type = getType(fieldRef.DeclaringType);
public MField GetField(IField fieldRef) {
var type = GetType(fieldRef.DeclaringType);
if (type != null)
return type.getField(fieldRef);
return type.GetField(fieldRef);
if (!new SigComparer().Equals(moduleType, fieldRef.DeclaringType))
return null;
initGlobalFields();
InitGlobalFields();
foreach (var field in tokenToGlobalField.Values) {
if (new SigComparer().Equals(fieldRef, field.fieldDef))
return field;
@ -94,21 +94,21 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public MMethod getMethod(MethodBase method) {
public MMethod GetMethod(MethodBase method) {
if (method.Module != module)
throw new ApplicationException("Not our module");
if (method.DeclaringType == null)
return getGlobalMethod(method);
return GetGlobalMethod(method);
var type = tokenToType[method.DeclaringType.MetadataToken];
return type.getMethod(method.MetadataToken);
return type.GetMethod(method.MetadataToken);
}
public MMethod getGlobalMethod(MethodBase method) {
initGlobalMethods();
public MMethod GetGlobalMethod(MethodBase method) {
InitGlobalMethods();
return tokenToGlobalMethod[method.MetadataToken];
}
void initGlobalMethods() {
void InitGlobalMethods() {
if (tokenToGlobalMethod != null)
return;
tokenToGlobalMethod = new Dictionary<int, MMethod>();
@ -125,7 +125,7 @@ namespace AssemblyData.methodsrewriter {
}
}
void initGlobalFields() {
void InitGlobalFields() {
if (tokenToGlobalField != null)
return;
tokenToGlobalField = new Dictionary<int, MField>();

View File

@ -37,27 +37,27 @@ namespace AssemblyData.methodsrewriter {
this.typeDef = typeDef;
}
public MMethod getMethod(IMethod methodRef) {
initMethods();
return methodRefToMethod.find(methodRef);
public MMethod GetMethod(IMethod methodRef) {
InitMethods();
return methodRefToMethod.Find(methodRef);
}
public MField getField(IField fieldRef) {
initFields();
return fieldRefToField.find(fieldRef);
public MField GetField(IField fieldRef) {
InitFields();
return fieldRefToField.Find(fieldRef);
}
public MMethod getMethod(int token) {
initMethods();
public MMethod GetMethod(int token) {
InitMethods();
return tokenToMethod[token];
}
public MField getField(int token) {
initFields();
public MField GetField(int token) {
InitFields();
return tokenToField[token];
}
void initMethods() {
void InitMethods() {
if (tokenToMethod != null)
return;
tokenToMethod = new Dictionary<int, MMethod>(typeDef.Methods.Count);
@ -65,17 +65,17 @@ namespace AssemblyData.methodsrewriter {
var tmpTokenToMethod = new Dictionary<int, MethodBase>();
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var m in ResolverUtils.getMethodBases(type, flags))
foreach (var m in ResolverUtils.GetMethodBases(type, flags))
tmpTokenToMethod[m.MetadataToken] = m;
foreach (var m in typeDef.Methods) {
var token = (int)m.MDToken.Raw;
var method = new MMethod(tmpTokenToMethod[token], m);
tokenToMethod[token] = method;
methodRefToMethod.add(method.methodDef, method);
methodRefToMethod.Add(method.methodDef, method);
}
}
void initFields() {
void InitFields() {
if (tokenToField != null)
return;
tokenToField = new Dictionary<int, MField>(typeDef.Fields.Count);
@ -89,7 +89,7 @@ namespace AssemblyData.methodsrewriter {
var token = (int)f.MDToken.Raw;
var field = new MField(tmpTokenToField[token], f);
tokenToField[token] = field;
fieldRefToField.add(field.fieldDef, field);
fieldRefToField.Add(field.fieldDef, field);
}
}

View File

@ -62,16 +62,16 @@ namespace AssemblyData.methodsrewriter {
}
}
public MethodBase getNext() {
public MethodBase GetNext() {
return methods[next++ % methods.Count];
}
}
public MethodBase getMethod(Module module) {
public MethodBase GetMethod(Module module) {
MethodsModule methodsModule;
if (!moduleToMethods.TryGetValue(module, out methodsModule))
moduleToMethods[module] = methodsModule = new MethodsModule(module);
return methodsModule.getNext();
return methodsModule.GetNext();
}
}
@ -112,20 +112,20 @@ namespace AssemblyData.methodsrewriter {
this.rewrittenMethodName = rewrittenMethodName;
}
public bool isRewrittenMethod(string name) {
public bool IsRewrittenMethod(string name) {
return name == rewrittenMethodName;
}
public bool isDelegateMethod(string name) {
public bool IsDelegateMethod(string name) {
return name == delegateMethodName;
}
}
public Type getDelegateType(MethodBase methodBase) {
public Type GetDelegateType(MethodBase methodBase) {
return realMethodToNewMethod[methodBase].delegateType;
}
public RewrittenMethod createDelegate(MethodBase realMethod) {
public RewrittenMethod CreateDelegate(MethodBase realMethod) {
var newMethodInfo = realMethodToNewMethod[realMethod];
if (newMethodInfo.rewrittenMethod != null)
return newMethodInfo.rewrittenMethod;
@ -135,7 +135,7 @@ namespace AssemblyData.methodsrewriter {
ilg.Emit(ROpCodes.Ldarg_0);
ilg.Emit(ROpCodes.Ldc_I4, newMethodInfo.delegateIndex);
ilg.Emit(ROpCodes.Call, GetType().GetMethod("rtGetDelegateInstance", BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance));
ilg.Emit(ROpCodes.Call, GetType().GetMethod("RtGetDelegateInstance", BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Instance));
ilg.Emit(ROpCodes.Castclass, newMethodInfo.delegateType);
var args = newMethodInfo.oldMethod.GetParameters();
@ -156,7 +156,7 @@ namespace AssemblyData.methodsrewriter {
var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance;
var invokeMethod = newMethodInfo.delegateType.GetMethod("Invoke", flags);
ilg.Emit(ROpCodes.Call, invokeMethod);
if (ResolverUtils.getReturnType(newMethodInfo.oldMethod) == typeof(void))
if (ResolverUtils.GetReturnType(newMethodInfo.oldMethod) == typeof(void))
ilg.Emit(ROpCodes.Ldnull);
ilg.Emit(ROpCodes.Ret);
@ -164,50 +164,50 @@ namespace AssemblyData.methodsrewriter {
return newMethodInfo.rewrittenMethod;
}
public void setCaller(RewrittenMethod rewrittenMethod, MethodBase caller) {
public void SetCaller(RewrittenMethod rewrittenMethod, MethodBase caller) {
if (caller == null)
return;
var newMethodInfo = getNewMethodInfo(rewrittenMethod.Method.Name);
var newMethodInfo = GetNewMethodInfo(rewrittenMethod.Method.Name);
newStackMethodDict[newMethodInfo] = caller;
}
string getDelegateMethodName(MethodBase method) {
string GetDelegateMethodName(MethodBase method) {
string name = null;
do {
name = string.Format(" {0} {1:X8} DMN {2:X8} ", method.Name, method.MetadataToken, Utils.getRandomUint());
name = string.Format(" {0} {1:X8} DMN {2:X8} ", method.Name, method.MetadataToken, Utils.GetRandomUint());
} while (delegateNameToNewMethodInfo.ContainsKey(name));
return name;
}
public void createMethod(MethodBase realMethod) {
public void CreateMethod(MethodBase realMethod) {
if (realMethodToNewMethod.ContainsKey(realMethod))
return;
var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, getDelegateMethodName(realMethod), getDelegateMethodName(realMethod));
var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, GetDelegateMethodName(realMethod), GetDelegateMethodName(realMethod));
newMethodInfos.Add(newMethodInfo);
delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName] = newMethodInfo;
delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo;
realMethodToNewMethod[realMethod] = newMethodInfo;
var moduleInfo = Resolver.loadAssembly(realMethod.Module);
var methodInfo = moduleInfo.getMethod(realMethod);
if (!methodInfo.hasInstructions())
var moduleInfo = Resolver.LoadAssembly(realMethod.Module);
var methodInfo = moduleInfo.GetMethod(realMethod);
if (!methodInfo.HasInstructions())
throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw));
var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName);
codeGenerator.setMethodInfo(methodInfo);
codeGenerator.SetMethodInfo(methodInfo);
newMethodInfo.delegateType = codeGenerator.DelegateType;
var blocks = new Blocks(methodInfo.methodDef);
foreach (var block in blocks.MethodBlocks.getAllBlocks())
update(block, newMethodInfo);
foreach (var block in blocks.MethodBlocks.GetAllBlocks())
Update(block, newMethodInfo);
IList<Instruction> allInstructions;
IList<ExceptionHandler> allExceptionHandlers;
blocks.getCode(out allInstructions, out allExceptionHandlers);
newMethodInfo.delegateInstance = codeGenerator.generate(allInstructions, allExceptionHandlers);
blocks.GetCode(out allInstructions, out allExceptionHandlers);
newMethodInfo.delegateInstance = codeGenerator.Generate(allInstructions, allExceptionHandlers);
}
static Instruction create(OpCode opcode, object operand) {
static Instruction Create(OpCode opcode, object operand) {
return new Instruction {
OpCode = opcode,
Operand = operand,
@ -215,17 +215,17 @@ namespace AssemblyData.methodsrewriter {
}
// Inserts ldarg THIS, and returns number of instructions inserted at 'i'
int insertLoadThis(Block block, int i) {
block.insert(i, create(OpCodes.Ldarg, new Operand(Operand.Type.ThisArg)));
int InsertLoadThis(Block block, int i) {
block.Insert(i, Create(OpCodes.Ldarg, new Operand(Operand.Type.ThisArg)));
return 1;
}
int insertCallOurMethod(Block block, int i, string methodName) {
block.insert(i, create(OpCodes.Call, new Operand(Operand.Type.OurMethod, methodName)));
int InsertCallOurMethod(Block block, int i, string methodName) {
block.Insert(i, Create(OpCodes.Call, new Operand(Operand.Type.OurMethod, methodName)));
return 1;
}
void update(Block block, NewMethodInfo currentMethodInfo) {
void Update(Block block, NewMethodInfo currentMethodInfo) {
var instrs = block.Instructions;
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
@ -233,14 +233,14 @@ namespace AssemblyData.methodsrewriter {
var ctor = (IMethod)instr.Operand;
var ctorTypeFullName = ctor.DeclaringType.FullName;
if (ctorTypeFullName == "System.Diagnostics.StackTrace") {
insertLoadThis(block, i + 1);
insertCallOurMethod(block, i + 2, "static_rtFixStackTrace");
InsertLoadThis(block, i + 1);
InsertCallOurMethod(block, i + 2, "static_RtFixStackTrace");
i += 2;
continue;
}
else if (ctorTypeFullName == "System.Diagnostics.StackFrame") {
insertLoadThis(block, i + 1);
insertCallOurMethod(block, i + 2, "static_rtFixStackFrame");
InsertLoadThis(block, i + 1);
InsertCallOurMethod(block, i + 2, "static_RtFixStackFrame");
i += 2;
continue;
}
@ -251,67 +251,67 @@ namespace AssemblyData.methodsrewriter {
if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib()) {
var calledMethodFullName = calledMethod.FullName;
if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") {
block.replace(i, 1, OpCodes.Nop.ToInstruction());
insertLoadThis(block, i + 1);
insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg");
block.Replace(i, 1, OpCodes.Nop.ToInstruction());
InsertLoadThis(block, i + 1);
InsertCallOurMethod(block, i + 2, "static_RtGetAssembly_TypeArg");
i += 2;
continue;
}
else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" ||
calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" ||
calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") {
block.replace(i, 1, OpCodes.Nop.ToInstruction());
insertLoadThis(block, i + 1);
block.insert(i + 2, OpCodes.Ldc_I4.ToInstruction(currentMethodInfo.delegateIndex));
insertCallOurMethod(block, i + 3, "rtGetAssembly");
block.Replace(i, 1, OpCodes.Nop.ToInstruction());
InsertLoadThis(block, i + 1);
block.Insert(i + 2, OpCodes.Ldc_I4.ToInstruction(currentMethodInfo.delegateIndex));
InsertCallOurMethod(block, i + 3, "RtGetAssembly");
i += 3;
continue;
}
}
var method = Resolver.getMethod((IMethod)instr.Operand);
var method = Resolver.GetMethod((IMethod)instr.Operand);
if (method != null) {
createMethod(method.methodBase);
CreateMethod(method.methodBase);
var newMethodInfo = realMethodToNewMethod[method.methodBase];
block.replace(i, 1, OpCodes.Nop.ToInstruction());
block.Replace(i, 1, OpCodes.Nop.ToInstruction());
int n = i + 1;
// Pop all pushed args to a temp array
var mparams = getParameters(method.methodDef);
var mparams = GetParameters(method.methodDef);
if (mparams.Count > 0) {
block.insert(n++, OpCodes.Ldc_I4.ToInstruction(mparams.Count));
block.Insert(n++, OpCodes.Ldc_I4.ToInstruction(mparams.Count));
var objectType = method.methodDef.DeclaringType.Module.CorLibTypes.Object;
block.insert(n++, OpCodes.Newarr.ToInstruction(objectType));
block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));
block.Insert(n++, OpCodes.Newarr.ToInstruction(objectType));
block.Insert(n++, Create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray)));
for (int j = mparams.Count - 1; j >= 0; j--) {
var argType = mparams[j];
if (argType.RemovePinnedAndModifiers().IsValueType)
block.insert(n++, OpCodes.Box.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj)));
block.insert(n++, OpCodes.Stelem_Ref.ToInstruction());
block.Insert(n++, OpCodes.Box.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
block.Insert(n++, Create(OpCodes.Stloc, new Operand(Operand.Type.TempObj)));
block.Insert(n++, Create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
block.Insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
block.Insert(n++, Create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj)));
block.Insert(n++, OpCodes.Stelem_Ref.ToInstruction());
}
}
// Push delegate instance
insertLoadThis(block, n++);
block.insert(n++, OpCodes.Ldc_I4.ToInstruction(newMethodInfo.delegateIndex));
insertCallOurMethod(block, n++, "rtGetDelegateInstance");
block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType)));
InsertLoadThis(block, n++);
block.Insert(n++, OpCodes.Ldc_I4.ToInstruction(newMethodInfo.delegateIndex));
InsertCallOurMethod(block, n++, "RtGetDelegateInstance");
block.Insert(n++, Create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType)));
// Push all popped args
if (mparams.Count > 0) {
for (int j = 0; j < mparams.Count; j++) {
block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
block.insert(n++, OpCodes.Ldelem_Ref.ToInstruction());
block.Insert(n++, Create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray)));
block.Insert(n++, OpCodes.Ldc_I4.ToInstruction(j));
block.Insert(n++, OpCodes.Ldelem_Ref.ToInstruction());
var argType = mparams[j];
if (argType.RemovePinnedAndModifiers().IsValueType)
block.insert(n++, OpCodes.Unbox_Any.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
block.Insert(n++, OpCodes.Unbox_Any.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef));
else {
// Don't cast it to its correct type. This will sometimes cause
// an exception in some EF obfuscated assembly since we'll be
@ -322,8 +322,8 @@ namespace AssemblyData.methodsrewriter {
}
}
insertLoadThis(block, n++);
block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase)));
InsertLoadThis(block, n++);
block.Insert(n++, Create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase)));
i = n - 1;
continue;
}
@ -331,48 +331,48 @@ namespace AssemblyData.methodsrewriter {
}
}
static IList<TypeSig> getParameters(MethodDef method) {
static IList<TypeSig> GetParameters(MethodDef method) {
var list = new List<TypeSig>(method.Parameters.Count);
for (int i = 0; i < method.Parameters.Count; i++)
list.Add(method.Parameters[i].Type);
return list;
}
static FieldInfo getStackTraceStackFramesField() {
static FieldInfo GgetStackTraceStackFramesField() {
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
return ResolverUtils.getFieldThrow(typeof(StackTrace), typeof(StackFrame[]), flags, "Could not find StackTrace's frames (StackFrame[]) field");
return ResolverUtils.GetFieldThrow(typeof(StackTrace), typeof(StackFrame[]), flags, "Could not find StackTrace's frames (StackFrame[]) field");
}
static FieldInfo getStackFrameMethodField() {
static FieldInfo GetStackFrameMethodField() {
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
return ResolverUtils.getFieldThrow(typeof(StackFrame), typeof(MethodBase), flags, "Could not find StackFrame's method (MethodBase) field");
return ResolverUtils.GetFieldThrow(typeof(StackFrame), typeof(MethodBase), flags, "Could not find StackFrame's method (MethodBase) field");
}
static void writeMethodBase(StackFrame frame, MethodBase method) {
var methodField = getStackFrameMethodField();
static void WriteMethodBase(StackFrame frame, MethodBase method) {
var methodField = GetStackFrameMethodField();
methodField.SetValue(frame, method);
if (frame.GetMethod() != method)
throw new ApplicationException(string.Format("Could not set new method: {0}", method));
}
NewMethodInfo getNewMethodInfo(string name) {
NewMethodInfo GetNewMethodInfo(string name) {
NewMethodInfo info;
delegateNameToNewMethodInfo.TryGetValue(name, out info);
return info;
}
// Called after the StackTrace ctor has been called.
static StackTrace static_rtFixStackTrace(StackTrace stackTrace, MethodsRewriter self) {
return self.rtFixStackTrace(stackTrace);
static StackTrace static_RtFixStackTrace(StackTrace stackTrace, MethodsRewriter self) {
return self.RtFixStackTrace(stackTrace);
}
StackTrace rtFixStackTrace(StackTrace stackTrace) {
var framesField = getStackTraceStackFramesField();
StackTrace RtFixStackTrace(StackTrace stackTrace) {
var framesField = GgetStackTraceStackFramesField();
var frames = (StackFrame[])framesField.GetValue(stackTrace);
var newFrames = new List<StackFrame>(frames.Length);
foreach (var frame in frames) {
fixStackFrame(frame);
FixStackFrame(frame);
newFrames.Add(frame);
}
@ -380,52 +380,52 @@ namespace AssemblyData.methodsrewriter {
return stackTrace;
}
static StackFrame static_rtFixStackFrame(StackFrame stackFrame, MethodsRewriter self) {
return self.rtFixStackFrame(stackFrame);
static StackFrame static_RtFixStackFrame(StackFrame stackFrame, MethodsRewriter self) {
return self.RtFixStackFrame(stackFrame);
}
StackFrame rtFixStackFrame(StackFrame frame) {
fixStackFrame(frame);
StackFrame RtFixStackFrame(StackFrame frame) {
FixStackFrame(frame);
return frame;
}
void fixStackFrame(StackFrame frame) {
void FixStackFrame(StackFrame frame) {
var method = frame.GetMethod();
var info = getNewMethodInfo(method.Name);
var info = GetNewMethodInfo(method.Name);
if (info == null)
return;
MethodBase stackMethod;
if (newStackMethodDict.TryGetValue(info, out stackMethod)) {
writeMethodBase(frame, stackMethod);
WriteMethodBase(frame, stackMethod);
}
else if (info.isRewrittenMethod(method.Name)) {
else if (info.IsRewrittenMethod(method.Name)) {
// Write random method from the same module
writeMethodBase(frame, methodsFinder.getMethod(info.oldMethod.Module));
WriteMethodBase(frame, methodsFinder.GetMethod(info.oldMethod.Module));
}
else if (info.isDelegateMethod(method.Name)) {
else if (info.IsDelegateMethod(method.Name)) {
// Write original method
writeMethodBase(frame, info.oldMethod);
WriteMethodBase(frame, info.oldMethod);
}
else
throw new ApplicationException("BUG: Shouldn't be here");
}
// Called when the code calls GetCallingAssembly(), GetEntryAssembly(), or GetExecutingAssembly()
Assembly rtGetAssembly(int delegateIndex) {
Assembly RtGetAssembly(int delegateIndex) {
return newMethodInfos[delegateIndex].oldMethod.Module.Assembly;
}
// Called when the code calls GetAssembly(Type)
static Assembly static_rtGetAssembly_TypeArg(Type type, MethodsRewriter self) {
return self.rtGetAssembly_TypeArg(type);
static Assembly static_RtGetAssembly_TypeArg(Type type, MethodsRewriter self) {
return self.RtGetAssembly_TypeArg(type);
}
Assembly rtGetAssembly_TypeArg(Type type) {
Assembly RtGetAssembly_TypeArg(Type type) {
return Assembly.GetAssembly(type);
}
Delegate rtGetDelegateInstance(int delegateIndex) {
Delegate RtGetDelegateInstance(int delegateIndex) {
return newMethodInfos[delegateIndex].delegateInstance;
}
}

View File

@ -28,7 +28,7 @@ namespace AssemblyData.methodsrewriter {
static Dictionary<string, AssemblyResolver> assemblyResolvers = new Dictionary<string, AssemblyResolver>(StringComparer.Ordinal);
static Dictionary<Module, MModule> modules = new Dictionary<Module, MModule>();
public static MModule loadAssembly(Module module) {
public static MModule LoadAssembly(Module module) {
MModule info;
if (modules.TryGetValue(module, out info))
return info;
@ -38,7 +38,7 @@ namespace AssemblyData.methodsrewriter {
return info;
}
static MModule getModule(ModuleDef moduleDef) {
static MModule GetModule(ModuleDef moduleDef) {
foreach (var mm in modules.Values) {
if (mm.moduleDef == moduleDef)
return mm;
@ -46,7 +46,7 @@ namespace AssemblyData.methodsrewriter {
return null;
}
static MModule getModule(AssemblyRef asmRef) {
static MModule GetModule(AssemblyRef asmRef) {
foreach (var mm in modules.Values) {
var asm = mm.moduleDef.Assembly;
if (asm != null && asm.FullName == asmRef.FullName)
@ -55,83 +55,83 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public static MModule getModule(IScope scope) {
public static MModule GetModule(IScope scope) {
if (scope.ScopeType == ScopeType.ModuleDef)
return getModule((ModuleDef)scope);
return GetModule((ModuleDef)scope);
else if (scope.ScopeType == ScopeType.AssemblyRef)
return getModule((AssemblyRef)scope);
return GetModule((AssemblyRef)scope);
return null;
}
public static MType getType(IType typeRef) {
public static MType GetType(IType typeRef) {
if (typeRef == null)
return null;
var module = getModule(typeRef.Scope);
var module = GetModule(typeRef.Scope);
if (module != null)
return module.getType(typeRef);
return module.GetType(typeRef);
return null;
}
public static MMethod getMethod(IMethod methodRef) {
public static MMethod GetMethod(IMethod methodRef) {
if (methodRef == null)
return null;
var module = getModule(methodRef.DeclaringType.Scope);
var module = GetModule(methodRef.DeclaringType.Scope);
if (module != null)
return module.getMethod(methodRef);
return module.GetMethod(methodRef);
return null;
}
public static MField getField(IField fieldRef) {
public static MField GetField(IField fieldRef) {
if (fieldRef == null)
return null;
var module = getModule(fieldRef.DeclaringType.Scope);
var module = GetModule(fieldRef.DeclaringType.Scope);
if (module != null)
return module.getField(fieldRef);
return module.GetField(fieldRef);
return null;
}
public static object getRtObject(ITokenOperand memberRef) {
public static object GetRtObject(ITokenOperand memberRef) {
if (memberRef == null)
return null;
var tdr = memberRef as ITypeDefOrRef;
if (tdr != null)
return getRtType(tdr);
return GetRtType(tdr);
var field = memberRef as IField;
if (field != null && field.FieldSig != null)
return getRtField(field);
return GetRtField(field);
var method = memberRef as IMethod;
if (method != null && method.MethodSig != null)
return getRtMethod(method);
return GetRtMethod(method);
throw new ApplicationException(string.Format("Unknown MemberRef: {0}", memberRef));
}
public static Type getRtType(IType typeRef) {
var mtype = getType(typeRef);
public static Type GetRtType(IType typeRef) {
var mtype = GetType(typeRef);
if (mtype != null)
return mtype.type;
return Resolver.resolve(typeRef);
return Resolver.Resolve(typeRef);
}
public static FieldInfo getRtField(IField fieldRef) {
var mfield = getField(fieldRef);
public static FieldInfo GetRtField(IField fieldRef) {
var mfield = GetField(fieldRef);
if (mfield != null)
return mfield.fieldInfo;
return Resolver.resolve(fieldRef);
return Resolver.Resolve(fieldRef);
}
public static MethodBase getRtMethod(IMethod methodRef) {
var mmethod = getMethod(methodRef);
public static MethodBase GetRtMethod(IMethod methodRef) {
var mmethod = GetMethod(methodRef);
if (mmethod != null)
return mmethod.methodBase;
return Resolver.resolve(methodRef);
return Resolver.Resolve(methodRef);
}
static AssemblyResolver getAssemblyResolver(ITypeDefOrRef type) {
static AssemblyResolver GetAssemblyResolver(ITypeDefOrRef type) {
var asmName = type.DefinitionAssembly.FullName;
AssemblyResolver resolver;
if (!assemblyResolvers.TryGetValue(asmName, out resolver))
@ -139,38 +139,38 @@ namespace AssemblyData.methodsrewriter {
return resolver;
}
static Type resolve(IType typeRef) {
static Type Resolve(IType typeRef) {
if (typeRef == null)
return null;
var scopeType = typeRef.ScopeType;
var resolver = getAssemblyResolver(scopeType);
var resolvedType = resolver.resolve(scopeType);
var resolver = GetAssemblyResolver(scopeType);
var resolvedType = resolver.Resolve(scopeType);
if (resolvedType != null)
return fixType(typeRef, resolvedType);
return FixType(typeRef, resolvedType);
throw new ApplicationException(string.Format("Could not resolve type {0} ({1:X8}) in assembly {2}", typeRef, typeRef.MDToken.Raw, resolver));
}
static FieldInfo resolve(IField fieldRef) {
static FieldInfo Resolve(IField fieldRef) {
if (fieldRef == null)
return null;
var resolver = getAssemblyResolver(fieldRef.DeclaringType);
var fieldInfo = resolver.resolve(fieldRef);
var resolver = GetAssemblyResolver(fieldRef.DeclaringType);
var fieldInfo = resolver.Resolve(fieldRef);
if (fieldInfo != null)
return fieldInfo;
throw new ApplicationException(string.Format("Could not resolve field {0} ({1:X8}) in assembly {2}", fieldRef, fieldRef.MDToken.Raw, resolver));
}
static MethodBase resolve(IMethod methodRef) {
static MethodBase Resolve(IMethod methodRef) {
if (methodRef == null)
return null;
var resolver = getAssemblyResolver(methodRef.DeclaringType);
var methodBase = resolver.resolve(methodRef);
var resolver = GetAssemblyResolver(methodRef.DeclaringType);
var methodBase = resolver.Resolve(methodRef);
if (methodBase != null)
return methodBase;
throw new ApplicationException(string.Format("Could not resolve method {0} ({1:X8}) in assembly {2}", methodRef, methodRef.MDToken.Raw, resolver));
}
static Type fixType(IType typeRef, Type type) {
static Type FixType(IType typeRef, Type type) {
var sig = typeRef as TypeSig;
if (sig == null) {
var ts = typeRef as TypeSpec;
@ -203,7 +203,7 @@ namespace AssemblyData.methodsrewriter {
var arg = git.GenericArguments[i];
if (!(arg is GenericSig))
isGenericTypeDef = false;
args[i] = Resolver.resolve(arg);
args[i] = Resolver.Resolve(arg);
}
if (!isGenericTypeDef)
type = type.MakeGenericType(args);

View File

@ -25,27 +25,27 @@ using de4dot.blocks;
namespace AssemblyData.methodsrewriter {
static class ResolverUtils {
public static bool compareTypes(Type a, IType b) {
public static bool CompareTypes(Type a, IType b) {
return new SigComparer().Equals(a, b);
}
public static bool compareFields(FieldInfo a, IField b) {
public static bool CompareFields(FieldInfo a, IField b) {
return new SigComparer().Equals(a, b);
}
public static bool hasThis(MethodBase method) {
public static bool HasThis(MethodBase method) {
return (method.CallingConvention & CallingConventions.HasThis) != 0;
}
public static bool explicitThis(MethodBase method) {
public static bool ExplicitThis(MethodBase method) {
return (method.CallingConvention & CallingConventions.ExplicitThis) != 0;
}
public static bool compareMethods(MethodBase a, IMethod b) {
public static bool CompareMethods(MethodBase a, IMethod b) {
return new SigComparer().Equals(a, b);
}
public static Type getReturnType(MethodBase methodBase) {
public static Type GetReturnType(MethodBase methodBase) {
var methodInfo = methodBase as MethodInfo;
if (methodInfo != null)
return methodInfo.ReturnType;
@ -57,7 +57,7 @@ namespace AssemblyData.methodsrewriter {
throw new ApplicationException(string.Format("Could not figure out return type: {0} ({1:X8})", methodBase, methodBase.MetadataToken));
}
public static Type[] getGenericArguments(MethodBase methodBase) {
public static Type[] GetGenericArguments(MethodBase methodBase) {
try {
return methodBase.GetGenericArguments();
}
@ -66,7 +66,7 @@ namespace AssemblyData.methodsrewriter {
}
}
public static IEnumerable<MethodBase> getMethodBases(Type type, BindingFlags flags) {
public static IEnumerable<MethodBase> GetMethodBases(Type type, BindingFlags flags) {
if (type.TypeInitializer != null)
yield return type.TypeInitializer;
foreach (var ctor in type.GetConstructors(flags))
@ -96,7 +96,7 @@ namespace AssemblyData.methodsrewriter {
}
static Dictionary<CachedMemberInfo, FieldInfo> cachedFieldInfos = new Dictionary<CachedMemberInfo, FieldInfo>();
public static FieldInfo getField(Type type, Type fieldType, BindingFlags flags) {
public static FieldInfo GetField(Type type, Type fieldType, BindingFlags flags) {
var key = new CachedMemberInfo(type, fieldType);
FieldInfo fieldInfo;
if (cachedFieldInfos.TryGetValue(key, out fieldInfo))
@ -111,14 +111,14 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public static FieldInfo getFieldThrow(Type type, Type fieldType, BindingFlags flags, string msg) {
var info = getField(type, fieldType, flags);
public static FieldInfo GetFieldThrow(Type type, Type fieldType, BindingFlags flags, string msg) {
var info = GetField(type, fieldType, flags);
if (info != null)
return info;
throw new ApplicationException(msg);
}
public static List<FieldInfo> getFields(Type type, Type fieldType, BindingFlags flags) {
public static List<FieldInfo> GetFields(Type type, Type fieldType, BindingFlags flags) {
var list = new List<FieldInfo>();
foreach (var field in type.GetFields(flags)) {
if (field.FieldType == fieldType)
@ -127,7 +127,7 @@ namespace AssemblyData.methodsrewriter {
return list;
}
public static Type makeInstanceType(Type type, ITypeDefOrRef typeRef) {
public static Type MakeInstanceType(Type type, ITypeDefOrRef typeRef) {
var ts = typeRef as TypeSpec;
if (ts == null)
return type;
@ -140,7 +140,7 @@ namespace AssemblyData.methodsrewriter {
var arg = git.GenericArguments[i];
if (!(arg is GenericSig))
isTypeDef = false;
types[i] = Resolver.getRtType(arg);
types[i] = Resolver.GetRtType(arg);
}
if (isTypeDef)
return type;

View File

@ -30,27 +30,27 @@ namespace AssemblyData.methodsrewriter {
Dictionary<string, List<FieldInfo>> fields;
public TypeInstanceResolver(Type type, ITypeDefOrRef typeRef) {
this.type = ResolverUtils.makeInstanceType(type, typeRef);
this.type = ResolverUtils.MakeInstanceType(type, typeRef);
}
public FieldInfo resolve(IField fieldRef) {
initFields();
public FieldInfo Resolve(IField fieldRef) {
InitFields();
List<FieldInfo> list;
if (!fields.TryGetValue(fieldRef.Name.String, out list))
return null;
fieldRef = GenericArgsSubstitutor.create(fieldRef, fieldRef.DeclaringType.TryGetGenericInstSig());
fieldRef = GenericArgsSubstitutor.Create(fieldRef, fieldRef.DeclaringType.TryGetGenericInstSig());
foreach (var field in list) {
if (ResolverUtils.compareFields(field, fieldRef))
if (ResolverUtils.CompareFields(field, fieldRef))
return field;
}
return null;
}
void initFields() {
void InitFields() {
if (fields != null)
return;
fields = new Dictionary<string, List<FieldInfo>>(StringComparer.Ordinal);
@ -64,30 +64,30 @@ namespace AssemblyData.methodsrewriter {
}
}
public MethodBase resolve(IMethod methodRef) {
initMethods();
public MethodBase Resolve(IMethod methodRef) {
InitMethods();
List<MethodBase> list;
if (!methods.TryGetValue(methodRef.Name.String, out list))
return null;
methodRef = GenericArgsSubstitutor.create(methodRef, methodRef.DeclaringType.TryGetGenericInstSig());
methodRef = GenericArgsSubstitutor.Create(methodRef, methodRef.DeclaringType.TryGetGenericInstSig());
foreach (var method in list) {
if (ResolverUtils.compareMethods(method, methodRef))
if (ResolverUtils.CompareMethods(method, methodRef))
return method;
}
return null;
}
void initMethods() {
void InitMethods() {
if (methods != null)
return;
methods = new Dictionary<string, List<MethodBase>>(StringComparer.Ordinal);
var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
foreach (var method in ResolverUtils.getMethodBases(type, flags)) {
foreach (var method in ResolverUtils.GetMethodBases(type, flags)) {
List<MethodBase> list;
if (!methods.TryGetValue(method.Name, out list))
methods[method.Name] = list = new List<MethodBase>();

View File

@ -32,19 +32,19 @@ namespace AssemblyData.methodsrewriter {
this.type = type;
}
TypeInstanceResolver getTypeInstance(ITypeDefOrRef typeRef) {
TypeInstanceResolver GetTypeInstance(ITypeDefOrRef typeRef) {
TypeInstanceResolver instance;
if (!typeRefToInstance.TryGetValue(typeRef, out instance))
typeRefToInstance[typeRef] = instance = new TypeInstanceResolver(type, typeRef);
return instance;
}
public FieldInfo resolve(IField fieldRef) {
return getTypeInstance(fieldRef.DeclaringType).resolve(fieldRef);
public FieldInfo Resolve(IField fieldRef) {
return GetTypeInstance(fieldRef.DeclaringType).Resolve(fieldRef);
}
public MethodBase resolve(IMethod methodRef) {
return getTypeInstance(methodRef.DeclaringType).resolve(methodRef);
public MethodBase Resolve(IMethod methodRef) {
return GetTypeInstance(methodRef.DeclaringType).Resolve(methodRef);
}
}
}

View File

@ -20,7 +20,7 @@
namespace AssemblyServer_CLR20_x64 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
return AssemblyServer.Start.Main2(args);
}
}
}

View File

@ -20,7 +20,7 @@
namespace AssemblyServer_CLR20 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
return AssemblyServer.Start.Main2(args);
}
}
}

View File

@ -20,7 +20,7 @@
namespace AssemblyServer_CLR40_x64 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
return AssemblyServer.Start.Main2(args);
}
}
}

View File

@ -20,7 +20,7 @@
namespace AssemblyServer_CLR40 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
return AssemblyServer.Start.Main2(args);
}
}
}

View File

@ -20,7 +20,7 @@
namespace AssemblyServer_x64 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
return AssemblyServer.Start.Main2(args);
}
}
}

View File

@ -20,7 +20,7 @@
namespace AssemblyServer_x86 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
return AssemblyServer.Start.Main2(args);
}
}
}

View File

@ -52,7 +52,7 @@ namespace de4dot.blocks {
public Instr FirstInstr {
get {
if (instructions.Count == 0)
add(new Instr(OpCodes.Nop.ToInstruction()));
Add(new Instr(OpCodes.Nop.ToInstruction()));
return instructions[0];
}
}
@ -60,16 +60,16 @@ namespace de4dot.blocks {
public Instr LastInstr {
get {
if (instructions.Count == 0)
add(new Instr(OpCodes.Nop.ToInstruction()));
Add(new Instr(OpCodes.Nop.ToInstruction()));
return instructions[instructions.Count - 1];
}
}
public void add(Instr instr) {
public void Add(Instr instr) {
instructions.Add(instr);
}
public void insert(int index, Instruction instr) {
public void Insert(int index, Instruction instr) {
instructions.Insert(index, new Instr(instr));
}
@ -78,8 +78,8 @@ namespace de4dot.blocks {
}
// If last instr is a br/br.s, removes it and replaces it with a fall through
public void removeLastBr() {
if (!LastInstr.isBr())
public void RemoveLastBr() {
if (!LastInstr.IsBr())
return;
if (fallThrough != null || (LastInstr.Operand != null && (targets == null || targets.Count != 1)))
@ -89,111 +89,111 @@ namespace de4dot.blocks {
instructions.RemoveAt(instructions.Count - 1);
}
public void replace(int index, int num, Instruction instruction) {
public void Replace(int index, int num, Instruction instruction) {
if (num <= 0)
throw new ArgumentOutOfRangeException("num");
remove(index, num);
Remove(index, num);
instructions.Insert(index, new Instr(instruction));
}
public void remove(int index, int num) {
public void Remove(int index, int num) {
if (index + num > instructions.Count)
throw new ApplicationException("Overflow");
if (num > 0 && index + num == instructions.Count && LastInstr.isConditionalBranch())
disconnectFromFallThroughAndTargets();
if (num > 0 && index + num == instructions.Count && LastInstr.IsConditionalBranch())
DisconnectFromFallThroughAndTargets();
instructions.RemoveRange(index, num);
}
public void remove(IEnumerable<int> indexes) {
var instrsToDelete = new List<int>(Utils.unique(indexes));
public void Remove(IEnumerable<int> indexes) {
var instrsToDelete = new List<int>(Utils.Unique(indexes));
instrsToDelete.Sort();
instrsToDelete.Reverse();
foreach (var index in instrsToDelete)
remove(index, 1);
Remove(index, 1);
}
// Replace the last instructions with a branch to target
public void replaceLastInstrsWithBranch(int numInstrs, Block target) {
public void ReplaceLastInstrsWithBranch(int numInstrs, Block target) {
if (numInstrs < 0 || numInstrs > instructions.Count)
throw new ApplicationException("Invalid numInstrs to replace with branch");
if (target == null)
throw new ApplicationException("Invalid new target, it's null");
disconnectFromFallThroughAndTargets();
DisconnectFromFallThroughAndTargets();
if (numInstrs > 0)
instructions.RemoveRange(instructions.Count - numInstrs, numInstrs);
fallThrough = target;
target.sources.Add(this);
}
public void replaceLastNonBranchWithBranch(int numInstrs, Block target) {
if (LastInstr.isBr())
public void ReplaceLastNonBranchWithBranch(int numInstrs, Block target) {
if (LastInstr.IsBr())
numInstrs++;
replaceLastInstrsWithBranch(numInstrs, target);
ReplaceLastInstrsWithBranch(numInstrs, target);
}
public void replaceBccWithBranch(bool isTaken) {
public void ReplaceBccWithBranch(bool isTaken) {
Block target = isTaken ? targets[0] : fallThrough;
replaceLastInstrsWithBranch(1, target);
ReplaceLastInstrsWithBranch(1, target);
}
public void replaceSwitchWithBranch(Block target) {
public void ReplaceSwitchWithBranch(Block target) {
if (LastInstr.OpCode.Code != Code.Switch)
throw new ApplicationException("Last instruction is not a switch");
replaceLastInstrsWithBranch(1, target);
ReplaceLastInstrsWithBranch(1, target);
}
public void setNewFallThrough(Block newFallThrough) {
disconnectFromFallThrough();
public void SetNewFallThrough(Block newFallThrough) {
DisconnectFromFallThrough();
fallThrough = newFallThrough;
newFallThrough.sources.Add(this);
}
public void setNewTarget(int index, Block newTarget) {
disconnectFromBlock(targets[index]);
public void SetNewTarget(int index, Block newTarget) {
DisconnectFromBlock(targets[index]);
targets[index] = newTarget;
newTarget.sources.Add(this);
}
public void removeDeadBlock() {
public void RemoveDeadBlock() {
if (sources.Count != 0)
throw new ApplicationException("Trying to remove a non-dead block");
removeGuaranteedDeadBlock();
RemoveGuaranteedDeadBlock();
}
// Removes a block that has been guaranteed to be dead. This method won't verify
// that it really is dead.
public void removeGuaranteedDeadBlock() {
disconnectFromFallThroughAndTargets();
public void RemoveGuaranteedDeadBlock() {
DisconnectFromFallThroughAndTargets();
Parent = null;
}
void disconnectFromFallThroughAndTargets() {
disconnectFromFallThrough();
disconnectFromTargets();
void DisconnectFromFallThroughAndTargets() {
DisconnectFromFallThrough();
DisconnectFromTargets();
}
void disconnectFromFallThrough() {
void DisconnectFromFallThrough() {
if (fallThrough != null) {
disconnectFromBlock(fallThrough);
DisconnectFromBlock(fallThrough);
fallThrough = null;
}
}
void disconnectFromTargets() {
void DisconnectFromTargets() {
if (targets != null) {
foreach (var target in targets)
disconnectFromBlock(target);
DisconnectFromBlock(target);
targets = null;
}
}
void disconnectFromBlock(Block target) {
void DisconnectFromBlock(Block target) {
if (!target.sources.Remove(this))
throw new ApplicationException("Could not remove the block from its target block");
}
public int countTargets() {
public int CountTargets() {
int count = fallThrough != null ? 1 : 0;
if (targets != null)
count += targets.Count;
@ -201,8 +201,8 @@ namespace de4dot.blocks {
}
// Returns the target iff it has only ONE target. Else it returns null.
public Block getOnlyTarget() {
if (countTargets() != 1)
public Block GetOnlyTarget() {
if (CountTargets() != 1)
return null;
if (fallThrough != null)
return fallThrough;
@ -210,7 +210,7 @@ namespace de4dot.blocks {
}
// Returns all targets. FallThrough (if not null) is always returned first!
public IEnumerable<Block> getTargets() {
public IEnumerable<Block> GetTargets() {
if (fallThrough != null)
yield return fallThrough;
if (targets != null) {
@ -220,52 +220,52 @@ namespace de4dot.blocks {
}
// Returns true iff other is the only block in Sources
public bool isOnlySource(Block other) {
public bool IsOnlySource(Block other) {
return sources.Count == 1 && sources[0] == other;
}
// Returns true if we can merge other with this
public bool canMerge(Block other) {
return canAppend(other) && other.isOnlySource(this);
public bool CanMerge(Block other) {
return CanAppend(other) && other.IsOnlySource(this);
}
// Merge two blocks into one
public void merge(Block other) {
if (!canMerge(other))
public void Merge(Block other) {
if (!CanMerge(other))
throw new ApplicationException("Can't merge the two blocks!");
append(other);
other.disconnectFromFallThroughAndTargets();
Append(other);
other.DisconnectFromFallThroughAndTargets();
other.Parent = null;
}
public bool canAppend(Block other) {
if (other == null || other == this || getOnlyTarget() != other)
public bool CanAppend(Block other) {
if (other == null || other == this || GetOnlyTarget() != other)
return false;
// If it's eg. a leave, then don't merge them since it clears the stack.
return LastInstr.isBr() || Instr.isFallThrough(LastInstr.OpCode);
return LastInstr.IsBr() || Instr.IsFallThrough(LastInstr.OpCode);
}
public void append(Block other) {
if (!canAppend(other))
public void Append(Block other) {
if (!CanAppend(other))
throw new ApplicationException("Can't append the block!");
removeLastBr(); // Get rid of last br/br.s if present
RemoveLastBr(); // Get rid of last br/br.s if present
var newInstructions = new List<Instr>(instructions.Count + other.instructions.Count);
addInstructions(newInstructions, instructions, false);
addInstructions(newInstructions, other.instructions, true);
AddInstructions(newInstructions, instructions, false);
AddInstructions(newInstructions, other.instructions, true);
instructions = newInstructions;
disconnectFromFallThroughAndTargets();
DisconnectFromFallThroughAndTargets();
if (other.targets != null)
targets = new List<Block>(other.targets);
else
targets = null;
fallThrough = other.fallThrough;
updateSources();
UpdateSources();
}
void addInstructions(IList<Instr> dest, IList<Instr> instrs, bool clone) {
void AddInstructions(IList<Instr> dest, IList<Instr> instrs, bool clone) {
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
if (instr.OpCode != OpCodes.Nop)
@ -275,7 +275,7 @@ namespace de4dot.blocks {
// Update each target's Sources property. Must only be called if this isn't in the
// Sources list!
public void updateSources() {
public void UpdateSources() {
if (fallThrough != null)
fallThrough.sources.Add(this);
if (targets != null) {
@ -285,30 +285,30 @@ namespace de4dot.blocks {
}
// Returns true if it falls through
public bool isFallThrough() {
public bool IsFallThrough() {
return targets == null && fallThrough != null;
}
public bool canFlipConditionalBranch() {
return LastInstr.canFlipConditionalBranch();
public bool CanFlipConditionalBranch() {
return LastInstr.CanFlipConditionalBranch();
}
public void flipConditionalBranch() {
public void FlipConditionalBranch() {
if (fallThrough == null || targets == null || targets.Count != 1)
throw new ApplicationException("Invalid bcc block state");
LastInstr.flipConditonalBranch();
LastInstr.FlipConditonalBranch();
var oldFallThrough = fallThrough;
fallThrough = targets[0];
targets[0] = oldFallThrough;
}
// Returns true if it's a conditional branch
public bool isConditionalBranch() {
return LastInstr.isConditionalBranch();
public bool IsConditionalBranch() {
return LastInstr.IsConditionalBranch();
}
public bool isNopBlock() {
if (!isFallThrough())
public bool IsNopBlock() {
if (!IsFallThrough())
return false;
foreach (var instr in instructions) {
if (instr.OpCode.Code != Code.Nop)

View File

@ -42,28 +42,28 @@ namespace de4dot.blocks {
public Blocks(MethodDef method) {
this.method = method;
updateBlocks();
UpdateBlocks();
}
public void updateBlocks() {
public void UpdateBlocks() {
var body = method.Body;
locals = body.Variables;
methodBlocks = new InstructionListParser(body.Instructions, body.ExceptionHandlers).parse();
methodBlocks = new InstructionListParser(body.Instructions, body.ExceptionHandlers).Parse();
}
IEnumerable<ScopeBlock> getAllScopeBlocks(ScopeBlock scopeBlock) {
IEnumerable<ScopeBlock> GetAllScopeBlocks(ScopeBlock scopeBlock) {
var list = new List<ScopeBlock>();
list.Add(scopeBlock);
list.AddRange(scopeBlock.getAllScopeBlocks());
list.AddRange(scopeBlock.GetAllScopeBlocks());
return list;
}
public int removeDeadBlocks() {
return new DeadBlocksRemover(methodBlocks).remove();
public int RemoveDeadBlocks() {
return new DeadBlocksRemover(methodBlocks).Remove();
}
public void getCode(out IList<Instruction> allInstructions, out IList<ExceptionHandler> allExceptionHandlers) {
new CodeGenerator(methodBlocks).getCode(out allInstructions, out allExceptionHandlers);
public void GetCode(out IList<Instruction> allInstructions, out IList<ExceptionHandler> allExceptionHandlers) {
new CodeGenerator(methodBlocks).GetCode(out allInstructions, out allExceptionHandlers);
}
struct LocalVariableInfo {
@ -75,12 +75,12 @@ namespace de4dot.blocks {
}
}
public int optimizeLocals() {
public int OptimizeLocals() {
if (locals.Count == 0)
return 0;
var usedLocals = new Dictionary<Local, List<LocalVariableInfo>>();
foreach (var block in methodBlocks.getAllBlocks()) {
foreach (var block in methodBlocks.GetAllBlocks()) {
for (int i = 0; i < block.Instructions.Count; i++) {
var instr = block.Instructions[i];
Local local;
@ -97,7 +97,7 @@ namespace de4dot.blocks {
case Code.Stloc_1:
case Code.Stloc_2:
case Code.Stloc_3:
local = Instr.getLocalVar(locals, instr);
local = Instr.GetLocalVar(locals, instr);
break;
case Code.Ldloca_S:
@ -129,7 +129,7 @@ namespace de4dot.blocks {
newLocals.Add(local);
newLocalsDict[local] = true;
foreach (var info in usedLocals[local])
info.block.Instructions[info.index] = new Instr(optimizeLocalInstr(info.block.Instructions[info.index], local, (uint)newIndex));
info.block.Instructions[info.index] = new Instr(OptimizeLocalInstr(info.block.Instructions[info.index], local, (uint)newIndex));
}
// We can't remove all locals. Locals that reference another assembly will
@ -162,7 +162,7 @@ namespace de4dot.blocks {
return numRemoved;
}
static Instruction optimizeLocalInstr(Instr instr, Local local, uint newIndex) {
static Instruction OptimizeLocalInstr(Instr instr, Local local, uint newIndex) {
switch (instr.OpCode.Code) {
case Code.Ldloc:
case Code.Ldloc_S:
@ -211,11 +211,11 @@ namespace de4dot.blocks {
}
}
public void repartitionBlocks() {
mergeNopBlocks();
foreach (var scopeBlock in getAllScopeBlocks(methodBlocks)) {
public void RepartitionBlocks() {
MergeNopBlocks();
foreach (var scopeBlock in GetAllScopeBlocks(methodBlocks)) {
try {
scopeBlock.repartitionBlocks();
scopeBlock.RepartitionBlocks();
}
catch (NullReferenceException) {
//TODO: Send this message to the log
@ -225,12 +225,12 @@ namespace de4dot.blocks {
}
}
void mergeNopBlocks() {
var allBlocks = methodBlocks.getAllBlocks();
void MergeNopBlocks() {
var allBlocks = methodBlocks.GetAllBlocks();
var nopBlocks = new Dictionary<Block, bool>();
foreach (var nopBlock in allBlocks) {
if (nopBlock.isNopBlock())
if (nopBlock.IsNopBlock())
nopBlocks[nopBlock] = true;
}
@ -243,18 +243,18 @@ namespace de4dot.blocks {
foreach (var block in allBlocks) {
Block nopBlockTarget;
nopBlockTarget = getNopBlockTarget(nopBlocks, block, block.FallThrough);
nopBlockTarget = GetNopBlockTarget(nopBlocks, block, block.FallThrough);
if (nopBlockTarget != null) {
block.setNewFallThrough(nopBlockTarget);
block.SetNewFallThrough(nopBlockTarget);
changed = true;
}
if (block.Targets != null) {
for (int targetIndex = 0; targetIndex < block.Targets.Count; targetIndex++) {
nopBlockTarget = getNopBlockTarget(nopBlocks, block, block.Targets[targetIndex]);
nopBlockTarget = GetNopBlockTarget(nopBlocks, block, block.Targets[targetIndex]);
if (nopBlockTarget == null)
continue;
block.setNewTarget(targetIndex, nopBlockTarget);
block.SetNewTarget(targetIndex, nopBlockTarget);
changed = true;
}
}
@ -265,10 +265,10 @@ namespace de4dot.blocks {
}
foreach (var nopBlock in nopBlocks.Keys)
nopBlock.Parent.removeDeadBlock(nopBlock);
nopBlock.Parent.RemoveDeadBlock(nopBlock);
}
static Block getNopBlockTarget(Dictionary<Block, bool> nopBlocks, Block source, Block nopBlock) {
static Block GetNopBlockTarget(Dictionary<Block, bool> nopBlocks, Block source, Block nopBlock) {
if (nopBlock == null || !nopBlocks.ContainsKey(nopBlock) || source == nopBlock.FallThrough)
return null;
if (nopBlock.Parent.BaseBlocks[0] == nopBlock)

View File

@ -34,7 +34,7 @@ namespace de4dot.blocks {
this.baseBlock = baseBlock;
}
public bool visited() {
public bool Visited() {
return dfsNumber >= 0;
}
@ -62,7 +62,7 @@ namespace de4dot.blocks {
this.skipFirstBlock = skipFirstBlock;
}
public List<BaseBlock> sort() {
public List<BaseBlock> Sort() {
if (validBlocks.Count == 0)
return new List<BaseBlock>();
if (skipFirstBlock)
@ -77,14 +77,14 @@ namespace de4dot.blocks {
var finalList = new List<BaseBlock>(validBlocks.Count);
if (firstBlock is Block) {
foreach (var target in getTargets(firstBlock)) {
visit(target);
foreach (var target in GetTargets(firstBlock)) {
Visit(target);
finalList.AddRange(sorted);
sorted.Clear();
}
}
foreach (var bb in validBlocks) {
visit(bb);
Visit(bb);
finalList.AddRange(sorted);
sorted.Clear();
}
@ -103,19 +103,19 @@ namespace de4dot.blocks {
return finalList;
}
void visit(BaseBlock bb) {
var info = getInfo(bb);
void Visit(BaseBlock bb) {
var info = GetInfo(bb);
if (info == null)
return;
if (info.baseBlock == firstBlock)
return;
if (info.visited())
if (info.Visited())
return;
visit(info);
Visit(info);
}
BlockInfo getInfo(BaseBlock baseBlock) {
baseBlock = scopeBlock.toChild(baseBlock);
BlockInfo GetInfo(BaseBlock baseBlock) {
baseBlock = scopeBlock.ToChild(baseBlock);
if (baseBlock == null)
return null;
BlockInfo info;
@ -123,54 +123,54 @@ namespace de4dot.blocks {
return info;
}
List<BaseBlock> getTargets(BaseBlock baseBlock) {
List<BaseBlock> GetTargets(BaseBlock baseBlock) {
var list = new List<BaseBlock>();
if (baseBlock is Block) {
var block = (Block)baseBlock;
addTargets(list, block.getTargets());
AddTargets(list, block.GetTargets());
}
else if (baseBlock is TryBlock)
addTargets(list, (TryBlock)baseBlock);
AddTargets(list, (TryBlock)baseBlock);
else if (baseBlock is TryHandlerBlock)
addTargets(list, (TryHandlerBlock)baseBlock);
AddTargets(list, (TryHandlerBlock)baseBlock);
else
addTargets(list, (ScopeBlock)baseBlock);
AddTargets(list, (ScopeBlock)baseBlock);
return list;
}
void addTargets(List<BaseBlock> dest, TryBlock tryBlock) {
addTargets(dest, (ScopeBlock)tryBlock);
void AddTargets(List<BaseBlock> dest, TryBlock tryBlock) {
AddTargets(dest, (ScopeBlock)tryBlock);
foreach (var tryHandlerBlock in tryBlock.TryHandlerBlocks) {
dest.Add(tryHandlerBlock);
addTargets(dest, tryHandlerBlock);
AddTargets(dest, tryHandlerBlock);
}
}
void addTargets(List<BaseBlock> dest, TryHandlerBlock tryHandlerBlock) {
addTargets(dest, (ScopeBlock)tryHandlerBlock);
void AddTargets(List<BaseBlock> dest, TryHandlerBlock tryHandlerBlock) {
AddTargets(dest, (ScopeBlock)tryHandlerBlock);
dest.Add(tryHandlerBlock.FilterHandlerBlock);
addTargets(dest, tryHandlerBlock.FilterHandlerBlock);
AddTargets(dest, tryHandlerBlock.FilterHandlerBlock);
dest.Add(tryHandlerBlock.HandlerBlock);
addTargets(dest, tryHandlerBlock.HandlerBlock);
AddTargets(dest, tryHandlerBlock.HandlerBlock);
}
void addTargets(List<BaseBlock> dest, ScopeBlock scopeBlock) {
foreach (var block in scopeBlock.getAllBlocks())
addTargets(dest, block.getTargets());
void AddTargets(List<BaseBlock> dest, ScopeBlock scopeBlock) {
foreach (var block in scopeBlock.GetAllBlocks())
AddTargets(dest, block.GetTargets());
}
void addTargets(List<BaseBlock> dest, IEnumerable<Block> source) {
void AddTargets(List<BaseBlock> dest, IEnumerable<Block> source) {
var list = new List<Block>(source);
list.Reverse();
foreach (var block in list)
dest.Add(block);
}
void visit(BlockInfo info) {
void Visit(BlockInfo info) {
if (info.baseBlock == firstBlock)
throw new ApplicationException("Can't visit firstBlock");
stack.Push(info);
@ -179,15 +179,15 @@ namespace de4dot.blocks {
info.low = dfsNumber;
dfsNumber++;
foreach (var tmp in getTargets(info.baseBlock)) {
var targetInfo = getInfo(tmp);
foreach (var tmp in GetTargets(info.baseBlock)) {
var targetInfo = GetInfo(tmp);
if (targetInfo == null)
continue;
if (targetInfo.baseBlock == firstBlock)
continue;
if (!targetInfo.visited()) {
visit(targetInfo);
if (!targetInfo.Visited()) {
Visit(targetInfo);
info.low = Math.Min(info.low, targetInfo.low);
}
else if (targetInfo.onStack)
@ -206,8 +206,8 @@ namespace de4dot.blocks {
}
if (sccBlocks.Count > 1) {
sccBlocks.Reverse();
var result = new Sorter(scopeBlock, sccBlocks, true).sort();
sortLoopBlock(result);
var result = new Sorter(scopeBlock, sccBlocks, true).Sort();
SortLoopBlock(result);
sorted.InsertRange(0, result);
}
else {
@ -215,12 +215,12 @@ namespace de4dot.blocks {
}
}
void sortLoopBlock(List<BaseBlock> list) {
void SortLoopBlock(List<BaseBlock> list) {
// Some popular decompilers sometimes produce bad output unless the loop condition
// checker block is at the end of the loop. Eg., they may use a while loop when
// it's really a for/foreach loop.
var loopStart = getLoopStartBlock(list);
var loopStart = GetLoopStartBlock(list);
if (loopStart == null)
return;
@ -229,7 +229,7 @@ namespace de4dot.blocks {
list.Add(loopStart);
}
Block getLoopStartBlock(List<BaseBlock> list) {
Block GetLoopStartBlock(List<BaseBlock> list) {
var loopBlocks = new Dictionary<Block, bool>(list.Count);
foreach (var bb in list) {
var block = bb as Block;
@ -268,9 +268,9 @@ namespace de4dot.blocks {
this.scopeBlock = scopeBlock;
}
public List<BaseBlock> sort() {
var sorted = new Sorter(scopeBlock, scopeBlock.BaseBlocks, false).sort();
return new ForwardScanOrder(scopeBlock, sorted).fix();
public List<BaseBlock> Sort() {
var sorted = new Sorter(scopeBlock, scopeBlock.BaseBlocks, false).Sort();
return new ForwardScanOrder(scopeBlock, sorted).Fix();
}
}
}

View File

@ -67,11 +67,11 @@ namespace de4dot.blocks {
this.methodBlocks = methodBlocks;
}
public void getCode(out IList<Instruction> allInstructions, out IList<ExceptionHandler> allExceptionHandlers) {
fixEmptyBlocks();
layOutBlocks();
sortExceptions();
layOutInstructions(out allInstructions, out allExceptionHandlers);
public void GetCode(out IList<Instruction> allInstructions, out IList<ExceptionHandler> allExceptionHandlers) {
FixEmptyBlocks();
LayOutBlocks();
SortExceptions();
LayOutInstructions(out allInstructions, out allExceptionHandlers);
allInstructions.SimplifyBranches();
allInstructions.OptimizeBranches();
@ -87,7 +87,7 @@ namespace de4dot.blocks {
}
}
void layOutInstructions(out IList<Instruction> allInstructions, out IList<ExceptionHandler> allExceptionHandlers) {
void LayOutInstructions(out IList<Instruction> allInstructions, out IList<ExceptionHandler> allExceptionHandlers) {
allInstructions = new List<Instruction>();
allExceptionHandlers = new List<ExceptionHandler>();
@ -103,20 +103,20 @@ namespace de4dot.blocks {
var targets = new List<Instr>();
foreach (var target in block.Targets)
targets.Add(target.FirstInstr);
block.LastInstr.updateTargets(targets);
block.LastInstr.UpdateTargets(targets);
}
allInstructions.Add(block.LastInstr.Instruction);
var next = i + 1 < blocks.Count ? blocks[i + 1] : null;
// If eg. ble next, then change it to bgt XYZ and fall through to next.
if (block.Targets != null && block.canFlipConditionalBranch() && block.Targets[0] == next) {
block.flipConditionalBranch();
block.LastInstr.updateTargets(new List<Instr> { block.Targets[0].FirstInstr });
if (block.Targets != null && block.CanFlipConditionalBranch() && block.Targets[0] == next) {
block.FlipConditionalBranch();
block.LastInstr.UpdateTargets(new List<Instr> { block.Targets[0].FirstInstr });
}
else if (block.FallThrough != null && block.FallThrough != next) {
var instr = new Instr(OpCodes.Br.ToInstruction(block.FallThrough.FirstInstr.Instruction));
instr.updateTargets(new List<Instr> { block.FallThrough.FirstInstr });
instr.UpdateTargets(new List<Instr> { block.FallThrough.FirstInstr });
allInstructions.Add(instr.Instruction);
}
@ -126,25 +126,25 @@ namespace de4dot.blocks {
}
foreach (var ex in exceptions) {
var tryStart = getBlockInfo(blockInfos, ex.tryStart).start;
var tryEnd = getBlockInfo(blockInfos, ex.tryEnd).end;
var filterStart = ex.filterStart == -1 ? -1 : getBlockInfo(blockInfos, ex.filterStart).start;
var handlerStart = getBlockInfo(blockInfos, ex.handlerStart).start;
var handlerEnd = getBlockInfo(blockInfos, ex.handlerEnd).end;
var tryStart = GetBlockInfo(blockInfos, ex.tryStart).start;
var tryEnd = GetBlockInfo(blockInfos, ex.tryEnd).end;
var filterStart = ex.filterStart == -1 ? -1 : GetBlockInfo(blockInfos, ex.filterStart).start;
var handlerStart = GetBlockInfo(blockInfos, ex.handlerStart).start;
var handlerEnd = GetBlockInfo(blockInfos, ex.handlerEnd).end;
var eh = new ExceptionHandler(ex.handlerType);
eh.CatchType = ex.catchType;
eh.TryStart = getInstruction(allInstructions, tryStart);
eh.TryEnd = getInstruction(allInstructions, tryEnd + 1);
eh.FilterStart = filterStart == -1 ? null : getInstruction(allInstructions, filterStart);
eh.HandlerStart = getInstruction(allInstructions, handlerStart);
eh.HandlerEnd = getInstruction(allInstructions, handlerEnd + 1);
eh.TryStart = GetInstruction(allInstructions, tryStart);
eh.TryEnd = GetInstruction(allInstructions, tryEnd + 1);
eh.FilterStart = filterStart == -1 ? null : GetInstruction(allInstructions, filterStart);
eh.HandlerStart = GetInstruction(allInstructions, handlerStart);
eh.HandlerEnd = GetInstruction(allInstructions, handlerEnd + 1);
allExceptionHandlers.Add(eh);
}
}
static BlockInfo getBlockInfo(List<BlockInfo> blockInfos, int index) {
static BlockInfo GetBlockInfo(List<BlockInfo> blockInfos, int index) {
if (index >= blockInfos.Count)
index = blockInfos.Count - 1;
if (index < 0)
@ -152,13 +152,13 @@ namespace de4dot.blocks {
return blockInfos[index];
}
static Instruction getInstruction(IList<Instruction> allInstructions, int i) {
static Instruction GetInstruction(IList<Instruction> allInstructions, int i) {
if (i < allInstructions.Count)
return allInstructions[i];
return null;
}
void sortExceptions() {
void SortExceptions() {
exceptions.Sort((a, b) => {
// Make sure nested try blocks are sorted before the outer try block.
if (a.tryStart > b.tryStart) return -1; // a could be nested, but b is not
@ -184,8 +184,8 @@ namespace de4dot.blocks {
});
}
void fixEmptyBlocks() {
foreach (var block in methodBlocks.getAllBlocks()) {
void FixEmptyBlocks() {
foreach (var block in methodBlocks.GetAllBlocks()) {
if (block.Instructions.Count == 0) {
block.Instructions.Add(new Instr(OpCodes.Nop.ToInstruction()));
}
@ -193,12 +193,12 @@ namespace de4dot.blocks {
}
// Write all blocks to the blocks list
void layOutBlocks() {
void LayOutBlocks() {
if (methodBlocks.BaseBlocks.Count == 0)
return;
stateStack.Push(new BlockState(methodBlocks));
processBaseBlocks(methodBlocks.BaseBlocks, (block) => {
ProcessBaseBlocks(methodBlocks.BaseBlocks, (block) => {
return block.LastInstr.OpCode == OpCodes.Ret;
});
@ -212,7 +212,7 @@ namespace de4dot.blocks {
}
}
void processBaseBlocks(List<BaseBlock> lb, Func<Block, bool> placeLast) {
void ProcessBaseBlocks(List<BaseBlock> lb, Func<Block, bool> placeLast) {
var bbs = new List<BaseBlock>();
int lastIndex = -1;
for (int i = 0; i < lb.Count; i++) {
@ -228,22 +228,22 @@ namespace de4dot.blocks {
bbs.Add(block);
}
foreach (var bb in bbs)
doBaseBlock(bb);
DoBaseBlock(bb);
}
// Returns the BaseBlock's ScopeBlock. The return value is either current ScopeBlock,
// the ScopeBlock one step below current (current one's child), or null.
ScopeBlock getScopeBlock(BaseBlock bb) {
ScopeBlock GetScopeBlock(BaseBlock bb) {
BlockState current = stateStack.Peek();
if (current.scopeBlock.isOurBaseBlock(bb))
if (current.scopeBlock.IsOurBaseBlock(bb))
return current.scopeBlock;
return (ScopeBlock)current.scopeBlock.toChild(bb);
return (ScopeBlock)current.scopeBlock.ToChild(bb);
}
void doBaseBlock(BaseBlock bb) {
void DoBaseBlock(BaseBlock bb) {
BlockState current = stateStack.Peek();
ScopeBlock newOne = getScopeBlock(bb);
ScopeBlock newOne = GetScopeBlock(bb);
if (newOne == null)
return; // Not a BaseBlock somewhere inside this ScopeBlock
if (newOne != current.scopeBlock)
@ -257,13 +257,13 @@ namespace de4dot.blocks {
visited[bb] = true;
if (bb is Block)
doBlock(bb as Block);
DoBlock(bb as Block);
else if (bb is TryBlock)
doTryBlock(bb as TryBlock);
DoTryBlock(bb as TryBlock);
else if (bb is FilterHandlerBlock)
doFilterHandlerBlock(bb as FilterHandlerBlock);
DoFilterHandlerBlock(bb as FilterHandlerBlock);
else if (bb is HandlerBlock)
doHandlerBlock(bb as HandlerBlock);
DoHandlerBlock(bb as HandlerBlock);
else if (bb is TryHandlerBlock) {
// The try handler block is usually after the try block, but sometimes it isn't...
// Handle that case here.
@ -274,14 +274,14 @@ namespace de4dot.blocks {
throw new ApplicationException("Invalid block found");
}
void doBlock(Block block) {
void DoBlock(Block block) {
blocks.Add(block);
}
void doTryBlock(TryBlock tryBlock) {
void DoTryBlock(TryBlock tryBlock) {
var tryStart = blocks.Count;
stateStack.Push(new BlockState(tryBlock));
processBaseBlocks(tryBlock.BaseBlocks, (block) => {
ProcessBaseBlocks(tryBlock.BaseBlocks, (block) => {
return block.LastInstr.OpCode == OpCodes.Leave ||
block.LastInstr.OpCode == OpCodes.Leave_S;
});
@ -298,10 +298,10 @@ namespace de4dot.blocks {
var filterStart = blocks.Count;
if (handlerBlock.FilterHandlerBlock.BaseBlocks != null)
doBaseBlock(handlerBlock.FilterHandlerBlock);
DoBaseBlock(handlerBlock.FilterHandlerBlock);
var handlerStart = blocks.Count;
doBaseBlock(handlerBlock.HandlerBlock);
DoBaseBlock(handlerBlock.HandlerBlock);
var handlerEnd = blocks.Count - 1;
exceptions.Add(new ExceptionInfo(tryStart, tryEnd, filterStart, handlerStart, handlerEnd, handlerBlock.CatchType, handlerBlock.HandlerType));
@ -310,17 +310,17 @@ namespace de4dot.blocks {
}
}
void doFilterHandlerBlock(FilterHandlerBlock filterHandlerBlock) {
void DoFilterHandlerBlock(FilterHandlerBlock filterHandlerBlock) {
stateStack.Push(new BlockState(filterHandlerBlock));
processBaseBlocks(filterHandlerBlock.BaseBlocks, (block) => {
ProcessBaseBlocks(filterHandlerBlock.BaseBlocks, (block) => {
return block.LastInstr.OpCode == OpCodes.Endfilter; // MUST end with endfilter!
});
stateStack.Pop();
}
void doHandlerBlock(HandlerBlock handlerBlock) {
void DoHandlerBlock(HandlerBlock handlerBlock) {
stateStack.Push(new BlockState(handlerBlock));
processBaseBlocks(handlerBlock.BaseBlocks, (block) => {
ProcessBaseBlocks(handlerBlock.BaseBlocks, (block) => {
return block.LastInstr.OpCode == OpCodes.Endfinally ||
block.LastInstr.OpCode == OpCodes.Leave ||
block.LastInstr.OpCode == OpCodes.Leave_S;

View File

@ -32,10 +32,10 @@ namespace de4dot.blocks {
this.methodBlocks = methodBlocks;
}
public int remove() {
addScopeBlock(methodBlocks);
processAll();
return removeDeadBlocks();
public int Remove() {
AddScopeBlock(methodBlocks);
ProcessAll();
return RemoveDeadBlocks();
}
class ScopeBlockInfo {
@ -46,12 +46,12 @@ namespace de4dot.blocks {
}
}
int removeDeadBlocks() {
int RemoveDeadBlocks() {
int numDeadBlocks = 0;
var infos = new Dictionary<ScopeBlock, ScopeBlockInfo>();
var deadBlocksDict = new Dictionary<BaseBlock, bool>();
foreach (var baseBlock in findDeadBlocks()) {
foreach (var baseBlock in FindDeadBlocks()) {
deadBlocksDict[baseBlock] = true;
ScopeBlock parent = baseBlock.Parent;
ScopeBlockInfo info;
@ -62,15 +62,15 @@ namespace de4dot.blocks {
}
foreach (var info in infos.Values)
info.scopeBlock.removeAllDeadBlocks(info.deadBlocks, deadBlocksDict);
info.scopeBlock.RemoveAllDeadBlocks(info.deadBlocks, deadBlocksDict);
return numDeadBlocks;
}
IList<BaseBlock> findDeadBlocks() {
IList<BaseBlock> FindDeadBlocks() {
var deadBlocks = new List<BaseBlock>();
foreach (var bb in methodBlocks.getAllBaseBlocks()) {
foreach (var bb in methodBlocks.GetAllBaseBlocks()) {
if (!checkedBaseBlocks.ContainsKey(bb))
deadBlocks.Add(bb);
}
@ -78,66 +78,66 @@ namespace de4dot.blocks {
return deadBlocks;
}
void addScopeBlock(ScopeBlock scopeBlock) {
void AddScopeBlock(ScopeBlock scopeBlock) {
scopeBlocksToCheck.Push(scopeBlock);
}
void processAll() {
void ProcessAll() {
bool didSomething;
do {
didSomething = false;
while (baseBlocksToCheck.Count > 0) {
processBaseBlock(baseBlocksToCheck.Pop());
ProcessBaseBlock(baseBlocksToCheck.Pop());
didSomething = true;
}
while (scopeBlocksToCheck.Count > 0) {
processScopeBlock(scopeBlocksToCheck.Pop());
ProcessScopeBlock(scopeBlocksToCheck.Pop());
didSomething = true;
}
} while (didSomething);
}
void processBaseBlock(BaseBlock baseBlock) {
void ProcessBaseBlock(BaseBlock baseBlock) {
if (baseBlock == null || checkedBaseBlocks.ContainsKey(baseBlock))
return;
checkedBaseBlocks[baseBlock] = true;
if (baseBlock is Block) {
var block = (Block)baseBlock;
foreach (var block2 in block.getTargets())
addBaseBlock(block2);
foreach (var block2 in block.GetTargets())
AddBaseBlock(block2);
}
else if (baseBlock is ScopeBlock) {
var scopeBlock = (ScopeBlock)baseBlock;
addScopeBlock(scopeBlock);
AddScopeBlock(scopeBlock);
if (scopeBlock.BaseBlocks != null && scopeBlock.BaseBlocks.Count > 0)
addBaseBlock(scopeBlock.BaseBlocks[0]);
AddBaseBlock(scopeBlock.BaseBlocks[0]);
}
else
throw new ApplicationException(string.Format("Unknown BaseBlock type {0}", baseBlock.GetType()));
}
// Add a block to be processed later, including all its enclosing ScopeBlocks.
void addBaseBlock(BaseBlock baseBlock) {
void AddBaseBlock(BaseBlock baseBlock) {
for (BaseBlock bb = baseBlock; bb != null; bb = bb.Parent)
baseBlocksToCheck.Push(bb);
}
void processScopeBlock(ScopeBlock scopeBlock) {
void ProcessScopeBlock(ScopeBlock scopeBlock) {
if (scopeBlock == null || checkedScopeBlocks.ContainsKey(scopeBlock))
return;
checkedScopeBlocks[scopeBlock] = true;
addBaseBlock(scopeBlock);
AddBaseBlock(scopeBlock);
if (scopeBlock is TryBlock) {
var tryBlock = (TryBlock)scopeBlock;
foreach (var handler in tryBlock.TryHandlerBlocks)
addScopeBlock(handler);
AddScopeBlock(handler);
}
else if (scopeBlock is TryHandlerBlock) {
var tryHandlerBlock = (TryHandlerBlock)scopeBlock;
addScopeBlock(tryHandlerBlock.FilterHandlerBlock);
addScopeBlock(tryHandlerBlock.HandlerBlock);
AddScopeBlock(tryHandlerBlock.FilterHandlerBlock);
AddScopeBlock(tryHandlerBlock.HandlerBlock);
}
}
}

View File

@ -35,18 +35,18 @@ namespace de4dot.blocks {
public class CallCounter {
Dictionary<IMethod, int> calls = new Dictionary<IMethod, int>(MethodEqualityComparer.CompareDeclaringTypes);
public void add(IMethod calledMethod) {
public void Add(IMethod calledMethod) {
int count;
calls.TryGetValue(calledMethod, out count);
calls[calledMethod] = count + 1;
}
public IMethod most() {
public IMethod Most() {
int numCalls;
return most(out numCalls);
return Most(out numCalls);
}
public IMethod most(out int numCalls) {
public IMethod Most(out int numCalls) {
IMethod method = null;
int callCount = 0;
foreach (var key in calls.Keys) {
@ -61,15 +61,15 @@ namespace de4dot.blocks {
}
public static class DotNetUtils {
public static TypeDef getModuleType(ModuleDef module) {
public static TypeDef GetModuleType(ModuleDef module) {
return module.GlobalType;
}
public static MethodDef getModuleTypeCctor(ModuleDef module) {
public static MethodDef GetModuleTypeCctor(ModuleDef module) {
return module.GlobalType.FindStaticConstructor();
}
public static bool isEmpty(MethodDef method) {
public static bool IsEmpty(MethodDef method) {
if (method.Body == null)
return false;
foreach (var instr in method.Body.Instructions) {
@ -80,18 +80,18 @@ namespace de4dot.blocks {
return true;
}
public static bool isEmptyObfuscated(MethodDef method) {
public static bool IsEmptyObfuscated(MethodDef method) {
if (method.Body == null)
return false;
int index = 0;
var instr = getInstruction(method.Body.Instructions, ref index);
var instr = GetInstruction(method.Body.Instructions, ref index);
if (instr == null || instr.OpCode.Code != Code.Ret)
return false;
return true;
}
public static FieldDef findFieldType(TypeDef typeDef, string typeName, bool isStatic) {
public static FieldDef FindFieldType(TypeDef typeDef, string typeName, bool isStatic) {
if (typeDef == null)
return null;
foreach (var field in typeDef.Fields) {
@ -101,11 +101,11 @@ namespace de4dot.blocks {
return null;
}
public static IEnumerable<MethodDef> findMethods(IEnumerable<MethodDef> methods, string returnType, string[] argsTypes) {
return findMethods(methods, returnType, argsTypes, true);
public static IEnumerable<MethodDef> FindMethods(IEnumerable<MethodDef> methods, string returnType, string[] argsTypes) {
return FindMethods(methods, returnType, argsTypes, true);
}
public static IEnumerable<MethodDef> findMethods(IEnumerable<MethodDef> methods, string returnType, string[] argsTypes, bool isStatic) {
public static IEnumerable<MethodDef> FindMethods(IEnumerable<MethodDef> methods, string returnType, string[] argsTypes, bool isStatic) {
foreach (var method in methods) {
var sig = method.MethodSig;
if (sig == null || !method.HasBody || !sig.IsDefault)
@ -125,32 +125,32 @@ namespace de4dot.blocks {
}
}
public static bool isDelegate(IType type) {
public static bool IsDelegate(IType type) {
if (type == null)
return false;
var fn = type.FullName;
return fn == "System.Delegate" || fn == "System.MulticastDelegate";
}
public static bool derivesFromDelegate(TypeDef type) {
return type != null && isDelegate(type.BaseType);
public static bool DerivesFromDelegate(TypeDef type) {
return type != null && IsDelegate(type.BaseType);
}
public static bool isMethod(IMethod method, string returnType, string parameters) {
public static bool IsMethod(IMethod method, string returnType, string parameters) {
return method != null && method.FullName == returnType + " " + method.DeclaringType.FullName + "::" + method.Name + parameters;
}
public static string getDllName(string dll) {
public static string GetDllName(string dll) {
if (dll.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
return dll.Substring(0, dll.Length - 4);
return dll;
}
public static bool hasPinvokeMethod(TypeDef type, string methodName) {
return getPInvokeMethod(type, methodName) != null;
public static bool HasPinvokeMethod(TypeDef type, string methodName) {
return GetPInvokeMethod(type, methodName) != null;
}
public static MethodDef getPInvokeMethod(TypeDef type, string methodName) {
public static MethodDef GetPInvokeMethod(TypeDef type, string methodName) {
if (type == null)
return null;
UTF8String mname = methodName;
@ -163,69 +163,69 @@ namespace de4dot.blocks {
return null;
}
public static MethodDef getPInvokeMethod(TypeDef type, string dll, string funcName) {
public static MethodDef GetPInvokeMethod(TypeDef type, string dll, string funcName) {
foreach (var method in type.Methods) {
if (isPinvokeMethod(method, dll, funcName))
if (IsPinvokeMethod(method, dll, funcName))
return method;
}
return null;
}
public static bool isPinvokeMethod(MethodDef method, string dll, string funcName) {
public static bool IsPinvokeMethod(MethodDef method, string dll, string funcName) {
if (method == null)
return false;
if (method.ImplMap == null || method.ImplMap.Name.String != funcName)
return false;
return getDllName(dll).Equals(getDllName(method.ImplMap.Module.Name.String), StringComparison.OrdinalIgnoreCase);
return GetDllName(dll).Equals(GetDllName(method.ImplMap.Module.Name.String), StringComparison.OrdinalIgnoreCase);
}
public static MethodDef getMethod(ModuleDefMD module, IMethod method) {
public static MethodDef GetMethod(ModuleDefMD module, IMethod method) {
if (method == null)
return null;
return getMethod(module, method, method.DeclaringType);
return GetMethod(module, method, method.DeclaringType);
}
public static MethodDef getMethod2(ModuleDefMD module, IMethod method) {
public static MethodDef GetMethod2(ModuleDefMD module, IMethod method) {
if (method == null)
return null;
if (method is MethodDef)
return (MethodDef)method;
var git = method.DeclaringType.TryGetGenericInstSig();
var dt = git == null ? method.DeclaringType : git.GenericType.TypeDefOrRef;
return getMethod(module, method, dt);
return GetMethod(module, method, dt);
}
static MethodDef getMethod(ModuleDefMD module, IMethod method, ITypeDefOrRef declaringType) {
static MethodDef GetMethod(ModuleDefMD module, IMethod method, ITypeDefOrRef declaringType) {
if (method == null)
return null;
if (method is MethodDef)
return (MethodDef)method;
return getMethod(getType(module, declaringType), method);
return GetMethod(GetType(module, declaringType), method);
}
public static MethodDef getMethod(TypeDef type, string returnType, string parameters) {
public static MethodDef GetMethod(TypeDef type, string returnType, string parameters) {
foreach (var method in type.Methods) {
if (isMethod(method, returnType, parameters))
if (IsMethod(method, returnType, parameters))
return method;
}
return null;
}
public static MethodDef getMethod2(ModuleDef module, IMethod method) {
public static MethodDef GetMethod2(ModuleDef module, IMethod method) {
if (method == null)
return null;
return getMethod(module, method, method.DeclaringType.ScopeType);
return GetMethod(module, method, method.DeclaringType.ScopeType);
}
public static TypeDef getType(ModuleDef module, TypeSig type) {
public static TypeDef GetType(ModuleDef module, TypeSig type) {
type = type.RemovePinnedAndModifiers();
var tdr = type as TypeDefOrRefSig;
if (tdr == null)
return null;
return getType(module, tdr.TypeDefOrRef);
return GetType(module, tdr.TypeDefOrRef);
}
public static TypeDef getType(ModuleDef module, ITypeDefOrRef type) {
public static TypeDef GetType(ModuleDef module, ITypeDefOrRef type) {
var td = type as TypeDef;
if (td == null) {
var tr = type as TypeRef;
@ -239,15 +239,15 @@ namespace de4dot.blocks {
return td != null && td.Module == module ? td : null;
}
static MethodDef getMethod(ModuleDef module, IMethod method, ITypeDefOrRef declaringType) {
static MethodDef GetMethod(ModuleDef module, IMethod method, ITypeDefOrRef declaringType) {
if (method == null)
return null;
if (method is MethodDef)
return (MethodDef)method;
return getMethod(getType(module, declaringType), method);
return GetMethod(GetType(module, declaringType), method);
}
public static MethodDef getMethod(TypeDef type, IMethod methodRef) {
public static MethodDef GetMethod(TypeDef type, IMethod methodRef) {
if (type == null || methodRef == null)
return null;
if (methodRef is MethodDef)
@ -255,7 +255,7 @@ namespace de4dot.blocks {
return type.FindMethod(methodRef.Name, methodRef.MethodSig);
}
public static IEnumerable<MethodDef> getNormalMethods(TypeDef type) {
public static IEnumerable<MethodDef> GetNormalMethods(TypeDef type) {
foreach (var method in type.Methods) {
if (method.HasImplMap)
continue;
@ -266,15 +266,15 @@ namespace de4dot.blocks {
}
}
public static FieldDef getField(ModuleDef module, IField field) {
public static FieldDef GetField(ModuleDef module, IField field) {
if (field == null)
return null;
if (field is FieldDef)
return (FieldDef)field;
return getField(getType(module, field.DeclaringType), field);
return GetField(GetType(module, field.DeclaringType), field);
}
public static FieldDef getField(TypeDef type, IField fieldRef) {
public static FieldDef GetField(TypeDef type, IField fieldRef) {
if (type == null || fieldRef == null)
return null;
if (fieldRef is FieldDef)
@ -282,7 +282,7 @@ namespace de4dot.blocks {
return type.FindField(fieldRef.Name, fieldRef.FieldSig);
}
public static FieldDef getField(TypeDef type, string typeFullName) {
public static FieldDef GetField(TypeDef type, string typeFullName) {
if (type == null)
return null;
foreach (var field in type.Fields) {
@ -292,7 +292,7 @@ namespace de4dot.blocks {
return null;
}
public static IEnumerable<IMethod> getMethodCalls(MethodDef method) {
public static IEnumerable<IMethod> GetMethodCalls(MethodDef method) {
var list = new List<IMethod>();
if (method.HasBody) {
foreach (var instr in method.Body.Instructions) {
@ -304,7 +304,7 @@ namespace de4dot.blocks {
return list;
}
public static bool hasString(MethodDef method, string s) {
public static bool HasString(MethodDef method, string s) {
if (method == null || method.Body == null)
return false;
foreach (var instr in method.Body.Instructions) {
@ -314,7 +314,7 @@ namespace de4dot.blocks {
return false;
}
public static IList<string> getCodeStrings(MethodDef method) {
public static IList<string> GetCodeStrings(MethodDef method) {
var strings = new List<string>();
if (method != null && method.Body != null) {
foreach (var instr in method.Body.Instructions) {
@ -325,17 +325,17 @@ namespace de4dot.blocks {
return strings;
}
public static Resource getResource(ModuleDef module, string name) {
return getResource(module, new List<string> { name });
public static Resource GetResource(ModuleDef module, string name) {
return GetResource(module, new List<string> { name });
}
public static Resource getResource(ModuleDef module, IEnumerable<string> strings) {
public static Resource GetResource(ModuleDef module, IEnumerable<string> strings) {
if (!module.HasResources)
return null;
var resources = module.Resources;
foreach (var tmp in strings) {
var resourceName = removeFromNullChar(tmp);
var resourceName = RemoveFromNullChar(tmp);
if (resourceName == null)
continue;
UTF8String name = resourceName;
@ -348,7 +348,7 @@ namespace de4dot.blocks {
return null;
}
static string removeFromNullChar(string s) {
static string RemoveFromNullChar(string s) {
int index = s.IndexOf((char)0);
if (index < 0)
return s;
@ -356,7 +356,7 @@ namespace de4dot.blocks {
}
// Copies most things but not everything
public static MethodDef clone(MethodDef method) {
public static MethodDef Clone(MethodDef method) {
var newMethod = new MethodDefUser(method.Name, method.MethodSig, method.ImplAttributes, method.Attributes);
newMethod.Rid = method.Rid;
newMethod.DeclaringType2 = method.DeclaringType;
@ -369,11 +369,11 @@ namespace de4dot.blocks {
newMethod.GenericParameters.Add(newGp);
}
newMethod.Body = new CilBody();
copyBodyFromTo(method, newMethod);
CopyBodyFromTo(method, newMethod);
return newMethod;
}
public static void copyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) {
public static void CopyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) {
if (method == null || !method.HasBody) {
instructions = new List<Instruction>();
exceptionHandlers = new List<ExceptionHandler>();
@ -384,7 +384,7 @@ namespace de4dot.blocks {
var oldExHandlers = method.Body.ExceptionHandlers;
instructions = new List<Instruction>(oldInstrs.Count);
exceptionHandlers = new List<ExceptionHandler>(oldExHandlers.Count);
var oldToIndex = Utils.createObjectToIndexDictionary(oldInstrs);
var oldToIndex = Utils.CreateObjectToIndexDictionary(oldInstrs);
foreach (var oldInstr in oldInstrs)
instructions.Add(oldInstr.Clone());
@ -404,24 +404,24 @@ namespace de4dot.blocks {
foreach (var oldEx in oldExHandlers) {
var newEx = new ExceptionHandler(oldEx.HandlerType) {
TryStart = getInstruction(instructions, oldToIndex, oldEx.TryStart),
TryEnd = getInstruction(instructions, oldToIndex, oldEx.TryEnd),
FilterStart = getInstruction(instructions, oldToIndex, oldEx.FilterStart),
HandlerStart = getInstruction(instructions, oldToIndex, oldEx.HandlerStart),
HandlerEnd = getInstruction(instructions, oldToIndex, oldEx.HandlerEnd),
TryStart = GetInstruction(instructions, oldToIndex, oldEx.TryStart),
TryEnd = GetInstruction(instructions, oldToIndex, oldEx.TryEnd),
FilterStart = GetInstruction(instructions, oldToIndex, oldEx.FilterStart),
HandlerStart = GetInstruction(instructions, oldToIndex, oldEx.HandlerStart),
HandlerEnd = GetInstruction(instructions, oldToIndex, oldEx.HandlerEnd),
CatchType = oldEx.CatchType,
};
exceptionHandlers.Add(newEx);
}
}
static Instruction getInstruction(IList<Instruction> instructions, IDictionary<Instruction, int> instructionToIndex, Instruction instruction) {
static Instruction GetInstruction(IList<Instruction> instructions, IDictionary<Instruction, int> instructionToIndex, Instruction instruction) {
if (instruction == null)
return null;
return instructions[instructionToIndex[instruction]];
}
public static void restoreBody(MethodDef method, IEnumerable<Instruction> instructions, IEnumerable<ExceptionHandler> exceptionHandlers) {
public static void RestoreBody(MethodDef method, IEnumerable<Instruction> instructions, IEnumerable<ExceptionHandler> exceptionHandlers) {
if (method == null || method.Body == null)
return;
@ -436,19 +436,19 @@ namespace de4dot.blocks {
bodyExceptionHandlers.Add(eh);
}
public static void copyBodyFromTo(MethodDef fromMethod, MethodDef toMethod) {
public static void CopyBodyFromTo(MethodDef fromMethod, MethodDef toMethod) {
if (fromMethod == toMethod)
return;
IList<Instruction> instructions;
IList<ExceptionHandler> exceptionHandlers;
copyBody(fromMethod, out instructions, out exceptionHandlers);
restoreBody(toMethod, instructions, exceptionHandlers);
copyLocalsFromTo(fromMethod, toMethod);
updateInstructionOperands(fromMethod, toMethod);
CopyBody(fromMethod, out instructions, out exceptionHandlers);
RestoreBody(toMethod, instructions, exceptionHandlers);
CopyLocalsFromTo(fromMethod, toMethod);
UpdateInstructionOperands(fromMethod, toMethod);
}
static void copyLocalsFromTo(MethodDef fromMethod, MethodDef toMethod) {
static void CopyLocalsFromTo(MethodDef fromMethod, MethodDef toMethod) {
var fromBody = fromMethod.Body;
var toBody = toMethod.Body;
@ -457,7 +457,7 @@ namespace de4dot.blocks {
toBody.Variables.Add(new Local(local.Type));
}
static void updateInstructionOperands(MethodDef fromMethod, MethodDef toMethod) {
static void UpdateInstructionOperands(MethodDef fromMethod, MethodDef toMethod) {
var fromBody = fromMethod.Body;
var toBody = toMethod.Body;
@ -481,7 +481,7 @@ namespace de4dot.blocks {
}
}
public static string getCustomArgAsString(CustomAttribute cattr, int arg) {
public static string GetCustomArgAsString(CustomAttribute cattr, int arg) {
if (cattr == null || arg >= cattr.ConstructorArguments.Count)
return null;
var carg = cattr.ConstructorArguments[arg];
@ -490,7 +490,7 @@ namespace de4dot.blocks {
return UTF8String.ToSystemStringOrEmpty((UTF8String)carg.Value);
}
public static IEnumerable<MethodDef> getCalledMethods(ModuleDef module, MethodDef method) {
public static IEnumerable<MethodDef> GetCalledMethods(ModuleDef module, MethodDef method) {
if (method != null && method.HasBody) {
foreach (var call in method.Body.Instructions) {
if (call.OpCode.Code != Code.Call && call.OpCode.Code != Code.Callvirt)
@ -498,15 +498,15 @@ namespace de4dot.blocks {
var methodRef = call.Operand as IMethod;
if (methodRef == null)
continue;
var type = getType(module, methodRef.DeclaringType);
var methodDef = getMethod(type, methodRef);
var type = GetType(module, methodRef.DeclaringType);
var methodDef = GetMethod(type, methodRef);
if (methodDef != null)
yield return methodDef;
}
}
}
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)
return null;
if (opcodes.Length == 0)
@ -524,25 +524,25 @@ namespace de4dot.blocks {
return list;
}
public static bool hasReturnValue(IMethod method) {
public static bool HasReturnValue(IMethod method) {
if (method == null || method.MethodSig == null || method.MethodSig.RetType == null)
return false;
return method.MethodSig.RetType.RemovePinnedAndModifiers().ElementType != ElementType.Void;
}
public static Parameter getParameter(IList<Parameter> parameters, int index) {
public static Parameter GetParameter(IList<Parameter> parameters, int index) {
if (0 <= index && index < parameters.Count)
return parameters[index];
return null;
}
public static TypeSig getArg(IList<TypeSig> args, int index) {
public static TypeSig GetArg(IList<TypeSig> args, int index) {
if (0 <= index && index < args.Count)
return args[index];
return null;
}
public static List<TypeSig> getArgs(IMethod method) {
public static List<TypeSig> GetArgs(IMethod method) {
var sig = method.MethodSig;
var args = new List<TypeSig>(sig.Params.Count + 1);
if (sig.ImplicitThis)
@ -552,7 +552,7 @@ namespace de4dot.blocks {
return args;
}
public static int getArgsCount(IMethod method) {
public static int GetArgsCount(IMethod method) {
var sig = method.MethodSig;
if (sig == null)
return 0;
@ -562,22 +562,22 @@ namespace de4dot.blocks {
return count;
}
public static IList<TypeSig> replaceGenericParameters(GenericInstSig typeOwner, MethodSpec methodOwner, IList<TypeSig> types) {
public static IList<TypeSig> ReplaceGenericParameters(GenericInstSig typeOwner, MethodSpec methodOwner, IList<TypeSig> types) {
if (typeOwner == null && methodOwner == null)
return types;
for (int i = 0; i < types.Count; i++)
types[i] = getGenericArgument(typeOwner, methodOwner, types[i]);
types[i] = GetGenericArgument(typeOwner, methodOwner, types[i]);
return types;
}
public static TypeSig getGenericArgument(GenericInstSig typeOwner, MethodSpec methodOwner, TypeSig type) {
public static TypeSig GetGenericArgument(GenericInstSig typeOwner, MethodSpec methodOwner, TypeSig type) {
var typeArgs = typeOwner == null ? null : typeOwner.GenericArguments;
var genMethodArgs = methodOwner == null || methodOwner.GenericInstMethodSig == null ?
null : methodOwner.GenericInstMethodSig.GenericArguments;
return GenericArgsSubstitutor.create(type, typeArgs, genMethodArgs);
return GenericArgsSubstitutor.Create(type, typeArgs, genMethodArgs);
}
public static Instruction getInstruction(IList<Instruction> instructions, ref int index) {
public static Instruction GetInstruction(IList<Instruction> instructions, ref int index) {
for (int i = 0; i < 10; i++) {
if (index < 0 || index >= instructions.Count)
return null;
@ -596,7 +596,7 @@ namespace de4dot.blocks {
return null;
}
public static TypeDefOrRefSig findOrCreateTypeRef(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
public static TypeDefOrRefSig FindOrCreateTypeRef(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, asmRef));
if (isValueType)
return new ValueTypeSig(typeRef);
@ -604,7 +604,7 @@ namespace de4dot.blocks {
return new ClassSig(typeRef);
}
public static FrameworkType getFrameworkType(ModuleDefMD module) {
public static FrameworkType GetFrameworkType(ModuleDefMD module) {
foreach (var modRef in module.GetAssemblyRefs()) {
if (modRef.Name != "mscorlib")
continue;
@ -627,7 +627,7 @@ namespace de4dot.blocks {
return FrameworkType.Unknown;
}
public static int getMethodCalls(MethodDef method, string methodFullName) {
public static int GetMethodCalls(MethodDef method, string methodFullName) {
if (method == null || method.Body == null)
return 0;
@ -645,7 +645,7 @@ namespace de4dot.blocks {
return count;
}
public static bool callsMethod(MethodDef method, string methodFullName) {
public static bool CallsMethod(MethodDef method, string methodFullName) {
if (method == null || method.Body == null)
return false;
@ -662,25 +662,25 @@ namespace de4dot.blocks {
return false;
}
public static bool callsMethod(MethodDef method, string returnType, string parameters) {
public static bool CallsMethod(MethodDef method, string returnType, string parameters) {
if (method == null || method.Body == null)
return false;
foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Call && instr.OpCode.Code != Code.Callvirt && instr.OpCode.Code != Code.Newobj)
continue;
if (isMethod(instr.Operand as IMethod, returnType, parameters))
if (IsMethod(instr.Operand as IMethod, returnType, parameters))
return true;
}
return false;
}
public static IList<Instruction> getArgPushes(IList<Instruction> instrs, int index) {
return getArgPushes(instrs, ref index);
public static IList<Instruction> GetArgPushes(IList<Instruction> instrs, int index) {
return GetArgPushes(instrs, ref index);
}
public static IList<Instruction> getArgPushes(IList<Instruction> instrs, ref int index) {
public static IList<Instruction> GetArgPushes(IList<Instruction> instrs, ref int index) {
if (index < 0 || index >= instrs.Count)
return null;
var startInstr = instrs[index];
@ -707,7 +707,7 @@ namespace de4dot.blocks {
if (pops != 0) {
index++;
if (getArgPushes(instrs, ref index) == null)
if (GetArgPushes(instrs, ref index) == null)
return null;
}
}

View File

@ -31,21 +31,21 @@ namespace de4dot.blocks {
get { return methods.Count; }
}
public void add(uint token, DumpedMethod info) {
public void Add(uint token, DumpedMethod info) {
methods[token] = info;
}
public DumpedMethod get(MethodDef method) {
return get(method.MDToken.ToUInt32());
public DumpedMethod Get(MethodDef method) {
return Get(method.MDToken.ToUInt32());
}
public DumpedMethod get(uint token) {
public DumpedMethod Get(uint token) {
DumpedMethod dm;
methods.TryGetValue(token, out dm);
return dm;
}
public void add(DumpedMethod dm) {
public void Add(DumpedMethod dm) {
if (MDToken.ToTable(dm.token) != Table.Method || MDToken.ToRID(dm.token) == 0)
throw new ArgumentException("Invalid token");
methods[dm.token] = dm;

View File

@ -41,7 +41,7 @@ namespace de4dot.blocks {
this.stackStart = stackStart;
}
public void calculateStackUsage() {
public void CalculateStackUsage() {
Block block = baseBlock as Block;
if (block == null) {
stackEnd = stackStart;
@ -60,17 +60,17 @@ namespace de4dot.blocks {
this.sorted = sorted;
}
public List<BaseBlock> fix() {
createBlockInfos();
createNewList();
public List<BaseBlock> Fix() {
CreateBlockInfos();
CreateNewList();
return newList;
}
void createBlockInfos() {
void CreateBlockInfos() {
int firstBlockStackStart = scopeBlock is TryHandlerBlock ? 1 : 0;
foreach (var bb in getStartBlocks()) {
foreach (var bb in GetStartBlocks()) {
int stackStart = ReferenceEquals(bb, sorted[0]) ? firstBlockStackStart : 0;
scanBaseBlock(bb, stackStart);
ScanBaseBlock(bb, stackStart);
}
// One reason for this to fail is if there are still dead blocks left. Could also
@ -79,29 +79,29 @@ namespace de4dot.blocks {
throw new ApplicationException(string.Format("Didn't add all blocks: {0} vs {1}", blockInfos.Count, sorted.Count));
}
IEnumerable<BaseBlock> getStartBlocks() {
IEnumerable<BaseBlock> GetStartBlocks() {
if (sorted.Count > 0) {
yield return sorted[0];
foreach (var bb in sorted) {
if (ReferenceEquals(bb, sorted[0]))
continue;
var block = bb as Block;
if (block == null || block.Sources == null || isOneSourceInAnotherScopeBlock(block))
if (block == null || block.Sources == null || IsOneSourceInAnotherScopeBlock(block))
yield return bb;
}
}
}
bool isOneSourceInAnotherScopeBlock(Block block) {
bool IsOneSourceInAnotherScopeBlock(Block block) {
foreach (var source in block.Sources) {
if (!scopeBlock.isOurBaseBlock(source))
if (!scopeBlock.IsOurBaseBlock(source))
return true;
}
return false;
}
void scanBaseBlock(BaseBlock bb, int stackStart) {
if (blockInfos.ContainsKey(bb) || !scopeBlock.isOurBaseBlock(bb))
void ScanBaseBlock(BaseBlock bb, int stackStart) {
if (blockInfos.ContainsKey(bb) || !scopeBlock.IsOurBaseBlock(bb))
return;
var blockInfo = new BlockInfo(bb, stackStart);
@ -115,38 +115,38 @@ namespace de4dot.blocks {
return;
}
blockInfo.calculateStackUsage();
blockInfo.CalculateStackUsage();
foreach (var target in block.getTargets())
scanBaseBlock(target, blockInfo.stackEnd);
foreach (var target in block.GetTargets())
ScanBaseBlock(target, blockInfo.stackEnd);
}
void createNewList() {
void CreateNewList() {
newList = new List<BaseBlock>(sorted.Count);
foreach (var bb in sorted)
addToNewList(bb);
AddToNewList(bb);
if (newList.Count != sorted.Count)
throw new ApplicationException(string.Format("Too many/few blocks after sorting: {0} vs {1}", newList.Count, sorted.Count));
if (newList.Count > 0 && !ReferenceEquals(newList[0], sorted[0]))
throw new ApplicationException("Start block is not first block after sorting");
}
void addToNewList(BaseBlock bb) {
if (inNewList.ContainsKey(bb) || !scopeBlock.isOurBaseBlock(bb))
void AddToNewList(BaseBlock bb) {
if (inNewList.ContainsKey(bb) || !scopeBlock.IsOurBaseBlock(bb))
return;
inNewList[bb] = false;
var blockInfo = blockInfos[bb];
var block = bb as Block;
if (blockInfo.stackStart == 0 || ReferenceEquals(bb, sorted[0]) ||
block == null || block.Sources == null || isInNewList(block.Sources)) {
block == null || block.Sources == null || IsInNewList(block.Sources)) {
}
else {
foreach (var source in block.Sources) {
if (!scopeBlock.isOurBaseBlock(source))
if (!scopeBlock.IsOurBaseBlock(source))
continue;
int oldCount = newList.Count;
addToNewList(source); // Make sure it's before this block
AddToNewList(source); // Make sure it's before this block
if (oldCount != newList.Count)
break;
}
@ -156,7 +156,7 @@ namespace de4dot.blocks {
newList.Add(bb);
}
bool isInNewList(IEnumerable<Block> blocks) {
bool IsInNewList(IEnumerable<Block> blocks) {
foreach (var block in blocks) {
if (inNewList.ContainsKey(block) && inNewList[block])
return true;

View File

@ -26,115 +26,115 @@ namespace de4dot.blocks {
IList<TypeSig> genericMethodArgs;
bool updated;
public static ITypeDefOrRef create(ITypeDefOrRef type, GenericInstSig git) {
public static ITypeDefOrRef Create(ITypeDefOrRef type, GenericInstSig git) {
if (git == null)
return type;
return create(type, git.GenericArguments);
return Create(type, git.GenericArguments);
}
public static ITypeDefOrRef create(ITypeDefOrRef type, IList<TypeSig> genericArgs) {
public static ITypeDefOrRef Create(ITypeDefOrRef type, IList<TypeSig> genericArgs) {
if (genericArgs == null || genericArgs.Count == 0)
return type;
var ts = type as TypeSpec;
if (ts == null)
return type;
var newSig = create(ts.TypeSig, genericArgs);
var newSig = Create(ts.TypeSig, genericArgs);
return newSig == ts.TypeSig ? type : new TypeSpecUser(newSig);
}
public static TypeSig create(TypeSig type, IList<TypeSig> genericArgs) {
public static TypeSig Create(TypeSig type, IList<TypeSig> genericArgs) {
if (type == null || genericArgs == null || genericArgs.Count == 0)
return type;
return new GenericArgsSubstitutor(genericArgs).create(type);
return new GenericArgsSubstitutor(genericArgs).Create(type);
}
public static TypeSig create(TypeSig type, IList<TypeSig> genericArgs, IList<TypeSig> genericMethodArgs) {
public static TypeSig Create(TypeSig type, IList<TypeSig> genericArgs, IList<TypeSig> genericMethodArgs) {
if (type == null || ((genericArgs == null || genericArgs.Count == 0) &&
(genericMethodArgs == null || genericMethodArgs.Count == 0)))
return type;
return new GenericArgsSubstitutor(genericArgs, genericMethodArgs).create(type);
return new GenericArgsSubstitutor(genericArgs, genericMethodArgs).Create(type);
}
public static IField create(IField field, GenericInstSig git) {
public static IField Create(IField field, GenericInstSig git) {
if (git == null)
return field;
return create(field, git.GenericArguments);
return Create(field, git.GenericArguments);
}
public static IField create(IField field, IList<TypeSig> genericArgs) {
public static IField Create(IField field, IList<TypeSig> genericArgs) {
if (field == null || genericArgs == null || genericArgs.Count == 0)
return field;
var newSig = create(field.FieldSig, genericArgs);
var newSig = Create(field.FieldSig, genericArgs);
if (newSig == field.FieldSig)
return field;
var module = field.DeclaringType != null ? field.DeclaringType.Module : null;
return new MemberRefUser(module, field.Name, newSig, field.DeclaringType);
}
public static FieldSig create(FieldSig sig, GenericInstSig git) {
public static FieldSig Create(FieldSig sig, GenericInstSig git) {
if (git == null)
return sig;
return create(sig, git.GenericArguments);
return Create(sig, git.GenericArguments);
}
public static FieldSig create(FieldSig sig, IList<TypeSig> genericArgs) {
public static FieldSig Create(FieldSig sig, IList<TypeSig> genericArgs) {
if (sig == null || genericArgs == null || genericArgs.Count == 0)
return sig;
return new GenericArgsSubstitutor(genericArgs).create(sig);
return new GenericArgsSubstitutor(genericArgs).Create(sig);
}
public static IMethod create(IMethod method, GenericInstSig git) {
public static IMethod Create(IMethod method, GenericInstSig git) {
if (git == null)
return method;
var mdr = method as IMethodDefOrRef;
if (mdr != null)
return create(mdr, git);
return Create(mdr, git);
var ms = method as MethodSpec;
if (ms != null)
return create(ms, git);
return Create(ms, git);
return method;
}
public static MethodSpec create(MethodSpec method, GenericInstSig git) {
public static MethodSpec Create(MethodSpec method, GenericInstSig git) {
if (method == null || git == null)
return method;
var newMethod = create(method.Method, git);
var newInst = create(method.GenericInstMethodSig, git);
var newMethod = Create(method.Method, git);
var newInst = Create(method.GenericInstMethodSig, git);
bool updated = newMethod != method.Method || newInst != method.GenericInstMethodSig;
return updated ? new MethodSpecUser(newMethod, newInst) : method;
}
public static GenericInstMethodSig create(GenericInstMethodSig sig, GenericInstSig git) {
public static GenericInstMethodSig Create(GenericInstMethodSig sig, GenericInstSig git) {
if (git == null)
return sig;
return create(sig, git.GenericArguments);
return Create(sig, git.GenericArguments);
}
public static GenericInstMethodSig create(GenericInstMethodSig sig, IList<TypeSig> genericArgs) {
public static GenericInstMethodSig Create(GenericInstMethodSig sig, IList<TypeSig> genericArgs) {
if (sig == null || genericArgs == null || genericArgs.Count == 0)
return sig;
return new GenericArgsSubstitutor(genericArgs).create(sig);
return new GenericArgsSubstitutor(genericArgs).Create(sig);
}
public static IMethodDefOrRef create(IMethodDefOrRef method, GenericInstSig git) {
public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git) {
if (git == null)
return method;
return create(method, git.GenericArguments);
return Create(method, git.GenericArguments);
}
public static IMethodDefOrRef create(IMethodDefOrRef method, IList<TypeSig> genericArgs) {
return create(method, genericArgs, null);
public static IMethodDefOrRef Create(IMethodDefOrRef method, IList<TypeSig> genericArgs) {
return Create(method, genericArgs, null);
}
public static IMethodDefOrRef create(IMethodDefOrRef method, GenericInstSig git, IList<TypeSig> genericMethodArgs) {
return create(method, git == null ? null : git.GenericArguments, genericMethodArgs);
public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList<TypeSig> genericMethodArgs) {
return Create(method, git == null ? null : git.GenericArguments, genericMethodArgs);
}
// Creates a new method but keeps declaring type as is
public static IMethodDefOrRef create(IMethodDefOrRef method, IList<TypeSig> genericArgs, IList<TypeSig> genericMethodArgs) {
public static IMethodDefOrRef Create(IMethodDefOrRef method, IList<TypeSig> genericArgs, IList<TypeSig> genericMethodArgs) {
if (method == null)
return method;
if ((genericArgs == null || genericArgs.Count == 0) && (genericMethodArgs == null || genericMethodArgs.Count == 0))
@ -144,7 +144,7 @@ namespace de4dot.blocks {
if (sig == null)
return method;
var newSig = new GenericArgsSubstitutor(genericArgs, genericMethodArgs).create(sig);
var newSig = new GenericArgsSubstitutor(genericArgs, genericMethodArgs).Create(sig);
if (newSig == sig)
return method;
@ -163,12 +163,12 @@ namespace de4dot.blocks {
this.updated = false;
}
TypeSig create(TypeSig type) {
var newType = create2(type);
TypeSig Create(TypeSig type) {
var newType = Create2(type);
return updated ? newType : type;
}
TypeSig create2(TypeSig type) {
TypeSig Create2(TypeSig type) {
if (type == null)
return type;
TypeSig result;
@ -197,11 +197,11 @@ namespace de4dot.blocks {
break;
case ElementType.Ptr:
result = new PtrSig(create2(type.Next));
result = new PtrSig(Create2(type.Next));
break;
case ElementType.ByRef:
result = new ByRefSig(create2(type.Next));
result = new ByRefSig(Create2(type.Next));
break;
case ElementType.Array:
@ -210,11 +210,11 @@ namespace de4dot.blocks {
break;
case ElementType.SZArray:
result = new SZArraySig(create2(type.Next));
result = new SZArraySig(Create2(type.Next));
break;
case ElementType.Pinned:
result = new PinnedSig(create2(type.Next));
result = new PinnedSig(Create2(type.Next));
break;
case ElementType.ValueType:
@ -244,9 +244,9 @@ namespace de4dot.blocks {
case ElementType.GenericInst:
var gis = (GenericInstSig)type;
var newGis = new GenericInstSig(create2(gis.GenericType) as ClassOrValueTypeSig, gis.GenericArguments.Count);
var newGis = new GenericInstSig(Create2(gis.GenericType) as ClassOrValueTypeSig, gis.GenericArguments.Count);
for (int i = 0; i < gis.GenericArguments.Count; i++)
newGis.GenericArguments.Add(create2(gis.GenericArguments[i]));
newGis.GenericArguments.Add(Create2(gis.GenericArguments[i]));
result = newGis;
break;
@ -267,7 +267,7 @@ namespace de4dot.blocks {
break;
case ElementType.FnPtr:
result = new FnPtrSig(create(((FnPtrSig)type).MethodSig));
result = new FnPtrSig(Create(((FnPtrSig)type).MethodSig));
break;
case ElementType.End:
@ -282,31 +282,31 @@ namespace de4dot.blocks {
return result;
}
MethodSig create(MethodSig sig) {
MethodSig Create(MethodSig sig) {
if (sig == null)
return sig;
var newSig = new MethodSig(sig.GetCallingConvention());
newSig.RetType = create2(sig.RetType);
newSig.RetType = Create2(sig.RetType);
for (int i = 0; i < sig.Params.Count; i++)
newSig.Params.Add(create2(sig.Params[i]));
newSig.Params.Add(Create2(sig.Params[i]));
newSig.GenParamCount = sig.GenParamCount;
if (sig.ParamsAfterSentinel != null) {
newSig.ParamsAfterSentinel = new List<TypeSig>();
for (int i = 0; i < sig.ParamsAfterSentinel.Count; i++)
newSig.ParamsAfterSentinel.Add(create2(sig.ParamsAfterSentinel[i]));
newSig.ParamsAfterSentinel.Add(Create2(sig.ParamsAfterSentinel[i]));
}
return updated ? newSig : sig;
}
GenericInstMethodSig create(GenericInstMethodSig sig) {
GenericInstMethodSig Create(GenericInstMethodSig sig) {
var newSig = new GenericInstMethodSig();
for (int i = 0; i < sig.GenericArguments.Count; i++)
newSig.GenericArguments.Add(create2(sig.GenericArguments[i]));
newSig.GenericArguments.Add(Create2(sig.GenericArguments[i]));
return updated ? newSig : sig;
}
FieldSig create(FieldSig sig) {
var newSig = new FieldSig(create2(sig.Type));
FieldSig Create(FieldSig sig) {
var newSig = new FieldSig(Create2(sig.Type));
return updated ? newSig : sig;
}
}

View File

@ -44,11 +44,11 @@ namespace de4dot.blocks {
// Returns the variable or null if it's not a ldloc/stloc instruction. It does not return
// a local variable if it's a ldloca/ldloca.s instruction.
public static Local getLocalVar(IList<Local> locals, Instr instr) {
public static Local GetLocalVar(IList<Local> locals, Instr instr) {
return instr.Instruction.GetLocal(locals);
}
static public bool isFallThrough(OpCode opCode) {
static public bool IsFallThrough(OpCode opCode) {
switch (opCode.FlowControl) {
case FlowControl.Call:
return opCode != OpCodes.Jmp;
@ -61,7 +61,7 @@ namespace de4dot.blocks {
}
// Returns true if the instruction only pushes one value onto the stack and pops nothing
public bool isSimpleLoad() {
public bool IsSimpleLoad() {
switch (OpCode.Code) {
case Code.Ldarg:
case Code.Ldarg_S:
@ -103,55 +103,55 @@ namespace de4dot.blocks {
}
}
public bool isLdcI4() {
public bool IsLdcI4() {
return instruction.IsLdcI4();
}
public int getLdcI4Value() {
public int GetLdcI4Value() {
return instruction.GetLdcI4Value();
}
public bool isLdarg() {
public bool IsLdarg() {
return instruction.IsLdarg();
}
public bool isStloc() {
public bool IsStloc() {
return instruction.IsStloc();
}
public bool isLdloc() {
public bool IsLdloc() {
return instruction.IsLdloc();
}
public bool isNop() {
public bool IsNop() {
return OpCode == OpCodes.Nop;
}
public bool isPop() {
public bool IsPop() {
return OpCode == OpCodes.Pop;
}
public bool isLeave() {
public bool IsLeave() {
return instruction.IsLeave();
}
public bool isBr() {
public bool IsBr() {
return instruction.IsBr();
}
public bool isBrfalse() {
public bool IsBrfalse() {
return instruction.IsBrfalse();
}
public bool isBrtrue() {
public bool IsBrtrue() {
return instruction.IsBrtrue();
}
public bool isConditionalBranch() {
public bool IsConditionalBranch() {
return instruction.IsConditionalBranch();
}
public bool getFlippedBranchOpCode(out OpCode opcode) {
public bool GetFlippedBranchOpCode(out OpCode opcode) {
switch (OpCode.Code) {
case Code.Bge: opcode = OpCodes.Blt; return true;
case Code.Bge_S: opcode = OpCodes.Blt_S; return true;
@ -190,20 +190,20 @@ namespace de4dot.blocks {
}
}
public void flipConditonalBranch() {
public void FlipConditonalBranch() {
OpCode opcode;
if (!getFlippedBranchOpCode(out opcode))
if (!GetFlippedBranchOpCode(out opcode))
throw new ApplicationException("Can't flip conditional since it's not a supported conditional instruction");
instruction.OpCode = opcode;
}
// Returns true if we can flip a conditional branch
public bool canFlipConditionalBranch() {
public bool CanFlipConditionalBranch() {
OpCode opcode;
return getFlippedBranchOpCode(out opcode);
return GetFlippedBranchOpCode(out opcode);
}
public void updateTargets(List<Instr> targets) {
public void UpdateTargets(List<Instr> targets) {
switch (OpCode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:

View File

@ -33,44 +33,44 @@ namespace de4dot.blocks {
this.exceptionHandlers = exceptionHandlers;
this.branches = new Dictionary<int, List<int>>();
createInstrToIndex();
createBranches();
createExceptionBranches();
CreateInstrToIndex();
CreateBranches();
CreateExceptionBranches();
}
void createInstrToIndex() {
void CreateInstrToIndex() {
instrToIndex = new Dictionary<Instruction, int>();
for (int i = 0; i < instructions.Count; i++)
instrToIndex[instructions[i]] = i;
}
List<int> getBranchTargetList(int index) {
List<int> GetBranchTargetList(int index) {
List<int> targetsList;
if (!branches.TryGetValue(index, out targetsList))
branches[index] = targetsList = new List<int>();
return targetsList;
}
void markAsBranchTarget(Instruction instr) {
void MarkAsBranchTarget(Instruction instr) {
if (instr == null)
return;
int index = instrToIndex[instr];
getBranchTargetList(index); // Just create the list
GetBranchTargetList(index); // Just create the list
}
void createExceptionBranches() {
void CreateExceptionBranches() {
foreach (var eh in exceptionHandlers) {
markAsBranchTarget(eh.TryStart);
markAsBranchTarget(eh.TryEnd);
markAsBranchTarget(eh.FilterStart);
markAsBranchTarget(eh.HandlerStart);
markAsBranchTarget(eh.HandlerEnd);
MarkAsBranchTarget(eh.TryStart);
MarkAsBranchTarget(eh.TryEnd);
MarkAsBranchTarget(eh.FilterStart);
MarkAsBranchTarget(eh.HandlerStart);
MarkAsBranchTarget(eh.HandlerEnd);
}
}
void createBranches() {
void CreateBranches() {
for (int i = 0; i < instructions.Count; i++) {
var instr = instructions[i];
@ -113,13 +113,13 @@ namespace de4dot.blocks {
targets.Add(i + 1);
for (int j = 0; j < targets.Count; j++) {
int targetIndex = targets[j];
getBranchTargetList(targetIndex).Add(i);
GetBranchTargetList(targetIndex).Add(i);
}
}
}
}
void findBlocks(List<Block> instrToBlock, List<Block> allBlocks) {
void FindBlocks(List<Block> instrToBlock, List<Block> allBlocks) {
Block block = null;
for (var i = 0; i < instructions.Count; i++) {
List<int> branchSources;
@ -128,7 +128,7 @@ namespace de4dot.blocks {
allBlocks.Add(block);
}
block.add(new Instr(this.instructions[i]));
block.Add(new Instr(this.instructions[i]));
instrToBlock.Add(block);
}
}
@ -136,7 +136,7 @@ namespace de4dot.blocks {
// Fix all branches so they now point to a Block, and not an Instruction. The
// block's Targets field is updated, not the Instruction's Operand field.
// Also update Block.FallThrough with next Block if last instr falls through.
void fixBranchTargets(List<Block> instrToBlock, List<Block> allBlocks) {
void FixBranchTargets(List<Block> instrToBlock, List<Block> allBlocks) {
for (var i = 0; i < allBlocks.Count; i++) {
var block = allBlocks[i];
var lastInstr = block.LastInstr;
@ -160,15 +160,15 @@ namespace de4dot.blocks {
break;
}
if (i + 1 < allBlocks.Count && Instr.isFallThrough(lastInstr.OpCode))
if (i + 1 < allBlocks.Count && Instr.IsFallThrough(lastInstr.OpCode))
block.FallThrough = allBlocks[i + 1];
}
}
// Updates the sources field of each block
void fixBlockSources(List<Block> allBlocks) {
void FixBlockSources(List<Block> allBlocks) {
foreach (var block in allBlocks) {
block.updateSources();
block.UpdateSources();
}
}
@ -195,7 +195,7 @@ namespace de4dot.blocks {
}
}
List<List<ExceptionHandler>> getSortedExceptionInfos() {
List<List<ExceptionHandler>> GetSortedExceptionInfos() {
var exInfos = new Dictionary<EHInfo, List<ExceptionHandler>>();
foreach (var eh in exceptionHandlers) {
List<ExceptionHandler> handlers;
@ -220,8 +220,8 @@ namespace de4dot.blocks {
// Same start instruction. The nested one is the one that ends earliest,
// so it should be sorted before the outer one.
ai = getInstrIndex(a[0].TryEnd);
bi = getInstrIndex(b[0].TryEnd);
ai = GetInstrIndex(a[0].TryEnd);
bi = GetInstrIndex(b[0].TryEnd);
if (ai < bi) return -1;
if (ai > bi) return 1;
@ -245,7 +245,7 @@ namespace de4dot.blocks {
List<BaseBlockInfo> blocksLeft = new List<BaseBlockInfo>();
public void add(BaseBlock bb, int start, int end) {
public void Add(BaseBlock bb, int start, int end) {
if (start < 0 || end < 0 || end < start)
throw new ApplicationException("Invalid start and/or end index");
if (blocksLeft.Count != 0) {
@ -256,7 +256,7 @@ namespace de4dot.blocks {
blocksLeft.Add(new BaseBlockInfo(start, end, bb));
}
int findStart(int instrIndex) {
int FindStart(int instrIndex) {
for (int i = 0; i < blocksLeft.Count; i++) {
if (blocksLeft[i].startInstr == instrIndex)
return i;
@ -264,7 +264,7 @@ namespace de4dot.blocks {
throw new ApplicationException("Could not find start BaseBlockInfo");
}
int findEnd(int instrIndex) {
int FindEnd(int instrIndex) {
for (int i = 0; i < blocksLeft.Count; i++) {
if (blocksLeft[i].endInstr == instrIndex)
return i;
@ -272,14 +272,14 @@ namespace de4dot.blocks {
throw new ApplicationException("Could not find end BaseBlockInfo");
}
List<BaseBlock> getBlocks(int startInstr, int endInstr, out int startIndex, out int endIndex) {
List<BaseBlock> GetBlocks(int startInstr, int endInstr, out int startIndex, out int endIndex) {
if (endInstr < startInstr || startInstr < 0 || endInstr < 0)
throw new ApplicationException("Invalid startInstr and/or endInstr");
var rv = new List<BaseBlock>();
startIndex = findStart(startInstr);
endIndex = findEnd(endInstr);
startIndex = FindStart(startInstr);
endIndex = FindEnd(endInstr);
for (int i = startIndex; i <= endIndex; i++)
rv.Add(blocksLeft[i].baseBlock);
@ -288,13 +288,13 @@ namespace de4dot.blocks {
}
// Replace the BaseBlocks with a new BaseBlock, returning the old ones.
public List<BaseBlock> replace(int startInstr, int endInstr, ScopeBlock bb) {
public List<BaseBlock> Replace(int startInstr, int endInstr, ScopeBlock bb) {
if (endInstr < startInstr)
return new List<BaseBlock>();
int startIndex, endIndex;
var rv = getBlocks(startInstr, endInstr, out startIndex, out endIndex);
updateParent(rv, bb);
var rv = GetBlocks(startInstr, endInstr, out startIndex, out endIndex);
UpdateParent(rv, bb);
var bbi = new BaseBlockInfo(blocksLeft[startIndex].startInstr, blocksLeft[endIndex].endInstr, bb);
blocksLeft.RemoveRange(startIndex, endIndex - startIndex + 1);
@ -303,78 +303,78 @@ namespace de4dot.blocks {
return rv;
}
public List<BaseBlock> getBlocks(ScopeBlock parent) {
public List<BaseBlock> GetBlocks(ScopeBlock parent) {
if (blocksLeft.Count == 0)
return new List<BaseBlock>();
int startIndex, endIndex;
var lb = getBlocks(0, blocksLeft[blocksLeft.Count - 1].endInstr, out startIndex, out endIndex);
return updateParent(lb, parent);
var lb = GetBlocks(0, blocksLeft[blocksLeft.Count - 1].endInstr, out startIndex, out endIndex);
return UpdateParent(lb, parent);
}
List<BaseBlock> updateParent(List<BaseBlock> lb, ScopeBlock parent) {
List<BaseBlock> UpdateParent(List<BaseBlock> lb, ScopeBlock parent) {
foreach (var bb in lb)
bb.Parent = parent;
return lb;
}
}
BaseBlocksList createBaseBlockList(List<Block> allBlocks, List<List<ExceptionHandler>> exSorted) {
BaseBlocksList CreateBaseBlockList(List<Block> allBlocks, List<List<ExceptionHandler>> exSorted) {
var bbl = new BaseBlocksList();
foreach (var block in allBlocks) {
int start = instrToIndex[block.FirstInstr.Instruction];
int end = instrToIndex[block.LastInstr.Instruction];
bbl.add(block, start, end);
bbl.Add(block, start, end);
}
foreach (var exHandlers in exSorted) {
var tryBlock = new TryBlock();
var tryStart = instrToIndex[exHandlers[0].TryStart];
var tryEnd = getInstrIndex(exHandlers[0].TryEnd) - 1;
tryBlock.BaseBlocks = bbl.replace(tryStart, tryEnd, tryBlock);
var tryEnd = GetInstrIndex(exHandlers[0].TryEnd) - 1;
tryBlock.BaseBlocks = bbl.Replace(tryStart, tryEnd, tryBlock);
foreach (var exHandler in exHandlers) {
var tryHandlerBlock = new TryHandlerBlock(exHandler);
tryBlock.addTryHandler(tryHandlerBlock);
tryBlock.AddTryHandler(tryHandlerBlock);
int filterStart = -1, handlerStart = -1, handlerEnd = -1;
if (exHandler.FilterStart != null) {
filterStart = instrToIndex[exHandler.FilterStart];
var end = instrToIndex[exHandler.HandlerStart] - 1;
tryHandlerBlock.FilterHandlerBlock.BaseBlocks = bbl.replace(filterStart, end, tryHandlerBlock.FilterHandlerBlock);
tryHandlerBlock.FilterHandlerBlock.BaseBlocks = bbl.Replace(filterStart, end, tryHandlerBlock.FilterHandlerBlock);
}
handlerStart = instrToIndex[exHandler.HandlerStart];
handlerEnd = getInstrIndex(exHandler.HandlerEnd) - 1;
tryHandlerBlock.HandlerBlock.BaseBlocks = bbl.replace(handlerStart, handlerEnd, tryHandlerBlock.HandlerBlock);
handlerEnd = GetInstrIndex(exHandler.HandlerEnd) - 1;
tryHandlerBlock.HandlerBlock.BaseBlocks = bbl.Replace(handlerStart, handlerEnd, tryHandlerBlock.HandlerBlock);
tryHandlerBlock.BaseBlocks = bbl.replace(filterStart == -1 ? handlerStart : filterStart, handlerEnd, tryHandlerBlock);
tryHandlerBlock.BaseBlocks = bbl.Replace(filterStart == -1 ? handlerStart : filterStart, handlerEnd, tryHandlerBlock);
}
}
return bbl;
}
int getInstrIndex(Instruction instruction) {
int GetInstrIndex(Instruction instruction) {
if (instruction == null)
return instructions.Count;
return instrToIndex[instruction];
}
public MethodBlocks parse() {
public MethodBlocks Parse() {
var instrToBlock = new List<Block>(instructions.Count);
var allBlocks = new List<Block>();
findBlocks(instrToBlock, allBlocks);
fixBranchTargets(instrToBlock, allBlocks);
fixBlockSources(allBlocks);
var exSorted = getSortedExceptionInfos();
var bbl = createBaseBlockList(allBlocks, exSorted);
FindBlocks(instrToBlock, allBlocks);
FixBranchTargets(instrToBlock, allBlocks);
FixBlockSources(allBlocks);
var exSorted = GetSortedExceptionInfos();
var bbl = CreateBaseBlockList(allBlocks, exSorted);
foreach (var block in allBlocks)
block.removeLastBr();
block.RemoveLastBr();
var mb = new MethodBlocks();
mb.BaseBlocks = bbl.getBlocks(mb);
mb.BaseBlocks = bbl.GetBlocks(mb);
return mb;
}
}

View File

@ -32,23 +32,23 @@ namespace de4dot.blocks {
get { return tokenToValue.Count; }
}
public IEnumerable<TypeDef> getKeys() {
public IEnumerable<TypeDef> GetKeys() {
return tokenToKey.Values;
}
public IEnumerable<TValue> getValues() {
public IEnumerable<TValue> GetValues() {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(TypeDef typeDef) {
ScopeAndTokenKey GetTokenKey(TypeDef typeDef) {
return new ScopeAndTokenKey(typeDef);
}
public TValue find(IType typeRef) {
public TValue Find(IType typeRef) {
TValue value;
var typeDef = typeRef as TypeDef;
if (typeDef != null)
tokenToValue.TryGetValue(getTokenKey(typeDef), out value);
tokenToValue.TryGetValue(GetTokenKey(typeDef), out value);
else if (typeRef != null)
refToValue.TryGetValue(typeRef, out value);
else
@ -56,23 +56,23 @@ namespace de4dot.blocks {
return value;
}
public TValue findAny(IType type) {
public TValue FindAny(IType type) {
TValue value;
var typeDef = type as TypeDef;
if (typeDef != null && tokenToValue.TryGetValue(getTokenKey(typeDef), out value))
if (typeDef != null && tokenToValue.TryGetValue(GetTokenKey(typeDef), out value))
return value;
refToValue.TryGetValue(type, out value);
return value;
}
public void add(TypeDef typeDef, TValue value) {
var tokenKey = getTokenKey(typeDef);
public void Add(TypeDef typeDef, TValue value) {
var tokenKey = GetTokenKey(typeDef);
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = typeDef;
if (!refToValue.ContainsKey(typeDef) ||
getAccessibilityOrder(typeDef) < getAccessibilityOrder(refToKey[typeDef])) {
GetAccessibilityOrder(typeDef) < GetAccessibilityOrder(refToKey[typeDef])) {
refToKey[typeDef] = typeDef;
refToValue[typeDef] = value;
}
@ -89,11 +89,11 @@ namespace de4dot.blocks {
60, // NestedFamANDAssem
30, // NestedFamORAssem
};
static int getAccessibilityOrder(TypeDef typeDef) {
static int GetAccessibilityOrder(TypeDef typeDef) {
return accessibilityOrder[(int)typeDef.Attributes & 7];
}
public void onTypesRenamed() {
public void OnTypesRenamed() {
var newTypeRefToValue = new Dictionary<IType, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newTypeRefToValue[kvp.Key] = kvp.Value;
@ -111,48 +111,48 @@ namespace de4dot.blocks {
get { return tokenToValue.Count; }
}
public IEnumerable<FieldDef> getKeys() {
public IEnumerable<FieldDef> GetKeys() {
return tokenToKey.Values;
}
public IEnumerable<TValue> getValues() {
public IEnumerable<TValue> GetValues() {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(FieldDef fieldDef) {
ScopeAndTokenKey GetTokenKey(FieldDef fieldDef) {
return new ScopeAndTokenKey(fieldDef);
}
internal abstract IFieldRefKey getRefKey(IField fieldRef);
internal abstract IFieldRefKey GetRefKey(IField fieldRef);
public TValue find(IField fieldRef) {
public TValue Find(IField fieldRef) {
TValue value;
var fieldDef = fieldRef as FieldDef;
if (fieldDef != null)
tokenToValue.TryGetValue(getTokenKey(fieldDef), out value);
tokenToValue.TryGetValue(GetTokenKey(fieldDef), out value);
else
refToValue.TryGetValue(getRefKey(fieldRef), out value);
refToValue.TryGetValue(GetRefKey(fieldRef), out value);
return value;
}
public TValue findAny(IField fieldRef) {
public TValue FindAny(IField fieldRef) {
TValue value;
var fieldDef = fieldRef as FieldDef;
if (fieldDef != null && tokenToValue.TryGetValue(getTokenKey(fieldDef), out value))
if (fieldDef != null && tokenToValue.TryGetValue(GetTokenKey(fieldDef), out value))
return value;
refToValue.TryGetValue(getRefKey(fieldRef), out value);
refToValue.TryGetValue(GetRefKey(fieldRef), out value);
return value;
}
public void add(FieldDef fieldDef, TValue value) {
var tokenKey = getTokenKey(fieldDef);
public void Add(FieldDef fieldDef, TValue value) {
var tokenKey = GetTokenKey(fieldDef);
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = fieldDef;
var refKey = getRefKey(fieldDef);
var refKey = GetRefKey(fieldDef);
if (!refToValue.ContainsKey(refKey) ||
getAccessibilityOrder(fieldDef) < getAccessibilityOrder(refToKey[refKey])) {
GetAccessibilityOrder(fieldDef) < GetAccessibilityOrder(refToKey[refKey])) {
refToKey[refKey] = fieldDef;
refToValue[refKey] = value;
}
@ -169,26 +169,26 @@ namespace de4dot.blocks {
0, // Public
70, // <reserved>
};
static int getAccessibilityOrder(FieldDef fieldDef) {
static int GetAccessibilityOrder(FieldDef fieldDef) {
return accessibilityOrder[(int)fieldDef.Attributes & 7];
}
public void onTypesRenamed() {
public void OnTypesRenamed() {
var newFieldRefToDef = new Dictionary<IFieldRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getRefKey((FieldDef)kvp.Key.FieldRef)] = kvp.Value;
newFieldRefToDef[GetRefKey((FieldDef)kvp.Key.FieldRef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class FieldDefDict<TValue> : FieldDefDictBase<TValue> {
internal override IFieldRefKey getRefKey(IField fieldRef) {
internal override IFieldRefKey GetRefKey(IField fieldRef) {
return new FieldRefKey(fieldRef);
}
}
public class FieldDefAndDeclaringTypeDict<TValue> : FieldDefDictBase<TValue> {
internal override IFieldRefKey getRefKey(IField fieldRef) {
internal override IFieldRefKey GetRefKey(IField fieldRef) {
return new FieldRefAndDeclaringTypeKey(fieldRef);
}
}
@ -203,48 +203,48 @@ namespace de4dot.blocks {
get { return tokenToValue.Count; }
}
public IEnumerable<MethodDef> getKeys() {
public IEnumerable<MethodDef> GetKeys() {
return tokenToKey.Values;
}
public IEnumerable<TValue> getValues() {
public IEnumerable<TValue> GetValues() {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(MethodDef methodDef) {
ScopeAndTokenKey GetTokenKey(MethodDef methodDef) {
return new ScopeAndTokenKey(methodDef);
}
internal abstract IMethodRefKey getRefKey(IMethod methodRef);
internal abstract IMethodRefKey GetRefKey(IMethod methodRef);
public TValue find(IMethod methodRef) {
public TValue Find(IMethod methodRef) {
TValue value;
var methodDef = methodRef as MethodDef;
if (methodDef != null)
tokenToValue.TryGetValue(getTokenKey(methodDef), out value);
tokenToValue.TryGetValue(GetTokenKey(methodDef), out value);
else
refToValue.TryGetValue(getRefKey(methodRef), out value);
refToValue.TryGetValue(GetRefKey(methodRef), out value);
return value;
}
public TValue findAny(IMethod methodRef) {
public TValue FindAny(IMethod methodRef) {
TValue value;
var methodDef = methodRef as MethodDef;
if (methodDef != null && tokenToValue.TryGetValue(getTokenKey(methodDef), out value))
if (methodDef != null && tokenToValue.TryGetValue(GetTokenKey(methodDef), out value))
return value;
refToValue.TryGetValue(getRefKey(methodRef), out value);
refToValue.TryGetValue(GetRefKey(methodRef), out value);
return value;
}
public void add(MethodDef methodDef, TValue value) {
var tokenKey = getTokenKey(methodDef);
public void Add(MethodDef methodDef, TValue value) {
var tokenKey = GetTokenKey(methodDef);
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = methodDef;
var refKey = getRefKey(methodDef);
var refKey = GetRefKey(methodDef);
if (!refToValue.ContainsKey(refKey) ||
getAccessibilityOrder(methodDef) < getAccessibilityOrder(refToKey[refKey])) {
GetAccessibilityOrder(methodDef) < GetAccessibilityOrder(refToKey[refKey])) {
refToKey[refKey] = methodDef;
refToValue[refKey] = value;
}
@ -261,26 +261,26 @@ namespace de4dot.blocks {
0, // Public
70, // <reserved>
};
static int getAccessibilityOrder(MethodDef methodDef) {
static int GetAccessibilityOrder(MethodDef methodDef) {
return accessibilityOrder[(int)methodDef.Attributes & 7];
}
public void onTypesRenamed() {
public void OnTypesRenamed() {
var newFieldRefToDef = new Dictionary<IMethodRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getRefKey((MethodDef)kvp.Key.MethodRef)] = kvp.Value;
newFieldRefToDef[GetRefKey((MethodDef)kvp.Key.MethodRef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class MethodDefDict<TValue> : MethodDefDictBase<TValue> {
internal override IMethodRefKey getRefKey(IMethod methodRef) {
internal override IMethodRefKey GetRefKey(IMethod methodRef) {
return new MethodRefKey(methodRef);
}
}
public class MethodDefAndDeclaringTypeDict<TValue> : MethodDefDictBase<TValue> {
internal override IMethodRefKey getRefKey(IMethod methodRef) {
internal override IMethodRefKey GetRefKey(IMethod methodRef) {
return new MethodRefAndDeclaringTypeKey(methodRef);
}
}
@ -294,59 +294,59 @@ namespace de4dot.blocks {
get { return tokenToValue.Count; }
}
public IEnumerable<EventDef> getKeys() {
public IEnumerable<EventDef> GetKeys() {
return tokenToKey.Values;
}
public IEnumerable<TValue> getValues() {
public IEnumerable<TValue> GetValues() {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(EventDef eventRef) {
ScopeAndTokenKey GetTokenKey(EventDef eventRef) {
return new ScopeAndTokenKey(eventRef);
}
internal abstract IEventRefKey getRefKey(EventDef eventRef);
internal abstract IEventRefKey GetRefKey(EventDef eventRef);
public TValue find(EventDef eventRef) {
public TValue Find(EventDef eventRef) {
TValue value;
tokenToValue.TryGetValue(getTokenKey(eventRef), out value);
tokenToValue.TryGetValue(GetTokenKey(eventRef), out value);
return value;
}
public TValue findAny(EventDef eventRef) {
public TValue FindAny(EventDef eventRef) {
TValue value;
if (tokenToValue.TryGetValue(getTokenKey(eventRef), out value))
if (tokenToValue.TryGetValue(GetTokenKey(eventRef), out value))
return value;
refToValue.TryGetValue(getRefKey(eventRef), out value);
refToValue.TryGetValue(GetRefKey(eventRef), out value);
return value;
}
public void add(EventDef eventDef, TValue value) {
var tokenKey = getTokenKey(eventDef);
public void Add(EventDef eventDef, TValue value) {
var tokenKey = GetTokenKey(eventDef);
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = eventDef;
refToValue[getRefKey(eventDef)] = value;
refToValue[GetRefKey(eventDef)] = value;
}
public void onTypesRenamed() {
public void OnTypesRenamed() {
var newFieldRefToDef = new Dictionary<IEventRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getRefKey((EventDef)kvp.Key.EventDef)] = kvp.Value;
newFieldRefToDef[GetRefKey((EventDef)kvp.Key.EventDef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class EventDefDict<TValue> : EventDefDictBase<TValue> {
internal override IEventRefKey getRefKey(EventDef eventRef) {
internal override IEventRefKey GetRefKey(EventDef eventRef) {
return new EventRefKey(eventRef);
}
}
public class EventDefAndDeclaringTypeDict<TValue> : EventDefDictBase<TValue> {
internal override IEventRefKey getRefKey(EventDef eventRef) {
internal override IEventRefKey GetRefKey(EventDef eventRef) {
return new EventRefAndDeclaringTypeKey(eventRef);
}
}
@ -360,59 +360,59 @@ namespace de4dot.blocks {
get { return tokenToValue.Count; }
}
public IEnumerable<PropertyDef> getKeys() {
public IEnumerable<PropertyDef> GetKeys() {
return tokenToKey.Values;
}
public IEnumerable<TValue> getValues() {
public IEnumerable<TValue> GetValues() {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(PropertyDef propertyRef) {
ScopeAndTokenKey GetTokenKey(PropertyDef propertyRef) {
return new ScopeAndTokenKey(propertyRef);
}
internal abstract IPropertyRefKey getRefKey(PropertyDef propertyRef);
internal abstract IPropertyRefKey GetRefKey(PropertyDef propertyRef);
public TValue find(PropertyDef propRef) {
public TValue Find(PropertyDef propRef) {
TValue value;
tokenToValue.TryGetValue(getTokenKey(propRef), out value);
tokenToValue.TryGetValue(GetTokenKey(propRef), out value);
return value;
}
public TValue findAny(PropertyDef propRef) {
public TValue FindAny(PropertyDef propRef) {
TValue value;
if (tokenToValue.TryGetValue(getTokenKey(propRef), out value))
if (tokenToValue.TryGetValue(GetTokenKey(propRef), out value))
return value;
refToValue.TryGetValue(getRefKey(propRef), out value);
refToValue.TryGetValue(GetRefKey(propRef), out value);
return value;
}
public void add(PropertyDef propDef, TValue value) {
var tokenKey = getTokenKey(propDef);
public void Add(PropertyDef propDef, TValue value) {
var tokenKey = GetTokenKey(propDef);
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = propDef;
refToValue[getRefKey(propDef)] = value;
refToValue[GetRefKey(propDef)] = value;
}
public void onTypesRenamed() {
public void OnTypesRenamed() {
var newFieldRefToDef = new Dictionary<IPropertyRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getRefKey((PropertyDef)kvp.Key.PropertyDef)] = kvp.Value;
newFieldRefToDef[GetRefKey((PropertyDef)kvp.Key.PropertyDef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class PropertyDefDict<TValue> : PropertyDefDictBase<TValue> {
internal override IPropertyRefKey getRefKey(PropertyDef propRef) {
internal override IPropertyRefKey GetRefKey(PropertyDef propRef) {
return new PropertyRefKey(propRef);
}
}
public class PropertyDefAndDeclaringTypeDict<TValue> : PropertyDefDictBase<TValue> {
internal override IPropertyRefKey getRefKey(PropertyDef propRef) {
internal override IPropertyRefKey GetRefKey(PropertyDef propRef) {
return new PropertyRefAndDeclaringTypeKey(propRef);
}
}
@ -467,16 +467,16 @@ namespace de4dot.blocks {
return true;
if (a == null || b == null)
return false;
return getCanonicalizedScopeName(a) == getCanonicalizedScopeName(b);
return GetCanonicalizedScopeName(a) == GetCanonicalizedScopeName(b);
}
static int GetHashCode(IScope a) {
if (a == null)
return 0;
return getCanonicalizedScopeName(a).GetHashCode();
return GetCanonicalizedScopeName(a).GetHashCode();
}
static string getAssemblyName(IScope a) {
static string GetAssemblyName(IScope a) {
switch (a.ScopeType) {
case ScopeType.AssemblyRef:
return ((AssemblyRef)a).Name.String;
@ -489,10 +489,10 @@ namespace de4dot.blocks {
return null;
}
static string getCanonicalizedScopeName(IScope a) {
static string GetCanonicalizedScopeName(IScope a) {
if (a == null)
return string.Empty;
var asmName = getAssemblyName(a);
var asmName = GetAssemblyName(a);
if (asmName != null) {
// The version number should be ignored. Older code may reference an old version of
// the assembly, but if the newer one has been loaded, that one is used.

View File

@ -32,52 +32,52 @@ namespace de4dot.blocks {
set { baseBlocks = value; }
}
public IEnumerable<BaseBlock> getBaseBlocks() {
public IEnumerable<BaseBlock> GetBaseBlocks() {
if (baseBlocks != null) {
foreach (var bb in baseBlocks)
yield return bb;
}
}
public List<BaseBlock> getAllBaseBlocks() {
return getTheBlocks(new List<BaseBlock>());
public List<BaseBlock> GetAllBaseBlocks() {
return GetTheBlocks(new List<BaseBlock>());
}
public List<Block> getAllBlocks() {
return getTheBlocks(new List<Block>());
public List<Block> GetAllBlocks() {
return GetTheBlocks(new List<Block>());
}
public List<Block> getAllBlocks(List<Block> allBlocks) {
public List<Block> GetAllBlocks(List<Block> allBlocks) {
allBlocks.Clear();
return getTheBlocks(allBlocks);
return GetTheBlocks(allBlocks);
}
public List<ScopeBlock> getAllScopeBlocks() {
return getTheBlocks(new List<ScopeBlock>());
public List<ScopeBlock> GetAllScopeBlocks() {
return GetTheBlocks(new List<ScopeBlock>());
}
public List<T> getTheBlocks<T>(List<T> list) where T : BaseBlock {
addBlocks(list, this);
public List<T> GetTheBlocks<T>(List<T> list) where T : BaseBlock {
AddBlocks(list, this);
return list;
}
void addBlocks<T>(IList<T> list, ScopeBlock scopeBlock) where T : BaseBlock {
foreach (var bb in scopeBlock.getBaseBlocks()) {
void AddBlocks<T>(IList<T> list, ScopeBlock scopeBlock) where T : BaseBlock {
foreach (var bb in scopeBlock.GetBaseBlocks()) {
T t = bb as T;
if (t != null)
list.Add(t);
if (bb is ScopeBlock)
addBlocks(list, (ScopeBlock)bb);
AddBlocks(list, (ScopeBlock)bb);
}
}
List<Block> findBlocks() {
return findBlocks(null);
List<Block> FindBlocks() {
return FindBlocks(null);
}
List<Block> findBlocks(Func<Block, bool> blockChecker) {
List<Block> FindBlocks(Func<Block, bool> blockChecker) {
var blocks = new List<Block>();
foreach (var bb in getBaseBlocks()) {
foreach (var bb in GetBaseBlocks()) {
Block block = bb as Block;
if (block != null && (blockChecker == null || blockChecker(block)))
blocks.Add(block);
@ -85,7 +85,7 @@ namespace de4dot.blocks {
return blocks;
}
internal bool getLdcValue(Instr instr, out int value) {
internal bool GetLdcValue(Instr instr, out int value) {
if (Code.Ldc_I4_0 <= instr.OpCode.Code && instr.OpCode.Code <= Code.Ldc_I4_8)
value = instr.OpCode.Code - Code.Ldc_I4_0;
else if (instr.OpCode.Code == Code.Ldc_I4)
@ -103,18 +103,18 @@ namespace de4dot.blocks {
// Remove the block if it's a dead block. If it has refs to other dead blocks, those
// are also removed.
public void removeDeadBlock(Block block) {
removeDeadBlocks(new List<Block> { block });
public void RemoveDeadBlock(Block block) {
RemoveDeadBlocks(new List<Block> { block });
}
// Remove all dead blocks we can find
public void removeDeadBlocks() {
removeDeadBlocks(findBlocks());
public void RemoveDeadBlocks() {
RemoveDeadBlocks(FindBlocks());
}
// Remove the blocks if they're dead blocks. If they have refs to other dead blocks,
// those are also removed.
public void removeDeadBlocks(List<Block> blocks) {
public void RemoveDeadBlocks(List<Block> blocks) {
while (blocks.Count != 0) {
var block = blocks[blocks.Count - 1];
blocks.RemoveAt(blocks.Count - 1);
@ -122,7 +122,7 @@ namespace de4dot.blocks {
continue; // Not dead
if (block == baseBlocks[0])
continue; // It's the start of this block fence so must be present
if (!isOurBaseBlock(block))
if (!IsOurBaseBlock(block))
continue; // Some other ScopeBlock owns it, eg. first instr of an exception handler
// It's a dead block we can delete!
@ -131,27 +131,27 @@ namespace de4dot.blocks {
blocks.Add(block.FallThrough);
if (block.Targets != null)
blocks.AddRange(block.Targets);
block.removeDeadBlock();
block.RemoveDeadBlock();
if (!baseBlocks.Remove(block))
throw new ApplicationException("Could not remove dead block from baseBlocks");
}
}
public bool isOurBaseBlock(BaseBlock bb) {
public bool IsOurBaseBlock(BaseBlock bb) {
return bb != null && bb.Parent == this;
}
// For each block, if it has only one target, and the target has only one source, then
// merge them into one block.
public int mergeBlocks() {
public int MergeBlocks() {
int mergedBlocks = 0;
var blocks = findBlocks();
var blocks = FindBlocks();
for (int i = 0; i < blocks.Count; i++) {
var block = blocks[i];
var target = block.getOnlyTarget();
if (!isOurBaseBlock(target))
var target = block.GetOnlyTarget();
if (!IsOurBaseBlock(target))
continue; // Only merge blocks we own!
if (!block.canMerge(target))
if (!block.CanMerge(target))
continue; // Can't merge them!
if (target == baseBlocks[0])
continue; // The first one has an implicit source (eg. start of method or exception handler)
@ -160,7 +160,7 @@ namespace de4dot.blocks {
if (targetIndex < 0)
throw new ApplicationException("Could not remove target block from blocks");
blocks.RemoveAt(targetIndex);
block.merge(target);
block.Merge(target);
if (!baseBlocks.Remove(target))
throw new ApplicationException("Could not remove merged block from baseBlocks");
if (targetIndex < i)
@ -174,20 +174,20 @@ namespace de4dot.blocks {
// If bb is in baseBlocks (a direct child), return bb. If bb is a BaseBlock in a
// ScopeBlock that is a direct child, then return that ScopeBlock. Else return null.
public BaseBlock toChild(BaseBlock bb) {
if (isOurBaseBlock(bb))
public BaseBlock ToChild(BaseBlock bb) {
if (IsOurBaseBlock(bb))
return bb;
for (var sb = bb.Parent; sb != null; sb = sb.Parent) {
if (isOurBaseBlock(sb))
if (IsOurBaseBlock(sb))
return sb;
}
return null;
}
internal void repartitionBlocks() {
var newBaseBlocks = new BlocksSorter(this).sort();
internal void RepartitionBlocks() {
var newBaseBlocks = new BlocksSorter(this).Sort();
const bool insane = true;
if (insane) {
@ -206,7 +206,7 @@ namespace de4dot.blocks {
// Removes the TryBlock and all its TryHandlerBlocks. The code inside the try block
// is not removed.
public void removeTryBlock(TryBlock tryBlock) {
public void RemoveTryBlock(TryBlock tryBlock) {
int tryBlockIndex = baseBlocks.IndexOf(tryBlock);
if (tryBlockIndex < 0)
throw new ApplicationException("Can't remove the TryBlock since it's not this ScopeBlock's TryBlock");
@ -220,15 +220,15 @@ namespace de4dot.blocks {
// Get removed blocks and make sure they're not referenced by remaining code
var removedBlocks = new List<Block>();
foreach (var handler in tryBlock.TryHandlerBlocks)
handler.getTheBlocks(removedBlocks);
if (!verifyNoExternalRefs(removedBlocks))
handler.GetTheBlocks(removedBlocks);
if (!VerifyNoExternalRefs(removedBlocks))
throw new ApplicationException("Removed blocks are referenced by remaining code");
removeAllDeadBlocks(Utils.convert<TryHandlerBlock, BaseBlock>(tryBlock.TryHandlerBlocks));
RemoveAllDeadBlocks(Utils.Convert<TryHandlerBlock, BaseBlock>(tryBlock.TryHandlerBlocks));
}
// Returns true if no external blocks references the blocks
static bool verifyNoExternalRefs(IList<Block> removedBlocks) {
static bool VerifyNoExternalRefs(IList<Block> removedBlocks) {
var removedDict = new Dictionary<Block, bool>();
foreach (var removedBlock in removedBlocks)
removedDict[removedBlock] = true;
@ -243,13 +243,13 @@ namespace de4dot.blocks {
}
// Remove all blocks in deadBlocks. They're guaranteed to be dead.
void removeAllDeadBlocks(IEnumerable<BaseBlock> deadBlocks) {
removeAllDeadBlocks(deadBlocks, null);
void RemoveAllDeadBlocks(IEnumerable<BaseBlock> deadBlocks) {
RemoveAllDeadBlocks(deadBlocks, null);
}
// Remove all blocks in deadBlocks. They're guaranteed to be dead. deadBlocksDict is
// a dictionary of all dead blocks (even those not in this ScopeBlock).
internal void removeAllDeadBlocks(IEnumerable<BaseBlock> deadBlocks, Dictionary<BaseBlock, bool> deadBlocksDict) {
internal void RemoveAllDeadBlocks(IEnumerable<BaseBlock> deadBlocks, Dictionary<BaseBlock, bool> deadBlocksDict) {
// Verify that all the blocks really are dead. If all their source blocks are
// dead, then they are dead.
@ -260,7 +260,7 @@ namespace de4dot.blocks {
allDeadBlocks.Add(bb as Block);
else if (bb is ScopeBlock) {
var sb = (ScopeBlock)bb;
allDeadBlocks.AddRange(sb.getAllBlocks());
allDeadBlocks.AddRange(sb.GetAllBlocks());
}
else
throw new ApplicationException(string.Format("Unknown BaseBlock type {0}", bb.GetType()));
@ -278,20 +278,20 @@ namespace de4dot.blocks {
}
foreach (var block in allDeadBlocks)
block.removeGuaranteedDeadBlock();
block.RemoveGuaranteedDeadBlock();
foreach (var bb in deadBlocks) {
if (!baseBlocks.Remove(bb))
throw new ApplicationException("Could not remove dead base block from baseBlocks");
}
}
public void removeGuaranteedDeadBlock(Block block) {
public void RemoveGuaranteedDeadBlock(Block block) {
if (!baseBlocks.Remove(block))
throw new ApplicationException("Could not remove dead block");
block.removeGuaranteedDeadBlock();
block.RemoveGuaranteedDeadBlock();
}
public void add(Block block) {
public void Add(Block block) {
if (block.Parent != null)
throw new ApplicationException("Block already has a parent");
baseBlocks.Add(block);

View File

@ -31,7 +31,7 @@ namespace de4dot.blocks {
get { return handlerBlocks; }
}
public void addTryHandler(TryHandlerBlock tryHandlerBlock) {
public void AddTryHandler(TryHandlerBlock tryHandlerBlock) {
handlerBlocks.Add(tryHandlerBlock);
}
}

View File

@ -47,21 +47,21 @@ namespace de4dot.blocks {
}
static class Utils {
public static IDictionary<T, int> createObjectToIndexDictionary<T>(IList<T> objs) {
public static IDictionary<T, int> CreateObjectToIndexDictionary<T>(IList<T> objs) {
var dict = new Dictionary<T, int>();
for (int i = 0; i < objs.Count; i++)
dict[objs[i]] = i;
return dict;
}
public static List<TOut> convert<TIn, TOut>(IEnumerable<TIn> list) where TIn : TOut {
public static List<TOut> Convert<TIn, TOut>(IEnumerable<TIn> list) where TIn : TOut {
var olist = new List<TOut>();
foreach (var l in list)
olist.Add(l);
return olist;
}
public static IEnumerable<T> unique<T>(IEnumerable<T> values) {
public static IEnumerable<T> Unique<T>(IEnumerable<T> values) {
// HashSet is only available in .NET 3.5 and later.
var dict = new Dictionary<T, bool>();
foreach (var val in values)

View File

@ -31,11 +31,11 @@ namespace de4dot.blocks.cflow {
branchEmulator = new BranchEmulator(instructionEmulator, this);
}
protected override bool deobfuscate(Block block) {
protected override bool Deobfuscate(Block block) {
this.block = block;
if (!block.LastInstr.isConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch)
if (!block.LastInstr.IsConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch)
return false;
instructionEmulator.init(blocks);
instructionEmulator.Initialize(blocks);
var instructions = block.Instructions;
if (instructions.Count == 0)
@ -43,7 +43,7 @@ namespace de4dot.blocks.cflow {
try {
for (int i = 0; i < instructions.Count - 1; i++) {
var instr = instructions[i].Instruction;
instructionEmulator.emulate(instr);
instructionEmulator.Emulate(instr);
}
}
catch (NullReferenceException) {
@ -51,28 +51,28 @@ namespace de4dot.blocks.cflow {
return false;
}
return branchEmulator.emulate(block.LastInstr.Instruction);
return branchEmulator.Emulate(block.LastInstr.Instruction);
}
void popPushedArgs(int stackArgs) {
void PopPushedArgs(int stackArgs) {
// Pop the arguments to the bcc instruction. The dead code remover will get rid of the
// pop and any pushed arguments. Insert the pops just before the bcc instr.
for (int i = 0; i < stackArgs; i++)
block.insert(block.Instructions.Count - 1, OpCodes.Pop.ToInstruction());
block.Insert(block.Instructions.Count - 1, OpCodes.Pop.ToInstruction());
}
void IBranchHandler.handleNormal(int stackArgs, bool isTaken) {
popPushedArgs(stackArgs);
block.replaceBccWithBranch(isTaken);
void IBranchHandler.HandleNormal(int stackArgs, bool isTaken) {
PopPushedArgs(stackArgs);
block.ReplaceBccWithBranch(isTaken);
}
bool IBranchHandler.handleSwitch(Int32Value switchIndex) {
var target = CflowUtils.getSwitchTarget(block.Targets, block.FallThrough, switchIndex);
bool IBranchHandler.HandleSwitch(Int32Value switchIndex) {
var target = CflowUtils.GetSwitchTarget(block.Targets, block.FallThrough, switchIndex);
if (target == null)
return false;
popPushedArgs(1);
block.replaceSwitchWithBranch(target);
PopPushedArgs(1);
block.ReplaceSwitchWithBranch(target);
return true;
}
}

View File

@ -27,17 +27,17 @@ namespace de4dot.blocks.cflow {
public bool ExecuteOnNoChange { get; set; }
public virtual void deobfuscateBegin(Blocks blocks) {
public virtual void DeobfuscateBegin(Blocks blocks) {
this.blocks = blocks;
}
public bool deobfuscate(List<Block> allBlocks) {
init(allBlocks);
public bool Deobfuscate(List<Block> allBlocks) {
Initialize(allBlocks);
bool changed = false;
foreach (var block in allBlocks) {
try {
changed |= deobfuscate(block);
changed |= Deobfuscate(block);
}
catch (NullReferenceException) {
// Here if eg. invalid metadata token in a call instruction (operand is null)
@ -46,10 +46,10 @@ namespace de4dot.blocks.cflow {
return changed;
}
protected virtual void init(List<Block> allBlocks) {
protected virtual void Initialize(List<Block> allBlocks) {
this.allBlocks = allBlocks;
}
protected abstract bool deobfuscate(Block block);
protected abstract bool Deobfuscate(Block block);
}
}

View File

@ -28,15 +28,15 @@ namespace de4dot.blocks.cflow {
List<IBlocksDeobfuscator> ourBlocksDeobfuscators = new List<IBlocksDeobfuscator>();
public BlocksCflowDeobfuscator() {
init();
Initialize();
}
public BlocksCflowDeobfuscator(IEnumerable<IBlocksDeobfuscator> blocksDeobfuscator) {
init();
add(blocksDeobfuscator);
Initialize();
Add(blocksDeobfuscator);
}
void init() {
void Initialize() {
ourBlocksDeobfuscators.Add(new BlockCflowDeobfuscator { ExecuteOnNoChange = false });
ourBlocksDeobfuscators.Add(new SwitchCflowDeobfuscator { ExecuteOnNoChange = false });
ourBlocksDeobfuscators.Add(new DeadStoreRemover { ExecuteOnNoChange = false });
@ -46,73 +46,73 @@ namespace de4dot.blocks.cflow {
ourBlocksDeobfuscators.Add(new DupBlockCflowDeobfuscator { ExecuteOnNoChange = true });
}
public void add(IEnumerable<IBlocksDeobfuscator> blocksDeobfuscators) {
public void Add(IEnumerable<IBlocksDeobfuscator> blocksDeobfuscators) {
foreach (var bd in blocksDeobfuscators)
add(bd);
Add(bd);
}
public void add(IBlocksDeobfuscator blocksDeobfuscator) {
public void Add(IBlocksDeobfuscator blocksDeobfuscator) {
if (blocksDeobfuscator != null)
userBlocksDeobfuscators.Add(blocksDeobfuscator);
}
public void init(Blocks blocks) {
public void Initialize(Blocks blocks) {
this.blocks = blocks;
}
public void deobfuscate() {
public void Deobfuscate() {
bool changed;
int iterations = -1;
deobfuscateBegin(userBlocksDeobfuscators);
deobfuscateBegin(ourBlocksDeobfuscators);
DeobfuscateBegin(userBlocksDeobfuscators);
DeobfuscateBegin(ourBlocksDeobfuscators);
do {
iterations++;
changed = false;
removeDeadBlocks();
mergeBlocks();
RemoveDeadBlocks();
MergeBlocks();
blocks.MethodBlocks.getAllBlocks(allBlocks);
blocks.MethodBlocks.GetAllBlocks(allBlocks);
if (iterations == 0)
changed |= fixDotfuscatorLoop();
changed |= FixDotfuscatorLoop();
changed |= deobfuscate(userBlocksDeobfuscators, allBlocks);
changed |= deobfuscate(ourBlocksDeobfuscators, allBlocks);
changed |= deobfuscateNoChange(changed, userBlocksDeobfuscators, allBlocks);
changed |= deobfuscateNoChange(changed, ourBlocksDeobfuscators, allBlocks);
changed |= Deobfuscate(userBlocksDeobfuscators, allBlocks);
changed |= Deobfuscate(ourBlocksDeobfuscators, allBlocks);
changed |= DeobfuscateNoChange(changed, userBlocksDeobfuscators, allBlocks);
changed |= DeobfuscateNoChange(changed, ourBlocksDeobfuscators, allBlocks);
} while (changed);
}
void deobfuscateBegin(IEnumerable<IBlocksDeobfuscator> bds) {
void DeobfuscateBegin(IEnumerable<IBlocksDeobfuscator> bds) {
foreach (var bd in bds)
bd.deobfuscateBegin(blocks);
bd.DeobfuscateBegin(blocks);
}
bool deobfuscate(IEnumerable<IBlocksDeobfuscator> bds, List<Block> allBlocks) {
bool Deobfuscate(IEnumerable<IBlocksDeobfuscator> bds, List<Block> allBlocks) {
bool changed = false;
foreach (var bd in bds) {
if (bd.ExecuteOnNoChange)
continue;
changed |= bd.deobfuscate(allBlocks);
changed |= bd.Deobfuscate(allBlocks);
}
return changed;
}
bool deobfuscateNoChange(bool changed, IEnumerable<IBlocksDeobfuscator> bds, List<Block> allBlocks) {
bool DeobfuscateNoChange(bool changed, IEnumerable<IBlocksDeobfuscator> bds, List<Block> allBlocks) {
foreach (var bd in bds) {
if (changed)
break;
if (!bd.ExecuteOnNoChange)
continue;
changed |= bd.deobfuscate(allBlocks);
changed |= bd.Deobfuscate(allBlocks);
}
return changed;
}
// Hack for old Dotfuscator
bool fixDotfuscatorLoop() {
bool FixDotfuscatorLoop() {
/*
blk1:
...
@ -136,7 +136,7 @@ namespace de4dot.blocks.cflow {
continue;
if (instructions[1].OpCode.Code != Code.Dup)
continue;
if (!instructions[2].isLdcI4())
if (!instructions[2].IsLdcI4())
continue;
if (instructions[3].OpCode.Code != Code.Sub && instructions[3].OpCode.Code != Code.Add)
continue;
@ -148,32 +148,32 @@ namespace de4dot.blocks.cflow {
var prev = block.Sources[0];
if (prev == block)
prev = block.Sources[1];
if (prev == null || !prev.LastInstr.isLdcI4())
if (prev == null || !prev.LastInstr.IsLdcI4())
continue;
var next = block.FallThrough;
if (next.FirstInstr.OpCode.Code != Code.Pop)
continue;
block.replaceLastInstrsWithBranch(5, next);
block.ReplaceLastInstrsWithBranch(5, next);
changed = true;
}
return changed;
}
bool removeDeadBlocks() {
return new DeadBlocksRemover(blocks.MethodBlocks).remove() > 0;
bool RemoveDeadBlocks() {
return new DeadBlocksRemover(blocks.MethodBlocks).Remove() > 0;
}
bool mergeBlocks() {
bool MergeBlocks() {
bool changed = false;
foreach (var scopeBlock in getAllScopeBlocks(blocks.MethodBlocks))
changed |= scopeBlock.mergeBlocks() > 0;
foreach (var scopeBlock in GetAllScopeBlocks(blocks.MethodBlocks))
changed |= scopeBlock.MergeBlocks() > 0;
return changed;
}
IEnumerable<ScopeBlock> getAllScopeBlocks(ScopeBlock scopeBlock) {
IEnumerable<ScopeBlock> GetAllScopeBlocks(ScopeBlock scopeBlock) {
var list = new List<ScopeBlock>();
list.Add(scopeBlock);
list.AddRange(scopeBlock.getAllScopeBlocks());
list.AddRange(scopeBlock.GetAllScopeBlocks());
return list;
}
}

View File

@ -22,10 +22,10 @@ using dnlib.DotNet.Emit;
namespace de4dot.blocks.cflow {
public interface IBranchHandler {
// stackArgs is the number of args used by the branch instruction (1 or 2)
void handleNormal(int stackArgs, bool isTaken);
void HandleNormal(int stackArgs, bool isTaken);
// Returns true if the switch target was found (even if it was the fall-through)
bool handleSwitch(Int32Value switchIndex);
bool HandleSwitch(Int32Value switchIndex);
}
public class BranchEmulator {
@ -37,216 +37,216 @@ namespace de4dot.blocks.cflow {
this.branchHandler = branchHandler;
}
public bool emulate(Instruction instr) {
public bool Emulate(Instruction instr) {
switch (instr.OpCode.Code) {
case Code.Br:
case Code.Br_S: return emulate_Br();
case Code.Br_S: return Emulate_Br();
case Code.Beq:
case Code.Beq_S: return emulate_Beq();
case Code.Beq_S: return Emulate_Beq();
case Code.Bge:
case Code.Bge_S: return emulate_Bge();
case Code.Bge_S: return Emulate_Bge();
case Code.Bge_Un:
case Code.Bge_Un_S: return emulate_Bge_Un();
case Code.Bge_Un_S: return Emulate_Bge_Un();
case Code.Bgt:
case Code.Bgt_S: return emulate_Bgt();
case Code.Bgt_S: return Emulate_Bgt();
case Code.Bgt_Un:
case Code.Bgt_Un_S: return emulate_Bgt_Un();
case Code.Bgt_Un_S: return Emulate_Bgt_Un();
case Code.Ble:
case Code.Ble_S: return emulate_Ble();
case Code.Ble_S: return Emulate_Ble();
case Code.Ble_Un:
case Code.Ble_Un_S: return emulate_Ble_Un();
case Code.Ble_Un_S: return Emulate_Ble_Un();
case Code.Blt:
case Code.Blt_S: return emulate_Blt();
case Code.Blt_S: return Emulate_Blt();
case Code.Blt_Un:
case Code.Blt_Un_S: return emulate_Blt_Un();
case Code.Blt_Un_S: return Emulate_Blt_Un();
case Code.Bne_Un:
case Code.Bne_Un_S: return emulate_Bne_Un();
case Code.Bne_Un_S: return Emulate_Bne_Un();
case Code.Brfalse:
case Code.Brfalse_S:return emulate_Brfalse();
case Code.Brfalse_S:return Emulate_Brfalse();
case Code.Brtrue:
case Code.Brtrue_S: return emulate_Brtrue();
case Code.Switch: return emulate_Switch();
case Code.Brtrue_S: return Emulate_Brtrue();
case Code.Switch: return Emulate_Switch();
default:
return false;
}
}
bool emulateBranch(int stackArgs, Bool3 cond) {
bool EmulateBranch(int stackArgs, Bool3 cond) {
if (cond == Bool3.Unknown)
return false;
return emulateBranch(stackArgs, cond == Bool3.True);
return EmulateBranch(stackArgs, cond == Bool3.True);
}
bool emulateBranch(int stackArgs, bool isTaken) {
branchHandler.handleNormal(stackArgs, isTaken);
bool EmulateBranch(int stackArgs, bool isTaken) {
branchHandler.HandleNormal(stackArgs, isTaken);
return true;
}
bool emulate_Br() {
return emulateBranch(0, true);
bool Emulate_Br() {
return EmulateBranch(0, true);
}
bool emulate_Beq() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Beq() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareEq((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareEq((Int64Value)val1, (Int64Value)val2));
else if (val1.isNull() && val2.isNull())
return emulateBranch(2, true);
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareEq((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareEq((Int64Value)val1, (Int64Value)val2));
else if (val1.IsNull() && val2.IsNull())
return EmulateBranch(2, true);
else
return false;
}
bool emulate_Bne_Un() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Bne_Un() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareNeq((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareNeq((Int64Value)val1, (Int64Value)val2));
else if (val1.isNull() && val2.isNull())
return emulateBranch(2, false);
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareNeq((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareNeq((Int64Value)val1, (Int64Value)val2));
else if (val1.IsNull() && val2.IsNull())
return EmulateBranch(2, false);
else
return false;
}
bool emulate_Bge() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Bge() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareGe((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareGe((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareGe((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareGe((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Bge_Un() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Bge_Un() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareGe_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareGe_Un((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareGe_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareGe_Un((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Bgt() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Bgt() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareGt((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareGt((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareGt((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareGt((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Bgt_Un() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Bgt_Un() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareGt_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareGt_Un((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareGt_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareGt_Un((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Ble() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Ble() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareLe((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareLe((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareLe((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareLe((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Ble_Un() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Ble_Un() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareLe_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareLe_Un((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareLe_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareLe_Un((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Blt() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Blt() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareLt((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareLt((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareLt((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareLt((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Blt_Un() {
var val2 = instructionEmulator.pop();
var val1 = instructionEmulator.pop();
bool Emulate_Blt_Un() {
var val2 = instructionEmulator.Pop();
var val1 = instructionEmulator.Pop();
if (val1.isInt32() && val2.isInt32())
return emulateBranch(2, Int32Value.compareLt_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.isInt64() && val2.isInt64())
return emulateBranch(2, Int64Value.compareLt_Un((Int64Value)val1, (Int64Value)val2));
if (val1.IsInt32() && val2.IsInt32())
return EmulateBranch(2, Int32Value.CompareLt_Un((Int32Value)val1, (Int32Value)val2));
else if (val1.IsInt64() && val2.IsInt64())
return EmulateBranch(2, Int64Value.CompareLt_Un((Int64Value)val1, (Int64Value)val2));
else
return false;
}
bool emulate_Brfalse() {
var val1 = instructionEmulator.pop();
bool Emulate_Brfalse() {
var val1 = instructionEmulator.Pop();
if (val1.isInt32())
return emulateBranch(1, Int32Value.compareFalse((Int32Value)val1));
else if (val1.isInt64())
return emulateBranch(1, Int64Value.compareFalse((Int64Value)val1));
else if (val1.isNull())
return emulateBranch(1, true);
else if (val1.isObject() || val1.isString())
return emulateBranch(1, false);
if (val1.IsInt32())
return EmulateBranch(1, Int32Value.CompareFalse((Int32Value)val1));
else if (val1.IsInt64())
return EmulateBranch(1, Int64Value.CompareFalse((Int64Value)val1));
else if (val1.IsNull())
return EmulateBranch(1, true);
else if (val1.IsObject() || val1.IsString())
return EmulateBranch(1, false);
else
return false;
}
bool emulate_Brtrue() {
var val1 = instructionEmulator.pop();
bool Emulate_Brtrue() {
var val1 = instructionEmulator.Pop();
if (val1.isInt32())
return emulateBranch(1, Int32Value.compareTrue((Int32Value)val1));
else if (val1.isInt64())
return emulateBranch(1, Int64Value.compareTrue((Int64Value)val1));
else if (val1.isNull())
return emulateBranch(1, false);
else if (val1.isObject() || val1.isString())
return emulateBranch(1, true);
if (val1.IsInt32())
return EmulateBranch(1, Int32Value.CompareTrue((Int32Value)val1));
else if (val1.IsInt64())
return EmulateBranch(1, Int64Value.CompareTrue((Int64Value)val1));
else if (val1.IsNull())
return EmulateBranch(1, false);
else if (val1.IsObject() || val1.IsString())
return EmulateBranch(1, true);
else
return false;
}
bool emulate_Switch() {
var val1 = instructionEmulator.pop();
bool Emulate_Switch() {
var val1 = instructionEmulator.Pop();
if (!val1.isInt32())
if (!val1.IsInt32())
return false;
return branchHandler.handleSwitch((Int32Value)val1);
return branchHandler.HandleSwitch((Int32Value)val1);
}
}
}

View File

@ -31,19 +31,19 @@ namespace de4dot.blocks.cflow {
}
public CachedCflowDeobfuscator(IEnumerable<IBlocksDeobfuscator> blocksDeobfuscators) {
add(blocksDeobfuscators);
Add(blocksDeobfuscators);
}
public void add(IEnumerable<IBlocksDeobfuscator> blocksDeobfuscators) {
public void Add(IEnumerable<IBlocksDeobfuscator> blocksDeobfuscators) {
foreach (var bd in blocksDeobfuscators)
cflowDeobfuscator.add(bd);
cflowDeobfuscator.Add(bd);
}
public void add(IBlocksDeobfuscator blocksDeobfuscator) {
cflowDeobfuscator.add(blocksDeobfuscator);
public void Add(IBlocksDeobfuscator blocksDeobfuscator) {
cflowDeobfuscator.Add(blocksDeobfuscator);
}
public MethodDef deobfuscate(MethodDef method) {
public MethodDef Deobfuscate(MethodDef method) {
MethodDef deobfuscatedMethod;
if (deobfuscated.TryGetValue(method, out deobfuscatedMethod))
return deobfuscatedMethod;
@ -53,22 +53,22 @@ namespace de4dot.blocks.cflow {
return method;
}
deobfuscatedMethod = DotNetUtils.clone(method);
deobfuscatedMethod = DotNetUtils.Clone(method);
deobfuscated[method] = deobfuscatedMethod;
var blocks = new Blocks(deobfuscatedMethod);
deobfuscate(blocks);
Deobfuscate(blocks);
IList<Instruction> allInstructions;
IList<ExceptionHandler> allExceptionHandlers;
blocks.getCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.restoreBody(deobfuscatedMethod, allInstructions, allExceptionHandlers);
blocks.GetCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.RestoreBody(deobfuscatedMethod, allInstructions, allExceptionHandlers);
return deobfuscatedMethod;
}
void deobfuscate(Blocks blocks) {
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
void Deobfuscate(Blocks blocks) {
cflowDeobfuscator.Initialize(blocks);
cflowDeobfuscator.Deobfuscate();
}
}
}

View File

@ -29,30 +29,30 @@ namespace de4dot.blocks.cflow {
}
public CflowDeobfuscator(IBlocksDeobfuscator blocksDeobfuscator) {
cflowDeobfuscator.add(blocksDeobfuscator);
cflowDeobfuscator.Add(blocksDeobfuscator);
}
public void deobfuscate(MethodDef method) {
deobfuscate(method, (blocks) => {
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
public void Deobfuscate(MethodDef method) {
Deobfuscate(method, (blocks) => {
cflowDeobfuscator.Initialize(blocks);
cflowDeobfuscator.Deobfuscate();
});
}
static bool hasNonEmptyBody(MethodDef method) {
static bool HasNonEmptyBody(MethodDef method) {
return method.Body != null && method.Body.Instructions.Count > 0;
}
void deobfuscate(MethodDef method, Action<Blocks> handler) {
if (hasNonEmptyBody(method)) {
void Deobfuscate(MethodDef method, Action<Blocks> handler) {
if (HasNonEmptyBody(method)) {
var blocks = new Blocks(method);
handler(blocks);
IList<Instruction> allInstructions;
IList<ExceptionHandler> allExceptionHandlers;
blocks.getCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
blocks.GetCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers);
}
}
}

View File

@ -21,8 +21,8 @@ using System.Collections.Generic;
namespace de4dot.blocks.cflow {
static class CflowUtils {
public static Block getSwitchTarget(IList<Block> targets, Block fallThrough, Int32Value intValue) {
if (!intValue.allBitsValid())
public static Block GetSwitchTarget(IList<Block> targets, Block fallThrough, Int32Value intValue) {
if (!intValue.AllBitsValid())
return null;
int index = intValue.value;

View File

@ -29,15 +29,15 @@ namespace de4dot.blocks.cflow {
InstructionEmulator instructionEmulator = new InstructionEmulator();
IList<Parameter> args;
protected override void init(List<Block> allBlocks) {
base.init(allBlocks);
protected override void Initialize(List<Block> allBlocks) {
base.Initialize(allBlocks);
args = blocks.Method.Parameters;
}
protected override bool deobfuscate(Block block) {
protected override bool Deobfuscate(Block block) {
bool changed = false;
instructionEmulator.init(blocks);
instructionEmulator.Initialize(blocks);
var instrs = block.Instructions;
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
@ -49,7 +49,7 @@ namespace de4dot.blocks.cflow {
case Code.Ldarg_2:
case Code.Ldarg_3:
case Code.Ldarg_S:
changed |= fixLoadInstruction(block, i, instructionEmulator.getArg(instr.Instruction.GetParameter(args)));
changed |= FixLoadInstruction(block, i, instructionEmulator.GetArg(instr.Instruction.GetParameter(args)));
break;
case Code.Ldloc:
@ -58,22 +58,22 @@ namespace de4dot.blocks.cflow {
case Code.Ldloc_2:
case Code.Ldloc_3:
case Code.Ldloc_S:
changed |= fixLoadInstruction(block, i, instructionEmulator.getLocal(instr.Instruction.GetLocal(blocks.Locals)));
changed |= FixLoadInstruction(block, i, instructionEmulator.GetLocal(instr.Instruction.GetLocal(blocks.Locals)));
break;
case Code.Ldarga:
case Code.Ldarga_S:
instructionEmulator.makeArgUnknown((Parameter)instr.Operand);
instructionEmulator.MakeArgUnknown((Parameter)instr.Operand);
break;
case Code.Ldloca:
case Code.Ldloca_S:
instructionEmulator.makeLocalUnknown((Local)instr.Operand);
instructionEmulator.MakeLocalUnknown((Local)instr.Operand);
break;
}
try {
instructionEmulator.emulate(instr.Instruction);
instructionEmulator.Emulate(instr.Instruction);
}
catch (NullReferenceException) {
// Here if eg. invalid metadata token in a call instruction (operand is null)
@ -84,17 +84,17 @@ namespace de4dot.blocks.cflow {
return changed;
}
bool fixLoadInstruction(Block block, int index, Value value) {
if (value.isInt32()) {
bool FixLoadInstruction(Block block, int index, Value value) {
if (value.IsInt32()) {
var intValue = (Int32Value)value;
if (!intValue.allBitsValid())
if (!intValue.AllBitsValid())
return false;
block.Instructions[index] = new Instr(Instruction.CreateLdcI4(intValue.value));
return true;
}
else if (value.isInt64()) {
else if (value.IsInt64()) {
var intValue = (Int64Value)value;
if (!intValue.allBitsValid())
if (!intValue.AllBitsValid())
return false;
block.Instructions[index] = new Instr(OpCodes.Ldc_I8.ToInstruction(intValue.value));
return true;

View File

@ -27,7 +27,7 @@ namespace de4dot.blocks.cflow {
List<int> allDeadInstructions = new List<int>();
InstructionExpressionFinder instructionExpressionFinder = new InstructionExpressionFinder();
protected override bool deobfuscate(Block block) {
protected override bool Deobfuscate(Block block) {
allDeadInstructions.Clear();
bool changed = false;
@ -56,10 +56,10 @@ namespace de4dot.blocks.cflow {
case Code.Leave_S:
case Code.Endfinally:
case Code.Pop:
instructionExpressionFinder.init(block, false);
if (!instructionExpressionFinder.find(i))
instructionExpressionFinder.Initialize(block, false);
if (!instructionExpressionFinder.Find(i))
continue;
if (!okInstructions(block, instructionExpressionFinder.DeadInstructions))
if (!OkInstructions(block, instructionExpressionFinder.DeadInstructions))
continue;
allDeadInstructions.AddRange(instructionExpressionFinder.DeadInstructions);
break;
@ -70,14 +70,14 @@ namespace de4dot.blocks.cflow {
}
if (allDeadInstructions.Count > 0) {
block.remove(allDeadInstructions);
block.Remove(allDeadInstructions);
changed = true;
}
return changed;
}
bool okInstructions(Block block, IEnumerable<int> indexes) {
bool OkInstructions(Block block, IEnumerable<int> indexes) {
foreach (var index in indexes) {
var instr = block.Instructions[index];
switch (instr.OpCode.Code) {
@ -318,27 +318,27 @@ namespace de4dot.blocks.cflow {
get { return deadInstructions; }
}
public void init(Block block, bool methodHasReturnValue) {
public void Initialize(Block block, bool methodHasReturnValue) {
deadInstructions.Clear();
this.block = block;
this.methodHasReturnValue = methodHasReturnValue;
}
public bool find(int index) {
return find(ref index, true);
public bool Find(int index) {
return Find(ref index, true);
}
bool find(ref int index, bool addIt) {
bool Find(ref int index, bool addIt) {
if (index < 0)
return false;
var startInstr = block.Instructions[index];
int startInstrPushes, startInstrPops;
calculateStackUsage(startInstr.Instruction, false, out startInstrPushes, out startInstrPops);
CalculateStackUsage(startInstr.Instruction, false, out startInstrPushes, out startInstrPops);
// Don't add it if it clears the stack (eg. leave)
if (addIt && startInstrPops >= 0)
addIndex(index);
AddIndex(index);
if (startInstrPops == 0)
return true;
@ -349,19 +349,19 @@ namespace de4dot.blocks.cflow {
break;
int pushes, pops;
calculateStackUsage(instr.Instruction, methodHasReturnValue, out pushes, out pops);
CalculateStackUsage(instr.Instruction, methodHasReturnValue, out pushes, out pops);
if (pops < 0)
break; // eg. leave
index--;
if (pops > 0) { // if instr uses any args
bool otherExpr = pops > 0 && pushes == 0;
if (!find(ref index, addIt && !otherExpr))
if (!Find(ref index, addIt && !otherExpr))
break;
}
else if (pushes != 0 || pops != 0) {
if (addIt)
addIndex(index);
AddIndex(index);
}
if (pushes > 0 && startInstrPops >= 0) {
if (pushes > startInstrPops)
@ -373,12 +373,12 @@ namespace de4dot.blocks.cflow {
return startInstrPops <= 0;
}
void addIndex(int index) {
void AddIndex(int index) {
deadInstructions.Add(index);
}
}
static void calculateStackUsage(Instruction instr, bool methodHasReturnValue, out int pushes, out int pops) {
static void CalculateStackUsage(Instruction instr, bool methodHasReturnValue, out int pushes, out int pops) {
instr.CalculateStackUsage(false, out pushes, out pops);
}
}

View File

@ -41,16 +41,16 @@ namespace de4dot.blocks.cflow {
public bool ExecuteOnNoChange { get; set; }
public void deobfuscateBegin(Blocks blocks) {
public void DeobfuscateBegin(Blocks blocks) {
this.blocks = blocks;
}
public bool deobfuscate(List<Block> allBlocks) {
public bool Deobfuscate(List<Block> allBlocks) {
this.allBlocks = allBlocks;
return remove();
return Remove();
}
bool remove() {
bool Remove() {
if (blocks.Locals.Count == 0)
return false;
@ -61,7 +61,7 @@ namespace de4dot.blocks.cflow {
deadLocals.Add(false);
}
findLoadStores();
FindLoadStores();
bool deadStores = false;
for (int i = 0; i < blocks.Locals.Count; i++) {
@ -74,10 +74,10 @@ namespace de4dot.blocks.cflow {
if (!deadStores)
return false;
return removeDeadStores();
return RemoveDeadStores();
}
void findLoadStores() {
void FindLoadStores() {
foreach (var block in allBlocks) {
foreach (var instr in block.Instructions) {
Local local;
@ -89,7 +89,7 @@ namespace de4dot.blocks.cflow {
case Code.Ldloc_1:
case Code.Ldloc_2:
case Code.Ldloc_3:
local = Instr.getLocalVar(blocks.Locals, instr);
local = Instr.GetLocalVar(blocks.Locals, instr);
flags = AccessFlags.Read;
break;
@ -99,7 +99,7 @@ namespace de4dot.blocks.cflow {
case Code.Stloc_1:
case Code.Stloc_2:
case Code.Stloc_3:
local = Instr.getLocalVar(blocks.Locals, instr);
local = Instr.GetLocalVar(blocks.Locals, instr);
flags = AccessFlags.Write;
break;
@ -122,7 +122,7 @@ namespace de4dot.blocks.cflow {
}
}
bool removeDeadStores() {
bool RemoveDeadStores() {
bool changed = false;
foreach (var block in allBlocks) {
var instructions = block.Instructions;
@ -136,7 +136,7 @@ namespace de4dot.blocks.cflow {
case Code.Stloc_1:
case Code.Stloc_2:
case Code.Stloc_3:
local = Instr.getLocalVar(blocks.Locals, instr);
local = Instr.GetLocalVar(blocks.Locals, instr);
break;
default:

View File

@ -25,22 +25,22 @@ namespace de4dot.blocks.cflow {
// If a block is just a dup followed by a bcc, try to append the block
// to all its sources. Will fix some SA assemblies.
class DupBlockCflowDeobfuscator : BlockDeobfuscator {
protected override bool deobfuscate(Block block) {
protected override bool Deobfuscate(Block block) {
if (block.Instructions.Count != 2)
return false;
if (block.Instructions[0].OpCode.Code != Code.Dup)
return false;
if (!block.LastInstr.isConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch)
if (!block.LastInstr.IsConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch)
return false;
bool modified = false;
foreach (var source in new List<Block>(block.Sources)) {
if (source.getOnlyTarget() != block)
if (source.GetOnlyTarget() != block)
continue;
if (!source.canAppend(block))
if (!source.CanAppend(block))
continue;
source.append(block);
source.Append(block);
modified = true;
}
return modified;

View File

@ -23,9 +23,9 @@ namespace de4dot.blocks.cflow {
public interface IBlocksDeobfuscator {
bool ExecuteOnNoChange { get; }
void deobfuscateBegin(Blocks blocks);
void DeobfuscateBegin(Blocks blocks);
// Returns true if something was updated
bool deobfuscate(List<Block> allBlocks);
bool Deobfuscate(List<Block> allBlocks);
}
}

View File

@ -21,6 +21,6 @@ using dnlib.DotNet;
namespace de4dot.blocks.cflow {
public interface ICflowDeobfuscator {
void deobfuscate(MethodDef method);
void Deobfuscate(MethodDef method);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -40,75 +40,75 @@ namespace de4dot.blocks.cflow {
this.validMask = validMask;
}
public bool hasUnknownBits() {
public bool HasUnknownBits() {
return validMask != NO_UNKNOWN_BITS;
}
public bool allBitsValid() {
return !hasUnknownBits();
public bool AllBitsValid() {
return !HasUnknownBits();
}
bool isBitValid(int n) {
return isBitValid(validMask, n);
bool IsBitValid(int n) {
return IsBitValid(validMask, n);
}
static bool isBitValid(uint validMask, int n) {
static bool IsBitValid(uint validMask, int n) {
return (validMask & (1U << n)) != 0;
}
public static Int32Value createUnknownBool() {
public static Int32Value CreateUnknownBool() {
return new Int32Value(0, NO_UNKNOWN_BITS << 1);
}
public static Int32Value createUnknownUInt8() {
public static Int32Value CreateUnknownUInt8() {
return new Int32Value(0, NO_UNKNOWN_BITS << 8);
}
public static Int32Value createUnknownUInt16() {
public static Int32Value CreateUnknownUInt16() {
return new Int32Value(0, NO_UNKNOWN_BITS << 16);
}
public static Int32Value createUnknown() {
public static Int32Value CreateUnknown() {
return new Int32Value(0, 0U);
}
public bool isZero() {
return hasValue(0);
public bool IsZero() {
return HasValue(0);
}
public bool isNonZero() {
public bool IsNonZero() {
return (value & validMask) != 0;
}
public bool hasValue(int value) {
return allBitsValid() && this.value == value;
public bool HasValue(int value) {
return AllBitsValid() && this.value == value;
}
public bool hasValue(uint value) {
return hasValue((int)value);
public bool HasValue(uint value) {
return HasValue((int)value);
}
public Int32Value toBoolean() {
if (isNonZero())
public Int32Value ToBoolean() {
if (IsNonZero())
return new Int32Value(1, NO_UNKNOWN_BITS);
if (isZero())
if (IsZero())
return this;
return createUnknownBool();
return CreateUnknownBool();
}
public Int32Value toInt8() {
public Int32Value ToInt8() {
return Conv_I1(this);
}
public Int32Value toUInt8() {
public Int32Value ToUInt8() {
return Conv_U1(this);
}
public Int32Value toInt16() {
public Int32Value ToInt16() {
return Conv_I2(this);
}
public Int32Value toUInt16() {
public Int32Value ToUInt16() {
return Conv_U2(this);
}
@ -140,7 +140,7 @@ namespace de4dot.blocks.cflow {
public static Int32Value Conv_I1(int value, uint validMask) {
value = (int)(sbyte)value;
if (isBitValid(validMask, 7))
if (IsBitValid(validMask, 7))
validMask |= NO_UNKNOWN_BITS << 8;
else
validMask &= ~(NO_UNKNOWN_BITS << 8);
@ -179,7 +179,7 @@ namespace de4dot.blocks.cflow {
public static Int32Value Conv_I2(int value, uint validMask) {
value = (int)(short)value;
if (isBitValid(validMask, 15))
if (IsBitValid(validMask, 15))
validMask |= NO_UNKNOWN_BITS << 16;
else
validMask &= ~(NO_UNKNOWN_BITS << 16);
@ -215,97 +215,97 @@ namespace de4dot.blocks.cflow {
}
public static Int32Value Add(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
if (a.AllBitsValid() && b.AllBitsValid())
return new Int32Value(a.value + b.value);
if (ReferenceEquals(a, b))
return new Int32Value(a.value << 1, (a.validMask << 1) | 1);
return createUnknown();
return CreateUnknown();
}
public static Int32Value Sub(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
if (a.AllBitsValid() && b.AllBitsValid())
return new Int32Value(a.value - b.value);
if (ReferenceEquals(a, b))
return zero;
return createUnknown();
return CreateUnknown();
}
public static Int32Value Mul(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
if (a.AllBitsValid() && b.AllBitsValid())
return new Int32Value(a.value * b.value);
if (a.isZero() || b.isZero())
if (a.IsZero() || b.IsZero())
return zero;
if (a.hasValue(1))
if (a.HasValue(1))
return b;
if (b.hasValue(1))
if (b.HasValue(1))
return a;
return createUnknown();
return CreateUnknown();
}
public static Int32Value Div(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int32Value(a.value / b.value);
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if (ReferenceEquals(a, b) && a.isNonZero())
if (ReferenceEquals(a, b) && a.IsNonZero())
return one;
if (b.hasValue(1))
if (b.HasValue(1))
return a;
return createUnknown();
return CreateUnknown();
}
public static Int32Value Div_Un(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int32Value((int)((uint)a.value / (uint)b.value));
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if (ReferenceEquals(a, b) && a.isNonZero())
if (ReferenceEquals(a, b) && a.IsNonZero())
return one;
if (b.hasValue(1))
if (b.HasValue(1))
return a;
return createUnknown();
return CreateUnknown();
}
public static Int32Value Rem(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int32Value(a.value % b.value);
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if ((ReferenceEquals(a, b) && a.isNonZero()) || b.hasValue(1))
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
return zero;
return createUnknown();
return CreateUnknown();
}
public static Int32Value Rem_Un(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int32Value((int)((uint)a.value % (uint)b.value));
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if ((ReferenceEquals(a, b) && a.isNonZero()) || b.hasValue(1))
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
return zero;
return createUnknown();
return CreateUnknown();
}
public static Int32Value Neg(Int32Value a) {
if (a.allBitsValid())
if (a.AllBitsValid())
return new Int32Value(-a.value);
return createUnknown();
return CreateUnknown();
}
public static Int32Value And(Int32Value a, Int32Value b) {
@ -333,38 +333,38 @@ namespace de4dot.blocks.cflow {
}
public static Int32Value Shl(Int32Value a, Int32Value b) {
if (b.hasUnknownBits())
return createUnknown();
if (b.HasUnknownBits())
return CreateUnknown();
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(int) * 8)
return createUnknown();
return CreateUnknown();
int shift = b.value;
uint validMask = (a.validMask << shift) | (uint.MaxValue >> (sizeof(int) * 8 - shift));
return new Int32Value(a.value << shift, validMask);
}
public static Int32Value Shr(Int32Value a, Int32Value b) {
if (b.hasUnknownBits())
return createUnknown();
if (b.HasUnknownBits())
return CreateUnknown();
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(int) * 8)
return createUnknown();
return CreateUnknown();
int shift = b.value;
uint validMask = a.validMask >> shift;
if (a.isBitValid(sizeof(int) * 8 - 1))
if (a.IsBitValid(sizeof(int) * 8 - 1))
validMask |= (uint.MaxValue << (sizeof(int) * 8 - shift));
return new Int32Value(a.value >> shift, validMask);
}
public static Int32Value Shr_Un(Int32Value a, Int32Value b) {
if (b.hasUnknownBits())
return createUnknown();
if (b.HasUnknownBits())
return CreateUnknown();
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(int) * 8)
return createUnknown();
return CreateUnknown();
int shift = b.value;
uint validMask = (a.validMask >> shift) | (uint.MaxValue << (sizeof(int) * 8 - shift));
return new Int32Value((int)((uint)a.value >> shift), validMask);
@ -374,32 +374,32 @@ namespace de4dot.blocks.cflow {
switch (b) {
case Bool3.False: return zero;
case Bool3.True: return one;
default: return createUnknownBool();
default: return CreateUnknownBool();
}
}
public static Int32Value Ceq(Int32Value a, Int32Value b) {
return create(compareEq(a, b));
return create(CompareEq(a, b));
}
public static Int32Value Cgt(Int32Value a, Int32Value b) {
return create(compareGt(a, b));
return create(CompareGt(a, b));
}
public static Int32Value Cgt_Un(Int32Value a, Int32Value b) {
return create(compareGt_Un(a, b));
return create(CompareGt_Un(a, b));
}
public static Int32Value Clt(Int32Value a, Int32Value b) {
return create(compareLt(a, b));
return create(CompareLt(a, b));
}
public static Int32Value Clt_Un(Int32Value a, Int32Value b) {
return create(compareLt_Un(a, b));
return create(CompareLt_Un(a, b));
}
public static Bool3 compareEq(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareEq(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value == b.value ? Bool3.True : Bool3.False;
if (ReferenceEquals(a, b))
return Bool3.True;
@ -408,8 +408,8 @@ namespace de4dot.blocks.cflow {
return Bool3.Unknown;
}
public static Bool3 compareNeq(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareNeq(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value != b.value ? Bool3.True : Bool3.False;
if (ReferenceEquals(a, b))
return Bool3.False;
@ -418,96 +418,96 @@ namespace de4dot.blocks.cflow {
return Bool3.Unknown;
}
public static Bool3 compareGt(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGt(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value > b.value ? Bool3.True : Bool3.False;
if (a.hasValue(int.MinValue))
if (a.HasValue(int.MinValue))
return Bool3.False; // min > x => false
if (b.hasValue(int.MaxValue))
if (b.HasValue(int.MaxValue))
return Bool3.False; // x > max => false
return Bool3.Unknown;
}
public static Bool3 compareGt_Un(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGt_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (uint)a.value > (uint)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(uint.MinValue))
if (a.HasValue(uint.MinValue))
return Bool3.False; // min > x => false
if (b.hasValue(uint.MaxValue))
if (b.HasValue(uint.MaxValue))
return Bool3.False; // x > max => false
return Bool3.Unknown;
}
public static Bool3 compareGe(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGe(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value >= b.value ? Bool3.True : Bool3.False;
if (a.hasValue(int.MaxValue))
if (a.HasValue(int.MaxValue))
return Bool3.True; // max >= x => true
if (b.hasValue(int.MinValue))
if (b.HasValue(int.MinValue))
return Bool3.True; // x >= min => true
return Bool3.Unknown;
}
public static Bool3 compareGe_Un(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGe_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (uint)a.value >= (uint)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(uint.MaxValue))
if (a.HasValue(uint.MaxValue))
return Bool3.True; // max >= x => true
if (b.hasValue(uint.MinValue))
if (b.HasValue(uint.MinValue))
return Bool3.True; // x >= min => true
return Bool3.Unknown;
}
public static Bool3 compareLe(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLe(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value <= b.value ? Bool3.True : Bool3.False;
if (a.hasValue(int.MinValue))
if (a.HasValue(int.MinValue))
return Bool3.True; // min <= x => true
if (b.hasValue(int.MaxValue))
if (b.HasValue(int.MaxValue))
return Bool3.True; // x <= max => true
return Bool3.Unknown;
}
public static Bool3 compareLe_Un(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLe_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (uint)a.value <= (uint)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(uint.MinValue))
if (a.HasValue(uint.MinValue))
return Bool3.True; // min <= x => true
if (b.hasValue(uint.MaxValue))
if (b.HasValue(uint.MaxValue))
return Bool3.True; // x <= max => true
return Bool3.Unknown;
}
public static Bool3 compareLt(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLt(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value < b.value ? Bool3.True : Bool3.False;
if (a.hasValue(int.MaxValue))
if (a.HasValue(int.MaxValue))
return Bool3.False; // max < x => false
if (b.hasValue(int.MinValue))
if (b.HasValue(int.MinValue))
return Bool3.False; // x < min => false
return Bool3.Unknown;
}
public static Bool3 compareLt_Un(Int32Value a, Int32Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLt_Un(Int32Value a, Int32Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (uint)a.value < (uint)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(uint.MaxValue))
if (a.HasValue(uint.MaxValue))
return Bool3.False; // max < x => false
if (b.hasValue(uint.MinValue))
if (b.HasValue(uint.MinValue))
return Bool3.False; // x < min => false
return Bool3.Unknown;
}
public static Bool3 compareTrue(Int32Value a) {
if (a.allBitsValid())
public static Bool3 CompareTrue(Int32Value a) {
if (a.AllBitsValid())
return a.value != 0 ? Bool3.True : Bool3.False;
if ((a.value & a.validMask) != 0)
return Bool3.True;
return Bool3.Unknown;
}
public static Bool3 compareFalse(Int32Value a) {
if (a.allBitsValid())
public static Bool3 CompareFalse(Int32Value a) {
if (a.AllBitsValid())
return a.value == 0 ? Bool3.True : Bool3.False;
if ((a.value & a.validMask) != 0)
return Bool3.False;
@ -515,7 +515,7 @@ namespace de4dot.blocks.cflow {
}
public override string ToString() {
if (allBitsValid())
if (AllBitsValid())
return value.ToString();
return string.Format("0x{0:X8}({1:X8})", value, validMask);
}

View File

@ -40,40 +40,40 @@ namespace de4dot.blocks.cflow {
this.validMask = validMask;
}
bool hasUnknownBits() {
bool HasUnknownBits() {
return validMask != NO_UNKNOWN_BITS;
}
public bool allBitsValid() {
return !hasUnknownBits();
public bool AllBitsValid() {
return !HasUnknownBits();
}
bool isBitValid(int n) {
return isBitValid(validMask, n);
bool IsBitValid(int n) {
return IsBitValid(validMask, n);
}
static bool isBitValid(ulong validMask, int n) {
static bool IsBitValid(ulong validMask, int n) {
return (validMask & (1UL << n)) != 0;
}
public static Int64Value createUnknown() {
public static Int64Value CreateUnknown() {
return new Int64Value(0, 0UL);
}
public bool isZero() {
return hasValue(0);
public bool IsZero() {
return HasValue(0);
}
public bool isNonZero() {
public bool IsNonZero() {
return ((ulong)value & validMask) != 0;
}
public bool hasValue(long value) {
return allBitsValid() && this.value == value;
public bool HasValue(long value) {
return AllBitsValid() && this.value == value;
}
public bool hasValue(ulong value) {
return hasValue((long)value);
public bool HasValue(ulong value) {
return HasValue((long)value);
}
public static Int64Value Conv_U8(Int32Value a) {
@ -93,7 +93,7 @@ namespace de4dot.blocks.cflow {
public static Int64Value Conv_I8(Int32Value a) {
long value = a.value;
ulong validMask = a.validMask;
if (isBitValid(validMask, 31))
if (IsBitValid(validMask, 31))
validMask |= NO_UNKNOWN_BITS << 32;
else
validMask &= ~(NO_UNKNOWN_BITS << 32);
@ -109,97 +109,97 @@ namespace de4dot.blocks.cflow {
}
public static Int64Value Add(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
if (a.AllBitsValid() && b.AllBitsValid())
return new Int64Value(a.value + b.value);
if (ReferenceEquals(a, b))
return new Int64Value(a.value << 1, (a.validMask << 1) | 1);
return createUnknown();
return CreateUnknown();
}
public static Int64Value Sub(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
if (a.AllBitsValid() && b.AllBitsValid())
return new Int64Value(a.value - b.value);
if (ReferenceEquals(a, b))
return zero;
return createUnknown();
return CreateUnknown();
}
public static Int64Value Mul(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
if (a.AllBitsValid() && b.AllBitsValid())
return new Int64Value(a.value * b.value);
if (a.isZero() || b.isZero())
if (a.IsZero() || b.IsZero())
return zero;
if (a.hasValue(1))
if (a.HasValue(1))
return b;
if (b.hasValue(1))
if (b.HasValue(1))
return a;
return createUnknown();
return CreateUnknown();
}
public static Int64Value Div(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int64Value(a.value / b.value);
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if (ReferenceEquals(a, b) && a.isNonZero())
if (ReferenceEquals(a, b) && a.IsNonZero())
return one;
if (b.hasValue(1))
if (b.HasValue(1))
return a;
return createUnknown();
return CreateUnknown();
}
public static Int64Value Div_Un(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int64Value((long)((ulong)a.value / (ulong)b.value));
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if (ReferenceEquals(a, b) && a.isNonZero())
if (ReferenceEquals(a, b) && a.IsNonZero())
return one;
if (b.hasValue(1))
if (b.HasValue(1))
return a;
return createUnknown();
return CreateUnknown();
}
public static Int64Value Rem(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int64Value(a.value % b.value);
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if ((ReferenceEquals(a, b) && a.isNonZero()) || b.hasValue(1))
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
return zero;
return createUnknown();
return CreateUnknown();
}
public static Int64Value Rem_Un(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid()) {
if (a.AllBitsValid() && b.AllBitsValid()) {
try {
return new Int64Value((long)((ulong)a.value % (ulong)b.value));
}
catch (ArithmeticException) {
return createUnknown();
return CreateUnknown();
}
}
if ((ReferenceEquals(a, b) && a.isNonZero()) || b.hasValue(1))
if ((ReferenceEquals(a, b) && a.IsNonZero()) || b.HasValue(1))
return zero;
return createUnknown();
return CreateUnknown();
}
public static Int64Value Neg(Int64Value a) {
if (a.allBitsValid())
if (a.AllBitsValid())
return new Int64Value(-a.value);
return createUnknown();
return CreateUnknown();
}
public static Int64Value And(Int64Value a, Int64Value b) {
@ -227,73 +227,73 @@ namespace de4dot.blocks.cflow {
}
public static Int64Value Shl(Int64Value a, Int32Value b) {
if (b.hasUnknownBits())
return createUnknown();
if (b.HasUnknownBits())
return CreateUnknown();
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(long) * 8)
return createUnknown();
return CreateUnknown();
int shift = b.value;
ulong validMask = (a.validMask << shift) | (ulong.MaxValue >> (sizeof(long) * 8 - shift));
return new Int64Value(a.value << shift, validMask);
}
public static Int64Value Shr(Int64Value a, Int32Value b) {
if (b.hasUnknownBits())
return createUnknown();
if (b.HasUnknownBits())
return CreateUnknown();
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(long) * 8)
return createUnknown();
return CreateUnknown();
int shift = b.value;
ulong validMask = a.validMask >> shift;
if (a.isBitValid(sizeof(long) * 8 - 1))
if (a.IsBitValid(sizeof(long) * 8 - 1))
validMask |= (ulong.MaxValue << (sizeof(long) * 8 - shift));
return new Int64Value(a.value >> shift, validMask);
}
public static Int64Value Shr_Un(Int64Value a, Int32Value b) {
if (b.hasUnknownBits())
return createUnknown();
if (b.HasUnknownBits())
return CreateUnknown();
if (b.value == 0)
return a;
if (b.value < 0 || b.value >= sizeof(long) * 8)
return createUnknown();
return CreateUnknown();
int shift = b.value;
ulong validMask = (a.validMask >> shift) | (ulong.MaxValue << (sizeof(long) * 8 - shift));
return new Int64Value((long)((ulong)a.value >> shift), validMask);
}
static Int32Value create(Bool3 b) {
static Int32Value Create(Bool3 b) {
switch (b) {
case Bool3.False: return Int32Value.zero;
case Bool3.True: return Int32Value.one;
default: return Int32Value.createUnknownBool();
default: return Int32Value.CreateUnknownBool();
}
}
public static Int32Value Ceq(Int64Value a, Int64Value b) {
return create(compareEq(a, b));
return Create(CompareEq(a, b));
}
public static Int32Value Cgt(Int64Value a, Int64Value b) {
return create(compareGt(a, b));
return Create(CompareGt(a, b));
}
public static Int32Value Cgt_Un(Int64Value a, Int64Value b) {
return create(compareGt_Un(a, b));
return Create(CompareGt_Un(a, b));
}
public static Int32Value Clt(Int64Value a, Int64Value b) {
return create(compareLt(a, b));
return Create(CompareLt(a, b));
}
public static Int32Value Clt_Un(Int64Value a, Int64Value b) {
return create(compareLt_Un(a, b));
return Create(CompareLt_Un(a, b));
}
public static Bool3 compareEq(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareEq(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value == b.value ? Bool3.True : Bool3.False;
if (ReferenceEquals(a, b))
return Bool3.True;
@ -302,8 +302,8 @@ namespace de4dot.blocks.cflow {
return Bool3.Unknown;
}
public static Bool3 compareNeq(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareNeq(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value != b.value ? Bool3.True : Bool3.False;
if (ReferenceEquals(a, b))
return Bool3.False;
@ -312,96 +312,96 @@ namespace de4dot.blocks.cflow {
return Bool3.Unknown;
}
public static Bool3 compareGt(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGt(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value > b.value ? Bool3.True : Bool3.False;
if (a.hasValue(long.MinValue))
if (a.HasValue(long.MinValue))
return Bool3.False; // min > x => false
if (b.hasValue(long.MaxValue))
if (b.HasValue(long.MaxValue))
return Bool3.False; // x > max => false
return Bool3.Unknown;
}
public static Bool3 compareGt_Un(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGt_Un(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (ulong)a.value > (ulong)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(ulong.MinValue))
if (a.HasValue(ulong.MinValue))
return Bool3.False; // min > x => false
if (b.hasValue(ulong.MaxValue))
if (b.HasValue(ulong.MaxValue))
return Bool3.False; // x > max => false
return Bool3.Unknown;
}
public static Bool3 compareGe(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGe(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value >= b.value ? Bool3.True : Bool3.False;
if (a.hasValue(long.MaxValue))
if (a.HasValue(long.MaxValue))
return Bool3.True; // max >= x => true
if (b.hasValue(long.MinValue))
if (b.HasValue(long.MinValue))
return Bool3.True; // x >= min => true
return Bool3.Unknown;
}
public static Bool3 compareGe_Un(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareGe_Un(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (ulong)a.value >= (ulong)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(ulong.MaxValue))
if (a.HasValue(ulong.MaxValue))
return Bool3.True; // max >= x => true
if (b.hasValue(ulong.MinValue))
if (b.HasValue(ulong.MinValue))
return Bool3.True; // x >= min => true
return Bool3.Unknown;
}
public static Bool3 compareLe(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLe(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value <= b.value ? Bool3.True : Bool3.False;
if (a.hasValue(long.MinValue))
if (a.HasValue(long.MinValue))
return Bool3.True; // min <= x => true
if (b.hasValue(long.MaxValue))
if (b.HasValue(long.MaxValue))
return Bool3.True; // x <= max => true
return Bool3.Unknown;
}
public static Bool3 compareLe_Un(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLe_Un(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (ulong)a.value <= (ulong)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(ulong.MinValue))
if (a.HasValue(ulong.MinValue))
return Bool3.True; // min <= x => true
if (b.hasValue(ulong.MaxValue))
if (b.HasValue(ulong.MaxValue))
return Bool3.True; // x <= max => true
return Bool3.Unknown;
}
public static Bool3 compareLt(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLt(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return a.value < b.value ? Bool3.True : Bool3.False;
if (a.hasValue(long.MaxValue))
if (a.HasValue(long.MaxValue))
return Bool3.False; // max < x => false
if (b.hasValue(long.MinValue))
if (b.HasValue(long.MinValue))
return Bool3.False; // x < min => false
return Bool3.Unknown;
}
public static Bool3 compareLt_Un(Int64Value a, Int64Value b) {
if (a.allBitsValid() && b.allBitsValid())
public static Bool3 CompareLt_Un(Int64Value a, Int64Value b) {
if (a.AllBitsValid() && b.AllBitsValid())
return (ulong)a.value < (ulong)b.value ? Bool3.True : Bool3.False;
if (a.hasValue(ulong.MaxValue))
if (a.HasValue(ulong.MaxValue))
return Bool3.False; // max < x => false
if (b.hasValue(ulong.MinValue))
if (b.HasValue(ulong.MinValue))
return Bool3.False; // x < min => false
return Bool3.Unknown;
}
public static Bool3 compareTrue(Int64Value a) {
if (a.allBitsValid())
public static Bool3 CompareTrue(Int64Value a) {
if (a.AllBitsValid())
return a.value != 0 ? Bool3.True : Bool3.False;
if (((ulong)a.value & a.validMask) != 0)
return Bool3.True;
return Bool3.Unknown;
}
public static Bool3 compareFalse(Int64Value a) {
if (a.allBitsValid())
public static Bool3 CompareFalse(Int64Value a) {
if (a.AllBitsValid())
return a.value == 0 ? Bool3.True : Bool3.False;
if (((ulong)a.value & a.validMask) != 0)
return Bool3.False;
@ -409,7 +409,7 @@ namespace de4dot.blocks.cflow {
}
public override string ToString() {
if (allBitsValid())
if (AllBitsValid())
return value.ToString();
return string.Format("0x{0:X8}L({1:X8})", value, validMask);
}

View File

@ -29,18 +29,18 @@ namespace de4dot.blocks.cflow {
this.inlineInstanceMethods = inlineInstanceMethods;
}
protected override bool deobfuscateInternal() {
protected override bool DeobfuscateInternal() {
bool changed = false;
var instructions = block.Instructions;
for (int i = 0; i < instructions.Count; i++) {
var instr = instructions[i].Instruction;
if (instr.OpCode.Code == Code.Call)
changed |= inlineMethod(instr, i);
changed |= InlineMethod(instr, i);
}
return changed;
}
protected virtual bool canInline(MethodDef method) {
protected virtual bool CanInline(MethodDef method) {
if (method.GenericParameters.Count > 0)
return false;
if (method == blocks.Method)
@ -55,19 +55,19 @@ namespace de4dot.blocks.cflow {
return inlineInstanceMethods;
}
bool inlineMethod(Instruction callInstr, int instrIndex) {
bool InlineMethod(Instruction callInstr, int instrIndex) {
var methodToInline = callInstr.Operand as MethodDef;
if (methodToInline == null)
return false;
if (!canInline(methodToInline))
if (!CanInline(methodToInline))
return false;
var body = methodToInline.Body;
if (body == null)
return false;
int index = 0;
var instr = DotNetUtils.getInstruction(body.Instructions, ref index);
var instr = DotNetUtils.GetInstruction(body.Instructions, ref index);
if (instr == null)
return false;
@ -83,7 +83,7 @@ namespace de4dot.blocks.cflow {
case Code.Call:
case Code.Callvirt:
case Code.Newobj:
return inlineOtherMethod(instrIndex, methodToInline, instr, index);
return InlineOtherMethod(instrIndex, methodToInline, instr, index);
case Code.Ldc_I4:
case Code.Ldc_I4_0:
@ -106,17 +106,17 @@ namespace de4dot.blocks.cflow {
case Code.Ldtoken:
case Code.Ldsfld:
case Code.Ldsflda:
return inlineLoadMethod(instrIndex, methodToInline, instr, index);
return InlineLoadMethod(instrIndex, methodToInline, instr, index);
default:
return false;
}
}
protected override bool isCompatibleType(int paramIndex, IType origType, IType newType) {
protected override bool IsCompatibleType(int paramIndex, IType origType, IType newType) {
if (new SigComparer(SigComparerOptions.IgnoreModifiers).Equals(origType, newType))
return true;
if (isValueType(newType) || isValueType(origType))
if (IsValueType(newType) || IsValueType(origType))
return false;
return newType.FullName == "System.Object";
}

View File

@ -33,24 +33,24 @@ namespace de4dot.blocks.cflow {
public bool ExecuteOnNoChange { get; set; }
public void deobfuscateBegin(Blocks blocks) {
public void DeobfuscateBegin(Blocks blocks) {
this.blocks = blocks;
iteration = 0;
}
public bool deobfuscate(List<Block> allBlocks) {
public bool Deobfuscate(List<Block> allBlocks) {
if (iteration++ >= MAX_ITERATIONS)
return false;
bool changed = false;
foreach (var block in allBlocks) {
this.block = block;
changed |= deobfuscateInternal();
changed |= DeobfuscateInternal();
}
return changed;
}
protected abstract bool deobfuscateInternal();
protected abstract bool DeobfuscateInternal();
protected class InstructionPatcher {
readonly int patchIndex;
@ -64,53 +64,53 @@ namespace de4dot.blocks.cflow {
this.clonedInstr = new Instr(lastInstr.Clone());
}
public void patch(Block block) {
public void Patch(Block block) {
block.Instructions[patchIndex] = clonedInstr;
}
}
protected bool inlineLoadMethod(int patchIndex, MethodDef methodToInline, Instruction loadInstr, int instrIndex) {
if (!isReturn(methodToInline, instrIndex))
protected bool InlineLoadMethod(int patchIndex, MethodDef methodToInline, Instruction loadInstr, int instrIndex) {
if (!IsReturn(methodToInline, instrIndex))
return false;
int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);
int methodArgsCount = DotNetUtils.GetArgsCount(methodToInline);
for (int i = 0; i < methodArgsCount; i++)
block.insert(patchIndex++, OpCodes.Pop.ToInstruction());
block.Insert(patchIndex++, OpCodes.Pop.ToInstruction());
block.Instructions[patchIndex] = new Instr(loadInstr.Clone());
return true;
}
protected bool inlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex) {
return inlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, 0);
protected bool InlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex) {
return InlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, 0);
}
protected bool inlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex, int popLastArgs) {
return patchMethod(methodToInline, tryInlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, popLastArgs));
protected bool InlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex, int popLastArgs) {
return PatchMethod(methodToInline, TryInlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, popLastArgs));
}
protected bool patchMethod(MethodDef methodToInline, InstructionPatcher patcher) {
protected bool PatchMethod(MethodDef methodToInline, InstructionPatcher patcher) {
if (patcher == null)
return false;
if (!isReturn(methodToInline, patcher.afterIndex))
if (!IsReturn(methodToInline, patcher.afterIndex))
return false;
patcher.patch(block);
patcher.Patch(block);
return true;
}
protected InstructionPatcher tryInlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex) {
return tryInlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, 0);
protected InstructionPatcher TryInlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex) {
return TryInlineOtherMethod(patchIndex, methodToInline, instr, instrIndex, 0);
}
protected virtual Instruction onAfterLoadArg(MethodDef methodToInline, Instruction instr, ref int instrIndex) {
protected virtual Instruction OnAfterLoadArg(MethodDef methodToInline, Instruction instr, ref int instrIndex) {
return instr;
}
protected InstructionPatcher tryInlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex, int popLastArgs) {
protected InstructionPatcher TryInlineOtherMethod(int patchIndex, MethodDef methodToInline, Instruction instr, int instrIndex, int popLastArgs) {
int loadIndex = 0;
int methodArgsCount = DotNetUtils.getArgsCount(methodToInline);
int methodArgsCount = DotNetUtils.GetArgsCount(methodToInline);
bool foundLdarga = false;
while (instr != null && loadIndex < methodArgsCount) {
bool isLdarg = true;
@ -136,8 +136,8 @@ namespace de4dot.blocks.cflow {
if (instr.GetParameterIndex() != loadIndex)
return null;
loadIndex++;
instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
instr = onAfterLoadArg(methodToInline, instr, ref instrIndex);
instr = DotNetUtils.GetInstruction(methodToInline.Body.Instructions, ref instrIndex);
instr = OnAfterLoadArg(methodToInline, instr, ref instrIndex);
}
if (instr == null || loadIndex != methodArgsCount - popLastArgs)
return null;
@ -150,13 +150,13 @@ namespace de4dot.blocks.cflow {
if (calledMethod == null)
return null;
if (!isCompatibleType(-1, calledMethod.MethodSig.RetType, methodToInline.MethodSig.RetType))
if (!IsCompatibleType(-1, calledMethod.MethodSig.RetType, methodToInline.MethodSig.RetType))
return null;
if (!checkSameMethods(calledMethod, methodToInline, popLastArgs))
if (!CheckSameMethods(calledMethod, methodToInline, popLastArgs))
return null;
if (!hasAccessTo(instr.Operand))
if (!HasAccessTo(instr.Operand))
return null;
return new InstructionPatcher(patchIndex, instrIndex, callInstr);
@ -169,19 +169,19 @@ namespace de4dot.blocks.cflow {
if (ctor == null)
return null;
if (!isCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodSig.RetType))
if (!IsCompatibleType(-1, ctor.DeclaringType, methodToInline.MethodSig.RetType))
return null;
var methodArgs = methodToInline.Parameters;
var calledMethodArgs = DotNetUtils.getArgs(ctor);
var calledMethodArgs = DotNetUtils.GetArgs(ctor);
if (methodArgs.Count + 1 - popLastArgs != calledMethodArgs.Count)
return null;
for (int i = 1; i < calledMethodArgs.Count; i++) {
if (!isCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1].Type))
if (!IsCompatibleType(i, calledMethodArgs[i], methodArgs[i - 1].Type))
return null;
}
if (!hasAccessTo(instr.Operand))
if (!HasAccessTo(instr.Operand))
return null;
return new InstructionPatcher(patchIndex, instrIndex, newobjInstr);
@ -192,7 +192,7 @@ namespace de4dot.blocks.cflow {
if (methodArgsCount != 1)
return null;
if (!hasAccessTo(instr.Operand))
if (!HasAccessTo(instr.Operand))
return null;
return new InstructionPatcher(patchIndex, instrIndex, ldInstr);
@ -201,36 +201,36 @@ namespace de4dot.blocks.cflow {
return null;
}
bool hasAccessTo(object operand) {
bool HasAccessTo(object operand) {
if (operand == null)
return false;
accessChecker.UserType = blocks.Method.DeclaringType;
return accessChecker.CanAccess(operand) ?? getDefaultAccessResult();
return accessChecker.CanAccess(operand) ?? GetDefaultAccessResult();
}
protected virtual bool getDefaultAccessResult() {
protected virtual bool GetDefaultAccessResult() {
return true;
}
protected virtual bool isReturn(MethodDef methodToInline, int instrIndex) {
var instr = DotNetUtils.getInstruction(methodToInline.Body.Instructions, ref instrIndex);
protected virtual bool IsReturn(MethodDef methodToInline, int instrIndex) {
var instr = DotNetUtils.GetInstruction(methodToInline.Body.Instructions, ref instrIndex);
return instr != null && instr.OpCode.Code == Code.Ret;
}
protected bool checkSameMethods(IMethod method, MethodDef methodToInline) {
return checkSameMethods(method, methodToInline, 0);
protected bool CheckSameMethods(IMethod method, MethodDef methodToInline) {
return CheckSameMethods(method, methodToInline, 0);
}
protected bool checkSameMethods(IMethod method, MethodDef methodToInline, int ignoreLastMethodToInlineArgs) {
protected bool CheckSameMethods(IMethod method, MethodDef methodToInline, int ignoreLastMethodToInlineArgs) {
var methodToInlineArgs = methodToInline.Parameters;
var methodArgs = DotNetUtils.getArgs(method);
var methodArgs = DotNetUtils.GetArgs(method);
bool hasImplicitThis = method.MethodSig.ImplicitThis;
if (methodToInlineArgs.Count - ignoreLastMethodToInlineArgs != methodArgs.Count)
return false;
for (int i = 0; i < methodArgs.Count; i++) {
var methodArg = methodArgs[i];
var methodToInlineArg = getArgType(methodToInline, methodToInlineArgs[i].Type);
if (!isCompatibleType(i, methodArg, methodToInlineArg)) {
var methodToInlineArg = GetArgType(methodToInline, methodToInlineArgs[i].Type);
if (!IsCompatibleType(i, methodArg, methodToInlineArg)) {
if (i != 0 || !hasImplicitThis)
return false;
if (!isCompatibleValueThisPtr(methodArg, methodToInlineArg))
@ -241,7 +241,7 @@ namespace de4dot.blocks.cflow {
return true;
}
static TypeSig getArgType(MethodDef method, TypeSig arg) {
static TypeSig GetArgType(MethodDef method, TypeSig arg) {
if (arg.GetElementType() != ElementType.MVar)
return arg;
var mvar = (GenericMVar)arg;
@ -254,7 +254,7 @@ namespace de4dot.blocks.cflow {
return arg;
}
protected virtual bool isCompatibleType(int paramIndex, IType origType, IType newType) {
protected virtual bool IsCompatibleType(int paramIndex, IType origType, IType newType) {
return new SigComparer().Equals(origType, newType);
}
@ -262,12 +262,12 @@ namespace de4dot.blocks.cflow {
var newByRef = newType as ByRefSig;
if (newByRef == null)
return false;
if (!isValueType(newByRef.Next) || !isValueType(origType))
if (!IsValueType(newByRef.Next) || !IsValueType(origType))
return false;
return new SigComparer().Equals(origType, newByRef.Next);
}
protected static bool isValueType(IType type) {
protected static bool IsValueType(IType type) {
if (type == null)
return false;
var ts = type as TypeSig;

View File

@ -26,12 +26,12 @@ namespace de4dot.blocks.cflow {
class StLdlocFixer : BlockDeobfuscator {
IList<Local> locals;
protected override void init(List<Block> allBlocks) {
base.init(allBlocks);
protected override void Initialize(List<Block> allBlocks) {
base.Initialize(allBlocks);
locals = blocks.Locals;
}
protected override bool deobfuscate(Block block) {
protected override bool Deobfuscate(Block block) {
bool changed = false;
var instructions = block.Instructions;
for (int i = 0; i < instructions.Count; i++) {
@ -47,12 +47,12 @@ namespace de4dot.blocks.cflow {
case Code.Stloc_3:
if (i + 1 >= instructions.Count)
break;
if (!instructions[i + 1].isLdloc())
if (!instructions[i + 1].IsLdloc())
break;
var local = Instr.getLocalVar(locals, instr);
var local = Instr.GetLocalVar(locals, instr);
if (local.Type.ElementType != ElementType.Boolean)
continue;
if (local != Instr.getLocalVar(locals, instructions[i + 1]))
if (local != Instr.GetLocalVar(locals, instructions[i + 1]))
break;
instructions[i] = new Instr(OpCodes.Dup.ToInstruction());
instructions[i + 1] = instr;

View File

@ -26,50 +26,50 @@ namespace de4dot.blocks.cflow {
class SwitchCflowDeobfuscator : BlockDeobfuscator {
InstructionEmulator instructionEmulator = new InstructionEmulator();
protected override bool deobfuscate(Block switchBlock) {
protected override bool Deobfuscate(Block switchBlock) {
if (switchBlock.LastInstr.OpCode.Code != Code.Switch)
return false;
if (isSwitchTopOfStack(switchBlock) && deobfuscateTos(switchBlock))
if (IsSwitchTopOfStack(switchBlock) && DeobfuscateTOS(switchBlock))
return true;
if (isLdlocBranch(switchBlock, true) && deobfuscateLdloc(switchBlock))
if (IsLdlocBranch(switchBlock, true) && DeobfuscateLdloc(switchBlock))
return true;
if (isStLdlocBranch(switchBlock, true) && deobfuscateStLdloc(switchBlock))
if (IsStLdlocBranch(switchBlock, true) && DeobfuscateStLdloc(switchBlock))
return true;
if (isSwitchType1(switchBlock) && deobfuscateType1(switchBlock))
if (IsSwitchType1(switchBlock) && DeobfuscateType1(switchBlock))
return true;
if (isSwitchType2(switchBlock) && deobfuscateType2(switchBlock))
if (IsSwitchType2(switchBlock) && DeobfuscateType2(switchBlock))
return true;
if (switchBlock.FirstInstr.isLdloc() && fixSwitchBranch(switchBlock))
if (switchBlock.FirstInstr.IsLdloc() && FixSwitchBranch(switchBlock))
return true;
return false;
}
static bool isSwitchTopOfStack(Block switchBlock) {
static bool IsSwitchTopOfStack(Block switchBlock) {
return switchBlock.Instructions.Count == 1;
}
static bool isLdlocBranch(Block switchBlock, bool isSwitch) {
static bool IsLdlocBranch(Block switchBlock, bool isSwitch) {
int numInstrs = 1 + (isSwitch ? 1 : 0);
return switchBlock.Instructions.Count == numInstrs && switchBlock.Instructions[0].isLdloc();
return switchBlock.Instructions.Count == numInstrs && switchBlock.Instructions[0].IsLdloc();
}
static bool isSwitchType1(Block switchBlock) {
return switchBlock.FirstInstr.isLdloc();
static bool IsSwitchType1(Block switchBlock) {
return switchBlock.FirstInstr.IsLdloc();
}
bool isSwitchType2(Block switchBlock) {
bool IsSwitchType2(Block switchBlock) {
Local local = null;
foreach (var instr in switchBlock.Instructions) {
if (!instr.isLdloc())
if (!instr.IsLdloc())
continue;
local = Instr.getLocalVar(blocks.Locals, instr);
local = Instr.GetLocalVar(blocks.Locals, instr);
break;
}
if (local == null)
@ -79,12 +79,12 @@ namespace de4dot.blocks.cflow {
var instrs = source.Instructions;
for (int i = 1; i < instrs.Count; i++) {
var ldci4 = instrs[i - 1];
if (!ldci4.isLdcI4())
if (!ldci4.IsLdcI4())
continue;
var stloc = instrs[i];
if (!stloc.isStloc())
if (!stloc.IsStloc())
continue;
if (Instr.getLocalVar(blocks.Locals, stloc) != local)
if (Instr.GetLocalVar(blocks.Locals, stloc) != local)
continue;
return true;
@ -94,29 +94,29 @@ namespace de4dot.blocks.cflow {
return false;
}
bool isStLdlocBranch(Block switchBlock, bool isSwitch) {
bool IsStLdlocBranch(Block switchBlock, bool isSwitch) {
int numInstrs = 2 + (isSwitch ? 1 : 0);
return switchBlock.Instructions.Count == numInstrs &&
switchBlock.Instructions[0].isStloc() &&
switchBlock.Instructions[1].isLdloc() &&
Instr.getLocalVar(blocks.Locals, switchBlock.Instructions[0]) == Instr.getLocalVar(blocks.Locals, switchBlock.Instructions[1]);
switchBlock.Instructions[0].IsStloc() &&
switchBlock.Instructions[1].IsLdloc() &&
Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[0]) == Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[1]);
}
bool deobfuscateTos(Block switchBlock) {
bool DeobfuscateTOS(Block switchBlock) {
bool changed = false;
if (switchBlock.Targets == null)
return changed;
var targets = new List<Block>(switchBlock.Targets);
changed |= deobfuscateTos(targets, switchBlock.FallThrough, switchBlock);
changed |= DeobfuscateTOS(targets, switchBlock.FallThrough, switchBlock);
return changed;
}
bool deobfuscateLdloc(Block switchBlock) {
bool DeobfuscateLdloc(Block switchBlock) {
bool changed = false;
var switchVariable = Instr.getLocalVar(blocks.Locals, switchBlock.Instructions[0]);
var switchVariable = Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[0]);
if (switchVariable == null)
return changed;
@ -124,15 +124,15 @@ namespace de4dot.blocks.cflow {
return changed;
var targets = new List<Block>(switchBlock.Targets);
changed |= deobfuscateLdloc(targets, switchBlock.FallThrough, switchBlock, switchVariable);
changed |= DeobfuscateLdloc(targets, switchBlock.FallThrough, switchBlock, switchVariable);
return changed;
}
bool deobfuscateStLdloc(Block switchBlock) {
bool DeobfuscateStLdloc(Block switchBlock) {
bool changed = false;
var switchVariable = Instr.getLocalVar(blocks.Locals, switchBlock.Instructions[0]);
var switchVariable = Instr.GetLocalVar(blocks.Locals, switchBlock.Instructions[0]);
if (switchVariable == null)
return changed;
@ -140,7 +140,7 @@ namespace de4dot.blocks.cflow {
return changed;
var targets = new List<Block>(switchBlock.Targets);
changed |= deobfuscateStLdloc(targets, switchBlock.FallThrough, switchBlock);
changed |= DeobfuscateStLdloc(targets, switchBlock.FallThrough, switchBlock);
return changed;
}
@ -153,19 +153,19 @@ namespace de4dot.blocks.cflow {
// stloc N
// ldloc N
// switch (......)
bool deobfuscateStLdloc(IList<Block> switchTargets, Block switchFallThrough, Block block) {
bool DeobfuscateStLdloc(IList<Block> switchTargets, Block switchFallThrough, Block block) {
bool changed = false;
foreach (var source in new List<Block>(block.Sources)) {
if (!isBranchBlock(source))
continue;
instructionEmulator.init(blocks);
instructionEmulator.emulate(source.Instructions);
instructionEmulator.Initialize(blocks);
instructionEmulator.Emulate(source.Instructions);
var target = getSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.pop());
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop());
if (target == null)
continue;
source.replaceLastNonBranchWithBranch(0, target);
source.add(new Instr(OpCodes.Pop.ToInstruction()));
source.ReplaceLastNonBranchWithBranch(0, target);
source.Add(new Instr(OpCodes.Pop.ToInstruction()));
changed = true;
}
return changed;
@ -179,32 +179,32 @@ namespace de4dot.blocks.cflow {
// swblk:
// ldloc N
// switch (......)
bool deobfuscateLdloc(IList<Block> switchTargets, Block switchFallThrough, Block block, Local switchVariable) {
bool DeobfuscateLdloc(IList<Block> switchTargets, Block switchFallThrough, Block block, Local switchVariable) {
bool changed = false;
foreach (var source in new List<Block>(block.Sources)) {
if (isBranchBlock(source)) {
instructionEmulator.init(blocks);
instructionEmulator.emulate(source.Instructions);
instructionEmulator.Initialize(blocks);
instructionEmulator.Emulate(source.Instructions);
var target = getSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.getLocal(switchVariable));
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable));
if (target == null)
continue;
source.replaceLastNonBranchWithBranch(0, target);
source.ReplaceLastNonBranchWithBranch(0, target);
changed = true;
}
else if (isBccBlock(source)) {
instructionEmulator.init(blocks);
instructionEmulator.emulate(source.Instructions);
else if (IsBccBlock(source)) {
instructionEmulator.Initialize(blocks);
instructionEmulator.Emulate(source.Instructions);
var target = getSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.getLocal(switchVariable));
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.GetLocal(switchVariable));
if (target == null)
continue;
if (source.Targets[0] == block) {
source.setNewTarget(0, target);
source.SetNewTarget(0, target);
changed = true;
}
if (source.FallThrough == block) {
source.setNewFallThrough(target);
source.SetNewFallThrough(target);
changed = true;
}
}
@ -218,21 +218,21 @@ namespace de4dot.blocks.cflow {
// br swblk
// swblk:
// switch (......)
bool deobfuscateTos(IList<Block> switchTargets, Block switchFallThrough, Block block) {
bool DeobfuscateTOS(IList<Block> switchTargets, Block switchFallThrough, Block block) {
bool changed = false;
foreach (var source in new List<Block>(block.Sources)) {
if (!isBranchBlock(source))
continue;
instructionEmulator.init(blocks);
instructionEmulator.emulate(source.Instructions);
instructionEmulator.Initialize(blocks);
instructionEmulator.Emulate(source.Instructions);
var target = getSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.pop());
var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop());
if (target == null) {
changed |= deobfuscateTos_Ldloc(switchTargets, switchFallThrough, source);
changed |= DeobfuscateTos_Ldloc(switchTargets, switchFallThrough, source);
}
else {
source.replaceLastNonBranchWithBranch(0, target);
source.add(new Instr(OpCodes.Pop.ToInstruction()));
source.ReplaceLastNonBranchWithBranch(0, target);
source.Add(new Instr(OpCodes.Pop.ToInstruction()));
changed = true;
}
}
@ -245,15 +245,15 @@ namespace de4dot.blocks.cflow {
// stloc N
// ldloc N
// br swblk
bool deobfuscateTos_Ldloc(IList<Block> switchTargets, Block switchFallThrough, Block block) {
if (isLdlocBranch(block, false)) {
var switchVariable = Instr.getLocalVar(blocks.Locals, block.Instructions[0]);
bool DeobfuscateTos_Ldloc(IList<Block> switchTargets, Block switchFallThrough, Block block) {
if (IsLdlocBranch(block, false)) {
var switchVariable = Instr.GetLocalVar(blocks.Locals, block.Instructions[0]);
if (switchVariable == null)
return false;
return deobfuscateLdloc(switchTargets, switchFallThrough, block, switchVariable);
return DeobfuscateLdloc(switchTargets, switchFallThrough, block, switchVariable);
}
else if (isStLdlocBranch(block, false))
return deobfuscateStLdloc(switchTargets, switchFallThrough, block);
else if (IsStLdlocBranch(block, false))
return DeobfuscateStLdloc(switchTargets, switchFallThrough, block);
return false;
}
@ -273,7 +273,7 @@ namespace de4dot.blocks.cflow {
}
}
static bool isBccBlock(Block block) {
static bool IsBccBlock(Block block) {
if (block.Targets == null || block.Targets.Count != 1)
return false;
if (block.FallThrough == null)
@ -309,91 +309,91 @@ namespace de4dot.blocks.cflow {
}
}
bool deobfuscateType1(Block switchBlock) {
bool DeobfuscateType1(Block switchBlock) {
Block target;
if (!emulateGetTarget(switchBlock, out target) || target != null)
if (!EmulateGetTarget(switchBlock, out target) || target != null)
return false;
bool changed = false;
foreach (var source in new List<Block>(switchBlock.Sources)) {
if (!source.canAppend(switchBlock))
if (!source.CanAppend(switchBlock))
continue;
if (!willHaveKnownTarget(switchBlock, source))
if (!WillHaveKnownTarget(switchBlock, source))
continue;
source.append(switchBlock);
source.Append(switchBlock);
changed = true;
}
return changed;
}
bool deobfuscateType2(Block switchBlock) {
bool DeobfuscateType2(Block switchBlock) {
bool changed = false;
var bccSources = new List<Block>();
foreach (var source in new List<Block>(switchBlock.Sources)) {
if (source.LastInstr.isConditionalBranch()) {
if (source.LastInstr.IsConditionalBranch()) {
bccSources.Add(source);
continue;
}
if (!source.canAppend(switchBlock))
if (!source.CanAppend(switchBlock))
continue;
if (!willHaveKnownTarget(switchBlock, source))
if (!WillHaveKnownTarget(switchBlock, source))
continue;
source.append(switchBlock);
source.Append(switchBlock);
changed = true;
}
foreach (var bccSource in bccSources) {
if (!willHaveKnownTarget(switchBlock, bccSource))
if (!WillHaveKnownTarget(switchBlock, bccSource))
continue;
var consts = getBccLocalConstants(bccSource);
var consts = GetBccLocalConstants(bccSource);
if (consts.Count == 0)
continue;
var newFallThrough = createBlock(consts, bccSource.FallThrough);
var newTarget = createBlock(consts, bccSource.Targets[0]);
var newFallThrough = CreateBlock(consts, bccSource.FallThrough);
var newTarget = CreateBlock(consts, bccSource.Targets[0]);
var oldFallThrough = bccSource.FallThrough;
var oldTarget = bccSource.Targets[0];
bccSource.setNewFallThrough(newFallThrough);
bccSource.setNewTarget(0, newTarget);
newFallThrough.setNewFallThrough(oldFallThrough);
newTarget.setNewFallThrough(oldTarget);
bccSource.SetNewFallThrough(newFallThrough);
bccSource.SetNewTarget(0, newTarget);
newFallThrough.SetNewFallThrough(oldFallThrough);
newTarget.SetNewFallThrough(oldTarget);
changed = true;
}
return changed;
}
static Block createBlock(Dictionary<Local, int> consts, Block fallThrough) {
static Block CreateBlock(Dictionary<Local, int> consts, Block fallThrough) {
var block = new Block();
foreach (var kv in consts) {
block.Instructions.Add(new Instr(Instruction.CreateLdcI4(kv.Value)));
block.Instructions.Add(new Instr(OpCodes.Stloc.ToInstruction(kv.Key)));
}
fallThrough.Parent.add(block);
fallThrough.Parent.Add(block);
return block;
}
Dictionary<Local, int> getBccLocalConstants(Block block) {
Dictionary<Local, int> GetBccLocalConstants(Block block) {
var dict = new Dictionary<Local, int>();
var instrs = block.Instructions;
for (int i = 0; i < instrs.Count; i++) {
var instr = instrs[i];
if (instr.isStloc()) {
var local = Instr.getLocalVar(blocks.Locals, instr);
if (instr.IsStloc()) {
var local = Instr.GetLocalVar(blocks.Locals, instr);
if (local == null)
continue;
var ldci4 = i == 0 ? null : instrs[i - 1];
if (ldci4 == null || !ldci4.isLdcI4())
if (ldci4 == null || !ldci4.IsLdcI4())
dict.Remove(local);
else
dict[local] = ldci4.getLdcI4Value();
dict[local] = ldci4.GetLdcI4Value();
}
else if (instr.isLdloc()) {
var local = Instr.getLocalVar(blocks.Locals, instr);
else if (instr.IsLdloc()) {
var local = Instr.GetLocalVar(blocks.Locals, instr);
if (local != null)
dict.Remove(local);
}
@ -406,47 +406,47 @@ namespace de4dot.blocks.cflow {
return dict;
}
bool emulateGetTarget(Block switchBlock, out Block target) {
instructionEmulator.init(blocks);
bool EmulateGetTarget(Block switchBlock, out Block target) {
instructionEmulator.Initialize(blocks);
try {
instructionEmulator.emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
}
catch (NullReferenceException) {
// Here if eg. invalid metadata token in a call instruction (operand is null)
target = null;
return false;
}
target = getTarget(switchBlock);
target = GetTarget(switchBlock);
return true;
}
bool willHaveKnownTarget(Block switchBlock, Block source) {
instructionEmulator.init(blocks);
bool WillHaveKnownTarget(Block switchBlock, Block source) {
instructionEmulator.Initialize(blocks);
try {
instructionEmulator.emulate(source.Instructions);
instructionEmulator.emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
instructionEmulator.Emulate(source.Instructions);
instructionEmulator.Emulate(switchBlock.Instructions, 0, switchBlock.Instructions.Count - 1);
}
catch (NullReferenceException) {
// Here if eg. invalid metadata token in a call instruction (operand is null)
return false;
}
return getTarget(switchBlock) != null;
return GetTarget(switchBlock) != null;
}
Block getTarget(Block switchBlock) {
var val1 = instructionEmulator.pop();
if (!val1.isInt32())
Block GetTarget(Block switchBlock) {
var val1 = instructionEmulator.Pop();
if (!val1.IsInt32())
return null;
return CflowUtils.getSwitchTarget(switchBlock.Targets, switchBlock.FallThrough, (Int32Value)val1);
return CflowUtils.GetSwitchTarget(switchBlock.Targets, switchBlock.FallThrough, (Int32Value)val1);
}
static Block getSwitchTarget(IList<Block> targets, Block fallThrough, Value value) {
if (!value.isInt32())
static Block GetSwitchTarget(IList<Block> targets, Block fallThrough, Value value) {
if (!value.IsInt32())
return null;
return CflowUtils.getSwitchTarget(targets, fallThrough, (Int32Value)value);
return CflowUtils.GetSwitchTarget(targets, fallThrough, (Int32Value)value);
}
static bool fixSwitchBranch(Block switchBlock) {
static bool FixSwitchBranch(Block switchBlock) {
// Code:
// blk1:
// ldc.i4 XXX
@ -467,11 +467,11 @@ namespace de4dot.blocks.cflow {
foreach (var commonSource in new List<Block>(switchBlock.Sources)) {
if (commonSource.Instructions.Count != 1)
continue;
if (!commonSource.FirstInstr.isStloc())
if (!commonSource.FirstInstr.IsStloc())
continue;
foreach (var blk in new List<Block>(commonSource.Sources)) {
if (blk.canAppend(commonSource)) {
blk.append(commonSource);
if (blk.CanAppend(commonSource)) {
blk.Append(commonSource);
changed = true;
}
}

View File

@ -38,35 +38,35 @@ namespace de4dot.blocks.cflow {
public abstract class Value {
public readonly ValueType valueType;
public bool isUnknown() {
public bool IsUnknown() {
return valueType == ValueType.Unknown;
}
public bool isNull() {
public bool IsNull() {
return valueType == ValueType.Null;
}
public bool isObject() {
public bool IsObject() {
return valueType == ValueType.Object;
}
public bool isBoxed() {
public bool IsBoxed() {
return valueType == ValueType.Boxed;
}
public bool isInt32() {
public bool IsInt32() {
return valueType == ValueType.Int32;
}
public bool isInt64() {
public bool IsInt64() {
return valueType == ValueType.Int64;
}
public bool isReal8() {
public bool IsReal8() {
return valueType == ValueType.Real8;
}
public bool isString() {
public bool IsString() {
return valueType == ValueType.String;
}

View File

@ -29,43 +29,43 @@ namespace de4dot.blocks.cflow {
get { return stack.Count; }
}
public void init() {
public void Initialize() {
stack.Clear();
}
public void clear() {
public void Clear() {
stack.Clear();
}
public void push(Value value) {
public void Push(Value value) {
stack.Add(value);
}
public Value peek() {
public Value Peek() {
if (stack.Count == 0)
return new UnknownValue();
return stack[stack.Count - 1];
}
public Value pop() {
Value value = peek();
public Value Pop() {
Value value = Peek();
if (stack.Count != 0)
stack.RemoveAt(stack.Count - 1);
return value;
}
public void push(int count) {
public void Push(int count) {
if (count < 0)
throw new ArgumentOutOfRangeException("count");
for (int i = 0; i < count; i++)
pushUnknown();
PushUnknown();
}
public void pushUnknown() {
push(new UnknownValue());
public void PushUnknown() {
Push(new UnknownValue());
}
public void pop(int count) {
public void Pop(int count) {
if (count < 0)
throw new ArgumentOutOfRangeException("count");
if (count >= stack.Count)
@ -74,8 +74,8 @@ namespace de4dot.blocks.cflow {
stack.RemoveRange(stack.Count - count, count);
}
public void copyTop() {
push(peek());
public void CopyTop() {
Push(Peek());
}
public override string ToString() {

View File

@ -20,7 +20,7 @@
namespace de4dot_x64 {
class Program {
static int Main(string[] args) {
return de4dot.cui.Program.main(args);
return de4dot.cui.Program.Main2(args);
}
}
}

View File

@ -43,13 +43,13 @@ namespace de4dot.code.AssemblyClient {
this.loader = loader;
}
public void connect() {
loader.loadServer();
service = loader.createService();
public void Connect() {
loader.LoadServer();
service = loader.CreateService();
serverLoadedTime = DateTime.UtcNow;
}
public void waitConnected() {
public void WaitConnected() {
// If we don't wait here, we'll sometimes get stuck in doNothing(). Make sure the
// server has had time to start... This only seems to be needed when starting a
// server in a different process, though.
@ -61,7 +61,7 @@ namespace de4dot.code.AssemblyClient {
var startTime = DateTime.UtcNow;
while (true) {
try {
service.doNothing();
service.DoNothing();
break;
}
catch (RemotingException) {
@ -77,7 +77,7 @@ namespace de4dot.code.AssemblyClient {
public void Dispose() {
if (service != null) {
try {
service.exit();
service.Exit();
}
catch (RemotingException) {
// Couldn't connect

View File

@ -21,17 +21,17 @@ using dnlib.DotNet;
namespace de4dot.code.AssemblyClient {
public interface IAssemblyClientFactory {
IAssemblyClient create();
IAssemblyClient Create();
}
public class SameAppDomainAssemblyClientFactory : IAssemblyClientFactory {
public IAssemblyClient create() {
public IAssemblyClient Create() {
return new AssemblyClient(new SameAppDomainAssemblyServerLoader());
}
}
public class NewAppDomainAssemblyClientFactory : IAssemblyClientFactory {
public IAssemblyClient create() {
public IAssemblyClient Create() {
return new AssemblyClient(new NewAppDomainAssemblyServerLoader());
}
}
@ -47,15 +47,15 @@ namespace de4dot.code.AssemblyClient {
this.serverVersion = serverVersion;
}
public IAssemblyClient create(ModuleDef module) {
return new AssemblyClient(new NewProcessAssemblyServerLoader(getServerClrVersion(module)));
public IAssemblyClient Create(ModuleDef module) {
return new AssemblyClient(new NewProcessAssemblyServerLoader(GetServerClrVersion(module)));
}
public IAssemblyClient create() {
public IAssemblyClient Create() {
return new AssemblyClient(new NewProcessAssemblyServerLoader(serverVersion));
}
internal static ServerClrVersion getServerClrVersion(ModuleDef module) {
internal static ServerClrVersion GetServerClrVersion(ModuleDef module) {
switch (module.GetPointerSize()) {
default:
case 4:

View File

@ -23,7 +23,7 @@ using AssemblyData;
namespace de4dot.code.AssemblyClient {
public interface IAssemblyClient : IDisposable {
IAssemblyService Service { get; }
void connect();
void waitConnected();
void Connect();
void WaitConnected();
}
}

View File

@ -22,7 +22,7 @@ using AssemblyData;
namespace de4dot.code.AssemblyClient {
interface IAssemblyServerLoader : IDisposable {
void loadServer();
IAssemblyService createService();
void LoadServer();
IAssemblyService CreateService();
}
}

View File

@ -42,13 +42,13 @@ namespace de4dot.code.AssemblyClient {
}
protected IpcAssemblyServerLoader(ServerClrVersion serverVersion) {
assemblyServerFilename = getServerName(serverVersion);
ipcName = Utils.randomName(15, 20);
ipcUri = Utils.randomName(15, 20);
assemblyServerFilename = GetServerName(serverVersion);
ipcName = Utils.RandomName(15, 20);
ipcUri = Utils.RandomName(15, 20);
url = string.Format("ipc://{0}/{1}", ipcName, ipcUri);
}
static string getServerName(ServerClrVersion serverVersion) {
static string GetServerName(ServerClrVersion serverVersion) {
if (serverVersion == ServerClrVersion.CLR_ANY_ANYCPU)
serverVersion = IntPtr.Size == 4 ? ServerClrVersion.CLR_ANY_x86 : ServerClrVersion.CLR_ANY_x64;
switch (serverVersion) {
@ -62,13 +62,13 @@ namespace de4dot.code.AssemblyClient {
}
}
public void loadServer() {
loadServer(Utils.getPathOfOurFile(assemblyServerFilename));
public void LoadServer() {
LoadServer(Utils.GetPathOfOurFile(assemblyServerFilename));
}
public abstract void loadServer(string filename);
public abstract void LoadServer(string filename);
public IAssemblyService createService() {
public IAssemblyService CreateService() {
return (IAssemblyService)Activator.GetObject(typeof(AssemblyService), url);
}

View File

@ -26,11 +26,11 @@ namespace de4dot.code.AssemblyClient {
AppDomain appDomain;
Thread thread;
public override void loadServer(string filename) {
public override void LoadServer(string filename) {
if (appDomain != null)
throw new ApplicationException("Server is already loaded");
appDomain = AppDomain.CreateDomain(Utils.randomName(15, 20));
appDomain = AppDomain.CreateDomain(Utils.RandomName(15, 20));
thread = new Thread(new ThreadStart(() => {
try {
appDomain.ExecuteAssembly(filename, null, new string[] { ipcName, ipcUri });
@ -41,14 +41,14 @@ namespace de4dot.code.AssemblyClient {
catch (AppDomainUnloadedException) {
// Here if it was unloaded by Dispose()
}
unloadAppDomain(appDomain);
UnloadAppDomain(appDomain);
appDomain = null;
}));
thread.Start();
}
public override void Dispose() {
unloadAppDomain(appDomain);
UnloadAppDomain(appDomain);
if (thread != null) {
try {
if (!thread.Join(100))
@ -60,11 +60,11 @@ namespace de4dot.code.AssemblyClient {
thread = null;
}
// It could still be loaded if the thread was aborted so do it again
unloadAppDomain(appDomain);
UnloadAppDomain(appDomain);
appDomain = null;
}
static void unloadAppDomain(AppDomain appDomain) {
static void UnloadAppDomain(AppDomain appDomain) {
if (appDomain != null) {
try {
AppDomain.Unload(appDomain);

View File

@ -32,18 +32,18 @@ namespace de4dot.code.AssemblyClient {
: base(version) {
}
public override void loadServer(string filename) {
public override void LoadServer(string filename) {
if (process != null)
throw new ApplicationException("Server is already loaded");
var psi = new ProcessStartInfo {
Arguments = string.Format("{0} {1}", Utils.shellEscape(ipcName), Utils.shellEscape(ipcUri)),
Arguments = string.Format("{0} {1}", Utils.ShellEscape(ipcName), Utils.ShellEscape(ipcUri)),
CreateNoWindow = true,
ErrorDialog = false,
FileName = filename,
LoadUserProfile = false,
UseShellExecute = false,
WorkingDirectory = Utils.getOurBaseDir(),
WorkingDirectory = Utils.GetOurBaseDir(),
};
process = Process.Start(psi);
if (process == null)

View File

@ -25,13 +25,13 @@ namespace de4dot.code.AssemblyClient {
class SameAppDomainAssemblyServerLoader : IAssemblyServerLoader {
IAssemblyService service;
public void loadServer() {
public void LoadServer() {
if (service != null)
throw new ApplicationException("Server already loaded");
service = new AssemblyService();
}
public IAssemblyService createService() {
public IAssemblyService CreateService() {
return service;
}

View File

@ -31,27 +31,27 @@ namespace de4dot.code {
ModuleContext moduleContext;
public AssemblyModule(string filename, ModuleContext moduleContext) {
this.filename = Utils.getFullPath(filename);
this.filename = Utils.GetFullPath(filename);
this.moduleContext = moduleContext;
}
public ModuleDefMD load() {
return setModule(ModuleDefMD.Load(filename, moduleContext));
public ModuleDefMD Load() {
return SetModule(ModuleDefMD.Load(filename, moduleContext));
}
public ModuleDefMD load(byte[] fileData) {
return setModule(ModuleDefMD.Load(fileData, moduleContext));
public ModuleDefMD Load(byte[] fileData) {
return SetModule(ModuleDefMD.Load(fileData, moduleContext));
}
ModuleDefMD setModule(ModuleDefMD newModule) {
ModuleDefMD SetModule(ModuleDefMD newModule) {
module = newModule;
TheAssemblyResolver.Instance.addModule(module);
TheAssemblyResolver.Instance.AddModule(module);
module.EnableTypeDefFindCache = true;
module.Location = filename;
return module;
}
public void save(string newFilename, MetaDataFlags mdFlags, IModuleWriterListener writerListener) {
public void Save(string newFilename, MetaDataFlags mdFlags, IModuleWriterListener writerListener) {
if (module.IsILOnly) {
var writerOptions = new ModuleWriterOptions(module, writerListener);
writerOptions.MetaDataOptions.Flags |= mdFlags;
@ -68,7 +68,7 @@ namespace de4dot.code {
}
}
public ModuleDefMD reload(byte[] newModuleData, DumpedMethodsRestorer dumpedMethodsRestorer, IStringDecrypter stringDecrypter) {
public ModuleDefMD Reload(byte[] newModuleData, DumpedMethodsRestorer dumpedMethodsRestorer, IStringDecrypter stringDecrypter) {
TheAssemblyResolver.Instance.Remove(module);
var mod = ModuleDefMD.Load(newModuleData, moduleContext);
if (dumpedMethodsRestorer != null)
@ -77,7 +77,7 @@ namespace de4dot.code {
mod.MethodDecrypter = dumpedMethodsRestorer;
mod.TablesStream.ColumnReader = dumpedMethodsRestorer;
mod.TablesStream.MethodRowReader = dumpedMethodsRestorer;
return setModule(mod);
return SetModule(mod);
}
public override string ToString() {

View File

@ -27,16 +27,16 @@ namespace de4dot.code {
EnableTypeDefCache = true;
}
public void addSearchDirectory(string dir) {
public void AddSearchDirectory(string dir) {
if (!PostSearchPaths.Contains(dir))
PostSearchPaths.Add(dir);
}
public void addModule(ModuleDef module) {
public void AddModule(ModuleDef module) {
AddToCache(module.Assembly);
}
public void removeModule(ModuleDef module) {
public void RemoveModule(ModuleDef module) {
var assembly = module.Assembly;
if (assembly == null)
return;
@ -44,7 +44,7 @@ namespace de4dot.code {
Remove(module.Assembly);
}
public void clearAll() {
public void ClearAll() {
//TODO: cache.Clear();
//TODO: resetSearchPaths();
}

View File

@ -28,25 +28,25 @@ namespace de4dot.code {
public class DeobfuscatorContext : IDeobfuscatorContext {
Dictionary<string, object> dataDict = new Dictionary<string, object>(StringComparer.Ordinal);
public void clear() {
public void Clear() {
dataDict.Clear();
}
public void setData(string name, object data) {
public void SetData(string name, object data) {
dataDict[name] = data;
}
public object getData(string name) {
public object GetData(string name) {
object value;
dataDict.TryGetValue(name, out value);
return value;
}
public void clearData(string name) {
public void ClearData(string name) {
dataDict.Remove(name);
}
static ITypeDefOrRef getNonGenericTypeRef(ITypeDefOrRef typeRef) {
static ITypeDefOrRef GetNonGenericTypeRef(ITypeDefOrRef typeRef) {
var ts = typeRef as TypeSpec;
if (ts == null)
return typeRef;
@ -56,10 +56,10 @@ namespace de4dot.code {
return gis.GenericType.TypeDefOrRef;
}
public TypeDef resolveType(ITypeDefOrRef type) {
public TypeDef ResolveType(ITypeDefOrRef type) {
if (type == null)
return null;
type = getNonGenericTypeRef(type);
type = GetNonGenericTypeRef(type);
var typeDef = type as TypeDef;
if (typeDef != null)
@ -72,7 +72,7 @@ namespace de4dot.code {
return null;
}
public MethodDef resolveMethod(IMethod method) {
public MethodDef ResolveMethod(IMethod method) {
if (method == null)
return null;
@ -84,14 +84,14 @@ namespace de4dot.code {
if (mr == null || !mr.IsMethodRef)
return null;
var type = resolveType(mr.DeclaringType);
var type = ResolveType(mr.DeclaringType);
if (type == null)
return null;
return type.Resolve(mr) as MethodDef;
}
public FieldDef resolveField(IField field) {
public FieldDef ResolveField(IField field) {
if (field == null)
return null;
@ -103,7 +103,7 @@ namespace de4dot.code {
if (mr == null || !mr.IsFieldRef)
return null;
var type = resolveType(mr.DeclaringType);
var type = ResolveType(mr.DeclaringType);
if (type == null)
return null;

View File

@ -37,12 +37,12 @@ namespace de4dot.code {
this.dumpedMethods = dumpedMethods;
}
DumpedMethod getDumpedMethod(uint rid) {
return dumpedMethods.get(0x06000000 | rid);
DumpedMethod GetDumpedMethod(uint rid) {
return dumpedMethods.Get(0x06000000 | rid);
}
public RawMethodRow ReadRow(uint rid) {
var dm = getDumpedMethod(rid);
var dm = GetDumpedMethod(rid);
if (dm == null)
return null;
return new RawMethodRow(dm.mdRVA, dm.mdImplFlags, dm.mdFlags, dm.mdName, dm.mdSignature, dm.mdParamList);
@ -62,11 +62,11 @@ namespace de4dot.code {
}
public bool HasMethodBody(uint rid) {
return getDumpedMethod(rid) != null;
return GetDumpedMethod(rid) != null;
}
public MethodBody GetMethodBody(uint rid, RVA rva, IList<Parameter> parameters) {
var dm = getDumpedMethod(rid);
var dm = GetDumpedMethod(rid);
if (dm == null)
return null;
return MethodBodyReader.Create(module, dm.code, dm.extraSections, parameters, dm.mhFlags, dm.mhMaxStack, dm.mhCodeSize, dm.mhLocalVarSigTok);

View File

@ -21,12 +21,12 @@ using dnlib.DotNet;
namespace de4dot.code {
public interface IDeobfuscatorContext {
void clear();
void setData(string name, object data);
object getData(string name);
void clearData(string name);
TypeDef resolveType(ITypeDefOrRef type);
MethodDef resolveMethod(IMethod method);
FieldDef resolveField(IField field);
void Clear();
void SetData(string name, object data);
object GetData(string name);
void ClearData(string name);
TypeDef ResolveType(ITypeDefOrRef type);
MethodDef ResolveMethod(IMethod method);
FieldDef ResolveField(IField field);
}
}

View File

@ -35,12 +35,12 @@ namespace de4dot.code {
bool RemoveNamespaceWithOneType { get; }
bool RenameResourceKeys { get; }
void deobfuscateBegin();
void deobfuscate();
void deobfuscateEnd();
void deobfuscateCleanUp();
void DeobfuscateBegin();
void Deobfuscate();
void DeobfuscateEnd();
void DeobfuscateCleanUp();
void load(IList<IDeobfuscator> deobfuscators);
void save();
void Load(IList<IDeobfuscator> deobfuscators);
void Save();
}
}

View File

@ -39,7 +39,7 @@ namespace de4dot.code {
if (indentLevel == value)
return;
indentLevel = value;
initIndentString();
InitIndentString();
}
}
@ -66,20 +66,20 @@ namespace de4dot.code {
this.canIgnoreMessages = canIgnoreMessages;
}
void initIndentString() {
void InitIndentString() {
if (indentLevel < 0)
indentLevel = 0;
indentString = new string(' ', indentLevel * indentSize);
}
public void indent() {
public void Indent() {
indentLevel++;
initIndentString();
InitIndentString();
}
public void deIndent() {
public void DeIndent() {
indentLevel--;
initIndentString();
InitIndentString();
}
public void Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) {
@ -93,7 +93,7 @@ namespace de4dot.code {
public void Log(bool canIgnore, object sender, LoggerEvent loggerEvent, string format, params object[] args) {
if (IgnoresEvent(loggerEvent))
return;
if (canIgnore && ignoreMessage(loggerEvent, format, args))
if (canIgnore && IgnoreMessage(loggerEvent, format, args))
return;
switch (loggerEvent) {
@ -114,7 +114,7 @@ namespace de4dot.code {
}
}
bool ignoreMessage(LoggerEvent loggerEvent, string format, object[] args) {
bool IgnoreMessage(LoggerEvent loggerEvent, string format, object[] args) {
if (loggerEvent != LoggerEvent.Error && loggerEvent != LoggerEvent.Warning)
return false;
if (!canIgnoreMessages)
@ -138,7 +138,7 @@ namespace de4dot.code {
return loggerEvent > maxLoggerEvent;
}
public static void log(LoggerEvent loggerEvent, string format, params object[] args) {
public static void Log(LoggerEvent loggerEvent, string format, params object[] args) {
Instance.Log(null, loggerEvent, format, args);
}

View File

@ -41,13 +41,13 @@ namespace de4dot.code {
Dictionary<Instruction, ExInfo> exInfos = new Dictionary<Instruction, ExInfo>();
ExInfo lastExInfo;
public void print(LoggerEvent loggerEvent, IList<Instruction> allInstructions, IList<ExceptionHandler> allExceptionHandlers) {
public void Print(LoggerEvent loggerEvent, IList<Instruction> allInstructions, IList<ExceptionHandler> allExceptionHandlers) {
try {
this.loggerEvent = loggerEvent;
this.allInstructions = allInstructions;
this.allExceptionHandlers = allExceptionHandlers;
lastExInfo = new ExInfo();
print();
Print();
}
finally {
this.allInstructions = null;
@ -59,27 +59,27 @@ namespace de4dot.code {
}
}
void initTargets() {
void InitTargets() {
foreach (var instr in allInstructions) {
switch (instr.OpCode.OperandType) {
case OperandType.ShortInlineBrTarget:
case OperandType.InlineBrTarget:
setTarget(instr.Operand as Instruction);
SetTarget(instr.Operand as Instruction);
break;
case OperandType.InlineSwitch:
foreach (var targetInstr in (Instruction[])instr.Operand)
setTarget(targetInstr);
SetTarget(targetInstr);
break;
}
}
foreach (var ex in allExceptionHandlers) {
setTarget(ex.TryStart);
setTarget(ex.TryEnd);
setTarget(ex.FilterStart);
setTarget(ex.HandlerStart);
setTarget(ex.HandlerEnd);
SetTarget(ex.TryStart);
SetTarget(ex.TryEnd);
SetTarget(ex.FilterStart);
SetTarget(ex.HandlerStart);
SetTarget(ex.HandlerEnd);
}
var sortedTargets = new List<Instruction>(targets.Keys);
@ -88,27 +88,27 @@ namespace de4dot.code {
labels[sortedTargets[i]] = string.Format("label_{0}", i);
}
void setTarget(Instruction instr) {
void SetTarget(Instruction instr) {
if (instr != null)
targets[instr] = true;
}
void initExHandlers() {
void InitExHandlers() {
foreach (var ex in allExceptionHandlers) {
if (ex.TryStart != null) {
getExInfo(ex.TryStart).tryStarts.Add(ex);
getExInfo(ex.TryEnd).tryEnds.Add(ex);
GetExInfo(ex.TryStart).tryStarts.Add(ex);
GetExInfo(ex.TryEnd).tryEnds.Add(ex);
}
if (ex.FilterStart != null)
getExInfo(ex.FilterStart).filterStarts.Add(ex);
GetExInfo(ex.FilterStart).filterStarts.Add(ex);
if (ex.HandlerStart != null) {
getExInfo(ex.HandlerStart).handlerStarts.Add(ex);
getExInfo(ex.HandlerEnd).handlerEnds.Add(ex);
GetExInfo(ex.HandlerStart).handlerStarts.Add(ex);
GetExInfo(ex.HandlerEnd).handlerEnds.Add(ex);
}
}
}
ExInfo getExInfo(Instruction instruction) {
ExInfo GetExInfo(Instruction instruction) {
if (instruction == null)
return lastExInfo;
ExInfo exInfo;
@ -117,49 +117,49 @@ namespace de4dot.code {
return exInfo;
}
void print() {
initTargets();
initExHandlers();
void Print() {
InitTargets();
InitExHandlers();
Logger.Instance.indent();
Logger.Instance.Indent();
foreach (var instr in allInstructions) {
if (targets.ContainsKey(instr)) {
Logger.Instance.deIndent();
Logger.log(loggerEvent, "{0}:", getLabel(instr));
Logger.Instance.indent();
Logger.Instance.DeIndent();
Logger.Log(loggerEvent, "{0}:", GetLabel(instr));
Logger.Instance.Indent();
}
ExInfo exInfo;
if (exInfos.TryGetValue(instr, out exInfo))
printExInfo(exInfo);
PrintExInfo(exInfo);
var instrString = instr.OpCode.Name;
var operandString = getOperandString(instr);
var operandString = GetOperandString(instr);
var memberRef = instr.Operand as ITokenOperand;
if (operandString == "")
Logger.log(loggerEvent, "{0}", instrString);
Logger.Log(loggerEvent, "{0}", instrString);
else if (memberRef != null)
Logger.log(loggerEvent, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberRef.MDToken.ToUInt32());
Logger.Log(loggerEvent, "{0,-9} {1} // {2:X8}", instrString, Utils.RemoveNewlines(operandString), memberRef.MDToken.ToUInt32());
else
Logger.log(loggerEvent, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString));
Logger.Log(loggerEvent, "{0,-9} {1}", instrString, Utils.RemoveNewlines(operandString));
}
printExInfo(lastExInfo);
Logger.Instance.deIndent();
PrintExInfo(lastExInfo);
Logger.Instance.DeIndent();
}
string getOperandString(Instruction instr) {
string GetOperandString(Instruction instr) {
if (instr.Operand is Instruction)
return getLabel((Instruction)instr.Operand);
return GetLabel((Instruction)instr.Operand);
else if (instr.Operand is Instruction[]) {
var sb = new StringBuilder();
var targets = (Instruction[])instr.Operand;
for (int i = 0; i < targets.Length; i++) {
if (i > 0)
sb.Append(',');
sb.Append(getLabel(targets[i]));
sb.Append(GetLabel(targets[i]));
}
return sb.ToString();
}
else if (instr.Operand is string)
return Utils.toCsharpString((string)instr.Operand);
return Utils.ToCsharpString((string)instr.Operand);
else if (instr.Operand is Parameter) {
var arg = (Parameter)instr.Operand;
var s = InstructionPrinter.GetOperandString(instr);
@ -171,36 +171,36 @@ namespace de4dot.code {
return InstructionPrinter.GetOperandString(instr);
}
void printExInfo(ExInfo exInfo) {
Logger.Instance.deIndent();
void PrintExInfo(ExInfo exInfo) {
Logger.Instance.DeIndent();
foreach (var ex in exInfo.tryStarts)
Logger.log(loggerEvent, "// try start: {0}", getExceptionString(ex));
Logger.Log(loggerEvent, "// try start: {0}", GetExceptionString(ex));
foreach (var ex in exInfo.tryEnds)
Logger.log(loggerEvent, "// try end: {0}", getExceptionString(ex));
Logger.Log(loggerEvent, "// try end: {0}", GetExceptionString(ex));
foreach (var ex in exInfo.filterStarts)
Logger.log(loggerEvent, "// filter start: {0}", getExceptionString(ex));
Logger.Log(loggerEvent, "// filter start: {0}", GetExceptionString(ex));
foreach (var ex in exInfo.handlerStarts)
Logger.log(loggerEvent, "// handler start: {0}", getExceptionString(ex));
Logger.Log(loggerEvent, "// handler start: {0}", GetExceptionString(ex));
foreach (var ex in exInfo.handlerEnds)
Logger.log(loggerEvent, "// handler end: {0}", getExceptionString(ex));
Logger.Instance.indent();
Logger.Log(loggerEvent, "// handler end: {0}", GetExceptionString(ex));
Logger.Instance.Indent();
}
string getExceptionString(ExceptionHandler ex) {
string GetExceptionString(ExceptionHandler ex) {
var sb = new StringBuilder();
if (ex.TryStart != null)
sb.Append(string.Format("TRY: {0}-{1}", getLabel(ex.TryStart), getLabel(ex.TryEnd)));
sb.Append(string.Format("TRY: {0}-{1}", GetLabel(ex.TryStart), GetLabel(ex.TryEnd)));
if (ex.FilterStart != null)
sb.Append(string.Format(", FILTER: {0}", getLabel(ex.FilterStart)));
sb.Append(string.Format(", FILTER: {0}", GetLabel(ex.FilterStart)));
if (ex.HandlerStart != null)
sb.Append(string.Format(", HANDLER: {0}-{1}", getLabel(ex.HandlerStart), getLabel(ex.HandlerEnd)));
sb.Append(string.Format(", HANDLER: {0}-{1}", GetLabel(ex.HandlerStart), GetLabel(ex.HandlerEnd)));
sb.Append(string.Format(", TYPE: {0}", ex.HandlerType));
if (ex.CatchType != null)
sb.Append(string.Format(", CATCH: {0}", ex.CatchType));
return sb.ToString();
}
string getLabel(Instruction instr) {
string GetLabel(Instruction instr) {
if (instr == null)
return "<end>";
return labels[instr];

View File

@ -35,24 +35,24 @@ namespace de4dot.code {
object value;
bool unknownValue = false;
public bool isValid() {
public bool IsValid() {
return !unknownValue && writes == 1;
}
public object Value {
get {
if (!isValid())
if (!IsValid())
throw new ApplicationException("Unknown variable value");
return value;
}
set { this.value = value; }
}
public void addWrite() {
public void AddWrite() {
writes++;
}
public void setUnknown() {
public void SetUnknown() {
unknownValue = true;
}
}
@ -60,10 +60,10 @@ namespace de4dot.code {
public VariableValues(IList<Local> locals, IList<Block> allBlocks) {
this.locals = locals;
this.allBlocks = allBlocks;
init();
Initialize();
}
void init() {
void Initialize() {
foreach (var variable in locals)
variableToValue[variable] = new Variable();
@ -78,12 +78,12 @@ namespace de4dot.code {
case Code.Stloc_1:
case Code.Stloc_2:
case Code.Stloc_3:
var variable = Instr.getLocalVar(locals, instr);
var variable = Instr.GetLocalVar(locals, instr);
var val = variableToValue[variable];
val.addWrite();
val.AddWrite();
object obj;
if (!getValue(block, i, out obj))
val.setUnknown();
if (!GetValue(block, i, out obj))
val.SetUnknown();
val.Value = obj;
break;
@ -94,7 +94,7 @@ namespace de4dot.code {
}
}
bool getValue(Block block, int index, out object obj) {
bool GetValue(Block block, int index, out object obj) {
while (true) {
if (index <= 0) {
obj = null;
@ -135,7 +135,7 @@ namespace de4dot.code {
}
}
public Variable getValue(Local variable) {
public Variable GetValue(Local variable) {
return variableToValue[variable];
}
}
@ -165,7 +165,7 @@ namespace de4dot.code {
this.callEndIndex = callEndIndex;
}
public IMethod getMethodRef() {
public IMethod GetMethodRef() {
return (IMethod)block.Instructions[callEndIndex].Operand;
}
}
@ -180,18 +180,18 @@ namespace de4dot.code {
get { return theMethod; }
}
protected abstract void inlineAllCalls();
protected abstract void InlineAllCalls();
// Returns null if method is not a method we should inline
protected abstract CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex);
protected abstract CallResult CreateCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex);
public int decrypt(Blocks blocks) {
public int Decrypt(Blocks blocks) {
if (!HasHandlers)
return 0;
return decrypt(blocks.Method, blocks.MethodBlocks.getAllBlocks());
return Decrypt(blocks.Method, blocks.MethodBlocks.GetAllBlocks());
}
public int decrypt(MethodDef method, List<Block> allBlocks) {
public int Decrypt(MethodDef method, List<Block> allBlocks) {
if (!HasHandlers)
return 0;
try {
@ -199,9 +199,9 @@ namespace de4dot.code {
callResults = new List<CallResult>();
this.allBlocks = allBlocks;
findAllCallResults();
inlineAllCalls();
inlineReturnValues();
FindAllCallResults();
InlineAllCalls();
InlineReturnValues();
return callResults.Count;
}
catch {
@ -216,11 +216,11 @@ namespace de4dot.code {
}
}
bool getLocalVariableValue(Local variable, out object value) {
bool GetLocalVariableValue(Local variable, out object value) {
if (variableValues == null)
variableValues = new VariableValues(theMethod.Body.Variables, allBlocks);
var val = variableValues.getValue(variable);
if (!val.isValid()) {
var val = variableValues.GetValue(variable);
if (!val.IsValid()) {
value = null;
return false;
}
@ -228,12 +228,12 @@ namespace de4dot.code {
return true;
}
void findAllCallResults() {
void FindAllCallResults() {
foreach (var block in allBlocks)
findCallResults(block);
FindCallResults(block);
}
void findCallResults(Block block) {
void FindCallResults(Block block) {
for (int i = 0; i < block.Instructions.Count; i++) {
var instr = block.Instructions[i];
if (instr.OpCode != OpCodes.Call)
@ -246,31 +246,31 @@ namespace de4dot.code {
var gim = method as MethodSpec;
if (gim != null)
elementMethod = gim.Method;
var callResult = createCallResult(elementMethod, gim, block, i);
var callResult = CreateCallResult(elementMethod, gim, block, i);
if (callResult == null)
continue;
if (findArgs(callResult))
if (FindArgs(callResult))
callResults.Add(callResult);
}
}
bool findArgs(CallResult callResult) {
bool FindArgs(CallResult callResult) {
var block = callResult.block;
var method = callResult.getMethodRef();
var methodArgs = DotNetUtils.getArgs(method);
var method = callResult.GetMethodRef();
var methodArgs = DotNetUtils.GetArgs(method);
int numArgs = methodArgs.Count;
var args = new object[numArgs];
int instrIndex = callResult.callEndIndex - 1;
for (int i = numArgs - 1; i >= 0; i--) {
object arg = null;
if (!getArg(method, block, ref arg, ref instrIndex))
if (!GetArg(method, block, ref arg, ref instrIndex))
return false;
if (arg is int)
arg = fixIntArg(methodArgs[i], (int)arg);
arg = FixIntArg(methodArgs[i], (int)arg);
else if (arg is long)
arg = fixIntArg(methodArgs[i], (long)arg);
arg = FixIntArg(methodArgs[i], (long)arg);
args[i] = arg;
}
@ -279,7 +279,7 @@ namespace de4dot.code {
return true;
}
object fixIntArg(TypeSig type, long value) {
object FixIntArg(TypeSig type, long value) {
switch (type.ElementType) {
case ElementType.Boolean: return value != 0;
case ElementType.Char: return (char)value;
@ -295,14 +295,14 @@ namespace de4dot.code {
throw new ApplicationException(string.Format("Wrong type {0}", type));
}
bool getArg(IMethod method, Block block, ref object arg, ref int instrIndex) {
bool GetArg(IMethod method, Block block, ref object arg, ref int instrIndex) {
while (true) {
if (instrIndex < 0) {
// We're here if there were no cflow deobfuscation, or if there are two or
// more blocks branching to the decrypter method, or the two blocks can't be
// merged because one is outside the exception handler (eg. buggy obfuscator).
Logger.w("Could not find all arguments to method {0} ({1:X8})",
Utils.removeNewlines(method),
Utils.RemoveNewlines(method),
method.MDToken.ToInt32());
errors++;
return false;
@ -342,7 +342,7 @@ namespace de4dot.code {
case Code.Ldloc_1:
case Code.Ldloc_2:
case Code.Ldloc_3:
getLocalVariableValue(instr.Instruction.GetLocal(theMethod.Body.Variables), out arg);
GetLocalVariableValue(instr.Instruction.GetLocal(theMethod.Body.Variables), out arg);
break;
case Code.Ldfld:
@ -355,7 +355,7 @@ namespace de4dot.code {
instr.Instruction.CalculateStackUsage(false, out pushes, out pops);
if (!useUnknownArgs || pushes != 1) {
Logger.w("Could not find all arguments to method {0} ({1:X8}), instr: {2}",
Utils.removeNewlines(method),
Utils.RemoveNewlines(method),
method.MDToken.ToInt32(),
instr);
errors++;
@ -363,7 +363,7 @@ namespace de4dot.code {
}
for (int i = 0; i < pops; i++) {
if (!getArg(method, block, ref arg, ref instrIndex))
if (!GetArg(method, block, ref arg, ref instrIndex))
return false;
}
arg = null;
@ -375,8 +375,8 @@ namespace de4dot.code {
return true;
}
void inlineReturnValues() {
callResults = removeNulls(callResults);
void InlineReturnValues() {
callResults = RemoveNulls(callResults);
callResults.Sort((a, b) => {
int i1 = allBlocks.FindIndex((x) => a.block == x);
int i2 = allBlocks.FindIndex((x) => b.block == x);
@ -386,10 +386,10 @@ namespace de4dot.code {
return a.callStartIndex.CompareTo(b.callStartIndex);
});
callResults.Reverse();
inlineReturnValues(callResults);
InlineReturnValues(callResults);
}
static List<CallResult> removeNulls(List<CallResult> inList) {
static List<CallResult> RemoveNulls(List<CallResult> inList) {
var outList = new List<CallResult>(inList.Count);
foreach (var callResult in inList) {
if (callResult.returnValue != null)
@ -398,6 +398,6 @@ namespace de4dot.code {
return outList;
}
protected abstract void inlineReturnValues(IList<CallResult> callResults);
protected abstract void InlineReturnValues(IList<CallResult> callResults);
}
}

View File

@ -39,7 +39,7 @@ namespace de4dot.code {
}
// Returns true if the regex matches. Use MatchValue to get result.
public bool isMatch(string s) {
public bool IsMatch(string s) {
return regex.IsMatch(s);
}
@ -60,10 +60,10 @@ namespace de4dot.code {
}
public NameRegexes(string regex) {
set(regex);
Set(regex);
}
public void set(string regexesString) {
public void Set(string regexesString) {
regexes = new List<NameRegex>();
if (regexesString != "") {
foreach (var regex in regexesString.Split(new char[] { regexSeparatorChar }))
@ -71,9 +71,9 @@ namespace de4dot.code {
}
}
public bool isMatch(string s) {
public bool IsMatch(string s) {
foreach (var regex in regexes) {
if (regex.isMatch(s))
if (regex.IsMatch(s))
return regex.MatchValue;
}

View File

@ -55,27 +55,27 @@ namespace de4dot.code {
public SavedMethodBody(MethodDef method) {
this.method = method;
DotNetUtils.copyBody(method, out instructions, out exceptionHandlers);
DotNetUtils.CopyBody(method, out instructions, out exceptionHandlers);
}
public void restore() {
DotNetUtils.restoreBody(method, instructions, exceptionHandlers);
public void Restore() {
DotNetUtils.RestoreBody(method, instructions, exceptionHandlers);
}
}
public void save(MethodDef method) {
if (isSaved(method))
public void Save(MethodDef method) {
if (IsSaved(method))
return;
savedMethodBodies[method] = new SavedMethodBody(method);
}
public void restoreAll() {
public void RestoreAll() {
foreach (var smb in savedMethodBodies.Values)
smb.restore();
smb.Restore();
savedMethodBodies.Clear();
}
public bool isSaved(MethodDef method) {
public bool IsSaved(MethodDef method) {
return savedMethodBodies.ContainsKey(method);
}
}
@ -139,17 +139,17 @@ namespace de4dot.code {
this.assemblyClientFactory = assemblyClientFactory;
this.options = options;
userStringDecrypterMethods = options.StringDecrypterMethods.Count > 0;
options.Filename = Utils.getFullPath(options.Filename);
options.Filename = Utils.GetFullPath(options.Filename);
assemblyModule = new AssemblyModule(options.Filename, moduleContext);
if (options.NewFilename == null)
options.NewFilename = getDefaultNewFilename();
options.NewFilename = GetDefaultNewFilename();
if (string.Equals(options.Filename, options.NewFilename, StringComparison.OrdinalIgnoreCase))
throw new UserException(string.Format("filename is same as new filename! ({0})", options.Filename));
}
string getDefaultNewFilename() {
string GetDefaultNewFilename() {
int dotIndex = options.Filename.LastIndexOf('.');
string noExt, ext;
if (dotIndex != -1) {
@ -163,15 +163,15 @@ namespace de4dot.code {
return noExt + "-cleaned" + ext;
}
public void load(IList<IDeobfuscator> deobfuscators) {
public void Load(IList<IDeobfuscator> deobfuscators) {
try {
loadModule(deobfuscators);
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(Filename));
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(NewFilename));
detectObfuscator(deobfuscators);
LoadModule(deobfuscators);
TheAssemblyResolver.Instance.AddSearchDirectory(Utils.GetDirName(Filename));
TheAssemblyResolver.Instance.AddSearchDirectory(Utils.GetDirName(NewFilename));
DetectObfuscator(deobfuscators);
if (deob == null)
throw new ApplicationException("Could not detect obfuscator!");
initializeDeobfuscator();
InitializeDeobfuscator();
}
finally {
foreach (var d in deobfuscators) {
@ -181,13 +181,13 @@ namespace de4dot.code {
}
}
void loadModule(IEnumerable<IDeobfuscator> deobfuscators) {
void LoadModule(IEnumerable<IDeobfuscator> deobfuscators) {
ModuleDefMD oldModule = module;
try {
module = assemblyModule.load();
module = assemblyModule.Load();
}
catch (BadImageFormatException) {
if (!unpackNativeImage(deobfuscators))
if (!UnpackNativeImage(deobfuscators))
throw new BadImageFormatException();
Logger.v("Unpacked native file");
}
@ -197,12 +197,12 @@ namespace de4dot.code {
}
}
bool unpackNativeImage(IEnumerable<IDeobfuscator> deobfuscators) {
bool UnpackNativeImage(IEnumerable<IDeobfuscator> deobfuscators) {
using (var peImage = new PEImage(Filename)) {
foreach (var deob in deobfuscators) {
byte[] unpackedData = null;
try {
unpackedData = deob.unpackNativeFile(peImage);
unpackedData = deob.UnpackNativeFile(peImage);
}
catch {
}
@ -211,7 +211,7 @@ namespace de4dot.code {
var oldModule = module;
try {
module = assemblyModule.load(unpackedData);
module = assemblyModule.Load(unpackedData);
}
catch {
Logger.w("Could not load unpacked data. File: {0}, deobfuscator: {0}", peImage.FileName ?? "(unknown filename)", deob.TypeLong);
@ -229,16 +229,16 @@ namespace de4dot.code {
return false;
}
void initializeDeobfuscator() {
void InitializeDeobfuscator() {
if (options.StringDecrypterType == DecrypterType.Default)
options.StringDecrypterType = deob.DefaultDecrypterType;
if (options.StringDecrypterType == DecrypterType.Default)
options.StringDecrypterType = DecrypterType.Static;
deob.Operations = createOperations();
deob.Operations = CreateOperations();
}
IOperations createOperations() {
IOperations CreateOperations() {
var op = new Operations();
switch (options.StringDecrypterType) {
@ -260,7 +260,7 @@ namespace de4dot.code {
return op;
}
void detectObfuscator(IEnumerable<IDeobfuscator> deobfuscators) {
void DetectObfuscator(IEnumerable<IDeobfuscator> deobfuscators) {
// The deobfuscators may call methods to deobfuscate control flow and decrypt
// strings (statically) in order to detect the obfuscator.
@ -269,14 +269,14 @@ namespace de4dot.code {
// It's not null if it unpacked a native file
if (this.deob != null) {
deob.init(module);
deob.Initialize(module);
deob.DeobfuscatedFile = this;
deob.detect();
deob.Detect();
return;
}
foreach (var deob in deobfuscators) {
deob.init(module);
deob.Initialize(module);
deob.DeobfuscatedFile = this;
}
@ -284,16 +284,16 @@ namespace de4dot.code {
foreach (var deob in deobfuscators) {
if (string.Equals(options.ForcedObfuscatorType, deob.Type, StringComparison.OrdinalIgnoreCase)) {
this.deob = deob;
deob.detect();
deob.Detect();
return;
}
}
}
else
this.deob = detectObfuscator2(deobfuscators);
this.deob = DetectObfuscator2(deobfuscators);
}
IDeobfuscator detectObfuscator2(IEnumerable<IDeobfuscator> deobfuscators) {
IDeobfuscator DetectObfuscator2(IEnumerable<IDeobfuscator> deobfuscators) {
var allDetected = new List<IDeobfuscator>();
IDeobfuscator detected = null;
int detectVal = 0;
@ -301,7 +301,7 @@ namespace de4dot.code {
this.deob = deob; // So we can call deob.CanInlineMethods in deobfuscate()
int val;
try {
val = deob.detect();
val = deob.Detect();
}
catch {
val = deob.Type == "un" ? 1 : 0;
@ -318,16 +318,16 @@ namespace de4dot.code {
if (allDetected.Count > 1) {
Logger.n("More than one obfuscator detected:");
Logger.Instance.indent();
Logger.Instance.Indent();
foreach (var deob in allDetected)
Logger.n("{0} (use: -p {1})", deob.Name, deob.Type);
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
}
return detected;
}
MetaDataFlags getMetaDataFlags() {
MetaDataFlags GetMetaDataFlags() {
var mdFlags = options.MetaDataFlags | deob.MetaDataFlags;
// Always preserve tokens if it's an unknown obfuscator
@ -341,15 +341,15 @@ namespace de4dot.code {
return mdFlags;
}
public void save() {
public void Save() {
Logger.n("Saving {0}", options.NewFilename);
var mdFlags = getMetaDataFlags();
var mdFlags = GetMetaDataFlags();
if (!options.ControlFlowDeobfuscation)
mdFlags |= MetaDataFlags.KeepOldMaxStack;
assemblyModule.save(options.NewFilename, mdFlags, deob as IModuleWriterListener);
assemblyModule.Save(options.NewFilename, mdFlags, deob as IModuleWriterListener);
}
IList<MethodDef> getAllMethods() {
IList<MethodDef> GetAllMethods() {
var list = new List<MethodDef>();
foreach (var type in module.GetTypes()) {
@ -360,25 +360,25 @@ namespace de4dot.code {
return list;
}
public void deobfuscateBegin() {
public void DeobfuscateBegin() {
switch (options.StringDecrypterType) {
case DecrypterType.None:
checkSupportedStringDecrypter(StringFeatures.AllowNoDecryption);
CheckSupportedStringDecrypter(StringFeatures.AllowNoDecryption);
break;
case DecrypterType.Static:
checkSupportedStringDecrypter(StringFeatures.AllowStaticDecryption);
CheckSupportedStringDecrypter(StringFeatures.AllowStaticDecryption);
break;
case DecrypterType.Delegate:
case DecrypterType.Emulate:
checkSupportedStringDecrypter(StringFeatures.AllowDynamicDecryption);
CheckSupportedStringDecrypter(StringFeatures.AllowDynamicDecryption);
var newProcFactory = assemblyClientFactory as NewProcessAssemblyClientFactory;
if (newProcFactory != null)
assemblyClient = newProcFactory.create(module);
assemblyClient = newProcFactory.Create(module);
else
assemblyClient = assemblyClientFactory.create();
assemblyClient.connect();
assemblyClient = assemblyClientFactory.Create();
assemblyClient.Connect();
break;
default:
@ -386,73 +386,73 @@ namespace de4dot.code {
}
}
public void checkSupportedStringDecrypter(StringFeatures feature) {
public void CheckSupportedStringDecrypter(StringFeatures feature) {
if ((deob.StringFeatures & feature) == feature)
return;
throw new UserException(string.Format("Deobfuscator {0} does not support this string decryption type", deob.TypeLong));
}
public void deobfuscate() {
public void Deobfuscate() {
Logger.n("Cleaning {0}", options.Filename);
initAssemblyClient();
InitAssemblyClient();
for (int i = 0; ; i++) {
byte[] fileData = null;
DumpedMethods dumpedMethods = null;
if (!deob.getDecryptedModule(i, ref fileData, ref dumpedMethods))
if (!deob.GetDecryptedModule(i, ref fileData, ref dumpedMethods))
break;
reloadModule(fileData, dumpedMethods);
ReloadModule(fileData, dumpedMethods);
}
deob.deobfuscateBegin();
deobfuscateMethods();
deob.deobfuscateEnd();
deob.DeobfuscateBegin();
DeobfuscateMethods();
deob.DeobfuscateEnd();
}
void reloadModule(byte[] newModuleData, DumpedMethods dumpedMethods) {
void ReloadModule(byte[] newModuleData, DumpedMethods dumpedMethods) {
Logger.v("Reloading decrypted assembly (original filename: {0})", Filename);
simpleDeobfuscatorFlags.Clear();
using (var oldModule = module) {
module = assemblyModule.reload(newModuleData, createDumpedMethodsRestorer(dumpedMethods), deob as IStringDecrypter);
deob = deob.moduleReloaded(module);
module = assemblyModule.Reload(newModuleData, CreateDumpedMethodsRestorer(dumpedMethods), deob as IStringDecrypter);
deob = deob.ModuleReloaded(module);
}
initializeDeobfuscator();
InitializeDeobfuscator();
deob.DeobfuscatedFile = this;
updateDynamicStringInliner();
UpdateDynamicStringInliner();
}
DumpedMethodsRestorer createDumpedMethodsRestorer(DumpedMethods dumpedMethods) {
DumpedMethodsRestorer CreateDumpedMethodsRestorer(DumpedMethods dumpedMethods) {
if (dumpedMethods == null || dumpedMethods.Count == 0)
return null;
return new DumpedMethodsRestorer(dumpedMethods);
}
void initAssemblyClient() {
void InitAssemblyClient() {
if (assemblyClient == null)
return;
assemblyClient.waitConnected();
assemblyClient.Service.loadAssembly(options.Filename);
assemblyClient.WaitConnected();
assemblyClient.Service.LoadAssembly(options.Filename);
if (options.StringDecrypterType == DecrypterType.Delegate)
assemblyClient.Service.setStringDecrypterType(AssemblyData.StringDecrypterType.Delegate);
assemblyClient.Service.SetStringDecrypterType(AssemblyData.StringDecrypterType.Delegate);
else if (options.StringDecrypterType == DecrypterType.Emulate)
assemblyClient.Service.setStringDecrypterType(AssemblyData.StringDecrypterType.Emulate);
assemblyClient.Service.SetStringDecrypterType(AssemblyData.StringDecrypterType.Emulate);
else
throw new ApplicationException(string.Format("Invalid string decrypter type '{0}'", options.StringDecrypterType));
dynamicStringInliner = new DynamicStringInliner(assemblyClient);
updateDynamicStringInliner();
UpdateDynamicStringInliner();
}
void updateDynamicStringInliner() {
void UpdateDynamicStringInliner() {
if (dynamicStringInliner != null)
dynamicStringInliner.init(getMethodTokens());
dynamicStringInliner.Initialize(GetMethodTokens());
}
IEnumerable<int> getMethodTokens() {
IEnumerable<int> GetMethodTokens() {
if (!userStringDecrypterMethods)
return deob.getStringDecrypterMethods();
return deob.GetStringDecrypterMethods();
var tokens = new List<int>();
@ -464,18 +464,18 @@ namespace de4dot.code {
if (int.TryParse(tokenStr, NumberStyles.HexNumber, null, out methodToken))
tokens.Add(methodToken);
else
tokens.AddRange(findMethodTokens(val));
tokens.AddRange(FindMethodTokens(val));
}
return tokens;
}
IEnumerable<int> findMethodTokens(string methodDesc) {
IEnumerable<int> FindMethodTokens(string methodDesc) {
var tokens = new List<int>();
string typeString, methodName;
string[] argsStrings;
splitMethodDesc(methodDesc, out typeString, out methodName, out argsStrings);
SplitMethodDesc(methodDesc, out typeString, out methodName, out argsStrings);
foreach (var type in module.GetTypes()) {
if (typeString != null && typeString != type.FullName)
@ -502,7 +502,7 @@ namespace de4dot.code {
}
}
Logger.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MDToken.ToInt32(), Utils.removeNewlines(method.FullName));
Logger.v("Adding string decrypter; token: {0:X8}, method: {1}", method.MDToken.ToInt32(), Utils.RemoveNewlines(method.FullName));
tokens.Add(method.MDToken.ToInt32());
}
}
@ -510,7 +510,7 @@ namespace de4dot.code {
return tokens;
}
static void splitMethodDesc(string methodDesc, out string type, out string name, out string[] args) {
static void SplitMethodDesc(string methodDesc, out string type, out string name, out string[] args) {
string stringArgs = null;
args = null;
type = null;
@ -555,20 +555,20 @@ namespace de4dot.code {
name = null;
}
public void deobfuscateEnd() {
deobfuscateCleanUp();
public void DeobfuscateEnd() {
DeobfuscateCleanUp();
}
public void deobfuscateCleanUp() {
public void DeobfuscateCleanUp() {
if (assemblyClient != null) {
assemblyClient.Dispose();
assemblyClient = null;
}
}
void deobfuscateMethods() {
void DeobfuscateMethods() {
if (savedMethodBodies != null) {
savedMethodBodies.restoreAll();
savedMethodBodies.RestoreAll();
savedMethodBodies = null;
}
deob.DeobfuscatedFile = null;
@ -584,21 +584,21 @@ namespace de4dot.code {
Logger.v("Deobfuscating methods");
var methodPrinter = new MethodPrinter();
var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators);
foreach (var method in getAllMethods()) {
foreach (var method in GetAllMethods()) {
if (isVerbose) {
Logger.v("Deobfuscating {0} ({1:X8})", Utils.removeNewlines(method), method.MDToken.ToUInt32());
Logger.Instance.indent();
Logger.v("Deobfuscating {0} ({1:X8})", Utils.RemoveNewlines(method), method.MDToken.ToUInt32());
Logger.Instance.Indent();
}
int oldIndentLevel = Logger.Instance.IndentLevel;
try {
deobfuscate(method, cflowDeobfuscator, methodPrinter, isVerbose, isVV);
Deobfuscate(method, cflowDeobfuscator, methodPrinter, isVerbose, isVV);
}
catch (ApplicationException) {
throw;
}
catch (Exception ex) {
if (!canLoadMethodBody(method)) {
if (!CanLoadMethodBody(method)) {
if (isVerbose)
Logger.v("Invalid method body. {0:X8}", method.MDToken.ToInt32());
method.Body = new CilBody();
@ -612,14 +612,14 @@ namespace de4dot.code {
finally {
Logger.Instance.IndentLevel = oldIndentLevel;
}
removeNoInliningAttribute(method);
RemoveNoInliningAttribute(method);
if (isVerbose)
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
}
}
static bool canLoadMethodBody(MethodDef method) {
static bool CanLoadMethodBody(MethodDef method) {
try {
var body = method.Body;
return true;
@ -631,39 +631,39 @@ namespace de4dot.code {
bool CanOptimizeLocals() {
// Don't remove any locals if we must preserve StandAloneSig table
return (getMetaDataFlags() & MetaDataFlags.PreserveStandAloneSigRids) == 0;
return (GetMetaDataFlags() & MetaDataFlags.PreserveStandAloneSigRids) == 0;
}
void deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter, bool isVerbose, bool isVV) {
if (!hasNonEmptyBody(method))
void Deobfuscate(MethodDef method, BlocksCflowDeobfuscator cflowDeobfuscator, MethodPrinter methodPrinter, bool isVerbose, bool isVV) {
if (!HasNonEmptyBody(method))
return;
var blocks = new Blocks(method);
int numRemovedLocals = 0;
int oldNumInstructions = method.Body.Instructions.Count;
deob.deobfuscateMethodBegin(blocks);
deob.DeobfuscateMethodBegin(blocks);
if (options.ControlFlowDeobfuscation) {
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
cflowDeobfuscator.Initialize(blocks);
cflowDeobfuscator.Deobfuscate();
}
if (deob.deobfuscateOther(blocks) && options.ControlFlowDeobfuscation)
cflowDeobfuscator.deobfuscate();
if (deob.DeobfuscateOther(blocks) && options.ControlFlowDeobfuscation)
cflowDeobfuscator.Deobfuscate();
if (options.ControlFlowDeobfuscation) {
if (CanOptimizeLocals())
numRemovedLocals = blocks.optimizeLocals();
blocks.repartitionBlocks();
numRemovedLocals = blocks.OptimizeLocals();
blocks.RepartitionBlocks();
}
deobfuscateStrings(blocks);
deob.deobfuscateMethodEnd(blocks);
DeobfuscateStrings(blocks);
deob.DeobfuscateMethodEnd(blocks);
IList<Instruction> allInstructions;
IList<ExceptionHandler> allExceptionHandlers;
blocks.getCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
blocks.GetCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers);
if (isVerbose && numRemovedLocals > 0)
Logger.v("Removed {0} unused local(s)", numRemovedLocals);
@ -672,29 +672,29 @@ namespace de4dot.code {
Logger.v("Removed {0} dead instruction(s)", numRemovedInstructions);
if (isVV) {
Logger.log(LoggerEvent.VeryVerbose, "Deobfuscated code:");
Logger.Instance.indent();
methodPrinter.print(LoggerEvent.VeryVerbose, allInstructions, allExceptionHandlers);
Logger.Instance.deIndent();
Logger.Log(LoggerEvent.VeryVerbose, "Deobfuscated code:");
Logger.Instance.Indent();
methodPrinter.Print(LoggerEvent.VeryVerbose, allInstructions, allExceptionHandlers);
Logger.Instance.DeIndent();
}
}
bool hasNonEmptyBody(MethodDef method) {
bool HasNonEmptyBody(MethodDef method) {
return method.HasBody && method.Body.Instructions.Count > 0;
}
void deobfuscateStrings(Blocks blocks) {
void DeobfuscateStrings(Blocks blocks) {
switch (options.StringDecrypterType) {
case DecrypterType.None:
break;
case DecrypterType.Static:
deob.deobfuscateStrings(blocks);
deob.DeobfuscateStrings(blocks);
break;
case DecrypterType.Delegate:
case DecrypterType.Emulate:
dynamicStringInliner.decrypt(blocks);
dynamicStringInliner.Decrypt(blocks);
break;
default:
@ -702,14 +702,14 @@ namespace de4dot.code {
}
}
void removeNoInliningAttribute(MethodDef method) {
void RemoveNoInliningAttribute(MethodDef method) {
method.IsNoInlining = false;
for (int i = 0; i < method.CustomAttributes.Count; i++) {
var cattr = method.CustomAttributes[i];
if (cattr.TypeFullName != "System.Runtime.CompilerServices.MethodImplAttribute")
continue;
int options = 0;
if (!getMethodImplOptions(cattr, ref options))
if (!GetMethodImplOptions(cattr, ref options))
continue;
if (options != 0 && options != (int)MethodImplAttributes.NoInlining)
continue;
@ -718,7 +718,7 @@ namespace de4dot.code {
}
}
static bool getMethodImplOptions(CustomAttribute cattr, ref int value) {
static bool GetMethodImplOptions(CustomAttribute cattr, ref int value) {
if (cattr.IsRawBlob)
return false;
if (cattr.ConstructorArguments.Count != 1)
@ -751,21 +751,21 @@ namespace de4dot.code {
HasDeobfuscated = 0x1,
}
Dictionary<MethodDef, SimpleDeobFlags> simpleDeobfuscatorFlags = new Dictionary<MethodDef, SimpleDeobFlags>();
bool check(MethodDef method, SimpleDeobFlags flag) {
bool Check(MethodDef method, SimpleDeobFlags flag) {
SimpleDeobFlags oldFlags;
simpleDeobfuscatorFlags.TryGetValue(method, out oldFlags);
simpleDeobfuscatorFlags[method] = oldFlags | flag;
return (oldFlags & flag) == flag;
}
void deobfuscate(MethodDef method, string msg, Action<Blocks> handler) {
void Deobfuscate(MethodDef method, string msg, Action<Blocks> handler) {
if (savedMethodBodies != null)
savedMethodBodies.save(method);
savedMethodBodies.Save(method);
Logger.v("{0}: {1} ({2:X8})", msg, Utils.removeNewlines(method), method.MDToken.ToUInt32());
Logger.Instance.indent();
Logger.v("{0}: {1} ({2:X8})", msg, Utils.RemoveNewlines(method), method.MDToken.ToUInt32());
Logger.Instance.Indent();
if (hasNonEmptyBody(method)) {
if (HasNonEmptyBody(method)) {
try {
var blocks = new Blocks(method);
@ -773,55 +773,55 @@ namespace de4dot.code {
IList<Instruction> allInstructions;
IList<ExceptionHandler> allExceptionHandlers;
blocks.getCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.restoreBody(method, allInstructions, allExceptionHandlers);
blocks.GetCode(out allInstructions, out allExceptionHandlers);
DotNetUtils.RestoreBody(method, allInstructions, allExceptionHandlers);
}
catch {
Logger.v("Could not deobfuscate {0:X8}", method.MDToken.ToInt32());
}
}
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
}
void ISimpleDeobfuscator.deobfuscate(MethodDef method) {
((ISimpleDeobfuscator)this).deobfuscate(method, false);
void ISimpleDeobfuscator.Deobfuscate(MethodDef method) {
((ISimpleDeobfuscator)this).Deobfuscate(method, false);
}
void ISimpleDeobfuscator.deobfuscate(MethodDef method, bool force) {
if (!force && check(method, SimpleDeobFlags.HasDeobfuscated))
void ISimpleDeobfuscator.Deobfuscate(MethodDef method, bool force) {
if (!force && Check(method, SimpleDeobFlags.HasDeobfuscated))
return;
deobfuscate(method, "Deobfuscating control flow", (blocks) => {
Deobfuscate(method, "Deobfuscating control flow", (blocks) => {
var cflowDeobfuscator = new BlocksCflowDeobfuscator(deob.BlocksDeobfuscators);
cflowDeobfuscator.init(blocks);
cflowDeobfuscator.deobfuscate();
cflowDeobfuscator.Initialize(blocks);
cflowDeobfuscator.Deobfuscate();
});
}
void ISimpleDeobfuscator.decryptStrings(MethodDef method, IDeobfuscator theDeob) {
deobfuscate(method, "Static string decryption", (blocks) => theDeob.deobfuscateStrings(blocks));
void ISimpleDeobfuscator.DecryptStrings(MethodDef method, IDeobfuscator theDeob) {
Deobfuscate(method, "Static string decryption", (blocks) => theDeob.DeobfuscateStrings(blocks));
}
void IDeobfuscatedFile.createAssemblyFile(byte[] data, string assemblyName, string extension) {
void IDeobfuscatedFile.CreateAssemblyFile(byte[] data, string assemblyName, string extension) {
if (extension == null)
extension = ".dll";
var baseDir = Utils.getDirName(options.NewFilename);
var baseDir = Utils.GetDirName(options.NewFilename);
var newName = Path.Combine(baseDir, assemblyName + extension);
Logger.n("Creating file {0}", newName);
File.WriteAllBytes(newName, data);
}
void IDeobfuscatedFile.stringDecryptersAdded() {
updateDynamicStringInliner();
void IDeobfuscatedFile.StringDecryptersAdded() {
UpdateDynamicStringInliner();
}
void IDeobfuscatedFile.setDeobfuscator(IDeobfuscator deob) {
void IDeobfuscatedFile.SetDeobfuscator(IDeobfuscator deob) {
this.deob = deob;
}
public void Dispose() {
deobfuscateCleanUp();
DeobfuscateCleanUp();
if (module != null)
module.Dispose();
if (deob != null)

View File

@ -57,7 +57,7 @@ namespace de4dot.code {
}
// Returns true if the new value is set, or false on error. error string is also updated.
public abstract bool set(string val, out string error);
public abstract bool Set(string val, out string error);
public Option(string shortName, string longName, string description) {
if (shortName != null)
@ -79,7 +79,7 @@ namespace de4dot.code {
get { return "bool"; }
}
public override bool set(string newVal, out string error) {
public override bool Set(string newVal, out string error) {
if (string.Equals(newVal, "false", StringComparison.OrdinalIgnoreCase) ||
string.Equals(newVal, "off", StringComparison.OrdinalIgnoreCase) ||
string.Equals(newVal, "0", StringComparison.OrdinalIgnoreCase)) {
@ -107,7 +107,7 @@ namespace de4dot.code {
get { return "int"; }
}
public override bool set(string newVal, out string error) {
public override bool Set(string newVal, out string error) {
int newInt;
if (!int.TryParse(newVal, out newInt)) {
error = string.Format("Not an integer: '{0}'", newVal);
@ -135,7 +135,7 @@ namespace de4dot.code {
Default = this.val = val;
}
public override bool set(string newVal, out string error) {
public override bool Set(string newVal, out string error) {
val = newVal;
error = "";
return true;
@ -158,10 +158,10 @@ namespace de4dot.code {
Default = this.val = new NameRegexes(val);
}
public override bool set(string newVal, out string error) {
public override bool Set(string newVal, out string error) {
try {
var regexes = new NameRegexes();
regexes.set(newVal);
regexes.Set(newVal);
val = regexes;
}
catch (ArgumentException) {
@ -189,7 +189,7 @@ namespace de4dot.code {
Default = this.val = new Regex(val);
}
public override bool set(string newVal, out string error) {
public override bool Set(string newVal, out string error) {
try {
val = new Regex(newVal);
}
@ -223,7 +223,7 @@ namespace de4dot.code {
this.action = action;
}
public override bool set(string val, out string error) {
public override bool Set(string val, out string error) {
triggered = true;
if (action != null)
action();
@ -251,7 +251,7 @@ namespace de4dot.code {
Default = null;
}
public override bool set(string val, out string error) {
public override bool Set(string val, out string error) {
action(val);
error = "";
return true;

View File

@ -26,7 +26,7 @@ using de4dot.blocks;
namespace de4dot.code {
abstract class StringInlinerBase : MethodReturnValueInliner {
protected override void inlineReturnValues(IList<CallResult> callResults) {
protected override void InlineReturnValues(IList<CallResult> callResults) {
foreach (var callResult in callResults) {
var block = callResult.block;
int num = callResult.callEndIndex - callResult.callStartIndex + 1;
@ -36,13 +36,13 @@ namespace de4dot.code {
continue;
int ldstrIndex = callResult.callStartIndex;
block.replace(ldstrIndex, num, OpCodes.Ldstr.ToInstruction(decryptedString));
block.Replace(ldstrIndex, num, OpCodes.Ldstr.ToInstruction(decryptedString));
// If it's followed by castclass string, remove it
if (ldstrIndex + 1 < block.Instructions.Count) {
var instr = block.Instructions[ldstrIndex + 1];
if (instr.OpCode.Code == Code.Castclass && instr.Operand.ToString() == "System.String")
block.remove(ldstrIndex + 1, 1);
block.Remove(ldstrIndex + 1, 1);
}
// If it's followed by String.Intern(), then nop out that call
@ -52,12 +52,12 @@ namespace de4dot.code {
var calledMethod = instr.Operand as IMethod;
if (calledMethod != null &&
calledMethod.FullName == "System.String System.String::Intern(System.String)") {
block.remove(ldstrIndex + 1, 1);
block.Remove(ldstrIndex + 1, 1);
}
}
}
Logger.v("Decrypted string: {0}", Utils.toCsharpString(decryptedString));
Logger.v("Decrypted string: {0}", Utils.ToCsharpString(decryptedString));
}
}
}
@ -84,23 +84,23 @@ namespace de4dot.code {
this.assemblyClient = assemblyClient;
}
public void init(IEnumerable<int> methodTokens) {
public void Initialize(IEnumerable<int> methodTokens) {
methodTokenToId.Clear();
foreach (var methodToken in methodTokens) {
if (methodTokenToId.ContainsKey(methodToken))
continue;
methodTokenToId[methodToken] = assemblyClient.Service.defineStringDecrypter(methodToken);
methodTokenToId[methodToken] = assemblyClient.Service.DefineStringDecrypter(methodToken);
}
}
protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
protected override CallResult CreateCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
int methodId;
if (!methodTokenToId.TryGetValue(method.MDToken.ToInt32(), out methodId))
return null;
return new MyCallResult(block, callInstrIndex, methodId, gim);
}
protected override void inlineAllCalls() {
protected override void InlineAllCalls() {
var sortedCalls = new Dictionary<int, List<MyCallResult>>();
foreach (var tmp in callResults) {
var callResult = (MyCallResult)tmp;
@ -114,13 +114,13 @@ namespace de4dot.code {
var list = sortedCalls[methodId];
var args = new object[list.Count];
for (int i = 0; i < list.Count; i++) {
AssemblyData.SimpleData.pack(list[i].args);
AssemblyData.SimpleData.Pack(list[i].args);
args[i] = list[i].args;
}
var decryptedStrings = assemblyClient.Service.decryptStrings(methodId, args, Method.MDToken.ToInt32());
var decryptedStrings = assemblyClient.Service.DecryptStrings(methodId, args, Method.MDToken.ToInt32());
if (decryptedStrings.Length != args.Length)
throw new ApplicationException("Invalid decrypted strings array length");
AssemblyData.SimpleData.unpack(decryptedStrings);
AssemblyData.SimpleData.Unpack(decryptedStrings);
for (int i = 0; i < list.Count; i++)
list[i].returnValue = (string)decryptedStrings[i];
}
@ -135,7 +135,7 @@ namespace de4dot.code {
}
public IEnumerable<MethodDef> Methods {
get { return stringDecrypters.getKeys(); }
get { return stringDecrypters.GetKeys(); }
}
class MyCallResult : CallResult {
@ -148,21 +148,21 @@ namespace de4dot.code {
}
}
public void add(MethodDef method, Func<MethodDef, MethodSpec, object[], string> handler) {
public void Add(MethodDef method, Func<MethodDef, MethodSpec, object[], string> handler) {
if (method != null)
stringDecrypters.add(method, handler);
stringDecrypters.Add(method, handler);
}
protected override void inlineAllCalls() {
protected override void InlineAllCalls() {
foreach (var tmp in callResults) {
var callResult = (MyCallResult)tmp;
var handler = stringDecrypters.find(callResult.IMethod);
var handler = stringDecrypters.Find(callResult.IMethod);
callResult.returnValue = handler((MethodDef)callResult.IMethod, callResult.gim, callResult.args);
}
}
protected override CallResult createCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
if (stringDecrypters.find(method) == null)
protected override CallResult CreateCallResult(IMethod method, MethodSpec gim, Block block, int callInstrIndex) {
if (stringDecrypters.Find(method) == null)
return null;
return new MyCallResult(block, callInstrIndex, method, gim);
}

View File

@ -55,7 +55,7 @@ namespace de4dot.code {
public static class Utils {
static Random random = new Random();
public static IEnumerable<T> unique<T>(IEnumerable<T> values) {
public static IEnumerable<T> Unique<T>(IEnumerable<T> values) {
// HashSet is only available in .NET 3.5 and later.
var dict = new Dictionary<T, bool>();
foreach (var val in values)
@ -63,30 +63,30 @@ namespace de4dot.code {
return dict.Keys;
}
public static string toCsharpString(UTF8String s) {
return toCsharpString(UTF8String.ToSystemStringOrEmpty(s));
public static string ToCsharpString(UTF8String s) {
return ToCsharpString(UTF8String.ToSystemStringOrEmpty(s));
}
public static string toCsharpString(string s) {
public static string ToCsharpString(string s) {
var sb = new StringBuilder(s.Length + 2);
sb.Append('"');
foreach (var c in s) {
if ((int)c < 0x20) {
switch (c) {
case '\a': appendEscape(sb, 'a'); break;
case '\b': appendEscape(sb, 'b'); break;
case '\f': appendEscape(sb, 'f'); break;
case '\n': appendEscape(sb, 'n'); break;
case '\r': appendEscape(sb, 'r'); break;
case '\t': appendEscape(sb, 't'); break;
case '\v': appendEscape(sb, 'v'); break;
case '\a': AppendEscape(sb, 'a'); break;
case '\b': AppendEscape(sb, 'b'); break;
case '\f': AppendEscape(sb, 'f'); break;
case '\n': AppendEscape(sb, 'n'); break;
case '\r': AppendEscape(sb, 'r'); break;
case '\t': AppendEscape(sb, 't'); break;
case '\v': AppendEscape(sb, 'v'); break;
default:
sb.Append(string.Format(@"\u{0:X4}", (int)c));
break;
}
}
else if (c == '\\' || c == '"') {
appendEscape(sb, c);
AppendEscape(sb, c);
}
else
sb.Append(c);
@ -95,12 +95,12 @@ namespace de4dot.code {
return sb.ToString();
}
public static string shellEscape(string s) {
public static string ShellEscape(string s) {
var sb = new StringBuilder(s.Length + 2);
sb.Append('"');
foreach (var c in s) {
if (c == '"')
appendEscape(sb, c);
AppendEscape(sb, c);
else
sb.Append(c);
}
@ -108,20 +108,20 @@ namespace de4dot.code {
return sb.ToString();
}
static void appendEscape(StringBuilder sb, char c) {
static void AppendEscape(StringBuilder sb, char c) {
sb.Append('\\');
sb.Append(c);
}
public static string removeNewlines(object o) {
return removeNewlines(o.ToString());
public static string RemoveNewlines(object o) {
return RemoveNewlines(o.ToString());
}
public static string removeNewlines(string s) {
public static string RemoveNewlines(string s) {
return s.Replace('\n', ' ').Replace('\r', ' ');
}
public static string getFullPath(string path) {
public static string GetFullPath(string path) {
try {
return Path.GetFullPath(path);
}
@ -130,7 +130,7 @@ namespace de4dot.code {
}
}
public static string randomName(int min, int max) {
public static string RandomName(int min, int max) {
int numChars = random.Next(min, max + 1);
var sb = new StringBuilder(numChars);
int numLower = 0;
@ -150,26 +150,26 @@ namespace de4dot.code {
return sb.ToString();
}
public static string getBaseName(string name) {
public static string GetBaseName(string name) {
int index = name.LastIndexOf(Path.DirectorySeparatorChar);
if (index < 0)
return name;
return name.Substring(index + 1);
}
public static string getDirName(string name) {
public static string GetDirName(string name) {
return Path.GetDirectoryName(name);
}
static string ourBaseDir = null;
public static string getOurBaseDir() {
public static string GetOurBaseDir() {
if (ourBaseDir != null)
return ourBaseDir;
return ourBaseDir = getDirName(typeof(Utils).Assembly.Location);
return ourBaseDir = GetDirName(typeof(Utils).Assembly.Location);
}
public static string getPathOfOurFile(string filename) {
return Path.Combine(getOurBaseDir(), filename);
public static string GetPathOfOurFile(string filename) {
return Path.Combine(GetOurBaseDir(), filename);
}
// This fixes a mono (tested 2.10.5) String.StartsWith() bug. NB: stringComparison must be
@ -180,14 +180,14 @@ namespace de4dot.code {
return left.Substring(0, right.Length).Equals(right, stringComparison);
}
public static string getAssemblySimpleName(string name) {
public static string GetAssemblySimpleName(string name) {
int i = name.IndexOf(',');
if (i < 0)
return name;
return name.Substring(0, i);
}
public static bool pathExists(string path) {
public static bool PathExists(string path) {
try {
return new DirectoryInfo(path).Exists;
}
@ -196,7 +196,7 @@ namespace de4dot.code {
}
}
public static bool fileExists(string path) {
public static bool FileExists(string path) {
try {
return new FileInfo(path).Exists;
}
@ -205,7 +205,7 @@ namespace de4dot.code {
}
}
public static bool compare(byte[] a, byte[] b) {
public static bool Compare(byte[] a, byte[] b) {
if (a.Length != b.Length)
return false;
for (int i = 0; i < a.Length; i++) {
@ -215,7 +215,7 @@ namespace de4dot.code {
return true;
}
public static byte[] readFile(string filename) {
public static byte[] ReadFile(string filename) {
// If the file is on the network, and we read more than 2MB, we'll read from the wrong
// offset in the file! Tested: VMware 8, Win7 x64.
const int MAX_BYTES_READ = 0x200000;

View File

@ -63,26 +63,26 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public CliSecureRtType(ModuleDefMD module, CliSecureRtType oldOne) {
this.module = module;
cliSecureRtType = lookup(oldOne.cliSecureRtType, "Could not find CliSecureRt type");
postInitializeMethod = lookup(oldOne.postInitializeMethod, "Could not find postInitializeMethod method");
initializeMethod = lookup(oldOne.initializeMethod, "Could not find initializeMethod method");
stringDecrypterMethod = lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod method");
loadMethod = lookup(oldOne.loadMethod, "Could not find loadMethod method");
cliSecureRtType = Lookup(oldOne.cliSecureRtType, "Could not find CliSecureRt type");
postInitializeMethod = Lookup(oldOne.postInitializeMethod, "Could not find postInitializeMethod method");
initializeMethod = Lookup(oldOne.initializeMethod, "Could not find initializeMethod method");
stringDecrypterMethod = Lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod method");
loadMethod = Lookup(oldOne.loadMethod, "Could not find loadMethod method");
foundSig = oldOne.foundSig;
}
T lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
T Lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.Lookup(module, def, errorMessage);
}
public void find(byte[] moduleBytes) {
public void Find(byte[] moduleBytes) {
if (cliSecureRtType != null)
return;
if (find2())
if (Find2())
return;
if (find3())
if (Find3())
return;
findNativeCode(moduleBytes);
FindNativeCode(moduleBytes);
}
static readonly string[] requiredFields1 = new string[] {
@ -101,23 +101,23 @@ namespace de4dot.code.deobfuscators.Agile_NET {
"System.Reflection.Assembly",
"System.Byte[]",
};
bool find2() {
foreach (var cctor in DeobUtils.getInitCctors(module, 3)) {
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, cctor)) {
bool Find2() {
foreach (var cctor in DeobUtils.GetInitCctors(module, 3)) {
foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, cctor)) {
var type = calledMethod.DeclaringType;
if (type.IsPublic)
continue;
var fieldTypes = new FieldTypes(type);
if (!fieldTypes.exactly(requiredFields1) && !fieldTypes.exactly(requiredFields2) &&
!fieldTypes.exactly(requiredFields3) && !fieldTypes.exactly(requiredFields4))
if (!fieldTypes.Exactly(requiredFields1) && !fieldTypes.Exactly(requiredFields2) &&
!fieldTypes.Exactly(requiredFields3) && !fieldTypes.Exactly(requiredFields4))
continue;
if (!hasInitializeMethod(type, "_Initialize") && !hasInitializeMethod(type, "_Initialize64"))
if (!HasInitializeMethod(type, "_Initialize") && !HasInitializeMethod(type, "_Initialize64"))
continue;
stringDecrypterMethod = findStringDecrypterMethod(type);
stringDecrypterMethod = FindStringDecrypterMethod(type);
initializeMethod = calledMethod;
postInitializeMethod = findMethod(type, "System.Void", "PostInitialize", "()");
loadMethod = findMethod(type, "System.IntPtr", "Load", "()");
postInitializeMethod = FindMethod(type, "System.Void", "PostInitialize", "()");
loadMethod = FindMethod(type, "System.IntPtr", "Load", "()");
cliSecureRtType = type;
return true;
}
@ -126,7 +126,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return false;
}
bool find3() {
bool Find3() {
foreach (var type in module.Types) {
if (type.Fields.Count != 1)
continue;
@ -148,11 +148,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return false;
}
static MethodDef findStringDecrypterMethod(TypeDef type) {
static MethodDef FindStringDecrypterMethod(TypeDef type) {
foreach (var method in type.Methods) {
if (method.Body == null || !method.IsStatic)
continue;
if (!DotNetUtils.isMethod(method, "System.String", "(System.String)"))
if (!DotNetUtils.IsMethod(method, "System.String", "(System.String)"))
continue;
return method;
@ -161,7 +161,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return null;
}
static MethodDef findMethod(TypeDef type, string returnType, string name, string parameters) {
static MethodDef FindMethod(TypeDef type, string returnType, string name, string parameters) {
var methodName = returnType + " " + type.FullName + "::" + name + parameters;
foreach (var method in type.Methods) {
if (method.Body == null || !method.IsStatic)
@ -175,8 +175,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return null;
}
static bool hasInitializeMethod(TypeDef type, string name) {
var method = DotNetUtils.getPInvokeMethod(type, name);
static bool HasInitializeMethod(TypeDef type, string name) {
var method = DotNetUtils.GetPInvokeMethod(type, name);
if (method == null)
return false;
var sig = method.MethodSig;
@ -190,17 +190,17 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return true;
}
bool findNativeCode(byte[] moduleBytes) {
var bytes = moduleBytes != null ? moduleBytes : DeobUtils.readModule(module);
bool FindNativeCode(byte[] moduleBytes) {
var bytes = moduleBytes != null ? moduleBytes : DeobUtils.ReadModule(module);
using (var peImage = new MyPEImage(bytes))
return foundSig = MethodsDecrypter.detect(peImage);
return foundSig = MethodsDecrypter.Detect(peImage);
}
public bool isAtLeastVersion50() {
return DotNetUtils.hasPinvokeMethod(cliSecureRtType, "LoadLibraryA");
public bool IsAtLeastVersion50() {
return DotNetUtils.HasPinvokeMethod(cliSecureRtType, "LoadLibraryA");
}
public void findStringDecrypterMethod() {
public void FindStringDecrypterMethod() {
if (cliSecureRtType != null)
return;
@ -210,7 +210,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
if (type.Methods.Count != 1)
continue;
var cs = type.Methods[0];
if (!isOldStringDecrypterMethod(cs))
if (!IsOldStringDecrypterMethod(cs))
continue;
cliSecureRtType = type;
@ -219,12 +219,12 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
static bool isOldStringDecrypterMethod(MethodDef method) {
static bool IsOldStringDecrypterMethod(MethodDef method) {
if (method == null || method.Body == null || !method.IsStatic)
return false;
if (!DotNetUtils.isMethod(method, "System.String", "(System.String)"))
if (!DotNetUtils.IsMethod(method, "System.String", "(System.String)"))
return false;
if (!DeobUtils.hasInteger(method, 0xFF))
if (!DeobUtils.HasInteger(method, 0xFF))
return false;
return true;

View File

@ -26,7 +26,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(key) {
}
protected override void encrypt(ref uint rxl, ref uint rxr) {
protected override void Encrypt(ref uint rxl, ref uint rxr) {
uint xl = rxl, xr = rxr;
for (int i = 0; i < 16; i++) {
xl ^= P[i];
@ -38,7 +38,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
rxl = xr ^ P[17];
}
protected override void decrypt(ref uint rxl, ref uint rxr) {
protected override void Decrypt(ref uint rxl, ref uint rxr) {
uint xl = rxl, xr = rxr;
for (int i = 17; i >= 2; i--) {
xl ^= P[i];

View File

@ -37,11 +37,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public DeobfuscatorInfo()
: base(DEFAULT_REGEX) {
decryptMethods = new BoolOption(null, makeArgName("methods"), "Decrypt methods", true);
decryptResources = new BoolOption(null, makeArgName("rsrc"), "Decrypt resources", true);
removeStackFrameHelper = new BoolOption(null, makeArgName("stack"), "Remove all StackFrameHelper code", true);
restoreVmCode = new BoolOption(null, makeArgName("vm"), "Restore VM code", true);
setInitLocals = new BoolOption(null, makeArgName("initlocals"), "Set initlocals in method header", true);
decryptMethods = new BoolOption(null, MakeArgName("methods"), "Decrypt methods", true);
decryptResources = new BoolOption(null, MakeArgName("rsrc"), "Decrypt resources", true);
removeStackFrameHelper = new BoolOption(null, MakeArgName("stack"), "Remove all StackFrameHelper code", true);
restoreVmCode = new BoolOption(null, MakeArgName("vm"), "Restore VM code", true);
setInitLocals = new BoolOption(null, MakeArgName("initlocals"), "Set initlocals in method header", true);
}
public override string Name {
@ -52,7 +52,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
get { return THE_TYPE; }
}
public override IDeobfuscator createDeobfuscator() {
public override IDeobfuscator CreateDeobfuscator() {
return new Deobfuscator(new Deobfuscator.Options {
ValidNameRegex = validNameRegex.get(),
DecryptMethods = decryptMethods.get(),
@ -63,7 +63,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
});
}
protected override IEnumerable<Option> getOptionsInternal() {
protected override IEnumerable<Option> GetOptionsInternal() {
return new List<Option>() {
decryptMethods,
decryptResources,
@ -112,16 +112,16 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.options = options;
}
public override void init(ModuleDefMD module) {
base.init(module);
public override void Initialize(ModuleDefMD module) {
base.Initialize(module);
}
public override byte[] unpackNativeFile(IPEImage peImage) {
return unpackNativeFile1(peImage) ?? unpackNativeFile2(peImage);
public override byte[] UnpackNativeFile(IPEImage peImage) {
return UnpackNativeFile1(peImage) ?? UnpackNativeFile2(peImage);
}
// Old CS versions
byte[] unpackNativeFile1(IPEImage peImage) {
byte[] UnpackNativeFile1(IPEImage peImage) {
const int dataDirNum = 6; // debug dir
const int dotNetDirNum = 14;
@ -135,16 +135,16 @@ namespace de4dot.code.deobfuscators.Agile_NET {
long dataDirBaseOffset = (long)optHeader.DataDirectories[0].StartOffset;
int dataDir = (int)dataDirBaseOffset + dataDirNum * 8;
int dotNetDir = (int)dataDirBaseOffset + dotNetDirNum * 8;
writeUInt32(fileData, dotNetDir, BitConverter.ToUInt32(fileData, dataDir));
writeUInt32(fileData, dotNetDir + 4, BitConverter.ToUInt32(fileData, dataDir + 4));
writeUInt32(fileData, dataDir, 0);
writeUInt32(fileData, dataDir + 4, 0);
WriteUInt32(fileData, dotNetDir, BitConverter.ToUInt32(fileData, dataDir));
WriteUInt32(fileData, dotNetDir + 4, BitConverter.ToUInt32(fileData, dataDir + 4));
WriteUInt32(fileData, dataDir, 0);
WriteUInt32(fileData, dataDir + 4, 0);
ModuleBytes = fileData;
return fileData;
}
// CS 1.x
byte[] unpackNativeFile2(IPEImage peImage) {
byte[] UnpackNativeFile2(IPEImage peImage) {
var data = peImage.FindWin32ResourceData("ASSEMBLY", 101, 0);
if (data == null)
return null;
@ -152,21 +152,21 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return ModuleBytes = data.Data.ReadAllBytes();
}
static void writeUInt32(byte[] data, int offset, uint value) {
static void WriteUInt32(byte[] data, int offset, uint value) {
data[offset] = (byte)value;
data[offset + 1] = (byte)(value >> 8);
data[offset + 2] = (byte)(value >> 16);
data[offset + 3] = (byte)(value >> 24);
}
protected override int detectInternal() {
protected override int DetectInternal() {
int val = 0;
int sum = toInt32(cliSecureRtType.Detected) +
toInt32(stringDecrypter.Detected) +
toInt32(proxyCallFixer.Detected) +
toInt32(resourceDecrypter.Detected) +
toInt32(csvm.Detected);
int sum = ToInt32(cliSecureRtType.Detected) +
ToInt32(stringDecrypter.Detected) +
ToInt32(proxyCallFixer.Detected) +
ToInt32(resourceDecrypter.Detected) +
ToInt32(csvm.Detected);
if (sum > 0)
val += 100 + 10 * (sum - 1);
if (cliSecureAttributes.Count != 0)
@ -175,21 +175,21 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return val;
}
protected override void scanForObfuscator() {
findCliSecureAttribute();
protected override void ScanForObfuscator() {
FindCliSecureAttribute();
cliSecureRtType = new CliSecureRtType(module);
cliSecureRtType.find(ModuleBytes);
cliSecureRtType.Find(ModuleBytes);
stringDecrypter = new StringDecrypter(module, cliSecureRtType.StringDecrypterMethod);
stringDecrypter.find();
stringDecrypter.Find();
resourceDecrypter = new ResourceDecrypter(module);
resourceDecrypter.find();
resourceDecrypter.Find();
proxyCallFixer = new ProxyCallFixer(module);
proxyCallFixer.findDelegateCreator();
proxyCallFixer.FindDelegateCreator();
csvm = new vm.Csvm(DeobfuscatedFile.DeobfuscatorContext, module);
csvm.find();
csvm.Find();
}
void findCliSecureAttribute() {
void FindCliSecureAttribute() {
obfuscatorName = "CliSecure";
foreach (var type in module.Types) {
if (Utils.StartsWith(type.FullName, "SecureTeam.Attributes.ObfuscatedByCliSecureAttribute", StringComparison.Ordinal)) {
@ -203,13 +203,13 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
public override bool getDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) {
public override bool GetDecryptedModule(int count, ref byte[] newFileData, ref DumpedMethods dumpedMethods) {
if (count != 0 || !options.DecryptMethods)
return false;
byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module);
byte[] fileData = ModuleBytes ?? DeobUtils.ReadModule(module);
using (var peImage = new MyPEImage(fileData)) {
if (!new MethodsDecrypter().decrypt(peImage, module, cliSecureRtType, ref dumpedMethods)) {
if (!new MethodsDecrypter().Decrypt(peImage, module, cliSecureRtType, ref dumpedMethods)) {
Logger.v("Methods aren't encrypted or invalid signature");
return false;
}
@ -219,10 +219,10 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return true;
}
public override IDeobfuscator moduleReloaded(ModuleDefMD module) {
public override IDeobfuscator ModuleReloaded(ModuleDefMD module) {
var newOne = new Deobfuscator(options);
newOne.setModule(module);
newOne.cliSecureAttributes = lookup(module, cliSecureAttributes, "Could not find CliSecure attribute");
newOne.SetModule(module);
newOne.cliSecureAttributes = Lookup(module, cliSecureAttributes, "Could not find CliSecure attribute");
newOne.cliSecureRtType = new CliSecureRtType(module, cliSecureRtType);
newOne.stringDecrypter = new StringDecrypter(module, stringDecrypter);
newOne.resourceDecrypter = new ResourceDecrypter(module, resourceDecrypter);
@ -231,105 +231,105 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return newOne;
}
static List<TypeDef> lookup(ModuleDefMD module, List<TypeDef> types, string errorMsg) {
static List<TypeDef> Lookup(ModuleDefMD module, List<TypeDef> types, string errorMsg) {
var list = new List<TypeDef>(types.Count);
foreach (var type in types)
list.Add(DeobUtils.lookup(module, type, errorMsg));
list.Add(DeobUtils.Lookup(module, type, errorMsg));
return list;
}
public override void deobfuscateBegin() {
base.deobfuscateBegin();
public override void DeobfuscateBegin() {
base.DeobfuscateBegin();
cliSecureRtType.findStringDecrypterMethod();
cliSecureRtType.FindStringDecrypterMethod();
stringDecrypter.Method = cliSecureRtType.StringDecrypterMethod;
addAttributesToBeRemoved(cliSecureAttributes, "Obfuscator attribute");
AddAttributesToBeRemoved(cliSecureAttributes, "Obfuscator attribute");
if (options.DecryptResources) {
decryptResources(resourceDecrypter);
addCctorInitCallToBeRemoved(resourceDecrypter.RsrcRrrMethod);
DecryptResources(resourceDecrypter);
AddCctorInitCallToBeRemoved(resourceDecrypter.RsrcRrrMethod);
}
stackFrameHelper = new StackFrameHelper(module);
stackFrameHelper.find();
stackFrameHelper.Find();
foreach (var type in module.Types) {
if (type.FullName == "InitializeDelegate" && DotNetUtils.derivesFromDelegate(type))
this.addTypeToBeRemoved(type, "Obfuscator type");
if (type.FullName == "InitializeDelegate" && DotNetUtils.DerivesFromDelegate(type))
this.AddTypeToBeRemoved(type, "Obfuscator type");
}
proxyCallFixer.find();
proxyCallFixer.Find();
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0]));
DeobfuscatedFile.stringDecryptersAdded();
staticStringInliner.Add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.Decrypt((string)args[0]));
DeobfuscatedFile.StringDecryptersAdded();
if (options.DecryptMethods) {
addCctorInitCallToBeRemoved(cliSecureRtType.InitializeMethod);
addCctorInitCallToBeRemoved(cliSecureRtType.PostInitializeMethod);
findPossibleNamesToRemove(cliSecureRtType.LoadMethod);
AddCctorInitCallToBeRemoved(cliSecureRtType.InitializeMethod);
AddCctorInitCallToBeRemoved(cliSecureRtType.PostInitializeMethod);
FindPossibleNamesToRemove(cliSecureRtType.LoadMethod);
}
if (options.RestoreVmCode) {
if (csvm.restore())
addResourceToBeRemoved(csvm.Resource, "CSVM data resource");
if (csvm.Restore())
AddResourceToBeRemoved(csvm.Resource, "CSVM data resource");
else {
Logger.e("Couldn't restore VM methods. Use --dont-rename or it will not run");
preserveTokensAndTypes();
PreserveTokensAndTypes();
}
}
}
void decryptResources(ResourceDecrypter resourceDecrypter) {
var rsrc = resourceDecrypter.mergeResources();
void DecryptResources(ResourceDecrypter resourceDecrypter) {
var rsrc = resourceDecrypter.MergeResources();
if (rsrc == null)
return;
addResourceToBeRemoved(rsrc, "Encrypted resources");
addTypeToBeRemoved(resourceDecrypter.Type, "Resource decrypter type");
AddResourceToBeRemoved(rsrc, "Encrypted resources");
AddTypeToBeRemoved(resourceDecrypter.Type, "Resource decrypter type");
}
public override void deobfuscateMethodEnd(Blocks blocks) {
proxyCallFixer.deobfuscate(blocks);
removeStackFrameHelperCode(blocks);
base.deobfuscateMethodEnd(blocks);
public override void DeobfuscateMethodEnd(Blocks blocks) {
proxyCallFixer.Deobfuscate(blocks);
RemoveStackFrameHelperCode(blocks);
base.DeobfuscateMethodEnd(blocks);
}
public override void deobfuscateEnd() {
public override void DeobfuscateEnd() {
if (options.SetInitLocals)
setInitLocals();
removeProxyDelegates(proxyCallFixer);
SetInitLocals();
RemoveProxyDelegates(proxyCallFixer);
if (options.RemoveStackFrameHelper) {
if (stackFrameHelper.ExceptionLoggerRemover.NumRemovedExceptionLoggers > 0)
addTypeToBeRemoved(stackFrameHelper.Type, "StackFrameHelper type");
AddTypeToBeRemoved(stackFrameHelper.Type, "StackFrameHelper type");
}
if (CanRemoveStringDecrypterType) {
addTypeToBeRemoved(stringDecrypter.Type, "String decrypter type");
AddTypeToBeRemoved(stringDecrypter.Type, "String decrypter type");
if (options.DecryptMethods)
addTypeToBeRemoved(cliSecureRtType.Type, "Obfuscator type");
AddTypeToBeRemoved(cliSecureRtType.Type, "Obfuscator type");
}
if (options.DecryptMethods) {
addResources("Obfuscator protection files");
AddResources("Obfuscator protection files");
}
base.deobfuscateEnd();
base.DeobfuscateEnd();
// Call hasNativeMethods() after all types/methods/etc have been removed since
// some of the removed methods could be native methods
if (!module.IsILOnly && !hasNativeMethods())
if (!module.IsILOnly && !HasNativeMethods())
module.IsILOnly = true;
}
public override IEnumerable<int> getStringDecrypterMethods() {
public override IEnumerable<int> GetStringDecrypterMethods() {
var list = new List<int>();
if (stringDecrypter.Method != null)
list.Add(stringDecrypter.Method.MDToken.ToInt32());
return list;
}
void removeStackFrameHelperCode(Blocks blocks) {
void RemoveStackFrameHelperCode(Blocks blocks) {
if (!options.RemoveStackFrameHelper)
return;
if (stackFrameHelper.ExceptionLoggerRemover.remove(blocks))
if (stackFrameHelper.ExceptionLoggerRemover.Remove(blocks))
Logger.v("Removed StackFrameHelper code");
}
}

View File

@ -72,7 +72,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
SigType sigType;
interface IDecrypter {
MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections);
MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections);
}
abstract class DecrypterBase : IDecrypter {
@ -84,13 +84,13 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.peImage = peImage;
this.codeHeader = codeHeader;
var mdDir = peImage.Cor20Header.MetaData;
endOfMetadata = peImage.rvaToOffset((uint)mdDir.VirtualAddress + mdDir.Size);
endOfMetadata = peImage.RvaToOffset((uint)mdDir.VirtualAddress + mdDir.Size);
}
public abstract MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections);
public abstract MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections);
protected MethodBodyHeader getCodeBytes(byte[] methodBody, out byte[] code, out byte[] extraSections) {
return MethodBodyParser.parseMethodBody(MemoryImageStream.Create(methodBody), out code, out extraSections);
protected MethodBodyHeader GetCodeBytes(byte[] methodBody, out byte[] code, out byte[] extraSections) {
return MethodBodyParser.ParseMethodBody(MemoryImageStream.Create(methodBody), out code, out extraSections);
}
}
@ -104,10 +104,10 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.blowfish = new CsBlowfish(key);
}
public MethodBodyHeader decrypt(uint bodyOffset, out byte[] code, out byte[] extraSections) {
public MethodBodyHeader Decrypt(uint bodyOffset, out byte[] code, out byte[] extraSections) {
peImage.Reader.Position = bodyOffset;
var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
blowfish.decrypt(code);
var mbHeader = MethodBodyParser.ParseMethodBody(peImage.Reader, out code, out extraSections);
blowfish.Decrypt(code);
return mbHeader;
}
}
@ -118,9 +118,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(peImage, codeHeader) {
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
peImage.Reader.Position = peImage.rvaToOffset(methodInfo.codeOffs);
return MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
peImage.Reader.Position = peImage.RvaToOffset(methodInfo.codeOffs);
return MethodBodyParser.ParseMethodBody(peImage.Reader, out code, out extraSections);
}
}
@ -130,9 +130,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(peImage, codeHeader) {
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
peImage.Reader.Position = endOfMetadata + methodInfo.codeOffs;
return MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
return MethodBodyParser.ParseMethodBody(peImage.Reader, out code, out extraSections);
}
}
@ -142,14 +142,14 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(peImage, codeHeader) {
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
var data = peImage.offsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize);
public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
var data = peImage.OffsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize);
for (int i = 0; i < data.Length; i++) {
byte b = data[i];
b ^= codeHeader.decryptionKey[(methodInfo.codeOffs - 0x28 + i) % 16];
data[i] = b;
}
return getCodeBytes(data, out code, out extraSections);
return GetCodeBytes(data, out code, out extraSections);
}
}
@ -162,15 +162,15 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.codeHeaderSize = codeHeaderSize;
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
byte[] data = peImage.offsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize);
public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
byte[] data = peImage.OffsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize);
for (int i = 0; i < data.Length; i++) {
byte b = data[i];
b ^= codeHeader.decryptionKey[(methodInfo.codeOffs - codeHeaderSize + i) % 16];
b ^= codeHeader.decryptionKey[(methodInfo.codeOffs - codeHeaderSize + i + 7) % 16];
data[i] = b;
}
return getCodeBytes(data, out code, out extraSections);
return GetCodeBytes(data, out code, out extraSections);
}
}
@ -181,17 +181,17 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public ProDecrypter(MyPEImage peImage, CodeHeader codeHeader)
: base(peImage, codeHeader) {
for (int i = 0; i < 4; i++)
key[i] = be_readUInt32(codeHeader.decryptionKey, i * 4);
key[i] = ReadUInt32_be(codeHeader.decryptionKey, i * 4);
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
byte[] data = peImage.offsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize);
public override MethodBodyHeader Decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
byte[] data = peImage.OffsetReadBytes(endOfMetadata + methodInfo.codeOffs, (int)methodInfo.codeSize);
int numQwords = (int)(methodInfo.codeSize / 8);
for (int i = 0; i < numQwords; i++) {
int offset = i * 8;
uint q0 = be_readUInt32(data, offset);
uint q1 = be_readUInt32(data, offset + 4);
uint q0 = ReadUInt32_be(data, offset);
uint q1 = ReadUInt32_be(data, offset + 4);
const uint magic = 0x9E3779B8;
uint val = 0xC6EF3700; // magic * 0x20
@ -201,21 +201,21 @@ namespace de4dot.code.deobfuscators.Agile_NET {
val -= magic;
}
be_writeUInt32(data, offset, q0);
be_writeUInt32(data, offset + 4, q1);
WriteUInt32_be(data, offset, q0);
WriteUInt32_be(data, offset + 4, q1);
}
return getCodeBytes(data, out code, out extraSections);
return GetCodeBytes(data, out code, out extraSections);
}
static uint be_readUInt32(byte[] data, int offset) {
static uint ReadUInt32_be(byte[] data, int offset) {
return (uint)((data[offset] << 24) +
(data[offset + 1] << 16) +
(data[offset + 2] << 8) +
data[offset + 3]);
}
static void be_writeUInt32(byte[] data, int offset, uint value) {
static void WriteUInt32_be(byte[] data, int offset, uint value) {
data[offset] = (byte)(value >> 24);
data[offset + 1] = (byte)(value >> 16);
data[offset + 2] = (byte)(value >> 8);
@ -224,9 +224,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
interface ICsHeader {
IDecrypter createDecrypter();
List<MethodInfo> getMethodInfos(uint codeHeaderOffset);
void patchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos);
IDecrypter CreateDecrypter();
List<MethodInfo> GetMethodInfos(uint codeHeaderOffset);
void PatchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos);
}
abstract class CsHeaderBase : ICsHeader {
@ -238,42 +238,42 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.codeHeaderSize = codeHeaderSize;
}
public abstract IDecrypter createDecrypter();
public abstract IDecrypter CreateDecrypter();
public virtual void patchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos) {
public virtual void PatchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos) {
}
public abstract List<MethodInfo> getMethodInfos(uint codeHeaderOffset);
public abstract List<MethodInfo> GetMethodInfos(uint codeHeaderOffset);
protected List<MethodInfo> getMethodInfos1(uint codeHeaderOffset) {
protected List<MethodInfo> GetMethodInfos1(uint codeHeaderOffset) {
uint offset = codeHeaderOffset + methodsDecrypter.codeHeader.totalCodeSize + codeHeaderSize;
var methodInfos = new List<MethodInfo>((int)methodsDecrypter.codeHeader.numMethods);
for (int i = 0; i < (int)methodsDecrypter.codeHeader.numMethods; i++, offset += 4) {
uint codeOffs = methodsDecrypter.peImage.offsetReadUInt32(offset);
uint codeOffs = methodsDecrypter.peImage.OffsetReadUInt32(offset);
methodInfos.Add(new MethodInfo(codeOffs, 0, 0, 0));
}
return methodInfos;
}
protected List<MethodInfo> getMethodInfos2(uint codeHeaderOffset) {
protected List<MethodInfo> GetMethodInfos2(uint codeHeaderOffset) {
uint offset = codeHeaderOffset + methodsDecrypter.codeHeader.totalCodeSize + codeHeaderSize;
var methodInfos = new List<MethodInfo>((int)methodsDecrypter.codeHeader.numMethods);
for (int i = 0; i < (int)methodsDecrypter.codeHeader.numMethods; i++, offset += 8) {
uint codeOffs = methodsDecrypter.peImage.offsetReadUInt32(offset);
uint codeSize = methodsDecrypter.peImage.offsetReadUInt32(offset + 4);
uint codeOffs = methodsDecrypter.peImage.OffsetReadUInt32(offset);
uint codeSize = methodsDecrypter.peImage.OffsetReadUInt32(offset + 4);
methodInfos.Add(new MethodInfo(codeOffs, codeSize, 0, 0));
}
return methodInfos;
}
protected List<MethodInfo> getMethodInfos4(uint codeHeaderOffset) {
protected List<MethodInfo> GetMethodInfos4(uint codeHeaderOffset) {
uint offset = codeHeaderOffset + methodsDecrypter.codeHeader.totalCodeSize + codeHeaderSize;
var methodInfos = new List<MethodInfo>((int)methodsDecrypter.codeHeader.numMethods);
for (int i = 0; i < (int)methodsDecrypter.codeHeader.numMethods; i++, offset += 16) {
uint codeOffs = methodsDecrypter.peImage.offsetReadUInt32(offset);
uint codeSize = methodsDecrypter.peImage.offsetReadUInt32(offset + 4);
uint flags = methodsDecrypter.peImage.offsetReadUInt32(offset + 8);
uint localVarSigTok = methodsDecrypter.peImage.offsetReadUInt32(offset + 12);
uint codeOffs = methodsDecrypter.peImage.OffsetReadUInt32(offset);
uint codeSize = methodsDecrypter.peImage.OffsetReadUInt32(offset + 4);
uint flags = methodsDecrypter.peImage.OffsetReadUInt32(offset + 8);
uint localVarSigTok = methodsDecrypter.peImage.OffsetReadUInt32(offset + 12);
methodInfos.Add(new MethodInfo(codeOffs, codeSize, flags, localVarSigTok));
}
return methodInfos;
@ -286,12 +286,12 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(methodsDecrypter, 0x28) {
}
public override IDecrypter createDecrypter() {
public override IDecrypter CreateDecrypter() {
return new Decrypter30(methodsDecrypter.peImage, methodsDecrypter.codeHeader);
}
public override List<MethodInfo> getMethodInfos(uint codeHeaderOffset) {
return getMethodInfos1(codeHeaderOffset);
public override List<MethodInfo> GetMethodInfos(uint codeHeaderOffset) {
return GetMethodInfos1(codeHeaderOffset);
}
}
@ -301,12 +301,12 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(methodsDecrypter, 0x28) {
}
public override IDecrypter createDecrypter() {
public override IDecrypter CreateDecrypter() {
return new Decrypter40(methodsDecrypter.peImage, methodsDecrypter.codeHeader);
}
public override List<MethodInfo> getMethodInfos(uint codeHeaderOffset) {
return getMethodInfos1(codeHeaderOffset);
public override List<MethodInfo> GetMethodInfos(uint codeHeaderOffset) {
return GetMethodInfos1(codeHeaderOffset);
}
}
@ -316,12 +316,12 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(methodsDecrypter, 0x28) {
}
public override IDecrypter createDecrypter() {
public override IDecrypter CreateDecrypter() {
return new Decrypter45(methodsDecrypter.peImage, methodsDecrypter.codeHeader);
}
public override List<MethodInfo> getMethodInfos(uint codeHeaderOffset) {
return getMethodInfos2(codeHeaderOffset);
public override List<MethodInfo> GetMethodInfos(uint codeHeaderOffset) {
return GetMethodInfos2(codeHeaderOffset);
}
}
@ -331,8 +331,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
: base(methodsDecrypter, codeHeaderSize) {
}
public override IDecrypter createDecrypter() {
switch (getSigType(methodsDecrypter.codeHeader.signature)) {
public override IDecrypter CreateDecrypter() {
switch (GetSigType(methodsDecrypter.codeHeader.signature)) {
case SigType.Normal:
return new Decrypter5(methodsDecrypter.peImage, methodsDecrypter.codeHeader, codeHeaderSize);
@ -345,21 +345,21 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
public override List<MethodInfo> getMethodInfos(uint codeHeaderOffset) {
public override List<MethodInfo> GetMethodInfos(uint codeHeaderOffset) {
if (codeHeaderSize == 0x28)
return getMethodInfos2(codeHeaderOffset);
return getMethodInfos4(codeHeaderOffset);
return GetMethodInfos2(codeHeaderOffset);
return GetMethodInfos4(codeHeaderOffset);
}
public override void patchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos) {
public override void PatchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos) {
uint offset = (uint)methodDefTable.StartOffset - methodDefTable.RowSize;
foreach (var methodInfo in methodInfos) {
offset += methodDefTable.RowSize;
if (methodInfo.flags == 0 || methodInfo.codeOffs == 0)
continue;
uint rva = methodsDecrypter.peImage.offsetReadUInt32(offset);
methodsDecrypter.peImage.writeUInt16(rva, (ushort)methodInfo.flags);
methodsDecrypter.peImage.writeUInt32(rva + 8, methodInfo.localVarSigTok);
uint rva = methodsDecrypter.peImage.OffsetReadUInt32(offset);
methodsDecrypter.peImage.WriteUInt16(rva, (ushort)methodInfo.flags);
methodsDecrypter.peImage.WriteUInt32(rva + 8, methodInfo.localVarSigTok);
}
}
}
@ -374,14 +374,14 @@ namespace de4dot.code.deobfuscators.Agile_NET {
V52, // 5.2+ (or maybe 5.1+)
}
List<CsHeaderVersion> getCsHeaderVersions(uint codeHeaderOffset, MDTable methodDefTable) {
List<CsHeaderVersion> GetCsHeaderVersions(uint codeHeaderOffset, MDTable methodDefTable) {
if (sigType == SigType.Old)
return new List<CsHeaderVersion> { CsHeaderVersion.V10 };
if (!isOldHeader(methodDefTable))
if (!IsOldHeader(methodDefTable))
return new List<CsHeaderVersion> { CsHeaderVersion.V52 };
if (csRtType.isAtLeastVersion50())
if (csRtType.IsAtLeastVersion50())
return new List<CsHeaderVersion> { CsHeaderVersion.V50 };
if (isCsHeader40(codeHeaderOffset)) {
if (IsCsHeader40(codeHeaderOffset)) {
return new List<CsHeaderVersion> {
CsHeaderVersion.V40,
CsHeaderVersion.V30,
@ -393,12 +393,12 @@ namespace de4dot.code.deobfuscators.Agile_NET {
};
}
bool isCsHeader40(uint codeHeaderOffset) {
bool IsCsHeader40(uint codeHeaderOffset) {
try {
uint offset = codeHeaderOffset + codeHeader.totalCodeSize + 0x28;
uint prevCodeOffs = 0;
for (int i = 0; i < (int)codeHeader.numMethods; i++, offset += 4) {
uint codeOffs = peImage.offsetReadUInt32(offset);
uint codeOffs = peImage.OffsetReadUInt32(offset);
if (prevCodeOffs != 0 && codeOffs != 0 && codeOffs < prevCodeOffs)
return false;
if (codeOffs != 0)
@ -412,16 +412,16 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
bool isOldHeader(MDTable methodDefTable) {
bool IsOldHeader(MDTable methodDefTable) {
if (methodDefTable.RowSize != codeHeader.methodDefElemSize)
return true;
if ((uint)methodDefTable.StartOffset - peImage.rvaToOffset((uint)peImage.Cor20Header.MetaData.VirtualAddress) != codeHeader.methodDefTableOffset)
if ((uint)methodDefTable.StartOffset - peImage.RvaToOffset((uint)peImage.Cor20Header.MetaData.VirtualAddress) != codeHeader.methodDefTableOffset)
return true;
return false;
}
ICsHeader createCsHeader(CsHeaderVersion version) {
ICsHeader CreateCsHeader(CsHeaderVersion version) {
switch (version) {
case CsHeaderVersion.V30: return new CsHeader30(this);
case CsHeaderVersion.V40: return new CsHeader40(this);
@ -438,19 +438,19 @@ namespace de4dot.code.deobfuscators.Agile_NET {
Error,
}
public bool decrypt(MyPEImage peImage, ModuleDefMD module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) {
public bool Decrypt(MyPEImage peImage, ModuleDefMD module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) {
this.peImage = peImage;
this.csRtType = csRtType;
this.module = module;
switch (decrypt2(ref dumpedMethods)) {
switch (Decrypt2(ref dumpedMethods)) {
case DecryptResult.Decrypted: return true;
case DecryptResult.NotEncrypted: return false;
case DecryptResult.Error:
Logger.n("Using dynamic method decryption");
byte[] moduleCctorBytes = getModuleCctorBytes(csRtType);
dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.decrypt(module, moduleCctorBytes);
byte[] moduleCctorBytes = GetModuleCctorBytes(csRtType);
dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.Decrypt(module, moduleCctorBytes);
return true;
default:
@ -458,7 +458,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
static byte[] getModuleCctorBytes(CliSecureRtType csRtType) {
static byte[] GetModuleCctorBytes(CliSecureRtType csRtType) {
var initMethod = csRtType.InitializeMethod;
if (initMethod == null)
return null;
@ -473,24 +473,24 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return moduleCctorBytes;
}
static uint getCodeHeaderOffset(MyPEImage peImage) {
return peImage.rvaToOffset((uint)peImage.Cor20Header.MetaData.VirtualAddress + peImage.Cor20Header.MetaData.Size);
static uint GetCodeHeaderOffset(MyPEImage peImage) {
return peImage.RvaToOffset((uint)peImage.Cor20Header.MetaData.VirtualAddress + peImage.Cor20Header.MetaData.Size);
}
static string[] sections = new string[] {
".text", ".rsrc", ".data", ".rdata",
};
static uint getOldCodeHeaderOffset(MyPEImage peImage) {
var sect = getLastOf(peImage, sections);
static uint GetOldCodeHeaderOffset(MyPEImage peImage) {
var sect = GetLastOf(peImage, sections);
if (sect == null || sect.VirtualSize < 0x100)
return 0;
return peImage.rvaToOffset((uint)sect.VirtualAddress + sect.VirtualSize - 0x100);
return peImage.RvaToOffset((uint)sect.VirtualAddress + sect.VirtualSize - 0x100);
}
static ImageSectionHeader getLastOf(MyPEImage peImage, string[] sections) {
static ImageSectionHeader GetLastOf(MyPEImage peImage, string[] sections) {
ImageSectionHeader sect = null;
foreach (var name in sections) {
var sect2 = peImage.findSection(name);
var sect2 = peImage.FindSection(name);
if (sect2 == null)
continue;
if (sect == null || sect2.VirtualAddress > sect.VirtualAddress)
@ -499,19 +499,19 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return sect;
}
DecryptResult decrypt2(ref DumpedMethods dumpedMethods) {
uint codeHeaderOffset = initializeCodeHeader();
DecryptResult Decrypt2(ref DumpedMethods dumpedMethods) {
uint codeHeaderOffset = InitializeCodeHeader();
if (sigType == SigType.Unknown)
return DecryptResult.NotEncrypted;
var methodDefTable = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
foreach (var version in getCsHeaderVersions(codeHeaderOffset, methodDefTable)) {
foreach (var version in GetCsHeaderVersions(codeHeaderOffset, methodDefTable)) {
try {
if (version == CsHeaderVersion.V10)
decryptMethodsOld(methodDefTable, ref dumpedMethods);
DecryptMethodsOld(methodDefTable, ref dumpedMethods);
else
decryptMethods(codeHeaderOffset, methodDefTable, createCsHeader(version), ref dumpedMethods);
DecryptMethods(codeHeaderOffset, methodDefTable, CreateCsHeader(version), ref dumpedMethods);
return DecryptResult.Decrypted;
}
catch {
@ -521,23 +521,23 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return DecryptResult.Error;
}
uint initializeCodeHeader() {
uint codeHeaderOffset = getCodeHeaderOffset(peImage);
readCodeHeader(codeHeaderOffset);
sigType = getSigType(codeHeader.signature);
uint InitializeCodeHeader() {
uint codeHeaderOffset = GetCodeHeaderOffset(peImage);
ReadCodeHeader(codeHeaderOffset);
sigType = GetSigType(codeHeader.signature);
if (sigType == SigType.Unknown) {
codeHeaderOffset = getOldCodeHeaderOffset(peImage);
codeHeaderOffset = GetOldCodeHeaderOffset(peImage);
if (codeHeaderOffset != 0) {
readCodeHeader(codeHeaderOffset);
sigType = getSigType(codeHeader.signature);
ReadCodeHeader(codeHeaderOffset);
sigType = GetSigType(codeHeader.signature);
}
}
return codeHeaderOffset;
}
void decryptMethodsOld(MDTable methodDefTable, ref DumpedMethods dumpedMethods) {
void DecryptMethodsOld(MDTable methodDefTable, ref DumpedMethods dumpedMethods) {
dumpedMethods = new DumpedMethods();
var decrypter = new Decrypter10(peImage, codeHeader.decryptionKey);
for (uint rid = 1; rid <= methodDefTable.Rows; rid++) {
@ -547,74 +547,74 @@ namespace de4dot.code.deobfuscators.Agile_NET {
if (method == null || method.DeclaringType == module.GlobalType)
continue;
peImage.readMethodTableRowTo(dm, rid);
peImage.ReadMethodTableRowTo(dm, rid);
if (dm.mdRVA == 0)
continue;
uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
uint bodyOffset = peImage.RvaToOffset(dm.mdRVA);
var mbHeader = decrypter.decrypt(bodyOffset, out dm.code, out dm.extraSections);
peImage.updateMethodHeaderInfo(dm, mbHeader);
var mbHeader = decrypter.Decrypt(bodyOffset, out dm.code, out dm.extraSections);
peImage.UpdateMethodHeaderInfo(dm, mbHeader);
dumpedMethods.add(dm);
dumpedMethods.Add(dm);
}
}
void decryptMethods(uint codeHeaderOffset, MDTable methodDefTable, ICsHeader csHeader, ref DumpedMethods dumpedMethods) {
var methodInfos = csHeader.getMethodInfos(codeHeaderOffset);
csHeader.patchMethodTable(methodDefTable, methodInfos);
void DecryptMethods(uint codeHeaderOffset, MDTable methodDefTable, ICsHeader csHeader, ref DumpedMethods dumpedMethods) {
var methodInfos = csHeader.GetMethodInfos(codeHeaderOffset);
csHeader.PatchMethodTable(methodDefTable, methodInfos);
dumpedMethods = new DumpedMethods();
decrypter = csHeader.createDecrypter();
decrypter = csHeader.CreateDecrypter();
for (uint rid = 1; rid <= (uint)methodInfos.Count; rid++) {
var methodInfo = methodInfos[(int)rid - 1];
if (methodInfo.codeOffs == 0)
continue;
var dm = new DumpedMethod();
peImage.readMethodTableRowTo(dm, rid);
peImage.ReadMethodTableRowTo(dm, rid);
var mbHeader = decrypter.decrypt(methodInfo, out dm.code, out dm.extraSections);
peImage.updateMethodHeaderInfo(dm, mbHeader);
var mbHeader = decrypter.Decrypt(methodInfo, out dm.code, out dm.extraSections);
peImage.UpdateMethodHeaderInfo(dm, mbHeader);
dumpedMethods.add(dm);
dumpedMethods.Add(dm);
}
}
void readCodeHeader(uint offset) {
codeHeader.signature = peImage.offsetReadBytes(offset, 16);
codeHeader.decryptionKey = peImage.offsetReadBytes(offset + 0x10, 16);
codeHeader.totalCodeSize = peImage.offsetReadUInt32(offset + 0x20);
codeHeader.numMethods = peImage.offsetReadUInt32(offset + 0x24);
codeHeader.methodDefTableOffset = peImage.offsetReadUInt32(offset + 0x28);
codeHeader.methodDefElemSize = peImage.offsetReadUInt32(offset + 0x2C);
void ReadCodeHeader(uint offset) {
codeHeader.signature = peImage.OffsetReadBytes(offset, 16);
codeHeader.decryptionKey = peImage.OffsetReadBytes(offset + 0x10, 16);
codeHeader.totalCodeSize = peImage.OffsetReadUInt32(offset + 0x20);
codeHeader.numMethods = peImage.OffsetReadUInt32(offset + 0x24);
codeHeader.methodDefTableOffset = peImage.OffsetReadUInt32(offset + 0x28);
codeHeader.methodDefElemSize = peImage.OffsetReadUInt32(offset + 0x2C);
}
static SigType getSigType(byte[] sig) {
if (Utils.compare(sig, normalSignature))
static SigType GetSigType(byte[] sig) {
if (Utils.Compare(sig, normalSignature))
return SigType.Normal;
else if (Utils.compare(sig, proSignature))
else if (Utils.Compare(sig, proSignature))
return SigType.Pro;
else if (Utils.compare(sig, oldSignature))
else if (Utils.Compare(sig, oldSignature))
return SigType.Old;
return SigType.Unknown;
}
static bool isValidSignature(byte[] signature) {
return getSigType(signature) != SigType.Unknown;
static bool IsValidSignature(byte[] signature) {
return GetSigType(signature) != SigType.Unknown;
}
public static bool detect(MyPEImage peImage) {
public static bool Detect(MyPEImage peImage) {
try {
uint codeHeaderOffset = getCodeHeaderOffset(peImage);
if (isValidSignature(peImage.offsetReadBytes(codeHeaderOffset, 16)))
uint codeHeaderOffset = GetCodeHeaderOffset(peImage);
if (IsValidSignature(peImage.OffsetReadBytes(codeHeaderOffset, 16)))
return true;
}
catch {
}
try {
uint codeHeaderOffset = getOldCodeHeaderOffset(peImage);
if (codeHeaderOffset != 0 && isValidSignature(peImage.offsetReadBytes(codeHeaderOffset, 16)))
uint codeHeaderOffset = GetOldCodeHeaderOffset(peImage);
if (codeHeaderOffset != 0 && IsValidSignature(peImage.OffsetReadBytes(codeHeaderOffset, 16)))
return true;
}
catch {

View File

@ -32,28 +32,28 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public ProxyCallFixer(ModuleDefMD module, ProxyCallFixer oldOne)
: base(module) {
foreach (var method in oldOne.delegateCreatorMethods)
setDelegateCreatorMethod(lookup(method, "Could not find delegate creator method"));
SetDelegateCreatorMethod(Lookup(method, "Could not find delegate creator method"));
}
public void findDelegateCreator() {
public void FindDelegateCreator() {
foreach (var type in module.Types) {
var methodName = "System.Void " + type.FullName + "::icgd(System.Int32)";
foreach (var method in type.Methods) {
if (method.FullName == methodName) {
setDelegateCreatorMethod(method);
SetDelegateCreatorMethod(method);
return;
}
}
}
}
protected override object checkCctor(ref TypeDef type, MethodDef cctor) {
protected override object CheckCctor(ref TypeDef type, MethodDef cctor) {
var instrs = cctor.Body.Instructions;
if (instrs.Count != 3)
return null;
if (!instrs[0].IsLdcI4())
return null;
if (instrs[1].OpCode != OpCodes.Call || !isDelegateCreatorMethod(instrs[1].Operand as MethodDef))
if (instrs[1].OpCode != OpCodes.Call || !IsDelegateCreatorMethod(instrs[1].Operand as MethodDef))
return null;
if (instrs[2].OpCode != OpCodes.Ret)
return null;
@ -67,7 +67,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return new object();
}
protected override void getCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
protected override void GetCallInfo(object context, FieldDef field, out IMethod calledMethod, out OpCode callOpcode) {
var name = field.Name.String;
callOpcode = OpCodes.Call;
if (name.EndsWith("%", StringComparison.Ordinal)) {

View File

@ -49,39 +49,39 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public ResourceDecrypter(ModuleDefMD module, ResourceDecrypter oldOne) {
this.module = module;
rsrcType = lookup(oldOne.rsrcType, "Could not find rsrcType");
rsrcRrrMethod = lookup(oldOne.rsrcRrrMethod, "Could not find rsrcRrrMethod");
rsrcResolveMethod = lookup(oldOne.rsrcResolveMethod, "Could not find rsrcResolveMethod");
rsrcType = Lookup(oldOne.rsrcType, "Could not find rsrcType");
rsrcRrrMethod = Lookup(oldOne.rsrcRrrMethod, "Could not find rsrcRrrMethod");
rsrcResolveMethod = Lookup(oldOne.rsrcResolveMethod, "Could not find rsrcResolveMethod");
}
T lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
T Lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.Lookup(module, def, errorMessage);
}
public void find() {
findResourceType();
public void Find() {
FindResourceType();
}
static readonly string[] requiredFields = new string[] {
"System.Reflection.Assembly",
"System.String[]",
};
void findResourceType() {
var cctor = DotNetUtils.getModuleTypeCctor(module);
void FindResourceType() {
var cctor = DotNetUtils.GetModuleTypeCctor(module);
if (cctor == null)
return;
foreach (var calledMethod in DotNetUtils.getCalledMethods(module, cctor)) {
foreach (var calledMethod in DotNetUtils.GetCalledMethods(module, cctor)) {
if (!calledMethod.IsStatic || calledMethod.Body == null)
continue;
if (!DotNetUtils.isMethod(calledMethod, "System.Void", "()"))
if (!DotNetUtils.IsMethod(calledMethod, "System.Void", "()"))
continue;
var type = calledMethod.DeclaringType;
if (!new FieldTypes(type).exactly(requiredFields))
if (!new FieldTypes(type).Exactly(requiredFields))
continue;
var resolveHandler = DotNetUtils.getMethod(type, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)");
var decryptMethod = DotNetUtils.getMethod(type, "System.Byte[]", "(System.IO.Stream)");
var resolveHandler = DotNetUtils.GetMethod(type, "System.Reflection.Assembly", "(System.Object,System.ResolveEventArgs)");
var decryptMethod = DotNetUtils.GetMethod(type, "System.Byte[]", "(System.IO.Stream)");
if (resolveHandler == null || !resolveHandler.IsStatic)
continue;
if (decryptMethod == null || !decryptMethod.IsStatic)
@ -94,17 +94,17 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
public EmbeddedResource mergeResources() {
public EmbeddedResource MergeResources() {
if (rsrcResolveMethod == null)
return null;
var resource = DotNetUtils.getResource(module, DotNetUtils.getCodeStrings(rsrcResolveMethod)) as EmbeddedResource;
var resource = DotNetUtils.GetResource(module, DotNetUtils.GetCodeStrings(rsrcResolveMethod)) as EmbeddedResource;
if (resource == null)
return null;
DeobUtils.decryptAndAddResources(module, resource.Name.String, () => decryptResource(resource));
DeobUtils.DecryptAndAddResources(module, resource.Name.String, () => DecryptResource(resource));
return resource;
}
byte[] decryptResource(EmbeddedResource resource) {
byte[] DecryptResource(EmbeddedResource resource) {
var reader = resource.Data;
reader.Position = 0;
var key = reader.ReadString();

View File

@ -39,7 +39,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
this.module = module;
}
public void find() {
public void Find() {
foreach (var type in module.Types) {
if (!type.HasMethods)
continue;
@ -55,7 +55,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
var sig = method.MethodSig;
if (sig != null && method.IsStatic && method.HasBody &&
sig.Params.Count == 2 && !method.HasGenericParameters &&
!DotNetUtils.hasReturnValue(method) &&
!DotNetUtils.HasReturnValue(method) &&
sig.Params[0].GetFullName() == "System.Exception" &&
sig.Params[1].GetFullName() == "System.Object[]") {
errorMethod = method;
@ -65,7 +65,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
if (errorMethod != null) {
stackFrameHelperType = type;
exceptionLoggerRemover.add(errorMethod);
exceptionLoggerRemover.Add(errorMethod);
return;
}
}

View File

@ -48,16 +48,16 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public StringDecrypter(ModuleDefMD module, StringDecrypter oldOne) {
this.module = module;
stringDecrypterType = lookup(oldOne.stringDecrypterType, "Could not find stringDecrypterType");
stringDecrypterMethod = lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod");
stringDecrypterType = Lookup(oldOne.stringDecrypterType, "Could not find stringDecrypterType");
stringDecrypterMethod = Lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod");
stringDecrypterKey = oldOne.stringDecrypterKey;
}
T lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.lookup(module, def, errorMessage);
T Lookup<T>(T def, string errorMessage) where T : class, ICodedToken {
return DeobUtils.Lookup(module, def, errorMessage);
}
public void find() {
public void Find() {
stringDecrypterKey = new byte[1] { 0xFF };
foreach (var type in module.Types) {
if (type.FullName == "<D234>" || type.FullName == "<ClassD234>") {
@ -73,7 +73,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
public string decrypt(string es) {
public string Decrypt(string es) {
if (stringDecrypterKey == null)
throw new ApplicationException("Trying to decrypt strings when stringDecrypterKey is null (could not find it!)");
char[] buf = new char[es.Length];

View File

@ -29,7 +29,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
class CilOperandInstructionRestorer {
MethodDef method;
public bool restore(MethodDef method) {
public bool Restore(MethodDef method) {
this.method = method;
bool atLeastOneFailed = false;
@ -45,26 +45,26 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
TypeSig operandType = null;
switch (instr.OpCode.Code) {
case Code.Ldelema:
var arrayType = MethodStack.getLoadedType(method, instrs, i, 1) as SZArraySig;
var arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig;
if (arrayType == null)
break;
operandType = arrayType.Next;
break;
case Code.Ldobj:
operandType = getPtrElementType(MethodStack.getLoadedType(method, instrs, i, 0));
operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 0));
break;
case Code.Stobj:
operandType = MethodStack.getLoadedType(method, instrs, i, 0);
if (!isValidType(operandType))
operandType = getPtrElementType(MethodStack.getLoadedType(method, instrs, i, 1));
operandType = MethodStack.GetLoadedType(method, instrs, i, 0);
if (!IsValidType(operandType))
operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 1));
break;
default:
continue;
}
if (!isValidType(operandType)) {
if (!IsValidType(operandType)) {
atLeastOneFailed = true;
continue;
}
@ -75,7 +75,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return !atLeastOneFailed;
}
static TypeSig getPtrElementType(TypeSig type) {
static TypeSig GetPtrElementType(TypeSig type) {
if (type == null)
return null;
if (type.IsPointer || type.IsByRef)
@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return null;
}
bool isValidType(TypeSig type) {
bool IsValidType(TypeSig type) {
type = type.RemovePinnedAndModifiers();
if (type == null)
return false;

View File

@ -52,12 +52,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
this.vmAssemblyRef = module.ResolveAssemblyRef(oldOne.vmAssemblyRef.Rid);
}
public void find() {
resource = findCsvmResource();
vmAssemblyRef = findVmAssemblyRef();
public void Find() {
resource = FindCsvmResource();
vmAssemblyRef = FindVmAssemblyRef();
}
AssemblyRef findVmAssemblyRef() {
AssemblyRef FindVmAssemblyRef() {
foreach (var memberRef in module.GetMemberRefs()) {
var sig = memberRef.MethodSig;
if (sig == null)
@ -74,17 +74,17 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return null;
}
EmbeddedResource findCsvmResource() {
return DotNetUtils.getResource(module, "_CSVM") as EmbeddedResource;
EmbeddedResource FindCsvmResource() {
return DotNetUtils.GetResource(module, "_CSVM") as EmbeddedResource;
}
public bool restore() {
public bool Restore() {
if (!Detected)
return true;
int oldIndent = Logger.Instance.IndentLevel;
try {
restore2();
Restore2();
return true;
}
catch {
@ -95,66 +95,66 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
}
void restore2() {
void Restore2() {
Logger.v("Restoring CSVM methods");
Logger.Instance.indent();
Logger.Instance.Indent();
var opcodeDetector = getVmOpCodeHandlerDetector();
var csvmMethods = new CsvmDataReader(resource.Data).read();
var opcodeDetector = GetVmOpCodeHandlerDetector();
var csvmMethods = new CsvmDataReader(resource.Data).Read();
var converter = new CsvmToCilMethodConverter(deobfuscatorContext, module, opcodeDetector);
var methodPrinter = new MethodPrinter();
foreach (var csvmMethod in csvmMethods) {
var cilMethod = module.ResolveToken(csvmMethod.Token) as MethodDef;
if (cilMethod == null)
throw new ApplicationException(string.Format("Could not find method {0:X8}", csvmMethod.Token));
converter.convert(cilMethod, csvmMethod);
converter.Convert(cilMethod, csvmMethod);
Logger.v("Restored method {0:X8}", cilMethod.MDToken.ToInt32());
printMethod(methodPrinter, cilMethod);
PrintMethod(methodPrinter, cilMethod);
}
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
}
static void printMethod(MethodPrinter methodPrinter, MethodDef method) {
static void PrintMethod(MethodPrinter methodPrinter, MethodDef method) {
const LoggerEvent dumpLogLevel = LoggerEvent.Verbose;
if (Logger.Instance.IgnoresEvent(dumpLogLevel))
return;
Logger.Instance.indent();
Logger.Instance.Indent();
Logger.v("Locals:");
Logger.Instance.indent();
Logger.Instance.Indent();
for (int i = 0; i < method.Body.Variables.Count; i++)
Logger.v("#{0}: {1}", i, method.Body.Variables[i].Type);
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
Logger.v("Code:");
Logger.Instance.indent();
methodPrinter.print(dumpLogLevel, method.Body.Instructions, method.Body.ExceptionHandlers);
Logger.Instance.deIndent();
Logger.Instance.Indent();
methodPrinter.Print(dumpLogLevel, method.Body.Instructions, method.Body.ExceptionHandlers);
Logger.Instance.DeIndent();
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
}
VmOpCodeHandlerDetector getVmOpCodeHandlerDetector() {
VmOpCodeHandlerDetector GetVmOpCodeHandlerDetector() {
var vmFilename = vmAssemblyRef.Name + ".dll";
var vmModulePath = Path.Combine(Path.GetDirectoryName(module.Location), vmFilename);
Logger.v("CSVM filename: {0}", vmFilename);
var dataKey = "cs cached VmOpCodeHandlerDetector";
var dict = (Dictionary<string, VmOpCodeHandlerDetector>)deobfuscatorContext.getData(dataKey);
var dict = (Dictionary<string, VmOpCodeHandlerDetector>)deobfuscatorContext.GetData(dataKey);
if (dict == null)
deobfuscatorContext.setData(dataKey, dict = new Dictionary<string, VmOpCodeHandlerDetector>(StringComparer.OrdinalIgnoreCase));
deobfuscatorContext.SetData(dataKey, dict = new Dictionary<string, VmOpCodeHandlerDetector>(StringComparer.OrdinalIgnoreCase));
VmOpCodeHandlerDetector detector;
if (dict.TryGetValue(vmModulePath, out detector))
return detector;
dict[vmModulePath] = detector = new VmOpCodeHandlerDetector(ModuleDefMD.Load(vmModulePath));
detector.findHandlers();
detector.FindHandlers();
Logger.v("CSVM opcodes:");
Logger.Instance.indent();
Logger.Instance.Indent();
for (int i = 0; i < detector.Handlers.Count; i++)
Logger.v("{0:X4}: {1}", i, detector.Handlers[i].Name);
Logger.Instance.deIndent();
Logger.Instance.DeIndent();
return detector;
}

View File

@ -33,7 +33,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
this.reader = reader;
}
public List<CsvmMethodData> read() {
public List<CsvmMethodData> Read() {
int numMethods = reader.ReadInt32();
if (numMethods < 0)
throw new ApplicationException("Invalid number of methods");

View File

@ -37,33 +37,33 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
this.opCodeDetector = opCodeDetector;
}
public void convert(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var newInstructions = readInstructions(cilMethod, csvmMethod);
var newLocals = readLocals(cilMethod, csvmMethod);
var newExceptions = readExceptions(cilMethod, csvmMethod, newInstructions);
public void Convert(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var newInstructions = ReadInstructions(cilMethod, csvmMethod);
var newLocals = ReadLocals(cilMethod, csvmMethod);
var newExceptions = ReadExceptions(cilMethod, csvmMethod, newInstructions);
fixInstructionOperands(newInstructions);
fixLocals(newInstructions, cilMethod.Body.Variables);
fixArgs(newInstructions, cilMethod);
FixInstructionOperands(newInstructions);
FixLocals(newInstructions, cilMethod.Body.Variables);
FixArgs(newInstructions, cilMethod);
DotNetUtils.restoreBody(cilMethod, newInstructions, newExceptions);
DotNetUtils.RestoreBody(cilMethod, newInstructions, newExceptions);
if (!operandRestorer.restore(cilMethod))
if (!operandRestorer.Restore(cilMethod))
Logger.w("Failed to restore one or more instruction operands in CSVM method {0:X8}", cilMethod.MDToken.ToInt32());
restoreConstrainedPrefix(cilMethod);
RestoreConstrainedPrefix(cilMethod);
}
void fixLocals(IList<Instruction> instrs, IList<Local> locals) {
void FixLocals(IList<Instruction> instrs, IList<Local> locals) {
foreach (var instr in instrs) {
var op = instr.Operand as LocalOperand;
if (op == null)
continue;
updateLocalInstruction(instr, locals[op.local], op.local);
UpdateLocalInstruction(instr, locals[op.local], op.local);
}
}
static void updateLocalInstruction(Instruction instr, Local local, int index) {
static void UpdateLocalInstruction(Instruction instr, Local local, int index) {
object operand = null;
OpCode opcode;
@ -128,17 +128,17 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
instr.Operand = operand;
}
void fixArgs(IList<Instruction> instrs, MethodDef method) {
void FixArgs(IList<Instruction> instrs, MethodDef method) {
foreach (var instr in instrs) {
var op = instr.Operand as ArgOperand;
if (op == null)
continue;
updateArgInstruction(instr, method.Parameters[op.arg], op.arg);
UpdateArgInstruction(instr, method.Parameters[op.arg], op.arg);
}
}
static void updateArgInstruction(Instruction instr, Parameter arg, int index) {
static void UpdateArgInstruction(Instruction instr, Parameter arg, int index) {
switch (instr.OpCode.Code) {
case Code.Ldarg:
case Code.Ldarg_S:
@ -197,7 +197,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
}
List<Instruction> readInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
List<Instruction> ReadInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions));
var instrs = new List<Instruction>();
uint offset = 0;
@ -205,13 +205,13 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
int vmOpCode = reader.ReadUInt16();
var instr = opCodeDetector.Handlers[vmOpCode].Read(reader);
instr.Offset = offset;
offset += (uint)getInstructionSize(instr);
offset += (uint)GetInstructionSize(instr);
instrs.Add(instr);
}
return instrs;
}
static int getInstructionSize(Instruction instr) {
static int GetInstructionSize(Instruction instr) {
var opcode = instr.OpCode;
if (opcode == null)
return 5; // Load store/field
@ -221,7 +221,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return instr.OpCode.Size + (op.targetDisplacements.Length + 1) * 4;
}
List<Local> readLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
List<Local> ReadLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) {
var locals = new List<Local>();
var reader = new BinaryReader(new MemoryStream(csvmMethod.Locals));
@ -234,12 +234,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
throw new ApplicationException("Invalid number of locals");
for (int i = 0; i < numLocals; i++)
locals.Add(new Local(readTypeRef(reader)));
locals.Add(new Local(ReadTypeRef(reader)));
return locals;
}
TypeSig readTypeRef(BinaryReader reader) {
TypeSig ReadTypeRef(BinaryReader reader) {
var etype = (ElementType)reader.ReadInt32();
switch (etype) {
case ElementType.Void: return module.CorLibTypes.Void;
@ -289,7 +289,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
}
List<ExceptionHandler> readExceptions(MethodDef cilMethod, CsvmMethodData csvmMethod, List<Instruction> cilInstructions) {
List<ExceptionHandler> ReadExceptions(MethodDef cilMethod, CsvmMethodData csvmMethod, List<Instruction> cilInstructions) {
var reader = new BinaryReader(new MemoryStream(csvmMethod.Exceptions));
var ehs = new List<ExceptionHandler>();
@ -302,14 +302,14 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
for (int i = 0; i < numExceptions; i++) {
var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32());
eh.TryStart = getInstruction(cilInstructions, reader.ReadInt32());
eh.TryEnd = getInstructionEnd(cilInstructions, reader.ReadInt32());
eh.HandlerStart = getInstruction(cilInstructions, reader.ReadInt32());
eh.HandlerEnd = getInstructionEnd(cilInstructions, reader.ReadInt32());
eh.TryStart = GetInstruction(cilInstructions, reader.ReadInt32());
eh.TryEnd = GetInstructionEnd(cilInstructions, reader.ReadInt32());
eh.HandlerStart = GetInstruction(cilInstructions, reader.ReadInt32());
eh.HandlerEnd = GetInstructionEnd(cilInstructions, reader.ReadInt32());
if (eh.HandlerType == ExceptionHandlerType.Catch)
eh.CatchType = module.ResolveToken(reader.ReadUInt32()) as ITypeDefOrRef;
else if (eh.HandlerType == ExceptionHandlerType.Filter)
eh.FilterStart = getInstruction(cilInstructions, reader.ReadInt32());
eh.FilterStart = GetInstruction(cilInstructions, reader.ReadInt32());
ehs.Add(eh);
}
@ -317,44 +317,44 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return ehs;
}
static Instruction getInstruction(IList<Instruction> instrs, int index) {
static Instruction GetInstruction(IList<Instruction> instrs, int index) {
return instrs[index];
}
static Instruction getInstructionEnd(IList<Instruction> instrs, int index) {
static Instruction GetInstructionEnd(IList<Instruction> instrs, int index) {
index++;
if (index == instrs.Count)
return null;
return instrs[index];
}
static Instruction getInstruction(IList<Instruction> instrs, Instruction source, int displ) {
static Instruction GetInstruction(IList<Instruction> instrs, Instruction source, int displ) {
int sourceIndex = instrs.IndexOf(source);
if (sourceIndex < 0)
throw new ApplicationException("Could not find source instruction");
return instrs[sourceIndex + displ];
}
void fixInstructionOperands(IList<Instruction> instrs) {
void FixInstructionOperands(IList<Instruction> instrs) {
foreach (var instr in instrs) {
var op = instr.Operand as IVmOperand;
if (op != null)
instr.Operand = fixOperand(instrs, instr, op);
instr.Operand = FixOperand(instrs, instr, op);
}
}
object fixOperand(IList<Instruction> instrs, Instruction instr, IVmOperand vmOperand) {
object FixOperand(IList<Instruction> instrs, Instruction instr, IVmOperand vmOperand) {
if (vmOperand is TokenOperand)
return getMemberRef(((TokenOperand)vmOperand).token);
return GetMemberRef(((TokenOperand)vmOperand).token);
if (vmOperand is TargetDisplOperand)
return getInstruction(instrs, instr, ((TargetDisplOperand)vmOperand).displacement);
return GetInstruction(instrs, instr, ((TargetDisplOperand)vmOperand).displacement);
if (vmOperand is SwitchTargetDisplOperand) {
var targetDispls = ((SwitchTargetDisplOperand)vmOperand).targetDisplacements;
Instruction[] targets = new Instruction[targetDispls.Length];
for (int i = 0; i < targets.Length; i++)
targets[i] = getInstruction(instrs, instr, targetDispls[i]);
targets[i] = GetInstruction(instrs, instr, targetDispls[i]);
return targets;
}
@ -362,20 +362,20 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return vmOperand;
if (vmOperand is LoadFieldOperand)
return fixLoadStoreFieldInstruction(instr, ((LoadFieldOperand)vmOperand).token, OpCodes.Ldsfld, OpCodes.Ldfld);
return FixLoadStoreFieldInstruction(instr, ((LoadFieldOperand)vmOperand).token, OpCodes.Ldsfld, OpCodes.Ldfld);
if (vmOperand is LoadFieldAddressOperand)
return fixLoadStoreFieldInstruction(instr, ((LoadFieldAddressOperand)vmOperand).token, OpCodes.Ldsflda, OpCodes.Ldflda);
return FixLoadStoreFieldInstruction(instr, ((LoadFieldAddressOperand)vmOperand).token, OpCodes.Ldsflda, OpCodes.Ldflda);
if (vmOperand is StoreFieldOperand)
return fixLoadStoreFieldInstruction(instr, ((StoreFieldOperand)vmOperand).token, OpCodes.Stsfld, OpCodes.Stfld);
return FixLoadStoreFieldInstruction(instr, ((StoreFieldOperand)vmOperand).token, OpCodes.Stsfld, OpCodes.Stfld);
throw new ApplicationException(string.Format("Unknown operand type: {0}", vmOperand.GetType()));
}
IField fixLoadStoreFieldInstruction(Instruction instr, int token, OpCode staticInstr, OpCode instanceInstr) {
IField FixLoadStoreFieldInstruction(Instruction instr, int token, OpCode staticInstr, OpCode instanceInstr) {
var fieldRef = module.ResolveToken(token) as IField;
var field = deobfuscatorContext.resolveField(fieldRef);
var field = deobfuscatorContext.ResolveField(fieldRef);
bool isStatic;
if (field == null) {
Logger.w("Could not resolve field {0:X8}. Assuming it's not static.", token);
@ -387,14 +387,14 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return fieldRef;
}
ITokenOperand getMemberRef(int token) {
ITokenOperand GetMemberRef(int token) {
var memberRef = module.ResolveToken(token) as ITokenOperand;
if (memberRef == null)
throw new ApplicationException(string.Format("Could not find member ref: {0:X8}", token));
return memberRef;
}
static void restoreConstrainedPrefix(MethodDef method) {
static void RestoreConstrainedPrefix(MethodDef method) {
if (method == null || method.Body == null)
return;
@ -410,17 +410,17 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
var sig = calledMethod.MethodSig;
if (sig == null || !sig.HasThis)
continue;
var thisType = MethodStack.getLoadedType(method, instrs, i, sig.Params.Count) as ByRefSig;
var thisType = MethodStack.GetLoadedType(method, instrs, i, sig.Params.Count) as ByRefSig;
if (thisType == null)
continue;
if (hasPrefix(instrs, i, Code.Constrained))
if (HasPrefix(instrs, i, Code.Constrained))
continue;
instrs.Insert(i, OpCodes.Constrained.ToInstruction(thisType.Next.ToTypeDefOrRef()));
i++;
}
}
static bool hasPrefix(IList<Instruction> instrs, int index, Code prefix) {
static bool HasPrefix(IList<Instruction> instrs, int index, Code prefix) {
index--;
for (; index >= 0; index--) {
var instr = instrs[index];

View File

@ -35,36 +35,36 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
foreach (var field in fields) {
var fieldTypeDef = field.FieldSig.GetFieldType().TryGetTypeDef();
if (fieldTypeDef != null && fieldTypeDef.IsEnum)
addEnum();
AddEnum();
else
add(field.FieldSig.GetFieldType());
Add(field.FieldSig.GetFieldType());
}
}
public FieldsInfo(object[] fieldTypes) {
foreach (var o in fieldTypes) {
if (o == EnumType)
addEnum();
AddEnum();
else
add((string)o);
Add((string)o);
}
}
void add(TypeSig type) {
add(type.GetFullName());
void Add(TypeSig type) {
Add(type.GetFullName());
}
void add(string typeFullName) {
void Add(string typeFullName) {
int count;
fieldTypes.TryGetValue(typeFullName, out count);
fieldTypes[typeFullName] = count + 1;
}
void addEnum() {
void AddEnum() {
numEnums++;
}
public bool isSame(FieldsInfo other) {
public bool IsSame(FieldsInfo other) {
if (numEnums != other.numEnums)
return false;
if (fieldTypes.Count != other.fieldTypes.Count)

View File

@ -31,24 +31,24 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
public Predicate<UnknownHandlerInfo> Check { get; set; }
public Func<BinaryReader, Instruction> Read { get; set; }
public bool detect(UnknownHandlerInfo info) {
public bool Detect(UnknownHandlerInfo info) {
var sigInfo = OpCodeHandlerSigInfo;
if (!compare(sigInfo.NumStaticMethods, info.NumStaticMethods))
if (!Compare(sigInfo.NumStaticMethods, info.NumStaticMethods))
return false;
if (!compare(sigInfo.NumInstanceMethods, info.NumInstanceMethods))
if (!Compare(sigInfo.NumInstanceMethods, info.NumInstanceMethods))
return false;
if (!compare(sigInfo.NumVirtualMethods, info.NumVirtualMethods))
if (!Compare(sigInfo.NumVirtualMethods, info.NumVirtualMethods))
return false;
if (!compare(sigInfo.NumCtors, info.NumCtors))
if (!Compare(sigInfo.NumCtors, info.NumCtors))
return false;
if (!compare(sigInfo.ExecuteMethodThrows, info.ExecuteMethodThrows))
if (!Compare(sigInfo.ExecuteMethodThrows, info.ExecuteMethodThrows))
return false;
if (!compare(sigInfo.ExecuteMethodPops, info.ExecuteMethodPops))
if (!Compare(sigInfo.ExecuteMethodPops, info.ExecuteMethodPops))
return false;
if (!info.hasSameFieldTypes(sigInfo.RequiredFieldTypes))
if (!info.HasSameFieldTypes(sigInfo.RequiredFieldTypes))
return false;
if (sigInfo.ExecuteMethodLocals != null && !new LocalTypes(info.ExecuteMethod).all(sigInfo.ExecuteMethodLocals))
if (sigInfo.ExecuteMethodLocals != null && !new LocalTypes(info.ExecuteMethod).All(sigInfo.ExecuteMethodLocals))
return false;
if (Check != null)
@ -56,7 +56,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return true;
}
static bool compare(int? val1, int val2) {
static bool Compare(int? val1, int val2) {
if (!val1.HasValue)
return true;
return val1.Value == val2;
@ -88,7 +88,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool newarr_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)");
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)");
}
static Instruction newarr_read(BinaryReader reader) {
@ -286,7 +286,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool endfinally_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
}
static Instruction endfinally_read(BinaryReader reader) {
@ -365,7 +365,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool ldtoken_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
}
static Instruction ldtoken_read(BinaryReader reader) {
@ -376,9 +376,9 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool leave_check(UnknownHandlerInfo info) {
return !DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)") &&
!DotNetUtils.callsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)") &&
!DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
return !DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)") &&
!DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Type System.Reflection.Module::ResolveType(System.Int32)") &&
!DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MemberInfo System.Reflection.Module::ResolveMember(System.Int32)");
}
static Instruction leave_read(BinaryReader reader) {
@ -435,10 +435,10 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool nop_check(UnknownHandlerInfo info) {
return isEmptyMethod(info.ReadMethod) && isEmptyMethod(info.ExecuteMethod);
return IsEmptyMethod(info.ReadMethod) && IsEmptyMethod(info.ExecuteMethod);
}
static bool isEmptyMethod(MethodDef method) {
static bool IsEmptyMethod(MethodDef method) {
foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code == Code.Ret)
return true;
@ -453,7 +453,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool ret_check(UnknownHandlerInfo info) {
return DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
return DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodBase System.Reflection.Module::ResolveMethod(System.Int32)");
}
static Instruction ret_read(BinaryReader reader) {
@ -506,7 +506,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static bool throw_check(UnknownHandlerInfo info) {
return !DotNetUtils.callsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
return !DotNetUtils.CallsMethod(info.ExecuteMethod, "System.Reflection.MethodInfo System.Type::GetMethod(System.String,System.Reflection.BindingFlags)");
}
static Instruction throw_read(BinaryReader reader) {

Some files were not shown because too many files have changed in this diff Show More