Support generic decrypter methods
This commit is contained in:
parent
a2c8e99b3f
commit
cb6a3ac503
|
@ -21,6 +21,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Mono.Cecil;
|
using Mono.Cecil;
|
||||||
using Mono.Cecil.Cil;
|
using Mono.Cecil.Cil;
|
||||||
|
using Mono.Cecil.Metadata;
|
||||||
using de4dot.blocks;
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code {
|
namespace de4dot.code {
|
||||||
|
@ -183,7 +184,7 @@ namespace de4dot.code {
|
||||||
protected abstract void inlineAllCalls();
|
protected abstract void inlineAllCalls();
|
||||||
|
|
||||||
// Returns null if method is not a method we should inline
|
// Returns null if method is not a method we should inline
|
||||||
protected abstract CallResult createCallResult(MethodReference method, Block block, int callInstrIndex);
|
protected abstract CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex);
|
||||||
|
|
||||||
public int decrypt(Blocks theBlocks) {
|
public int decrypt(Blocks theBlocks) {
|
||||||
if (!HasHandlers)
|
if (!HasHandlers)
|
||||||
|
@ -232,7 +233,11 @@ namespace de4dot.code {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var callResult = createCallResult(method, block, i);
|
MethodReference elementMethod = method;
|
||||||
|
var gim = method as GenericInstanceMethod;
|
||||||
|
if (gim != null)
|
||||||
|
elementMethod = gim.ElementMethod;
|
||||||
|
var callResult = createCallResult(elementMethod, gim, block, i);
|
||||||
if (callResult == null)
|
if (callResult == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -255,6 +260,8 @@ namespace de4dot.code {
|
||||||
return false;
|
return false;
|
||||||
if (arg is int)
|
if (arg is int)
|
||||||
arg = fixIntArg(methodArgs[i].ParameterType, (int)arg);
|
arg = fixIntArg(methodArgs[i].ParameterType, (int)arg);
|
||||||
|
else if (arg is long)
|
||||||
|
arg = fixIntArg(methodArgs[i].ParameterType, (long)arg);
|
||||||
args[i] = arg;
|
args[i] = arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,18 +270,18 @@ namespace de4dot.code {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
object fixIntArg(TypeReference type, int value) {
|
object fixIntArg(TypeReference type, long value) {
|
||||||
if (type.IsPrimitive) {
|
switch (type.EType) {
|
||||||
switch (type.FullName) {
|
case ElementType.Boolean: return value != 0;
|
||||||
case "System.Boolean": return value != 0;
|
case ElementType.Char: return (char)value;
|
||||||
case "System.Char": return (char)value;
|
case ElementType.I1: return (sbyte)value;
|
||||||
case "System.Byte": return (byte)value;
|
case ElementType.U1: return (byte)value;
|
||||||
case "System.SByte": return (sbyte)value;
|
case ElementType.I2: return (short)value;
|
||||||
case "System.Int16": return (short)value;
|
case ElementType.U2: return (ushort)value;
|
||||||
case "System.UInt16": return (ushort)value;
|
case ElementType.I4: return (int)value;
|
||||||
case "System.Int32": return (int)value;
|
case ElementType.U4: return (uint)value;
|
||||||
case "System.UInt32": return (uint)value;
|
case ElementType.I8: return (long)value;
|
||||||
}
|
case ElementType.U8: return (ulong)value;
|
||||||
}
|
}
|
||||||
throw new ApplicationException(string.Format("Wrong type {0}", type));
|
throw new ApplicationException(string.Format("Wrong type {0}", type));
|
||||||
}
|
}
|
||||||
|
@ -360,6 +367,7 @@ namespace de4dot.code {
|
||||||
}
|
}
|
||||||
|
|
||||||
void inlineReturnValues() {
|
void inlineReturnValues() {
|
||||||
|
callResults = removeNulls(callResults);
|
||||||
callResults.Sort((a, b) => {
|
callResults.Sort((a, b) => {
|
||||||
int i1 = allBlocks.FindIndex((x) => a.block == x);
|
int i1 = allBlocks.FindIndex((x) => a.block == x);
|
||||||
int i2 = allBlocks.FindIndex((x) => b.block == x);
|
int i2 = allBlocks.FindIndex((x) => b.block == x);
|
||||||
|
@ -372,6 +380,15 @@ namespace de4dot.code {
|
||||||
inlineReturnValues(callResults);
|
inlineReturnValues(callResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<CallResult> removeNulls(List<CallResult> inList) {
|
||||||
|
var outList = new List<CallResult>(inList.Count);
|
||||||
|
foreach (var callResult in inList) {
|
||||||
|
if (callResult.returnValue != null)
|
||||||
|
outList.Add(callResult);
|
||||||
|
}
|
||||||
|
return outList;
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void inlineReturnValues(IList<CallResult> callResults);
|
protected abstract void inlineReturnValues(IList<CallResult> callResults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,9 +68,11 @@ namespace de4dot.code {
|
||||||
|
|
||||||
class MyCallResult : CallResult {
|
class MyCallResult : CallResult {
|
||||||
public int methodId;
|
public int methodId;
|
||||||
public MyCallResult(Block block, int callEndIndex, int methodId)
|
public GenericInstanceMethod gim;
|
||||||
|
public MyCallResult(Block block, int callEndIndex, int methodId, GenericInstanceMethod gim)
|
||||||
: base(block, callEndIndex) {
|
: base(block, callEndIndex) {
|
||||||
this.methodId = methodId;
|
this.methodId = methodId;
|
||||||
|
this.gim = gim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,11 +93,11 @@ namespace de4dot.code {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CallResult createCallResult(MethodReference method, Block block, int callInstrIndex) {
|
protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) {
|
||||||
int methodId;
|
int methodId;
|
||||||
if (!methodTokenToId.TryGetValue(method.MetadataToken.ToInt32(), out methodId))
|
if (!methodTokenToId.TryGetValue(method.MetadataToken.ToInt32(), out methodId))
|
||||||
return null;
|
return null;
|
||||||
return new MyCallResult(block, callInstrIndex, methodId);
|
return new MyCallResult(block, callInstrIndex, methodId, gim);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void inlineAllCalls() {
|
protected override void inlineAllCalls() {
|
||||||
|
@ -119,18 +121,14 @@ namespace de4dot.code {
|
||||||
if (decryptedStrings.Length != args.Length)
|
if (decryptedStrings.Length != args.Length)
|
||||||
throw new ApplicationException("Invalid decrypted strings array 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++) {
|
for (int i = 0; i < list.Count; i++)
|
||||||
var s = decryptedStrings[i];
|
list[i].returnValue = (string)decryptedStrings[i];
|
||||||
if (s == null)
|
|
||||||
throw new ApplicationException(string.Format("Decrypted string is null. Method: {0}", list[i].getMethodReference()));
|
|
||||||
list[i].returnValue = (string)s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StaticStringInliner : StringInlinerBase {
|
class StaticStringInliner : StringInlinerBase {
|
||||||
MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, object[], string>> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, object[], string>>();
|
MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], string>> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], string>>();
|
||||||
|
|
||||||
public override bool HasHandlers {
|
public override bool HasHandlers {
|
||||||
get { return stringDecrypters.Count != 0; }
|
get { return stringDecrypters.Count != 0; }
|
||||||
|
@ -142,13 +140,15 @@ namespace de4dot.code {
|
||||||
|
|
||||||
class MyCallResult : CallResult {
|
class MyCallResult : CallResult {
|
||||||
public MethodReference methodReference;
|
public MethodReference methodReference;
|
||||||
public MyCallResult(Block block, int callEndIndex, MethodReference method)
|
public GenericInstanceMethod gim;
|
||||||
|
public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim)
|
||||||
: base(block, callEndIndex) {
|
: base(block, callEndIndex) {
|
||||||
this.methodReference = method;
|
this.methodReference = method;
|
||||||
|
this.gim = gim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(MethodDefinition method, Func<MethodDefinition, object[], string> handler) {
|
public void add(MethodDefinition method, Func<MethodDefinition, GenericInstanceMethod, object[], string> handler) {
|
||||||
if (method != null)
|
if (method != null)
|
||||||
stringDecrypters.add(method, handler);
|
stringDecrypters.add(method, handler);
|
||||||
}
|
}
|
||||||
|
@ -157,14 +157,14 @@ namespace de4dot.code {
|
||||||
foreach (var tmp in callResults) {
|
foreach (var tmp in callResults) {
|
||||||
var callResult = (MyCallResult)tmp;
|
var callResult = (MyCallResult)tmp;
|
||||||
var handler = stringDecrypters.find(callResult.methodReference);
|
var handler = stringDecrypters.find(callResult.methodReference);
|
||||||
callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.args);
|
callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CallResult createCallResult(MethodReference method, Block block, int callInstrIndex) {
|
protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) {
|
||||||
if (stringDecrypters.find(method) == null)
|
if (stringDecrypters.find(method) == null)
|
||||||
return null;
|
return null;
|
||||||
return new MyCallResult(block, callInstrIndex, method);
|
return new MyCallResult(block, callInstrIndex, method, gim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
if (Operations.DecryptStrings != OpDecryptString.None) {
|
if (Operations.DecryptStrings != OpDecryptString.None) {
|
||||||
if (stringDecrypter.Resource != null)
|
if (stringDecrypter.Resource != null)
|
||||||
Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(stringDecrypter.Resource.Name));
|
Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(stringDecrypter.Resource.Name));
|
||||||
staticStringInliner.add(stringDecrypter.DecryptMethod, (method, args) => {
|
staticStringInliner.add(stringDecrypter.DecryptMethod, (method, gim, args) => {
|
||||||
return stringDecrypter.decrypt(args);
|
return stringDecrypter.decrypt(args);
|
||||||
});
|
});
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
@ -232,13 +232,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
|
||||||
addTypeToBeRemoved(constantsDecrypter.Type, "Constants decrypter type");
|
addTypeToBeRemoved(constantsDecrypter.Type, "Constants decrypter type");
|
||||||
addResourceToBeRemoved(constantsDecrypter.Resource, "Encrypted constants");
|
addResourceToBeRemoved(constantsDecrypter.Resource, "Encrypted constants");
|
||||||
int32ValueInliner = new Int32ValueInliner();
|
int32ValueInliner = new Int32ValueInliner();
|
||||||
int32ValueInliner.add(constantsDecrypter.Int32Decrypter, (method, args) => constantsDecrypter.decryptInt32((int)args[0]));
|
int32ValueInliner.add(constantsDecrypter.Int32Decrypter, (method, gim, args) => constantsDecrypter.decryptInt32((int)args[0]));
|
||||||
int64ValueInliner = new Int64ValueInliner();
|
int64ValueInliner = new Int64ValueInliner();
|
||||||
int64ValueInliner.add(constantsDecrypter.Int64Decrypter, (method, args) => constantsDecrypter.decryptInt64((int)args[0]));
|
int64ValueInliner.add(constantsDecrypter.Int64Decrypter, (method, gim, args) => constantsDecrypter.decryptInt64((int)args[0]));
|
||||||
singleValueInliner = new SingleValueInliner();
|
singleValueInliner = new SingleValueInliner();
|
||||||
singleValueInliner.add(constantsDecrypter.SingleDecrypter, (method, args) => constantsDecrypter.decryptSingle((int)args[0]));
|
singleValueInliner.add(constantsDecrypter.SingleDecrypter, (method, gim, args) => constantsDecrypter.decryptSingle((int)args[0]));
|
||||||
doubleValueInliner = new DoubleValueInliner();
|
doubleValueInliner = new DoubleValueInliner();
|
||||||
doubleValueInliner.add(constantsDecrypter.DoubleDecrypter, (method, args) => constantsDecrypter.decryptDouble((int)args[0]));
|
doubleValueInliner.add(constantsDecrypter.DoubleDecrypter, (method, gim, args) => constantsDecrypter.decryptDouble((int)args[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyCallFixer.find();
|
proxyCallFixer.find();
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace de4dot.code.deobfuscators.CliSecure {
|
||||||
|
|
||||||
proxyCallFixer.find();
|
proxyCallFixer.find();
|
||||||
|
|
||||||
staticStringInliner.add(stringDecrypter.Method, (method, args) => stringDecrypter.decrypt((string)args[0]));
|
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0]));
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
|
||||||
if (options.DecryptMethods) {
|
if (options.DecryptMethods) {
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace de4dot.code.deobfuscators.CodeFort {
|
||||||
public override void deobfuscateBegin() {
|
public override void deobfuscateBegin() {
|
||||||
base.deobfuscateBegin();
|
base.deobfuscateBegin();
|
||||||
|
|
||||||
staticStringInliner.add(stringDecrypter.Method, (method, args) => stringDecrypter.decrypt((string)args[0]));
|
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0]));
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
|
||||||
proxyCallFixer.find();
|
proxyCallFixer.find();
|
||||||
|
|
|
@ -185,7 +185,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
||||||
|
|
||||||
if (Operations.DecryptStrings != OpDecryptString.None) {
|
if (Operations.DecryptStrings != OpDecryptString.None) {
|
||||||
stringDecrypter.initialize();
|
stringDecrypter.initialize();
|
||||||
staticStringInliner.add(stringDecrypter.DecryptMethod, (method, args) => {
|
staticStringInliner.add(stringDecrypter.DecryptMethod, (method, gim, args) => {
|
||||||
return stringDecrypter.decrypt((int)args[0]);
|
return stringDecrypter.decrypt((int)args[0]);
|
||||||
});
|
});
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
|
|
@ -222,7 +222,7 @@ namespace de4dot.code.deobfuscators.CodeWall {
|
||||||
return;
|
return;
|
||||||
stringDecrypter.initialize(DeobfuscatedFile);
|
stringDecrypter.initialize(DeobfuscatedFile);
|
||||||
foreach (var info in stringDecrypter.Infos)
|
foreach (var info in stringDecrypter.Infos)
|
||||||
staticStringInliner.add(info.Method, (method, args) => stringDecrypter.decrypt(method, (int)args[0], (int)args[1], (int)args[2]));
|
staticStringInliner.add(info.Method, (method, gim, args) => stringDecrypter.decrypt(method, (int)args[0], (int)args[1], (int)args[2]));
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
hasInitializedStringDecrypter = true;
|
hasInitializedStringDecrypter = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
decryptResources();
|
decryptResources();
|
||||||
stringDecrypter.init(resourceDecrypter);
|
stringDecrypter.init(resourceDecrypter);
|
||||||
if (stringDecrypter.Method != null) {
|
if (stringDecrypter.Method != null) {
|
||||||
staticStringInliner.add(stringDecrypter.Method, (method, args) => {
|
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => {
|
||||||
return stringDecrypter.decrypt((int)args[0]);
|
return stringDecrypter.decrypt((int)args[0]);
|
||||||
});
|
});
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
@ -196,13 +196,13 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
|
||||||
if (options.DecryptConstants) {
|
if (options.DecryptConstants) {
|
||||||
constantsDecrypter.init(resourceDecrypter);
|
constantsDecrypter.init(resourceDecrypter);
|
||||||
int32ValueInliner = new Int32ValueInliner();
|
int32ValueInliner = new Int32ValueInliner();
|
||||||
int32ValueInliner.add(constantsDecrypter.Int32Decrypter, (method, args) => constantsDecrypter.decryptInt32((int)args[0]));
|
int32ValueInliner.add(constantsDecrypter.Int32Decrypter, (method, gim, args) => constantsDecrypter.decryptInt32((int)args[0]));
|
||||||
int64ValueInliner = new Int64ValueInliner();
|
int64ValueInliner = new Int64ValueInliner();
|
||||||
int64ValueInliner.add(constantsDecrypter.Int64Decrypter, (method, args) => constantsDecrypter.decryptInt64((int)args[0]));
|
int64ValueInliner.add(constantsDecrypter.Int64Decrypter, (method, gim, args) => constantsDecrypter.decryptInt64((int)args[0]));
|
||||||
singleValueInliner = new SingleValueInliner();
|
singleValueInliner = new SingleValueInliner();
|
||||||
singleValueInliner.add(constantsDecrypter.SingleDecrypter, (method, args) => constantsDecrypter.decryptSingle((int)args[0]));
|
singleValueInliner.add(constantsDecrypter.SingleDecrypter, (method, gim, args) => constantsDecrypter.decryptSingle((int)args[0]));
|
||||||
doubleValueInliner = new DoubleValueInliner();
|
doubleValueInliner = new DoubleValueInliner();
|
||||||
doubleValueInliner.add(constantsDecrypter.DoubleDecrypter, (method, args) => constantsDecrypter.decryptDouble((int)args[0]));
|
doubleValueInliner.add(constantsDecrypter.DoubleDecrypter, (method, gim, args) => constantsDecrypter.decryptDouble((int)args[0]));
|
||||||
addTypeToBeRemoved(constantsDecrypter.Type, "Constants decrypter type");
|
addTypeToBeRemoved(constantsDecrypter.Type, "Constants decrypter type");
|
||||||
addResourceToBeRemoved(constantsDecrypter.Resource, "Encrypted constants");
|
addResourceToBeRemoved(constantsDecrypter.Resource, "Encrypted constants");
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var method in stringDecrypter.DecrypterMethods) {
|
foreach (var method in stringDecrypter.DecrypterMethods) {
|
||||||
staticStringInliner.add(method, (method2, args) => {
|
staticStringInliner.add(method, (method2, gim, args) => {
|
||||||
return stringDecrypter.decrypt(method2, args);
|
return stringDecrypter.decrypt(method2, args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.Dotfuscator {
|
||||||
public override void deobfuscateBegin() {
|
public override void deobfuscateBegin() {
|
||||||
base.deobfuscateBegin();
|
base.deobfuscateBegin();
|
||||||
foreach (var info in stringDecrypter.StringDecrypterInfos)
|
foreach (var info in stringDecrypter.StringDecrypterInfos)
|
||||||
staticStringInliner.add(info.method, (method, args) => stringDecrypter.decrypt(method, (string)args[0], (int)args[1]));
|
staticStringInliner.add(info.method, (method, gim, args) => stringDecrypter.decrypt(method, (string)args[0], (int)args[1]));
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ namespace de4dot.code.deobfuscators.Eazfuscator_NET {
|
||||||
base.deobfuscateBegin();
|
base.deobfuscateBegin();
|
||||||
|
|
||||||
stringDecrypter.initialize(DeobfuscatedFile);
|
stringDecrypter.initialize(DeobfuscatedFile);
|
||||||
staticStringInliner.add(stringDecrypter.Method, (method2, args) => {
|
staticStringInliner.add(stringDecrypter.Method, (method2, gim, args) => {
|
||||||
return stringDecrypter.decrypt((int)args[0]);
|
return stringDecrypter.decrypt((int)args[0]);
|
||||||
});
|
});
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
|
|
@ -191,7 +191,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
if (options.DecryptIntegers) {
|
if (options.DecryptIntegers) {
|
||||||
int32ValueInliner = new Int32ValueInliner();
|
int32ValueInliner = new Int32ValueInliner();
|
||||||
foreach (var method in integerDecrypter.getMethods()) {
|
foreach (var method in integerDecrypter.getMethods()) {
|
||||||
int32ValueInliner.add(method, (method2, args) => {
|
int32ValueInliner.add(method, (method2, gim, args) => {
|
||||||
return integerDecrypter.decrypt(method2);
|
return integerDecrypter.decrypt(method2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -200,14 +200,14 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
|
||||||
if (options.DecryptArrays) {
|
if (options.DecryptArrays) {
|
||||||
arrayValueInliner = new ArrayValueInliner(module, initializedDataCreator);
|
arrayValueInliner = new ArrayValueInliner(module, initializedDataCreator);
|
||||||
foreach (var method in arrayDecrypter.getMethods()) {
|
foreach (var method in arrayDecrypter.getMethods()) {
|
||||||
arrayValueInliner.add(method, (method2, args) => {
|
arrayValueInliner.add(method, (method2, gim, args) => {
|
||||||
return arrayDecrypter.decrypt(method2);
|
return arrayDecrypter.decrypt(method2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var method in stringDecrypter.getMethods()) {
|
foreach (var method in stringDecrypter.getMethods()) {
|
||||||
staticStringInliner.add(method, (method2, args) => {
|
staticStringInliner.add(method, (method2, gim, args) => {
|
||||||
return stringDecrypter.decrypt(method2);
|
return stringDecrypter.decrypt(method2);
|
||||||
});
|
});
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
|
||||||
stringDecrypter.find();
|
stringDecrypter.find();
|
||||||
if (stringDecrypter.Detected) {
|
if (stringDecrypter.Detected) {
|
||||||
stringDecrypter.initialize(getEncoding(options.StringCodePage));
|
stringDecrypter.initialize(getEncoding(options.StringCodePage));
|
||||||
staticStringInliner.add(stringDecrypter.Method, (method, args) => stringDecrypter.decrypt((uint)args[0]));
|
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((uint)args[0]));
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -417,11 +417,11 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
|
||||||
Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(info.StringsResource.Name));
|
Log.v("Adding string decrypter. Resource: {0}", Utils.toCsharpString(info.StringsResource.Name));
|
||||||
var decrypter = new StringDecrypter(info);
|
var decrypter = new StringDecrypter(info);
|
||||||
if (decrypter.CanDecrypt) {
|
if (decrypter.CanDecrypt) {
|
||||||
staticStringInliner.add(DotNetUtils.getMethod(info.GetStringDelegate, "Invoke"), (method, args) => {
|
staticStringInliner.add(DotNetUtils.getMethod(info.GetStringDelegate, "Invoke"), (method, gim, args) => {
|
||||||
var fieldDefinition = DotNetUtils.getField(module, (FieldReference)args[0]);
|
var fieldDefinition = DotNetUtils.getField(module, (FieldReference)args[0]);
|
||||||
return decrypter.decrypt(fieldDefinition.MetadataToken.ToInt32(), (int)args[1]);
|
return decrypter.decrypt(fieldDefinition.MetadataToken.ToInt32(), (int)args[1]);
|
||||||
});
|
});
|
||||||
staticStringInliner.add(info.StringDecrypterMethod, (method, args) => {
|
staticStringInliner.add(info.StringDecrypterMethod, (method, gim, args) => {
|
||||||
return decrypter.decrypt(0, (int)args[0]);
|
return decrypter.decrypt(0, (int)args[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ namespace de4dot.code.deobfuscators.Spices_Net {
|
||||||
|
|
||||||
stringDecrypter.initialize();
|
stringDecrypter.initialize();
|
||||||
foreach (var info in stringDecrypter.DecrypterInfos) {
|
foreach (var info in stringDecrypter.DecrypterInfos) {
|
||||||
staticStringInliner.add(info.method, (method2, args) => {
|
staticStringInliner.add(info.method, (method2, gim, args) => {
|
||||||
return stringDecrypter.decrypt(method2);
|
return stringDecrypter.decrypt(method2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,15 @@ using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators {
|
namespace de4dot.code.deobfuscators {
|
||||||
abstract class ValueInlinerBase<TValue> : MethodReturnValueInliner {
|
abstract class ValueInlinerBase<TValue> : MethodReturnValueInliner {
|
||||||
MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, object[], TValue>> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, object[], TValue>>();
|
MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], object>> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDefinition, GenericInstanceMethod, object[], object>>();
|
||||||
|
|
||||||
class MyCallResult : CallResult {
|
class MyCallResult : CallResult {
|
||||||
public MethodReference methodReference;
|
public MethodReference methodReference;
|
||||||
public MyCallResult(Block block, int callEndIndex, MethodReference method)
|
public GenericInstanceMethod gim;
|
||||||
|
public MyCallResult(Block block, int callEndIndex, MethodReference method, GenericInstanceMethod gim)
|
||||||
: base(block, callEndIndex) {
|
: base(block, callEndIndex) {
|
||||||
this.methodReference = method;
|
this.methodReference = method;
|
||||||
|
this.gim = gim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ namespace de4dot.code.deobfuscators {
|
||||||
get { return decrypterMethods.getKeys(); }
|
get { return decrypterMethods.getKeys(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(MethodDefinition method, Func<MethodDefinition, object[], TValue> handler) {
|
public void add(MethodDefinition method, Func<MethodDefinition, GenericInstanceMethod, object[], object> handler) {
|
||||||
if (method == null)
|
if (method == null)
|
||||||
return;
|
return;
|
||||||
if (decrypterMethods.find(method) != null)
|
if (decrypterMethods.find(method) != null)
|
||||||
|
@ -56,14 +58,14 @@ namespace de4dot.code.deobfuscators {
|
||||||
foreach (var tmp in callResults) {
|
foreach (var tmp in callResults) {
|
||||||
var callResult = (MyCallResult)tmp;
|
var callResult = (MyCallResult)tmp;
|
||||||
var handler = decrypterMethods.find(callResult.methodReference);
|
var handler = decrypterMethods.find(callResult.methodReference);
|
||||||
callResult.returnValue = handler((MethodDefinition)callResult.methodReference, callResult.args);
|
callResult.returnValue = (TValue)handler((MethodDefinition)callResult.methodReference, callResult.gim, callResult.args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override CallResult createCallResult(MethodReference method, Block block, int callInstrIndex) {
|
protected override CallResult createCallResult(MethodReference method, GenericInstanceMethod gim, Block block, int callInstrIndex) {
|
||||||
if (decrypterMethods.find(method) == null)
|
if (decrypterMethods.find(method) == null)
|
||||||
return null;
|
return null;
|
||||||
return new MyCallResult(block, callInstrIndex, method);
|
return new MyCallResult(block, callInstrIndex, method, gim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ namespace de4dot.code.deobfuscators.Xenocode {
|
||||||
public override void deobfuscateBegin() {
|
public override void deobfuscateBegin() {
|
||||||
base.deobfuscateBegin();
|
base.deobfuscateBegin();
|
||||||
|
|
||||||
staticStringInliner.add(stringDecrypter.Method, (method, args) => stringDecrypter.decrypt((string)args[0], (int)args[1]));
|
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((string)args[0], (int)args[1]));
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,10 +253,10 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v3 {
|
||||||
|
|
||||||
antiStrongName = new AntiStrongName();
|
antiStrongName = new AntiStrongName();
|
||||||
|
|
||||||
staticStringInliner.add(decrypterType.StringDecrypter1, (method2, args) => {
|
staticStringInliner.add(decrypterType.StringDecrypter1, (method2, gim, args) => {
|
||||||
return decrypterType.decrypt1((string)args[0]);
|
return decrypterType.decrypt1((string)args[0]);
|
||||||
});
|
});
|
||||||
staticStringInliner.add(decrypterType.StringDecrypter2, (method2, args) => {
|
staticStringInliner.add(decrypterType.StringDecrypter2, (method2, gim, args) => {
|
||||||
return decrypterType.decrypt2((string)args[0]);
|
return decrypterType.decrypt2((string)args[0]);
|
||||||
});
|
});
|
||||||
DeobfuscatedFile.stringDecryptersAdded();
|
DeobfuscatedFile.stringDecryptersAdded();
|
||||||
|
|
|
@ -426,18 +426,18 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor.v4 {
|
||||||
emptyClass = new EmptyClass(module);
|
emptyClass = new EmptyClass(module);
|
||||||
|
|
||||||
if (options.DecryptBools) {
|
if (options.DecryptBools) {
|
||||||
booleanValueInliner.add(booleanDecrypter.Method, (method, args) => {
|
booleanValueInliner.add(booleanDecrypter.Method, (method, gim, args) => {
|
||||||
return booleanDecrypter.decrypt((int)args[0]);
|
return booleanDecrypter.decrypt((int)args[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var info in stringDecrypter.DecrypterInfos) {
|
foreach (var info in stringDecrypter.DecrypterInfos) {
|
||||||
staticStringInliner.add(info.method, (method2, args) => {
|
staticStringInliner.add(info.method, (method2, gim, args) => {
|
||||||
return stringDecrypter.decrypt(method2, (int)args[0]);
|
return stringDecrypter.decrypt(method2, (int)args[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (stringDecrypter.OtherStringDecrypter != null) {
|
if (stringDecrypter.OtherStringDecrypter != null) {
|
||||||
staticStringInliner.add(stringDecrypter.OtherStringDecrypter, (method2, args) => {
|
staticStringInliner.add(stringDecrypter.OtherStringDecrypter, (method2, gim, args) => {
|
||||||
return stringDecrypter.decrypt((string)args[0]);
|
return stringDecrypter.decrypt((string)args[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user