de4dot-cex/de4dot.code/deobfuscators/Agile_NET/vm/v1/Csvm.cs

164 lines
5.2 KiB
C#
Raw Normal View History

2012-04-06 00:06:56 +08:00
/*
2014-03-12 05:15:43 +08:00
Copyright (C) 2011-2014 de4dot@gmail.com
2012-04-06 00:06:56 +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 dnlib.DotNet;
2012-04-06 00:06:56 +08:00
using de4dot.blocks;
2013-10-30 01:11:31 +08:00
namespace de4dot.code.deobfuscators.Agile_NET.vm.v1 {
2012-04-06 00:06:56 +08:00
class Csvm {
IDeobfuscatorContext deobfuscatorContext;
2012-11-07 12:17:45 +08:00
ModuleDefMD module;
2012-04-06 00:06:56 +08:00
EmbeddedResource resource;
2012-11-22 16:14:51 +08:00
AssemblyRef vmAssemblyRef;
2012-04-06 00:06:56 +08:00
public bool Detected {
2012-11-22 16:14:51 +08:00
get { return resource != null && vmAssemblyRef != null; }
2012-04-06 00:06:56 +08:00
}
public EmbeddedResource Resource {
get { return Detected ? resource : null; }
}
2012-11-07 12:17:45 +08:00
public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module) {
2012-04-06 00:06:56 +08:00
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
}
2012-11-07 12:17:45 +08:00
public Csvm(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, Csvm oldOne) {
2012-04-06 00:06:56 +08:00
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
if (oldOne.resource != null)
this.resource = (EmbeddedResource)module.Resources[oldOne.module.Resources.IndexOf(oldOne.resource)];
2012-11-22 16:14:51 +08:00
if (oldOne.vmAssemblyRef != null)
this.vmAssemblyRef = module.ResolveAssemblyRef(oldOne.vmAssemblyRef.Rid);
2012-04-06 00:06:56 +08:00
}
2013-01-19 20:03:57 +08:00
public void Find() {
resource = FindCsvmResource();
vmAssemblyRef = FindVmAssemblyRef();
2012-04-06 00:06:56 +08:00
}
2013-01-19 20:03:57 +08:00
AssemblyRef FindVmAssemblyRef() {
2012-11-07 12:17:45 +08:00
foreach (var memberRef in module.GetMemberRefs()) {
2012-11-08 14:07:02 +08:00
var sig = memberRef.MethodSig;
if (sig == null)
continue;
if (sig.RetType.GetElementType() != ElementType.Object)
continue;
if (sig.Params.Count != 2)
continue;
if (memberRef.Name != "RunMethod")
2012-04-06 00:06:56 +08:00
continue;
2012-11-07 12:17:45 +08:00
if (memberRef.FullName == "System.Object VMRuntime.Libraries.CSVMRuntime::RunMethod(System.String,System.Object[])")
return memberRef.DeclaringType.Scope as AssemblyRef;
2012-04-06 00:06:56 +08:00
}
return null;
}
2013-01-19 20:03:57 +08:00
EmbeddedResource FindCsvmResource() {
return DotNetUtils.GetResource(module, "_CSVM") as EmbeddedResource;
2012-04-06 00:06:56 +08:00
}
2013-01-19 20:03:57 +08:00
public bool Restore() {
2012-04-06 00:06:56 +08:00
if (!Detected)
return true;
2012-04-06 00:06:56 +08:00
int oldIndent = Logger.Instance.IndentLevel;
2012-04-06 00:06:56 +08:00
try {
2013-01-19 20:03:57 +08:00
Restore2();
return true;
}
catch {
return false;
2012-04-06 00:06:56 +08:00
}
finally {
Logger.Instance.IndentLevel = oldIndent;
2012-04-06 00:06:56 +08:00
}
}
2013-01-19 20:03:57 +08:00
void Restore2() {
Logger.v("Restoring CSVM methods");
2013-01-19 20:03:57 +08:00
Logger.Instance.Indent();
2012-04-06 00:06:56 +08:00
2013-01-19 20:03:57 +08:00
var opcodeDetector = GetVmOpCodeHandlerDetector();
var csvmMethods = new CsvmDataReader(resource.Data).Read();
2012-04-06 00:06:56 +08:00
var converter = new CsvmToCilMethodConverter(deobfuscatorContext, module, opcodeDetector);
2012-04-06 03:18:09 +08:00
var methodPrinter = new MethodPrinter();
2012-04-06 00:06:56 +08:00
foreach (var csvmMethod in csvmMethods) {
2012-11-07 12:17:45 +08:00
var cilMethod = module.ResolveToken(csvmMethod.Token) as MethodDef;
2012-04-06 00:06:56 +08:00
if (cilMethod == null)
throw new ApplicationException(string.Format("Could not find method {0:X8}", csvmMethod.Token));
2013-01-19 20:03:57 +08:00
converter.Convert(cilMethod, csvmMethod);
Logger.v("Restored method {0:X8}", cilMethod.MDToken.ToInt32());
2013-01-19 20:03:57 +08:00
PrintMethod(methodPrinter, cilMethod);
2012-04-06 00:06:56 +08:00
}
2013-01-19 20:03:57 +08:00
Logger.Instance.DeIndent();
2014-03-12 05:05:54 +08:00
Logger.n("Restored {0} CSVM methods", csvmMethods.Count);
2012-04-06 03:18:09 +08:00
}
2013-01-19 20:03:57 +08:00
static void PrintMethod(MethodPrinter methodPrinter, MethodDef method) {
const LoggerEvent dumpLogLevel = LoggerEvent.Verbose;
if (Logger.Instance.IgnoresEvent(dumpLogLevel))
2012-04-06 03:18:09 +08:00
return;
2013-01-19 20:03:57 +08:00
Logger.Instance.Indent();
2012-04-06 03:18:09 +08:00
Logger.v("Locals:");
2013-01-19 20:03:57 +08:00
Logger.Instance.Indent();
for (int i = 0; i < method.Body.Variables.Count; i++)
Logger.v("#{0}: {1}", i, method.Body.Variables[i].Type);
2013-01-19 20:03:57 +08:00
Logger.Instance.DeIndent();
2012-04-06 03:18:09 +08:00
Logger.v("Code:");
2013-01-19 20:03:57 +08:00
Logger.Instance.Indent();
methodPrinter.Print(dumpLogLevel, method.Body.Instructions, method.Body.ExceptionHandlers);
Logger.Instance.DeIndent();
2012-04-06 03:18:09 +08:00
2013-01-19 20:03:57 +08:00
Logger.Instance.DeIndent();
2012-04-06 00:06:56 +08:00
}
2013-01-19 20:03:57 +08:00
VmOpCodeHandlerDetector GetVmOpCodeHandlerDetector() {
2012-11-22 16:14:51 +08:00
var vmFilename = vmAssemblyRef.Name + ".dll";
2012-11-07 12:17:45 +08:00
var vmModulePath = Path.Combine(Path.GetDirectoryName(module.Location), vmFilename);
Logger.v("CSVM filename: {0}", vmFilename);
2012-04-06 00:06:56 +08:00
2013-11-08 18:05:17 +08:00
var dataKey = "cs cached VmOpCodeHandlerDetector v1";
2013-01-19 20:03:57 +08:00
var dict = (Dictionary<string, VmOpCodeHandlerDetector>)deobfuscatorContext.GetData(dataKey);
2012-04-06 00:06:56 +08:00
if (dict == null)
2013-01-19 20:03:57 +08:00
deobfuscatorContext.SetData(dataKey, dict = new Dictionary<string, VmOpCodeHandlerDetector>(StringComparer.OrdinalIgnoreCase));
2012-04-06 00:06:56 +08:00
VmOpCodeHandlerDetector detector;
if (dict.TryGetValue(vmModulePath, out detector))
return detector;
2012-11-07 12:17:45 +08:00
dict[vmModulePath] = detector = new VmOpCodeHandlerDetector(ModuleDefMD.Load(vmModulePath));
2012-04-06 00:06:56 +08:00
2013-01-19 20:03:57 +08:00
detector.FindHandlers();
Logger.v("CSVM opcodes:");
2013-01-19 20:03:57 +08:00
Logger.Instance.Indent();
2012-04-06 00:06:56 +08:00
for (int i = 0; i < detector.Handlers.Count; i++)
Logger.v("{0:X4}: {1}", i, detector.Handlers[i].Name);
2013-01-19 20:03:57 +08:00
Logger.Instance.DeIndent();
2012-04-06 00:06:56 +08:00
return detector;
}
}
}