Support more than one string decrypter method
This commit is contained in:
parent
291b83e325
commit
43453f3863
|
@ -66,6 +66,7 @@
|
||||||
<Compile Include="deobfuscators\Agile_NET\ResourceDecrypter.cs" />
|
<Compile Include="deobfuscators\Agile_NET\ResourceDecrypter.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\StackFrameHelper.cs" />
|
<Compile Include="deobfuscators\Agile_NET\StackFrameHelper.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\StringDecrypter.cs" />
|
<Compile Include="deobfuscators\Agile_NET\StringDecrypter.cs" />
|
||||||
|
<Compile Include="deobfuscators\Agile_NET\StringDecrypterInfo.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\vm\CilOperandInstructionRestorer.cs" />
|
<Compile Include="deobfuscators\Agile_NET\vm\CilOperandInstructionRestorer.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\vm\CsvmDataReader.cs" />
|
<Compile Include="deobfuscators\Agile_NET\vm\CsvmDataReader.cs" />
|
||||||
<Compile Include="deobfuscators\Agile_NET\vm\CsvmMethodData.cs" />
|
<Compile Include="deobfuscators\Agile_NET\vm\CsvmMethodData.cs" />
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
TypeDef cliSecureRtType;
|
TypeDef cliSecureRtType;
|
||||||
MethodDef postInitializeMethod;
|
MethodDef postInitializeMethod;
|
||||||
MethodDef initializeMethod;
|
MethodDef initializeMethod;
|
||||||
MethodDef stringDecrypterMethod;
|
Dictionary<StringDecrypterInfo, bool> stringDecrypterInfos = new Dictionary<StringDecrypterInfo, bool>();
|
||||||
MethodDef loadMethod;
|
MethodDef loadMethod;
|
||||||
bool foundSig;
|
bool foundSig;
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
get { return cliSecureRtType; }
|
get { return cliSecureRtType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef StringDecrypterMethod {
|
public IEnumerable<StringDecrypterInfo> StringDecrypterInfos {
|
||||||
get { return stringDecrypterMethod; }
|
get { return stringDecrypterInfos.Keys; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef PostInitializeMethod {
|
public MethodDef PostInitializeMethod {
|
||||||
|
@ -66,7 +66,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
cliSecureRtType = Lookup(oldOne.cliSecureRtType, "Could not find CliSecureRt type");
|
cliSecureRtType = Lookup(oldOne.cliSecureRtType, "Could not find CliSecureRt type");
|
||||||
postInitializeMethod = Lookup(oldOne.postInitializeMethod, "Could not find postInitializeMethod method");
|
postInitializeMethod = Lookup(oldOne.postInitializeMethod, "Could not find postInitializeMethod method");
|
||||||
initializeMethod = Lookup(oldOne.initializeMethod, "Could not find initializeMethod method");
|
initializeMethod = Lookup(oldOne.initializeMethod, "Could not find initializeMethod method");
|
||||||
stringDecrypterMethod = Lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod method");
|
foreach (var info in oldOne.stringDecrypterInfos.Keys) {
|
||||||
|
var m = Lookup(info.Method, "Could not find string decrypter method");
|
||||||
|
var f = Lookup(info.Field, "Could not find string decrypter field");
|
||||||
|
stringDecrypterInfos[new StringDecrypterInfo(m, f)] = true;
|
||||||
|
}
|
||||||
loadMethod = Lookup(oldOne.loadMethod, "Could not find loadMethod method");
|
loadMethod = Lookup(oldOne.loadMethod, "Could not find loadMethod method");
|
||||||
foundSig = oldOne.foundSig;
|
foundSig = oldOne.foundSig;
|
||||||
}
|
}
|
||||||
|
@ -100,11 +104,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
if (!HasInitializeMethod(type, "_Initialize") && !HasInitializeMethod(type, "_Initialize64"))
|
if (!HasInitializeMethod(type, "_Initialize") && !HasInitializeMethod(type, "_Initialize64"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
stringDecrypterMethod = FindStringDecrypterMethod(type);
|
|
||||||
initializeMethod = calledMethod;
|
initializeMethod = calledMethod;
|
||||||
postInitializeMethod = FindMethod(type, "System.Void", "PostInitialize", "()");
|
postInitializeMethod = FindMethod(type, "System.Void", "PostInitialize", "()");
|
||||||
loadMethod = FindMethod(type, "System.IntPtr", "Load", "()");
|
loadMethod = FindMethod(type, "System.IntPtr", "Load", "()");
|
||||||
cliSecureRtType = type;
|
cliSecureRtType = type;
|
||||||
|
FindStringDecrypters();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,6 +116,15 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindStringDecrypters() {
|
||||||
|
AddStringDecrypterMethod(FindStringDecrypterMethod(cliSecureRtType));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddStringDecrypterMethod(MethodDef method) {
|
||||||
|
if (method != null)
|
||||||
|
stringDecrypterInfos[new StringDecrypterInfo(method)] = true;
|
||||||
|
}
|
||||||
|
|
||||||
static string[] requiredFields6 = new string[] {
|
static string[] requiredFields6 = new string[] {
|
||||||
"System.Byte[]",
|
"System.Byte[]",
|
||||||
};
|
};
|
||||||
|
@ -134,7 +147,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
if (cs == null)
|
if (cs == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
stringDecrypterMethod = cs;
|
AddStringDecrypterMethod(cs);
|
||||||
cliSecureRtType = type;
|
cliSecureRtType = type;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +221,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cliSecureRtType = type;
|
cliSecureRtType = type;
|
||||||
stringDecrypterMethod = cs;
|
AddStringDecrypterMethod(cs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,7 +180,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
FindCliSecureAttribute();
|
FindCliSecureAttribute();
|
||||||
cliSecureRtType = new CliSecureRtType(module);
|
cliSecureRtType = new CliSecureRtType(module);
|
||||||
cliSecureRtType.Find(ModuleBytes);
|
cliSecureRtType.Find(ModuleBytes);
|
||||||
stringDecrypter = new StringDecrypter(module, cliSecureRtType.StringDecrypterMethod);
|
stringDecrypter = new StringDecrypter(module, cliSecureRtType.StringDecrypterInfos);
|
||||||
stringDecrypter.Find();
|
stringDecrypter.Find();
|
||||||
resourceDecrypter = new ResourceDecrypter(module);
|
resourceDecrypter = new ResourceDecrypter(module);
|
||||||
resourceDecrypter.Find();
|
resourceDecrypter.Find();
|
||||||
|
@ -246,7 +246,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
base.DeobfuscateBegin();
|
base.DeobfuscateBegin();
|
||||||
|
|
||||||
cliSecureRtType.FindStringDecrypterMethod();
|
cliSecureRtType.FindStringDecrypterMethod();
|
||||||
stringDecrypter.Method = cliSecureRtType.StringDecrypterMethod;
|
stringDecrypter.AddDecrypterInfos(cliSecureRtType.StringDecrypterInfos);
|
||||||
|
stringDecrypter.Initialize();
|
||||||
|
|
||||||
AddAttributesToBeRemoved(cliSecureAttributes, "Obfuscator attribute");
|
AddAttributesToBeRemoved(cliSecureAttributes, "Obfuscator attribute");
|
||||||
|
|
||||||
|
@ -265,7 +266,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
|
|
||||||
proxyCallFixer.Find();
|
proxyCallFixer.Find();
|
||||||
|
|
||||||
staticStringInliner.Add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.Decrypt((string)args[0]));
|
foreach (var info in stringDecrypter.StringDecrypterInfos)
|
||||||
|
staticStringInliner.Add(info.Method, (method, gim, args) => stringDecrypter.Decrypt((string)args[0]));
|
||||||
DeobfuscatedFile.StringDecryptersAdded();
|
DeobfuscatedFile.StringDecryptersAdded();
|
||||||
|
|
||||||
if (options.DecryptMethods) {
|
if (options.DecryptMethods) {
|
||||||
|
@ -295,6 +297,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DeobfuscateMethodEnd(Blocks blocks) {
|
public override void DeobfuscateMethodEnd(Blocks blocks) {
|
||||||
|
if (Operations.DecryptStrings != OpDecryptString.None)
|
||||||
|
stringDecrypter.Deobfuscate(blocks);
|
||||||
proxyCallFixer.Deobfuscate(blocks);
|
proxyCallFixer.Deobfuscate(blocks);
|
||||||
RemoveStackFrameHelperCode(blocks);
|
RemoveStackFrameHelperCode(blocks);
|
||||||
base.DeobfuscateMethodEnd(blocks);
|
base.DeobfuscateMethodEnd(blocks);
|
||||||
|
@ -310,8 +314,14 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
}
|
}
|
||||||
if (CanRemoveStringDecrypterType) {
|
if (CanRemoveStringDecrypterType) {
|
||||||
AddTypeToBeRemoved(stringDecrypter.Type, "String decrypter type");
|
AddTypeToBeRemoved(stringDecrypter.Type, "String decrypter type");
|
||||||
|
foreach (var info in stringDecrypter.StringDecrypterInfos) {
|
||||||
|
if (info.Method.DeclaringType != cliSecureRtType.Type)
|
||||||
|
AddMethodToBeRemoved(info.Method, "String decrypter method");
|
||||||
|
if (info.Field != null && info.Field.DeclaringType != stringDecrypter.Type)
|
||||||
|
AddFieldToBeRemoved(info.Field, "String decrypter field");
|
||||||
|
}
|
||||||
if (options.DecryptMethods)
|
if (options.DecryptMethods)
|
||||||
AddTypeToBeRemoved(cliSecureRtType.Type, "Obfuscator type");
|
AddTypeToBeRemoved(cliSecureRtType.Type ?? stringDecrypter.KeyArrayFieldType, "Obfuscator type");
|
||||||
}
|
}
|
||||||
if (options.DecryptMethods) {
|
if (options.DecryptMethods) {
|
||||||
AddResources("Obfuscator protection files");
|
AddResources("Obfuscator protection files");
|
||||||
|
@ -327,8 +337,8 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
|
|
||||||
public override IEnumerable<int> GetStringDecrypterMethods() {
|
public override IEnumerable<int> GetStringDecrypterMethods() {
|
||||||
var list = new List<int>();
|
var list = new List<int>();
|
||||||
if (stringDecrypter.Method != null)
|
foreach (var info in stringDecrypter.StringDecrypterInfos)
|
||||||
list.Add(stringDecrypter.Method.MDToken.ToInt32());
|
list.Add(info.Method.MDToken.ToInt32());
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,38 +18,53 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using dnlib.DotNet;
|
using dnlib.DotNet;
|
||||||
|
using dnlib.DotNet.Emit;
|
||||||
|
using de4dot.blocks;
|
||||||
|
|
||||||
namespace de4dot.code.deobfuscators.Agile_NET {
|
namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
class StringDecrypter {
|
class StringDecrypter {
|
||||||
ModuleDefMD module;
|
ModuleDefMD module;
|
||||||
TypeDef stringDecrypterType;
|
TypeDef stringDecrypterType;
|
||||||
MethodDef stringDecrypterMethod;
|
FieldDef keyInitField;
|
||||||
|
FieldDef keyArrayField;
|
||||||
|
Dictionary<StringDecrypterInfo, bool> stringDecrypterInfos = new Dictionary<StringDecrypterInfo, bool>();
|
||||||
byte[] stringDecrypterKey;
|
byte[] stringDecrypterKey;
|
||||||
|
|
||||||
public bool Detected {
|
public bool Detected {
|
||||||
get { return stringDecrypterMethod != null; }
|
get { return stringDecrypterInfos.Count != 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypeDef Type {
|
public TypeDef Type {
|
||||||
get { return stringDecrypterType; }
|
get { return stringDecrypterType; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodDef Method {
|
public TypeDef KeyArrayFieldType {
|
||||||
get { return stringDecrypterMethod; }
|
get { return keyArrayField == null ? null : keyArrayField.DeclaringType; }
|
||||||
set { stringDecrypterMethod = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringDecrypter(ModuleDefMD module, MethodDef stringDecrypterMethod) {
|
public IEnumerable<StringDecrypterInfo> StringDecrypterInfos {
|
||||||
|
get { return stringDecrypterInfos.Keys; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDecrypter(ModuleDefMD module, IEnumerable<StringDecrypterInfo> stringDecrypterMethods) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.stringDecrypterMethod = stringDecrypterMethod;
|
foreach (var sdm in stringDecrypterMethods)
|
||||||
|
this.stringDecrypterInfos[sdm] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringDecrypter(ModuleDefMD module, StringDecrypter oldOne) {
|
public StringDecrypter(ModuleDefMD module, StringDecrypter oldOne) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
stringDecrypterType = Lookup(oldOne.stringDecrypterType, "Could not find stringDecrypterType");
|
stringDecrypterType = Lookup(oldOne.stringDecrypterType, "Could not find stringDecrypterType");
|
||||||
stringDecrypterMethod = Lookup(oldOne.stringDecrypterMethod, "Could not find stringDecrypterMethod");
|
keyInitField = Lookup(oldOne.keyInitField, "Could not find key init field");
|
||||||
|
keyArrayField = Lookup(oldOne.keyArrayField, "Could not find key array field");
|
||||||
|
foreach (var info in oldOne.stringDecrypterInfos.Keys) {
|
||||||
|
var m = Lookup(info.Method, "Could not find string decrypter method");
|
||||||
|
var f = Lookup(info.Field, "Could not find string decrypter field");
|
||||||
|
stringDecrypterInfos[new StringDecrypterInfo(m, f)] = true;
|
||||||
|
}
|
||||||
stringDecrypterKey = oldOne.stringDecrypterKey;
|
stringDecrypterKey = oldOne.stringDecrypterKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +72,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
return DeobUtils.Lookup(module, def, errorMessage);
|
return DeobUtils.Lookup(module, def, errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddDecrypterInfos(IEnumerable<StringDecrypterInfo> infos) {
|
||||||
|
foreach (var info in infos)
|
||||||
|
stringDecrypterInfos[info] = true;
|
||||||
|
}
|
||||||
|
|
||||||
public void Find() {
|
public void Find() {
|
||||||
stringDecrypterKey = new byte[1] { 0xFF };
|
stringDecrypterKey = new byte[1] { 0xFF };
|
||||||
foreach (var type in module.Types) {
|
foreach (var type in module.Types) {
|
||||||
|
@ -64,6 +84,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
stringDecrypterType = type;
|
stringDecrypterType = type;
|
||||||
foreach (var field in type.Fields) {
|
foreach (var field in type.Fields) {
|
||||||
if (field.FullName == "<D234> <D234>::345" || field.FullName == "<ClassD234>/D234 <ClassD234>::345") {
|
if (field.FullName == "<D234> <D234>::345" || field.FullName == "<ClassD234>/D234 <ClassD234>::345") {
|
||||||
|
keyInitField = field;
|
||||||
stringDecrypterKey = field.InitialValue;
|
stringDecrypterKey = field.InitialValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +94,119 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Initialize() {
|
||||||
|
if (keyInitField == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var type in module.Types) {
|
||||||
|
var cctor = type.FindStaticConstructor();
|
||||||
|
if (cctor == null)
|
||||||
|
continue;
|
||||||
|
keyArrayField = GetKeyArrayField(cctor, keyInitField);
|
||||||
|
if (keyArrayField != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (keyArrayField == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var type in module.GetTypes()) {
|
||||||
|
FieldDef field;
|
||||||
|
var method = FindStringDecrypters(type, keyArrayField, out field);
|
||||||
|
if (method == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stringDecrypterInfos[new StringDecrypterInfo(method, field)] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FieldDef GetKeyArrayField(MethodDef method, FieldDef keyInitField) {
|
||||||
|
if (method == null || method.Body == null)
|
||||||
|
return null;
|
||||||
|
var instrs = method.Body.Instructions;
|
||||||
|
for (int i = 0; i < instrs.Count; i++) {
|
||||||
|
if (instrs[i].OpCode.Code != Code.Ldtoken)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
for (; i < instrs.Count; i++) {
|
||||||
|
var instr = instrs[i];
|
||||||
|
if (instr.OpCode.Code != Code.Stsfld)
|
||||||
|
continue;
|
||||||
|
var field = instr.Operand as FieldDef;
|
||||||
|
if (field == null || !field.IsStatic || field.DeclaringType != method.DeclaringType)
|
||||||
|
continue;
|
||||||
|
if (field.FieldSig.GetFieldType().GetFullName() != "System.Byte[]")
|
||||||
|
continue;
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MethodDef FindStringDecrypters(TypeDef type, FieldDef keyArrayField, out FieldDef field) {
|
||||||
|
FieldDef foundField = null;
|
||||||
|
foreach (var method in type.Methods) {
|
||||||
|
if (!method.IsAssembly || !method.IsStatic)
|
||||||
|
continue;
|
||||||
|
if (!DotNetUtils.IsMethod(method, "System.String", "(System.String)"))
|
||||||
|
continue;
|
||||||
|
if (!method.HasBody)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool accessedArrayField = false;
|
||||||
|
foreach (var instr in method.Body.Instructions) {
|
||||||
|
var f = instr.Operand as FieldDef;
|
||||||
|
accessedArrayField |= f == keyArrayField;
|
||||||
|
if (f == null || f == keyArrayField || f == foundField)
|
||||||
|
continue;
|
||||||
|
if (f.FieldSig.GetFieldType().GetFullName() != "System.Collections.Hashtable" ||
|
||||||
|
foundField != null)
|
||||||
|
goto exit;
|
||||||
|
foundField = f;
|
||||||
|
}
|
||||||
|
if (!accessedArrayField)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
field = foundField;
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
exit: ;
|
||||||
|
field = null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deobfuscate(Blocks blocks) {
|
||||||
|
if (!blocks.Method.IsStaticConstructor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var decrypterFields = new Dictionary<FieldDef, bool>(stringDecrypterInfos.Count);
|
||||||
|
foreach (var info in stringDecrypterInfos.Keys) {
|
||||||
|
if (info.Field != null)
|
||||||
|
decrypterFields[info.Field] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var block in blocks.MethodBlocks.GetAllBlocks()) {
|
||||||
|
var instrs = block.Instructions;
|
||||||
|
for (int i = instrs.Count - 2; i >= 0; i--) {
|
||||||
|
var newobj = instrs[i];
|
||||||
|
if (newobj.OpCode.Code != Code.Newobj)
|
||||||
|
continue;
|
||||||
|
var ctor = newobj.Operand as IMethod;
|
||||||
|
if (ctor == null || ctor.FullName != "System.Void System.Collections.Hashtable::.ctor()")
|
||||||
|
continue;
|
||||||
|
var stsfld = instrs[i + 1];
|
||||||
|
if (stsfld.OpCode.Code != Code.Stsfld)
|
||||||
|
continue;
|
||||||
|
var field = stsfld.Operand as FieldDef;
|
||||||
|
if (field == null || !decrypterFields.ContainsKey(field))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
block.Remove(i, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Decrypt(string es) {
|
public string Decrypt(string es) {
|
||||||
if (stringDecrypterKey == null)
|
if (stringDecrypterKey == null)
|
||||||
throw new ApplicationException("Trying to decrypt strings when stringDecrypterKey is null (could not find it!)");
|
throw new ApplicationException("Trying to decrypt strings when stringDecrypterKey is null (could not find it!)");
|
||||||
|
|
52
de4dot.code/deobfuscators/Agile_NET/StringDecrypterInfo.cs
Normal file
52
de4dot.code/deobfuscators/Agile_NET/StringDecrypterInfo.cs
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2011-2014 de4dot@gmail.com
|
||||||
|
|
||||||
|
This file is part of de4dot.
|
||||||
|
|
||||||
|
de4dot is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
de4dot is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using dnlib.DotNet;
|
||||||
|
|
||||||
|
namespace de4dot.code.deobfuscators.Agile_NET {
|
||||||
|
class StringDecrypterInfo {
|
||||||
|
public readonly MethodDef Method;
|
||||||
|
public readonly FieldDef Field;
|
||||||
|
|
||||||
|
public StringDecrypterInfo(MethodDef method)
|
||||||
|
: this(method, null) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringDecrypterInfo(MethodDef method, FieldDef field) {
|
||||||
|
this.Method = method;
|
||||||
|
this.Field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
if (Method != null)
|
||||||
|
hash ^= Method.GetHashCode();
|
||||||
|
if (Field != null)
|
||||||
|
hash ^= Field.GetHashCode();
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj) {
|
||||||
|
var other = obj as StringDecrypterInfo;
|
||||||
|
return other != null &&
|
||||||
|
Method == other.Method &&
|
||||||
|
Field == other.Field;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,11 +33,13 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm.v2 {
|
||||||
public MyDeobfuscator(ModuleDefMD module) {
|
public MyDeobfuscator(ModuleDefMD module) {
|
||||||
cliSecureRtType = new CliSecureRtType(module);
|
cliSecureRtType = new CliSecureRtType(module);
|
||||||
cliSecureRtType.Find(null);
|
cliSecureRtType.Find(null);
|
||||||
stringDecrypter = new StringDecrypter(module, cliSecureRtType.StringDecrypterMethod);
|
stringDecrypter = new StringDecrypter(module, cliSecureRtType.StringDecrypterInfos);
|
||||||
stringDecrypter.Find();
|
stringDecrypter.Find();
|
||||||
cliSecureRtType.FindStringDecrypterMethod();
|
cliSecureRtType.FindStringDecrypterMethod();
|
||||||
stringDecrypter.Method = cliSecureRtType.StringDecrypterMethod;
|
stringDecrypter.AddDecrypterInfos(cliSecureRtType.StringDecrypterInfos);
|
||||||
staticStringInliner.Add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.Decrypt((string)args[0]));
|
stringDecrypter.Initialize();
|
||||||
|
foreach (var info in stringDecrypter.StringDecrypterInfos)
|
||||||
|
staticStringInliner.Add(info.Method, (method, gim, args) => stringDecrypter.Decrypt((string)args[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RestoreMethod(Blocks blocks) {
|
void RestoreMethod(Blocks blocks) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user