de4dot-cex/de4dot.code/deobfuscators/SmartAssembly/Deobfuscator.cs

548 lines
17 KiB
C#
Raw Permalink Normal View History

2011-09-22 10:55:30 +08:00
/*
2015-10-30 05:45:26 +08:00
Copyright (C) 2011-2015 de4dot@gmail.com
2011-09-22 10:55:30 +08:00
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 System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
2011-09-22 10:55:30 +08:00
using de4dot.blocks;
namespace de4dot.code.deobfuscators.SmartAssembly {
public class DeobfuscatorInfo : DeobfuscatorInfoBase {
2011-11-04 03:03:32 +08:00
public const string THE_NAME = "SmartAssembly";
2011-11-12 18:31:07 +08:00
public const string THE_TYPE = "sa";
const string DEFAULT_REGEX = DeobfuscatorBase.DEFAULT_ASIAN_VALID_NAME_REGEX;
2011-09-22 10:55:30 +08:00
BoolOption removeAutomatedErrorReporting;
BoolOption removeTamperProtection;
BoolOption removeMemoryManager;
public DeobfuscatorInfo()
: base(DEFAULT_REGEX) {
2013-01-19 20:03:57 +08:00
removeAutomatedErrorReporting = new BoolOption(null, MakeArgName("error"), "Remove automated error reporting code", true);
removeTamperProtection = new BoolOption(null, MakeArgName("tamper"), "Remove tamper protection code", true);
removeMemoryManager = new BoolOption(null, MakeArgName("memory"), "Remove memory manager code", true);
2011-09-22 10:55:30 +08:00
}
2011-11-04 03:03:32 +08:00
public override string Name {
get { return THE_NAME; }
2011-09-22 10:55:30 +08:00
}
public override string Type {
2011-11-12 18:31:07 +08:00
get { return THE_TYPE; }
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
public override IDeobfuscator CreateDeobfuscator() {
2011-09-22 10:55:30 +08:00
return new Deobfuscator(new Deobfuscator.Options {
2013-11-18 23:28:44 +08:00
ValidNameRegex = validNameRegex.Get(),
RemoveAutomatedErrorReporting = removeAutomatedErrorReporting.Get(),
RemoveTamperProtection = removeTamperProtection.Get(),
RemoveMemoryManager = removeMemoryManager.Get(),
2011-09-22 10:55:30 +08:00
});
}
2013-01-19 20:03:57 +08:00
protected override IEnumerable<Option> GetOptionsInternal() {
2011-09-22 10:55:30 +08:00
return new List<Option>() {
removeAutomatedErrorReporting,
removeTamperProtection,
removeMemoryManager,
};
}
}
class Deobfuscator : DeobfuscatorBase {
Options options;
2011-10-13 18:22:17 +08:00
bool foundVersion = false;
2012-01-17 09:54:48 +08:00
Version approxVersion = new Version(0, 0, 0, 0);
bool canRemoveTypes;
2011-10-13 18:22:17 +08:00
string poweredByAttributeString = null;
2011-11-12 18:31:07 +08:00
string obfuscatorName = DeobfuscatorInfo.THE_NAME;
2011-09-22 10:55:30 +08:00
bool foundSmartAssemblyAttribute = false;
IList<StringDecrypterInfo> stringDecrypterInfos = new List<StringDecrypterInfo>();
IList<StringDecrypter> stringDecrypters = new List<StringDecrypter>();
ResourceDecrypterInfo resourceDecrypterInfo;
ResourceDecrypter resourceDecrypter;
AssemblyResolverInfo assemblyResolverInfo;
AssemblyResolver assemblyResolver;
ResourceResolverInfo resourceResolverInfo;
ResourceResolver resourceResolver;
MemoryManagerInfo memoryManagerInfo;
2012-05-29 17:13:39 +08:00
ProxyCallFixer proxyCallFixer;
2011-09-22 10:55:30 +08:00
AutomatedErrorReportingFinder automatedErrorReportingFinder;
TamperProtectionRemover tamperProtectionRemover;
internal class Options : OptionsBase {
public bool RemoveAutomatedErrorReporting { get; set; }
public bool RemoveTamperProtection { get; set; }
public bool RemoveMemoryManager { get; set; }
}
public override string Type {
2011-11-12 18:31:07 +08:00
get { return DeobfuscatorInfo.THE_TYPE; }
}
public override string TypeLong {
2011-11-04 03:03:32 +08:00
get { return DeobfuscatorInfo.THE_NAME; }
2011-09-22 10:55:30 +08:00
}
public override string Name {
get { return obfuscatorName; }
}
2011-10-13 18:22:17 +08:00
string ObfuscatorName {
set {
obfuscatorName = value;
foundVersion = true;
}
}
2011-09-22 10:55:30 +08:00
public Deobfuscator(Options options)
: base(options) {
this.options = options;
StringFeatures = StringFeatures.AllowStaticDecryption;
}
2013-01-19 20:03:57 +08:00
public override void Initialize(ModuleDefMD module) {
base.Initialize(module);
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
protected override int DetectInternal() {
2011-09-22 10:55:30 +08:00
int val = 0;
if (memoryManagerInfo.Detected)
2012-02-29 07:13:57 +08:00
val += 100;
if (foundSmartAssemblyAttribute)
2011-09-22 10:55:30 +08:00
val += 10;
return val;
}
2013-01-19 20:03:57 +08:00
protected override void ScanForObfuscator() {
FindSmartAssemblyAttributes();
2011-09-22 10:55:30 +08:00
memoryManagerInfo = new MemoryManagerInfo(module);
2013-01-19 20:03:57 +08:00
memoryManagerInfo.Find();
2012-05-29 17:13:39 +08:00
proxyCallFixer = new ProxyCallFixer(module, DeobfuscatedFile);
2013-01-19 20:03:57 +08:00
proxyCallFixer.FindDelegateCreator(module);
2011-10-13 18:22:17 +08:00
if (!foundVersion)
2013-01-19 20:03:57 +08:00
GuessVersion();
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void FindSmartAssemblyAttributes() {
2011-09-22 10:55:30 +08:00
foreach (var type in module.Types) {
if (Utils.StartsWith(type.FullName, "SmartAssembly.Attributes.PoweredByAttribute", StringComparison.Ordinal)) {
2011-09-22 10:55:30 +08:00
foundSmartAssemblyAttribute = true;
2013-01-19 20:03:57 +08:00
AddAttributeToBeRemoved(type, "Obfuscator attribute");
InitializeVersion(type);
2011-09-22 10:55:30 +08:00
}
}
}
2013-01-19 20:03:57 +08:00
void InitializeVersion(TypeDef attr) {
var s = DotNetUtils.GetCustomArgAsString(GetAssemblyAttribute(attr), 0);
2011-09-22 10:55:30 +08:00
if (s == null)
2011-10-13 18:22:17 +08:00
return;
poweredByAttributeString = s;
2011-09-22 10:55:30 +08:00
2012-01-17 09:54:48 +08:00
var val = System.Text.RegularExpressions.Regex.Match(s, @"^Powered by (SmartAssembly (\d+)\.(\d+)\.(\d+)\.(\d+))$");
if (val.Groups.Count < 6)
2011-10-13 18:22:17 +08:00
return;
ObfuscatorName = val.Groups[1].ToString();
2012-01-17 09:54:48 +08:00
approxVersion = new Version(int.Parse(val.Groups[2].ToString()),
int.Parse(val.Groups[3].ToString()),
int.Parse(val.Groups[4].ToString()),
int.Parse(val.Groups[5].ToString()));
2011-10-13 18:22:17 +08:00
return;
2011-10-13 05:16:03 +08:00
}
2013-01-19 20:03:57 +08:00
void GuessVersion() {
2011-10-13 18:22:17 +08:00
if (poweredByAttributeString == "Powered by SmartAssembly") {
ObfuscatorName = "SmartAssembly 5.0/5.1";
2012-01-17 09:54:48 +08:00
approxVersion = new Version(5, 0, 0, 0);
2011-10-13 18:22:17 +08:00
return;
}
if (poweredByAttributeString == "Powered by {smartassembly}") {
// It's SA 1.x - 4.x
2013-01-19 20:03:57 +08:00
if (proxyCallFixer.Detected || HasEmptyClassesInEveryNamespace()) {
2011-10-13 18:22:17 +08:00
ObfuscatorName = "SmartAssembly 4.x";
2012-01-17 09:54:48 +08:00
approxVersion = new Version(4, 0, 0, 0);
2011-10-13 18:22:17 +08:00
return;
}
2013-01-19 20:03:57 +08:00
int ver = CheckTypeIdAttribute();
2011-10-13 18:22:17 +08:00
if (ver == 2) {
ObfuscatorName = "SmartAssembly 2.x";
2012-01-17 09:54:48 +08:00
approxVersion = new Version(2, 0, 0, 0);
2011-10-13 18:22:17 +08:00
return;
}
if (ver == 1) {
ObfuscatorName = "SmartAssembly 1.x-2.x";
2012-01-17 09:54:48 +08:00
approxVersion = new Version(1, 0, 0, 0);
2011-10-13 18:22:17 +08:00
return;
}
2013-01-19 20:03:57 +08:00
if (HasModuleCctor()) {
2011-10-13 18:22:17 +08:00
ObfuscatorName = "SmartAssembly 3.x";
2012-01-17 09:54:48 +08:00
approxVersion = new Version(3, 0, 0, 0);
2011-10-13 18:22:17 +08:00
return;
}
ObfuscatorName = "SmartAssembly 1.x-4.x";
2012-01-17 09:54:48 +08:00
approxVersion = new Version(1, 0, 0, 0);
2011-10-13 18:22:17 +08:00
return;
}
}
2013-01-19 20:03:57 +08:00
int CheckTypeIdAttribute() {
var type = GetTypeIdAttribute();
2011-10-13 18:22:17 +08:00
if (type == null)
return -1;
var fields = type.Fields;
if (fields.Count == 1)
return 1; // 1.x: int ID
if (fields.Count == 2)
return 2; // 2.x: int ID, static int AssemblyID
return -1;
}
2013-01-19 20:03:57 +08:00
TypeDef GetTypeIdAttribute() {
Dictionary<TypeDef, bool> attrs = null;
2011-10-13 18:22:17 +08:00
int counter = 0;
foreach (var type in module.GetTypes()) {
counter++;
var cattrs = type.CustomAttributes;
if (cattrs.Count == 0)
return null;
var attrs2 = new Dictionary<TypeDef, bool>();
2011-10-13 18:22:17 +08:00
foreach (var cattr in cattrs) {
if (!DotNetUtils.IsMethod(cattr.Constructor, "System.Void", "(System.Int32)"))
2011-10-13 18:22:17 +08:00
continue;
var attrType = cattr.AttributeType as TypeDef;
2011-10-13 18:22:17 +08:00
if (attrType == null)
continue;
if (attrs != null && !attrs.ContainsKey(attrType))
continue;
attrs2[attrType] = true;
}
attrs = attrs2;
if (attrs.Count == 0)
return null;
if (attrs.Count == 1 && counter >= 30)
break;
}
if (attrs == null)
return null;
foreach (var type in attrs.Keys)
return type;
return null;
2011-10-13 05:16:03 +08:00
}
2013-01-19 20:03:57 +08:00
bool HasModuleCctor() {
return DotNetUtils.GetModuleTypeCctor(module) != null;
2011-10-13 18:22:17 +08:00
}
2013-01-19 20:03:57 +08:00
bool HasEmptyClassesInEveryNamespace() {
2011-10-13 05:16:03 +08:00
var namespaces = new Dictionary<string, int>(StringComparer.Ordinal);
2013-01-19 20:03:57 +08:00
var moduleType = DotNetUtils.GetModuleType(module);
2011-10-13 05:16:03 +08:00
foreach (var type in module.Types) {
2012-01-09 01:46:23 +08:00
if (type == moduleType)
2011-10-13 18:22:17 +08:00
continue;
2012-11-19 00:07:02 +08:00
var ns = type.Namespace.String;
2011-10-13 05:16:03 +08:00
if (!namespaces.ContainsKey(ns))
namespaces[ns] = 0;
2011-10-13 05:30:57 +08:00
if (type.Name != "" || type.IsPublic || type.HasFields || type.HasMethods || type.HasProperties || type.HasEvents)
2011-10-13 05:16:03 +08:00
continue;
namespaces[ns]++;
}
foreach (int count in namespaces.Values) {
if (count < 1)
return false;
}
return true;
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
public override void DeobfuscateBegin() {
base.DeobfuscateBegin();
2012-01-17 09:54:48 +08:00
tamperProtectionRemover = new TamperProtectionRemover(module);
automatedErrorReportingFinder = new AutomatedErrorReportingFinder(module);
automatedErrorReportingFinder.find();
2011-11-05 17:10:36 +08:00
if (options.RemoveMemoryManager) {
2013-01-19 20:03:57 +08:00
AddModuleCctorInitCallToBeRemoved(memoryManagerInfo.CctorInitMethod);
AddCallToBeRemoved(module.EntryPoint, memoryManagerInfo.CctorInitMethod);
2011-11-05 17:10:36 +08:00
}
2012-01-17 09:54:48 +08:00
2013-01-19 20:03:57 +08:00
InitDecrypters();
proxyCallFixer.Find();
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void InitDecrypters() {
2011-09-22 10:55:30 +08:00
assemblyResolverInfo = new AssemblyResolverInfo(module, DeobfuscatedFile, this);
2013-01-19 20:03:57 +08:00
assemblyResolverInfo.FindTypes();
2012-01-17 09:54:48 +08:00
resourceDecrypterInfo = new ResourceDecrypterInfo(module, assemblyResolverInfo.SimpleZipTypeMethod, DeobfuscatedFile);
2011-11-13 04:04:24 +08:00
resourceResolverInfo = new ResourceResolverInfo(module, DeobfuscatedFile, this, assemblyResolverInfo);
2013-01-19 20:03:57 +08:00
resourceResolverInfo.FindTypes();
2011-09-22 10:55:30 +08:00
resourceDecrypter = new ResourceDecrypter(resourceDecrypterInfo);
assemblyResolver = new AssemblyResolver(resourceDecrypter, assemblyResolverInfo);
resourceResolver = new ResourceResolver(module, assemblyResolver, resourceResolverInfo);
2013-01-19 20:03:57 +08:00
InitStringDecrypterInfos();
assemblyResolverInfo.FindTypes();
resourceResolverInfo.FindTypes();
2011-09-22 10:55:30 +08:00
2013-01-19 20:03:57 +08:00
AddModuleCctorInitCallToBeRemoved(assemblyResolverInfo.CallResolverMethod);
AddCallToBeRemoved(module.EntryPoint, assemblyResolverInfo.CallResolverMethod);
AddModuleCctorInitCallToBeRemoved(resourceResolverInfo.CallResolverMethod);
AddCallToBeRemoved(module.EntryPoint, resourceResolverInfo.CallResolverMethod);
2011-09-22 10:55:30 +08:00
2013-01-19 20:03:57 +08:00
resourceDecrypterInfo.SetSimpleZipType(GetGlobalSimpleZipTypeMethod(), DeobfuscatedFile);
2011-09-22 10:55:30 +08:00
2013-01-19 20:03:57 +08:00
if (!DecryptResources())
2011-09-22 10:55:30 +08:00
throw new ApplicationException("Could not decrypt resources");
2013-01-19 20:03:57 +08:00
DumpEmbeddedAssemblies();
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void DumpEmbeddedAssemblies() {
assemblyResolver.ResolveResources();
foreach (var tuple in assemblyResolver.GetDecryptedResources()) {
DeobfuscatedFile.CreateAssemblyFile(tuple.Item2, tuple.Item1.simpleName, null);
AddResourceToBeRemoved(tuple.Item1.resource, string.Format("Embedded assembly: {0}", tuple.Item1.assemblyName));
2011-09-22 10:55:30 +08:00
}
}
2013-01-19 20:03:57 +08:00
bool DecryptResources() {
if (!resourceResolver.CanDecryptResource())
2011-09-22 10:55:30 +08:00
return false;
2013-01-19 20:03:57 +08:00
var info = resourceResolver.MergeResources();
2011-11-13 04:04:24 +08:00
if (info == null)
2011-09-22 10:55:30 +08:00
return true;
2013-01-19 20:03:57 +08:00
AddResourceToBeRemoved(info.resource, "Encrypted resources");
assemblyResolver.ResolveResources();
2011-09-22 10:55:30 +08:00
return true;
}
2013-01-19 20:03:57 +08:00
MethodDef GetGlobalSimpleZipTypeMethod() {
2012-01-17 09:54:48 +08:00
if (assemblyResolverInfo.SimpleZipTypeMethod != null)
return assemblyResolverInfo.SimpleZipTypeMethod;
2011-09-22 10:55:30 +08:00
foreach (var info in stringDecrypterInfos) {
2012-01-17 09:54:48 +08:00
if (info.SimpleZipTypeMethod != null)
return info.SimpleZipTypeMethod;
2011-09-22 10:55:30 +08:00
}
return null;
}
2013-01-19 20:03:57 +08:00
void InitStringDecrypterInfos() {
2011-09-22 10:55:30 +08:00
var stringEncoderClassFinder = new StringEncoderClassFinder(module, DeobfuscatedFile);
2013-01-19 20:03:57 +08:00
stringEncoderClassFinder.Find();
2011-09-22 10:55:30 +08:00
foreach (var info in stringEncoderClassFinder.StringsEncoderInfos) {
var sinfo = new StringDecrypterInfo(module, info.StringDecrypterClass) {
GetStringDelegate = info.GetStringDelegate,
StringsType = info.StringsType,
CreateStringDelegateMethod = info.CreateStringDelegateMethod,
};
stringDecrypterInfos.Add(sinfo);
}
// There may be more than one string decrypter. The strings in the first one's
// methods may be decrypted by the other string decrypter.
var initd = new Dictionary<StringDecrypterInfo, bool>(stringDecrypterInfos.Count);
while (initd.Count != stringDecrypterInfos.Count) {
StringDecrypterInfo initdInfo = null;
for (int i = 0; i < 2; i++) {
foreach (var info in stringDecrypterInfos) {
if (initd.ContainsKey(info))
continue;
2013-01-19 20:03:57 +08:00
if (info.Initialize(this, DeobfuscatedFile)) {
resourceDecrypterInfo.SetSimpleZipType(info.SimpleZipTypeMethod, DeobfuscatedFile);
2011-09-22 10:55:30 +08:00
initdInfo = info;
break;
}
}
if (initdInfo != null)
break;
2013-01-19 20:03:57 +08:00
assemblyResolverInfo.FindTypes();
resourceResolverInfo.FindTypes();
DecryptResources();
2011-09-22 10:55:30 +08:00
}
if (initdInfo == null)
break;
2011-09-22 10:55:30 +08:00
initd[initdInfo] = true;
2013-01-19 20:03:57 +08:00
InitStringDecrypter(initdInfo);
2011-09-22 10:55:30 +08:00
}
// Sometimes there could be a string decrypter present that isn't called by anyone.
foreach (var info in stringDecrypterInfos) {
if (initd.ContainsKey(info))
continue;
Logger.v("String decrypter not initialized. Token {0:X8}", info.StringsEncodingClass.MDToken.ToInt32());
}
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void InitStringDecrypter(StringDecrypterInfo info) {
Logger.v("Adding string decrypter. Resource: {0}", Utils.ToCsharpString(info.StringsResource.Name));
2011-09-22 10:55:30 +08:00
var decrypter = new StringDecrypter(info);
if (decrypter.CanDecrypt) {
2012-11-19 00:07:02 +08:00
var invokeMethod = info.GetStringDelegate == null ? null : info.GetStringDelegate.FindMethod("Invoke");
2013-01-19 20:03:57 +08:00
staticStringInliner.Add(invokeMethod, (method, gim, args) => {
var fieldDef = DotNetUtils.GetField(module, (IField)args[0]);
return decrypter.Decrypt(fieldDef.MDToken.ToInt32(), (int)args[1]);
2011-09-22 10:55:30 +08:00
});
2013-01-19 20:03:57 +08:00
staticStringInliner.Add(info.StringDecrypterMethod, (method, gim, args) => {
return decrypter.Decrypt(0, (int)args[0]);
2011-09-22 10:55:30 +08:00
});
}
stringDecrypters.Add(decrypter);
2013-01-19 20:03:57 +08:00
DeobfuscatedFile.StringDecryptersAdded();
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
public override void DeobfuscateMethodEnd(Blocks blocks) {
proxyCallFixer.Deobfuscate(blocks);
RemoveAutomatedErrorReportingCode(blocks);
RemoveTamperProtection(blocks);
RemoveStringsInitCode(blocks);
base.DeobfuscateMethodEnd(blocks);
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
public override void DeobfuscateEnd() {
canRemoveTypes = FindBigType() == null;
RemoveProxyDelegates(proxyCallFixer, canRemoveTypes);
RemoveMemoryManagerStuff();
RemoveTamperProtectionStuff();
RemoveStringDecryptionStuff();
RemoveResolverInfoTypes(assemblyResolverInfo, "Assembly");
RemoveResolverInfoTypes(resourceResolverInfo, "Resource");
base.DeobfuscateEnd();
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
TypeDef FindBigType() {
2012-01-17 09:54:48 +08:00
if (approxVersion <= new Version(6, 5, 3, 53))
return null;
TypeDef bigType = null;
2012-01-17 09:54:48 +08:00
foreach (var type in module.Types) {
2013-01-19 20:03:57 +08:00
if (IsBigType(type)) {
2012-01-17 09:54:48 +08:00
if (bigType == null || type.Methods.Count > bigType.Methods.Count)
bigType = type;
}
}
return bigType;
}
2013-01-19 20:03:57 +08:00
bool IsBigType(TypeDef type) {
2012-01-17 09:54:48 +08:00
if (type.Methods.Count < 50)
return false;
if (type.HasProperties || type.HasEvents)
return false;
if (type.Fields.Count > 3)
return false;
foreach (var method in type.Methods) {
if (!method.IsStatic)
return false;
}
return true;
}
2013-01-19 20:03:57 +08:00
void RemoveResolverInfoTypes(ResolverInfoBase info, string typeName) {
2012-01-17 09:54:48 +08:00
if (!canRemoveTypes)
return;
2012-01-30 16:12:26 +08:00
if (info.CallResolverType == null || info.Type == null)
return;
2013-01-19 20:03:57 +08:00
AddTypeToBeRemoved(info.CallResolverType, string.Format("{0} resolver type #1", typeName));
AddTypeToBeRemoved(info.Type, string.Format("{0} resolver type #2", typeName));
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void RemoveAutomatedErrorReportingCode(Blocks blocks) {
2011-09-22 10:55:30 +08:00
if (!options.RemoveAutomatedErrorReporting)
return;
2013-01-19 20:03:57 +08:00
if (automatedErrorReportingFinder.Remove(blocks))
Logger.v("Removed Automated Error Reporting code");
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void RemoveTamperProtection(Blocks blocks) {
2011-09-22 10:55:30 +08:00
if (!options.RemoveTamperProtection)
return;
2013-01-19 20:03:57 +08:00
if (tamperProtectionRemover.Remove(blocks))
Logger.v("Removed Tamper Protection code");
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void RemoveMemoryManagerStuff() {
2012-01-17 09:54:48 +08:00
if (!canRemoveTypes || !options.RemoveMemoryManager)
2011-09-22 10:55:30 +08:00
return;
2013-01-19 20:03:57 +08:00
AddTypeToBeRemoved(memoryManagerInfo.Type, "Memory manager type");
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void RemoveTamperProtectionStuff() {
2011-09-22 10:55:30 +08:00
if (!options.RemoveTamperProtection)
return;
2013-01-19 20:03:57 +08:00
AddMethodsToBeRemoved(tamperProtectionRemover.PinvokeMethods, "Tamper protection PInvoke method");
2011-09-22 10:55:30 +08:00
}
2013-01-19 20:03:57 +08:00
void RemoveStringDecryptionStuff() {
if (!CanRemoveStringDecrypterType)
2011-09-22 10:55:30 +08:00
return;
foreach (var decrypter in stringDecrypters) {
var info = decrypter.StringDecrypterInfo;
2013-01-19 20:03:57 +08:00
AddResourceToBeRemoved(info.StringsResource, "Encrypted strings");
AddFieldsToBeRemoved(info.GetAllStringDelegateFields(), "String decrypter delegate field");
2011-09-22 10:55:30 +08:00
2012-01-17 09:54:48 +08:00
if (canRemoveTypes) {
2013-01-19 20:03:57 +08:00
AddTypeToBeRemoved(info.StringsEncodingClass, "String decrypter type");
AddTypeToBeRemoved(info.StringsType, "Creates the string decrypter delegates");
AddTypeToBeRemoved(info.GetStringDelegate, "String decrypter delegate type");
2012-01-17 09:54:48 +08:00
}
2011-09-22 10:55:30 +08:00
}
}
2013-01-19 20:03:57 +08:00
void RemoveStringsInitCode(Blocks blocks) {
if (!CanRemoveStringDecrypterType)
2011-09-22 10:55:30 +08:00
return;
if (blocks.Method.Name == ".cctor") {
foreach (var decrypter in stringDecrypters)
2013-01-19 20:03:57 +08:00
decrypter.StringDecrypterInfo.RemoveInitCode(blocks);
2011-09-22 10:55:30 +08:00
}
}
2013-01-19 20:03:57 +08:00
public override IEnumerable<int> GetStringDecrypterMethods() {
2012-02-25 13:25:40 +08:00
var list = new List<int>();
2012-01-20 02:16:44 +08:00
foreach (var method in staticStringInliner.Methods)
list.Add(method.MDToken.ToInt32());
2011-09-22 10:55:30 +08:00
return list;
}
}
}