/*
Copyright (C) 2011-2015 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 .
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using dnlib.IO;
using dnlib.DotNet;
using dnlib.DotNet.Emit;
using de4dot.blocks;
using CR = System.Runtime.InteropServices;
using DR = dnlib.DotNet;
namespace de4dot.code.deobfuscators.Babel_NET {
class ImageReader {
static int METHODS_SIG = 0x0000BEBA;
static int METADATA_SIG = 0x0100BEBA;
static int METHOD_NAMES_SIG = 0x0200BEBA;
static int ASSEMBLY_NAMES_SIG = 0x0201BEBA;
static int TYPEREFS_SIG = 0x0202BEBA;
static int STRINGS_SIG = 0x0203BEBA;
enum TypeId : byte {
TypeRef = 0,
GenericInstance = 1,
Pointer = 2,
Array = 3,
ByRef = 4,
}
ModuleDefMD module;
IBinaryReader reader;
string[] strings;
AssemblyRef[] assemblyNames;
Dictionary methodOffsets;
List typeRefs;
MemberRefConverter memberRefConverter;
IDeobfuscatorContext deobfuscatorContext;
public ImageReader(IDeobfuscatorContext deobfuscatorContext, ModuleDefMD module, byte[] data) {
this.deobfuscatorContext = deobfuscatorContext;
this.module = module;
this.reader = MemoryImageStream.Create(data);
this.memberRefConverter = new MemberRefConverter(module);
}
public bool Initialize() {
if (reader.ReadInt32() != METHODS_SIG)
return false;
int metadataOffset = GetMetadataOffset();
if (metadataOffset < 0)
return false;
long pos = metadataOffset + 4;
reader.Position = pos;
int version = reader.ReadInt16(); // major, minor
if (version == 0x0001) {
InitializeV10();
return true;
}
reader.Position = pos;
InitializeV55();
return true;
}
void InitializeV10() {
reader.ReadInt16();
int methodNamesOffset = (int)reader.ReadInt64();
int typeRefsOffset = (int)reader.ReadInt64();
int assemblyRefsOffset = (int)reader.ReadInt64();
int stringsOffset = (int)reader.ReadInt64();
InitializeStrings(stringsOffset);
InitializeAssemblyNames(assemblyRefsOffset);
InitializeMethodNames(methodNamesOffset);
InitializeTypeRefs(typeRefsOffset);
}
void InitializeV55() {
int methodNamesOffset = (int)reader.ReadInt64() ^ METADATA_SIG;
int typeRefsOffset = (int)reader.ReadInt64() ^ (METADATA_SIG << 1);
int assemblyRefsOffset = (int)reader.ReadInt64() ^ ((METADATA_SIG << 1) + 1);
int stringsOffset = (int)reader.ReadInt64() ^ (((METADATA_SIG << 1) + 1) << 1);
InitializeStrings(stringsOffset);
InitializeAssemblyNames(assemblyRefsOffset);
InitializeMethodNames(methodNamesOffset);
InitializeTypeRefs(typeRefsOffset);
}
public void Restore(string name, MethodDef method) {
var babelMethod = GetMethod(name);
var body = method.Body;
body.MaxStack = babelMethod.MaxStack;
body.InitLocals = babelMethod.InitLocals;
body.Variables.Clear();
foreach (var local in babelMethod.Locals)
body.Variables.Add(local);
var toNewOperand = new Dictionary