Merge branch 'port' into confuser

This commit is contained in:
de4dot 2012-11-30 21:04:22 +01:00
commit c3608908c5
132 changed files with 1500 additions and 2500 deletions

View File

@ -34,7 +34,7 @@ using ROpCodes = System.Reflection.Emit.OpCodes;
namespace AssemblyData.methodsrewriter {
class CodeGenerator {
static Dictionary<OpCode, ROpCode> cecilToReflection = new Dictionary<OpCode, ROpCode>();
static Dictionary<OpCode, ROpCode> dot10ToReflection = new Dictionary<OpCode, ROpCode>();
static CodeGenerator() {
var refDict = new Dictionary<short, ROpCode>(0x100);
foreach (var f in typeof(ROpCodes).GetFields(BindingFlags.Static | BindingFlags.Public)) {
@ -51,7 +51,7 @@ namespace AssemblyData.methodsrewriter {
ROpCode ropcode;
if (!refDict.TryGetValue(opcode.Value, out ropcode))
continue;
cecilToReflection[opcode] = ropcode;
dot10ToReflection[opcode] = ropcode;
}
}
@ -332,7 +332,7 @@ namespace AssemblyData.methodsrewriter {
ROpCode convertOpCode(OpCode opcode) {
ROpCode ropcode;
if (cecilToReflection.TryGetValue(opcode, out ropcode))
if (dot10ToReflection.TryGetValue(opcode, out ropcode))
return ropcode;
return ROpCodes.Nop;
}

View File

@ -24,9 +24,9 @@ namespace AssemblyData.methodsrewriter {
class MMethod {
public MethodBase methodBase;
public MethodDef methodDef;
public MMethod(MethodBase methodBase, MethodDef methodDefinition) {
public MMethod(MethodBase methodBase, MethodDef methodDef) {
this.methodBase = methodBase;
this.methodDef = methodDefinition;
this.methodDef = methodDef;
}
public bool hasInstructions() {

View File

@ -27,15 +27,15 @@ namespace AssemblyData.methodsrewriter {
class MModule {
public Module module;
public ModuleDefMD moduleDef;
TypeDefinitionDict<MType> typeReferenceToType = new TypeDefinitionDict<MType>();
TypeDefDict<MType> typeRefToType = new TypeDefDict<MType>();
Dictionary<int, MType> tokenToType = new Dictionary<int, MType>();
Dictionary<int, MMethod> tokenToGlobalMethod;
Dictionary<int, MField> tokenToGlobalField;
TypeDef moduleType;
public MModule(Module module, ModuleDefMD moduleDefinition) {
public MModule(Module module, ModuleDefMD moduleDef) {
this.module = module;
this.moduleDef = moduleDefinition;
this.moduleDef = moduleDef;
initTokenToType();
}
@ -49,17 +49,17 @@ namespace AssemblyData.methodsrewriter {
}
catch {
tokenToType[token] = null;
typeReferenceToType.add(typeDef, null);
typeRefToType.add(typeDef, null);
continue;
}
var mtype = new MType(type, typeDef);
tokenToType[token] = mtype;
typeReferenceToType.add(typeDef, mtype);
typeRefToType.add(typeDef, mtype);
}
}
public MType getType(IType typeRef) {
return typeReferenceToType.find(typeRef);
return typeRefToType.find(typeRef);
}
public MMethod getMethod(IMethod methodRef) {

View File

@ -28,23 +28,23 @@ namespace AssemblyData.methodsrewriter {
public Type type;
public TypeDef typeDef;
Dictionary<int, MMethod> tokenToMethod;
MethodDefinitionDict<MMethod> methodReferenceToMethod;
MethodDefDict<MMethod> methodRefToMethod;
Dictionary<int, MField> tokenToField;
FieldDefinitionDict<MField> fieldReferenceToField;
FieldDefDict<MField> fieldRefToField;
public MType(Type type, TypeDef typeDefinition) {
public MType(Type type, TypeDef typeDef) {
this.type = type;
this.typeDef = typeDefinition;
this.typeDef = typeDef;
}
public MMethod getMethod(IMethod methodRef) {
initMethods();
return methodReferenceToMethod.find(methodRef);
return methodRefToMethod.find(methodRef);
}
public MField getField(IField fieldRef) {
initFields();
return fieldReferenceToField.find(fieldRef);
return fieldRefToField.find(fieldRef);
}
public MMethod getMethod(int token) {
@ -61,7 +61,7 @@ namespace AssemblyData.methodsrewriter {
if (tokenToMethod != null)
return;
tokenToMethod = new Dictionary<int, MMethod>(typeDef.Methods.Count);
methodReferenceToMethod = new MethodDefinitionDict<MMethod>();
methodRefToMethod = new MethodDefDict<MMethod>();
var tmpTokenToMethod = new Dictionary<int, MethodBase>();
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
@ -71,7 +71,7 @@ namespace AssemblyData.methodsrewriter {
var token = (int)m.MDToken.Raw;
var method = new MMethod(tmpTokenToMethod[token], m);
tokenToMethod[token] = method;
methodReferenceToMethod.add(method.methodDef, method);
methodRefToMethod.add(method.methodDef, method);
}
}
@ -79,7 +79,7 @@ namespace AssemblyData.methodsrewriter {
if (tokenToField != null)
return;
tokenToField = new Dictionary<int, MField>(typeDef.Fields.Count);
fieldReferenceToField = new FieldDefinitionDict<MField>();
fieldRefToField = new FieldDefDict<MField>();
var tmpTokenToField = new Dictionary<int, FieldInfo>();
var flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
@ -89,7 +89,7 @@ namespace AssemblyData.methodsrewriter {
var token = (int)f.MDToken.Raw;
var field = new MField(tmpTokenToField[token], f);
tokenToField[token] = field;
fieldReferenceToField.add(field.fieldDef, field);
fieldRefToField.add(field.fieldDef, field);
}
}

View File

@ -73,21 +73,21 @@ namespace AssemblyData.methodsrewriter {
return null;
}
public static MMethod getMethod(IMethod methodReference) {
if (methodReference == null)
public static MMethod getMethod(IMethod methodRef) {
if (methodRef == null)
return null;
var module = getModule(methodReference.DeclaringType.Scope);
var module = getModule(methodRef.DeclaringType.Scope);
if (module != null)
return module.getMethod(methodReference);
return module.getMethod(methodRef);
return null;
}
public static MField getField(IField fieldReference) {
if (fieldReference == null)
public static MField getField(IField fieldRef) {
if (fieldRef == null)
return null;
var module = getModule(fieldReference.DeclaringType.Scope);
var module = getModule(fieldRef.DeclaringType.Scope);
if (module != null)
return module.getField(fieldReference);
return module.getField(fieldRef);
return null;
}
@ -104,7 +104,7 @@ namespace AssemblyData.methodsrewriter {
if (method != null && method.MethodSig != null)
return getRtMethod(method);
throw new ApplicationException(string.Format("Unknown MemberReference: {0}", memberRef));
throw new ApplicationException(string.Format("Unknown MemberRef: {0}", memberRef));
}
public static Type getRtType(IType typeRef) {

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9F84607D-3662-4CF2-BA40-8BDB11935643}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssemblyServer_CLR20_x64</RootNamespace>
<AssemblyName>AssemblyServer-CLR20-x64</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\de4dot.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Release\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoStdLib>true</NoStdLib>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<!-- Fix a warning that the referenced mscorlib is not 64-bit... -->
<Reference Include="$(Windir)\Microsoft.NET\Framework64\v2.0.50727\mscorlib.dll" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssemblyData\AssemblyData.csproj">
<Project>{FBD84077-9D35-41FE-89DF-8D79EFE0B595}</Project>
<Name>AssemblyData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -17,20 +17,10 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System.IO;
namespace de4dot.PE {
public struct DataDirectory {
public uint virtualAddress;
public uint size;
public void read(BinaryReader reader) {
virtualAddress = reader.ReadUInt32();
size = reader.ReadUInt32();
}
public override string ToString() {
return string.Format("{0:X8} {1:X8}", virtualAddress, size);
namespace AssemblyServer_CLR20_x64 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
}
}
}

View File

@ -0,0 +1,33 @@
/*
Copyright (C) 2011-2012 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 System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssemblyServer-CLR20-x64")]
[assembly: AssemblyDescription("Assembly Server - CLR v2.0 - x64")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyServer-CLR20-x64")]
[assembly: AssemblyCopyright("Copyright (C) 2011-2012 de4dot@gmail.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.9.1.3405")]
[assembly: AssemblyFileVersion("1.9.1.3405")]

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C72DC899-1760-432B-B429-3CD88B669A6A}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssemblyServer_CLR20</RootNamespace>
<AssemblyName>AssemblyServer-CLR20</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\de4dot.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Release\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssemblyData\AssemblyData.csproj">
<Project>{FBD84077-9D35-41FE-89DF-8D79EFE0B595}</Project>
<Name>AssemblyData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -17,9 +17,10 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
namespace de4dot.PE {
public interface IFileLocation {
uint Offset { get; }
uint Length { get; }
namespace AssemblyServer_CLR20 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
}
}
}

View File

@ -0,0 +1,33 @@
/*
Copyright (C) 2011-2012 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 System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssemblyServer-CLR20")]
[assembly: AssemblyDescription("Assembly Server - CLR v2.0 - x86")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyServer-CLR20")]
[assembly: AssemblyCopyright("Copyright (C) 2011-2012 de4dot@gmail.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.9.1.3405")]
[assembly: AssemblyFileVersion("1.9.1.3405")]

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
</startup>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A0F58B9F-BB56-4D9B-B04A-726F9E7961EB}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssemblyServer_CLR40_x64</RootNamespace>
<AssemblyName>AssemblyServer-CLR40-x64</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\de4dot.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<NoWarn>1685</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Release\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoStdLib>true</NoStdLib>
<NoWarn>1685</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<!-- Fix a warning that the referenced mscorlib is not 64-bit... -->
<Reference Include="$(Windir)\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssemblyData\AssemblyData.csproj">
<Project>{FBD84077-9D35-41FE-89DF-8D79EFE0B595}</Project>
<Name>AssemblyData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -17,30 +17,10 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System.IO;
namespace de4dot.PE {
public class DotNetStream : IFileLocation {
public string name;
public uint fileOffset;
public uint length;
public uint Offset {
get { return fileOffset; }
}
public uint Length {
get { return length; }
}
public DotNetStream(string name, uint fileOffset, uint length) {
this.name = name;
this.fileOffset = fileOffset;
this.length = length;
}
public override string ToString() {
return string.Format("{0:X8} {1:X8} {2}", fileOffset, length, name);
namespace AssemblyServer_CLR40_x64 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
}
}
}

View File

@ -0,0 +1,33 @@
/*
Copyright (C) 2011-2012 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 System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssemblyServer-CLR40-x64")]
[assembly: AssemblyDescription("Assembly Server - CLR v4.0 - x64")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyServer-CLR40-x64")]
[assembly: AssemblyCopyright("Copyright (C) 2011-2012 de4dot@gmail.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.9.1.3405")]
[assembly: AssemblyFileVersion("1.9.1.3405")]

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
</startup>
<runtime>
<loadFromRemoteSources enabled="true"/>
</runtime>
</configuration>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B8FF4ADD-BAD8-47FD-B126-63234E2BB0B3}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AssemblyServer_CLR40</RootNamespace>
<AssemblyName>AssemblyServer-CLR40</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>..\de4dot.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Debug\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Release\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssemblyData\AssemblyData.csproj">
<Project>{FBD84077-9D35-41FE-89DF-8D79EFE0B595}</Project>
<Name>AssemblyData</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -17,33 +17,10 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
namespace de4dot.PE {
public class ResourceData : ResourceDirectoryEntry {
uint rva;
uint size;
public uint RVA {
get { return rva; }
}
public uint Size {
get { return size; }
}
public ResourceData(int id, uint rva, uint size)
: base(id) {
this.rva = rva;
this.size = size;
}
public ResourceData(string name, uint dataOffset, uint dataSize)
: base(name) {
this.rva = dataOffset;
this.size = dataSize;
}
public override string ToString() {
return string.Format("RVA: {0:X8} SIZE: {1:X8}, NAME: {2}", rva, size, getName());
namespace AssemblyServer_CLR40 {
class Program {
static int Main(string[] args) {
return AssemblyServer.Start.main(args);
}
}
}

View File

@ -0,0 +1,33 @@
/*
Copyright (C) 2011-2012 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 System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssemblyServer-CLR40")]
[assembly: AssemblyDescription("Assembly Server - CLR v4.0 - x86")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyServer-CLR40")]
[assembly: AssemblyCopyright("Copyright (C) 2011-2012 de4dot@gmail.com")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.9.1.3405")]
[assembly: AssemblyFileVersion("1.9.1.3405")]

View File

@ -21,7 +21,7 @@ using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssemblyServer-x64")]
[assembly: AssemblyDescription("Assembly Server - x64")]
[assembly: AssemblyDescription("Assembly Server - CLR any version - x64")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyServer-x64")]

View File

@ -21,7 +21,7 @@ using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("AssemblyServer")]
[assembly: AssemblyDescription("Assembly Server - AnyCpu")]
[assembly: AssemblyDescription("Assembly Server - CLR any version - x86")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AssemblyServer")]

View File

@ -91,10 +91,10 @@ namespace de4dot.blocks {
return true;
}
public static FieldDef findFieldType(TypeDef typeDefinition, string typeName, bool isStatic) {
if (typeDefinition == null)
public static FieldDef findFieldType(TypeDef typeDef, string typeName, bool isStatic) {
if (typeDef == null)
return null;
foreach (var field in typeDefinition.Fields) {
foreach (var field in typeDef.Fields) {
if (field.IsStatic == isStatic && field.FieldSig.GetFieldType().GetFullName() == typeName)
return field;
}
@ -274,12 +274,12 @@ namespace de4dot.blocks {
return getField(getType(module, field.DeclaringType), field);
}
public static FieldDef getField(TypeDef type, IField fieldReference) {
if (type == null || fieldReference == null)
public static FieldDef getField(TypeDef type, IField fieldRef) {
if (type == null || fieldRef == null)
return null;
if (fieldReference is FieldDef)
return (FieldDef)fieldReference;
return type.FindField(fieldReference.Name, fieldReference.FieldSig);
if (fieldRef is FieldDef)
return (FieldDef)fieldRef;
return type.FindField(fieldRef.Name, fieldRef.FieldSig);
}
public static FieldDef getField(TypeDef type, string typeFullName) {
@ -596,7 +596,7 @@ namespace de4dot.blocks {
return null;
}
public static TypeDefOrRefSig findOrCreateTypeReference(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
public static TypeDefOrRefSig findOrCreateTypeRef(ModuleDef module, AssemblyRef asmRef, string ns, string name, bool isValueType) {
var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, asmRef));
if (isValueType)
return new ValueTypeSig(typeRef);

View File

@ -23,7 +23,7 @@ using System.Collections.Generic;
namespace de4dot.blocks {
// This class makes sure that each block that is entered with a non-empty stack has at
// least one of its source blocks sorted before itself. This is to make sure peverify
// doesn't complain AND also to make sure Mono.Cecil sets the correct maxstack.
// doesn't complain AND also to make sure dot10 sets the correct maxstack.
class ForwardScanOrder {
ScopeBlock scopeBlock;
IList<BaseBlock> sorted;

View File

@ -22,7 +22,7 @@ using System.Collections.Generic;
using dot10.DotNet;
namespace de4dot.blocks {
public class TypeDefinitionDict<TValue> {
public class TypeDefDict<TValue> {
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
Dictionary<ScopeAndTokenKey, TypeDef> tokenToKey = new Dictionary<ScopeAndTokenKey, TypeDef>();
Dictionary<IType, TValue> refToValue = new Dictionary<IType, TValue>(TypeEqualityComparer.Instance);
@ -101,11 +101,11 @@ namespace de4dot.blocks {
}
}
public abstract class FieldDefinitionDictBase<TValue> {
public abstract class FieldDefDictBase<TValue> {
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
Dictionary<ScopeAndTokenKey, FieldDef> tokenToKey = new Dictionary<ScopeAndTokenKey, FieldDef>();
Dictionary<IFieldReferenceKey, TValue> refToValue = new Dictionary<IFieldReferenceKey, TValue>();
Dictionary<IFieldReferenceKey, FieldDef> refToKey = new Dictionary<IFieldReferenceKey, FieldDef>();
Dictionary<IFieldRefKey, TValue> refToValue = new Dictionary<IFieldRefKey, TValue>();
Dictionary<IFieldRefKey, FieldDef> refToKey = new Dictionary<IFieldRefKey, FieldDef>();
public int Count {
get { return tokenToValue.Count; }
@ -123,7 +123,7 @@ namespace de4dot.blocks {
return new ScopeAndTokenKey(fieldDef);
}
internal abstract IFieldReferenceKey getReferenceKey(IField fieldRef);
internal abstract IFieldRefKey getRefKey(IField fieldRef);
public TValue find(IField fieldRef) {
TValue value;
@ -131,7 +131,7 @@ namespace de4dot.blocks {
if (fieldDef != null)
tokenToValue.TryGetValue(getTokenKey(fieldDef), out value);
else
refToValue.TryGetValue(getReferenceKey(fieldRef), out value);
refToValue.TryGetValue(getRefKey(fieldRef), out value);
return value;
}
@ -141,7 +141,7 @@ namespace de4dot.blocks {
if (fieldDef != null && tokenToValue.TryGetValue(getTokenKey(fieldDef), out value))
return value;
refToValue.TryGetValue(getReferenceKey(fieldRef), out value);
refToValue.TryGetValue(getRefKey(fieldRef), out value);
return value;
}
@ -150,7 +150,7 @@ namespace de4dot.blocks {
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = fieldDef;
var refKey = getReferenceKey(fieldDef);
var refKey = getRefKey(fieldDef);
if (!refToValue.ContainsKey(refKey) ||
getAccessibilityOrder(fieldDef) < getAccessibilityOrder(refToKey[refKey])) {
refToKey[refKey] = fieldDef;
@ -169,35 +169,35 @@ namespace de4dot.blocks {
0, // Public
70, // <reserved>
};
static int getAccessibilityOrder(FieldDef fieldDefinition) {
return accessibilityOrder[(int)fieldDefinition.Attributes & 7];
static int getAccessibilityOrder(FieldDef fieldDef) {
return accessibilityOrder[(int)fieldDef.Attributes & 7];
}
public void onTypesRenamed() {
var newFieldRefToDef = new Dictionary<IFieldReferenceKey, TValue>(refToValue.Count);
var newFieldRefToDef = new Dictionary<IFieldRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getReferenceKey((FieldDef)kvp.Key.FieldReference)] = kvp.Value;
newFieldRefToDef[getRefKey((FieldDef)kvp.Key.FieldRef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class FieldDefinitionDict<TValue> : FieldDefinitionDictBase<TValue> {
internal override IFieldReferenceKey getReferenceKey(IField fieldRef) {
return new FieldReferenceKey(fieldRef);
public class FieldDefDict<TValue> : FieldDefDictBase<TValue> {
internal override IFieldRefKey getRefKey(IField fieldRef) {
return new FieldRefKey(fieldRef);
}
}
public class FieldDefinitionAndDeclaringTypeDict<TValue> : FieldDefinitionDictBase<TValue> {
internal override IFieldReferenceKey getReferenceKey(IField fieldRef) {
return new FieldReferenceAndDeclaringTypeKey(fieldRef);
public class FieldDefAndDeclaringTypeDict<TValue> : FieldDefDictBase<TValue> {
internal override IFieldRefKey getRefKey(IField fieldRef) {
return new FieldRefAndDeclaringTypeKey(fieldRef);
}
}
public abstract class MethodDefinitionDictBase<TValue> {
public abstract class MethodDefDictBase<TValue> {
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
Dictionary<ScopeAndTokenKey, MethodDef> tokenToKey = new Dictionary<ScopeAndTokenKey, MethodDef>();
Dictionary<IMethodReferenceKey, TValue> refToValue = new Dictionary<IMethodReferenceKey, TValue>();
Dictionary<IMethodReferenceKey, MethodDef> refToKey = new Dictionary<IMethodReferenceKey, MethodDef>();
Dictionary<IMethodRefKey, TValue> refToValue = new Dictionary<IMethodRefKey, TValue>();
Dictionary<IMethodRefKey, MethodDef> refToKey = new Dictionary<IMethodRefKey, MethodDef>();
public int Count {
get { return tokenToValue.Count; }
@ -215,7 +215,7 @@ namespace de4dot.blocks {
return new ScopeAndTokenKey(methodDef);
}
internal abstract IMethodReferenceKey getReferenceKey(IMethod methodRef);
internal abstract IMethodRefKey getRefKey(IMethod methodRef);
public TValue find(IMethod methodRef) {
TValue value;
@ -223,7 +223,7 @@ namespace de4dot.blocks {
if (methodDef != null)
tokenToValue.TryGetValue(getTokenKey(methodDef), out value);
else
refToValue.TryGetValue(getReferenceKey(methodRef), out value);
refToValue.TryGetValue(getRefKey(methodRef), out value);
return value;
}
@ -233,7 +233,7 @@ namespace de4dot.blocks {
if (methodDef != null && tokenToValue.TryGetValue(getTokenKey(methodDef), out value))
return value;
refToValue.TryGetValue(getReferenceKey(methodRef), out value);
refToValue.TryGetValue(getRefKey(methodRef), out value);
return value;
}
@ -242,7 +242,7 @@ namespace de4dot.blocks {
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = methodDef;
var refKey = getReferenceKey(methodDef);
var refKey = getRefKey(methodDef);
if (!refToValue.ContainsKey(refKey) ||
getAccessibilityOrder(methodDef) < getAccessibilityOrder(refToKey[refKey])) {
refToKey[refKey] = methodDef;
@ -261,34 +261,34 @@ namespace de4dot.blocks {
0, // Public
70, // <reserved>
};
static int getAccessibilityOrder(MethodDef methodDefinition) {
return accessibilityOrder[(int)methodDefinition.Attributes & 7];
static int getAccessibilityOrder(MethodDef methodDef) {
return accessibilityOrder[(int)methodDef.Attributes & 7];
}
public void onTypesRenamed() {
var newFieldRefToDef = new Dictionary<IMethodReferenceKey, TValue>(refToValue.Count);
var newFieldRefToDef = new Dictionary<IMethodRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getReferenceKey((MethodDef)kvp.Key.MethodReference)] = kvp.Value;
newFieldRefToDef[getRefKey((MethodDef)kvp.Key.MethodRef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class MethodDefinitionDict<TValue> : MethodDefinitionDictBase<TValue> {
internal override IMethodReferenceKey getReferenceKey(IMethod methodRef) {
return new MethodReferenceKey(methodRef);
public class MethodDefDict<TValue> : MethodDefDictBase<TValue> {
internal override IMethodRefKey getRefKey(IMethod methodRef) {
return new MethodRefKey(methodRef);
}
}
public class MethodDefinitionAndDeclaringTypeDict<TValue> : MethodDefinitionDictBase<TValue> {
internal override IMethodReferenceKey getReferenceKey(IMethod methodRef) {
return new MethodReferenceAndDeclaringTypeKey(methodRef);
public class MethodDefAndDeclaringTypeDict<TValue> : MethodDefDictBase<TValue> {
internal override IMethodRefKey getRefKey(IMethod methodRef) {
return new MethodRefAndDeclaringTypeKey(methodRef);
}
}
public abstract class EventDefinitionDictBase<TValue> {
public abstract class EventDefDictBase<TValue> {
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
Dictionary<ScopeAndTokenKey, EventDef> tokenToKey = new Dictionary<ScopeAndTokenKey, EventDef>();
Dictionary<IEventReferenceKey, TValue> refToValue = new Dictionary<IEventReferenceKey, TValue>();
Dictionary<IEventRefKey, TValue> refToValue = new Dictionary<IEventRefKey, TValue>();
public int Count {
get { return tokenToValue.Count; }
@ -302,11 +302,11 @@ namespace de4dot.blocks {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(EventDef eventReference) {
return new ScopeAndTokenKey(eventReference);
ScopeAndTokenKey getTokenKey(EventDef eventRef) {
return new ScopeAndTokenKey(eventRef);
}
internal abstract IEventReferenceKey getReferenceKey(EventDef eventRef);
internal abstract IEventRefKey getRefKey(EventDef eventRef);
public TValue find(EventDef eventRef) {
TValue value;
@ -319,7 +319,7 @@ namespace de4dot.blocks {
if (tokenToValue.TryGetValue(getTokenKey(eventRef), out value))
return value;
refToValue.TryGetValue(getReferenceKey(eventRef), out value);
refToValue.TryGetValue(getRefKey(eventRef), out value);
return value;
}
@ -328,33 +328,33 @@ namespace de4dot.blocks {
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = eventDef;
refToValue[getReferenceKey(eventDef)] = value;
refToValue[getRefKey(eventDef)] = value;
}
public void onTypesRenamed() {
var newFieldRefToDef = new Dictionary<IEventReferenceKey, TValue>(refToValue.Count);
var newFieldRefToDef = new Dictionary<IEventRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getReferenceKey((EventDef)kvp.Key.EventDef)] = kvp.Value;
newFieldRefToDef[getRefKey((EventDef)kvp.Key.EventDef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class EventDefinitionDict<TValue> : EventDefinitionDictBase<TValue> {
internal override IEventReferenceKey getReferenceKey(EventDef eventRef) {
return new EventReferenceKey(eventRef);
public class EventDefDict<TValue> : EventDefDictBase<TValue> {
internal override IEventRefKey getRefKey(EventDef eventRef) {
return new EventRefKey(eventRef);
}
}
public class EventDefinitionAndDeclaringTypeDict<TValue> : EventDefinitionDictBase<TValue> {
internal override IEventReferenceKey getReferenceKey(EventDef eventRef) {
return new EventReferenceAndDeclaringTypeKey(eventRef);
public class EventDefAndDeclaringTypeDict<TValue> : EventDefDictBase<TValue> {
internal override IEventRefKey getRefKey(EventDef eventRef) {
return new EventRefAndDeclaringTypeKey(eventRef);
}
}
public abstract class PropertyDefinitionDictBase<TValue> {
public abstract class PropertyDefDictBase<TValue> {
Dictionary<ScopeAndTokenKey, TValue> tokenToValue = new Dictionary<ScopeAndTokenKey, TValue>();
Dictionary<ScopeAndTokenKey, PropertyDef> tokenToKey = new Dictionary<ScopeAndTokenKey, PropertyDef>();
Dictionary<IPropertyReferenceKey, TValue> refToValue = new Dictionary<IPropertyReferenceKey, TValue>();
Dictionary<IPropertyRefKey, TValue> refToValue = new Dictionary<IPropertyRefKey, TValue>();
public int Count {
get { return tokenToValue.Count; }
@ -368,11 +368,11 @@ namespace de4dot.blocks {
return tokenToValue.Values;
}
ScopeAndTokenKey getTokenKey(PropertyDef propertyReference) {
return new ScopeAndTokenKey(propertyReference);
ScopeAndTokenKey getTokenKey(PropertyDef propertyRef) {
return new ScopeAndTokenKey(propertyRef);
}
internal abstract IPropertyReferenceKey getReferenceKey(PropertyDef propertyReference);
internal abstract IPropertyRefKey getRefKey(PropertyDef propertyRef);
public TValue find(PropertyDef propRef) {
TValue value;
@ -385,7 +385,7 @@ namespace de4dot.blocks {
if (tokenToValue.TryGetValue(getTokenKey(propRef), out value))
return value;
refToValue.TryGetValue(getReferenceKey(propRef), out value);
refToValue.TryGetValue(getRefKey(propRef), out value);
return value;
}
@ -394,26 +394,26 @@ namespace de4dot.blocks {
tokenToValue[tokenKey] = value;
tokenToKey[tokenKey] = propDef;
refToValue[getReferenceKey(propDef)] = value;
refToValue[getRefKey(propDef)] = value;
}
public void onTypesRenamed() {
var newFieldRefToDef = new Dictionary<IPropertyReferenceKey, TValue>(refToValue.Count);
var newFieldRefToDef = new Dictionary<IPropertyRefKey, TValue>(refToValue.Count);
foreach (var kvp in refToValue)
newFieldRefToDef[getReferenceKey((PropertyDef)kvp.Key.PropertyDef)] = kvp.Value;
newFieldRefToDef[getRefKey((PropertyDef)kvp.Key.PropertyDef)] = kvp.Value;
refToValue = newFieldRefToDef;
}
}
public class PropertyDefinitionDict<TValue> : PropertyDefinitionDictBase<TValue> {
internal override IPropertyReferenceKey getReferenceKey(PropertyDef propRef) {
return new PropertyReferenceKey(propRef);
public class PropertyDefDict<TValue> : PropertyDefDictBase<TValue> {
internal override IPropertyRefKey getRefKey(PropertyDef propRef) {
return new PropertyRefKey(propRef);
}
}
public class PropertyDefinitionAndDeclaringTypeDict<TValue> : PropertyDefinitionDictBase<TValue> {
internal override IPropertyReferenceKey getReferenceKey(PropertyDef propRef) {
return new PropertyReferenceAndDeclaringTypeKey(propRef);
public class PropertyDefAndDeclaringTypeDict<TValue> : PropertyDefDictBase<TValue> {
internal override IPropertyRefKey getRefKey(PropertyDef propRef) {
return new PropertyRefAndDeclaringTypeKey(propRef);
}
}
@ -502,30 +502,30 @@ namespace de4dot.blocks {
}
}
interface IFieldReferenceKey {
IField FieldReference { get; }
interface IFieldRefKey {
IField FieldRef { get; }
}
interface IMethodReferenceKey {
IMethod MethodReference { get; }
interface IMethodRefKey {
IMethod MethodRef { get; }
}
interface IEventReferenceKey {
interface IEventRefKey {
EventDef EventDef { get; }
}
interface IPropertyReferenceKey {
interface IPropertyRefKey {
PropertyDef PropertyDef { get; }
}
sealed class FieldReferenceKey : IFieldReferenceKey {
sealed class FieldRefKey : IFieldRefKey {
readonly IField fieldRef;
public IField FieldReference {
public IField FieldRef {
get { return fieldRef; }
}
public FieldReferenceKey(IField fieldRef) {
public FieldRefKey(IField fieldRef) {
this.fieldRef = fieldRef;
}
@ -534,7 +534,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as FieldReferenceKey;
var other = obj as FieldRefKey;
if (other == null)
return false;
return new SigComparer().Equals(fieldRef, other.fieldRef);
@ -545,14 +545,14 @@ namespace de4dot.blocks {
}
}
sealed class MethodReferenceKey : IMethodReferenceKey {
sealed class MethodRefKey : IMethodRefKey {
readonly IMethod methodRef;
public IMethod MethodReference {
public IMethod MethodRef {
get { return methodRef; }
}
public MethodReferenceKey(IMethod methodRef) {
public MethodRefKey(IMethod methodRef) {
this.methodRef = methodRef;
}
@ -561,7 +561,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as MethodReferenceKey;
var other = obj as MethodRefKey;
if (other == null)
return false;
return new SigComparer().Equals(methodRef, other.methodRef);
@ -572,14 +572,14 @@ namespace de4dot.blocks {
}
}
sealed class FieldReferenceAndDeclaringTypeKey : IFieldReferenceKey {
sealed class FieldRefAndDeclaringTypeKey : IFieldRefKey {
readonly IField fieldRef;
public IField FieldReference {
public IField FieldRef {
get { return fieldRef; }
}
public FieldReferenceAndDeclaringTypeKey(IField fieldRef) {
public FieldRefAndDeclaringTypeKey(IField fieldRef) {
this.fieldRef = fieldRef;
}
@ -588,7 +588,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as FieldReferenceAndDeclaringTypeKey;
var other = obj as FieldRefAndDeclaringTypeKey;
if (other == null)
return false;
return new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType).Equals(fieldRef, other.fieldRef);
@ -599,14 +599,14 @@ namespace de4dot.blocks {
}
}
sealed class MethodReferenceAndDeclaringTypeKey : IMethodReferenceKey {
sealed class MethodRefAndDeclaringTypeKey : IMethodRefKey {
readonly IMethod methodRef;
public IMethod MethodReference {
public IMethod MethodRef {
get { return methodRef; }
}
public MethodReferenceAndDeclaringTypeKey(IMethod methodRef) {
public MethodRefAndDeclaringTypeKey(IMethod methodRef) {
this.methodRef = methodRef;
}
@ -615,7 +615,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as MethodReferenceAndDeclaringTypeKey;
var other = obj as MethodRefAndDeclaringTypeKey;
if (other == null)
return false;
return new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType).Equals(methodRef, other.methodRef);
@ -626,14 +626,14 @@ namespace de4dot.blocks {
}
}
sealed class EventReferenceKey : IEventReferenceKey {
sealed class EventRefKey : IEventRefKey {
readonly EventDef eventRef;
public EventDef EventDef {
get { return eventRef; }
}
public EventReferenceKey(EventDef eventRef) {
public EventRefKey(EventDef eventRef) {
this.eventRef = eventRef;
}
@ -642,7 +642,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as EventReferenceKey;
var other = obj as EventRefKey;
if (other == null)
return false;
return new SigComparer().Equals(eventRef, other.eventRef);
@ -653,14 +653,14 @@ namespace de4dot.blocks {
}
}
sealed class EventReferenceAndDeclaringTypeKey : IEventReferenceKey {
sealed class EventRefAndDeclaringTypeKey : IEventRefKey {
readonly EventDef eventRef;
public EventDef EventDef {
get { return eventRef; }
}
public EventReferenceAndDeclaringTypeKey(EventDef eventRef) {
public EventRefAndDeclaringTypeKey(EventDef eventRef) {
this.eventRef = eventRef;
}
@ -669,7 +669,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as EventReferenceAndDeclaringTypeKey;
var other = obj as EventRefAndDeclaringTypeKey;
if (other == null)
return false;
return new SigComparer(SigComparerOptions.CompareEventDeclaringType).Equals(eventRef, other.eventRef);
@ -680,14 +680,14 @@ namespace de4dot.blocks {
}
}
sealed class PropertyReferenceKey : IPropertyReferenceKey {
sealed class PropertyRefKey : IPropertyRefKey {
readonly PropertyDef propRef;
public PropertyDef PropertyDef {
get { return propRef; }
}
public PropertyReferenceKey(PropertyDef propRef) {
public PropertyRefKey(PropertyDef propRef) {
this.propRef = propRef;
}
@ -696,7 +696,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as PropertyReferenceKey;
var other = obj as PropertyRefKey;
if (other == null)
return false;
return new SigComparer().Equals(propRef, other.propRef);
@ -707,14 +707,14 @@ namespace de4dot.blocks {
}
}
sealed class PropertyReferenceAndDeclaringTypeKey : IPropertyReferenceKey {
sealed class PropertyRefAndDeclaringTypeKey : IPropertyRefKey {
readonly PropertyDef propRef;
public PropertyDef PropertyDef {
get { return propRef; }
}
public PropertyReferenceAndDeclaringTypeKey(PropertyDef propRef) {
public PropertyRefAndDeclaringTypeKey(PropertyDef propRef) {
this.propRef = propRef;
}
@ -723,7 +723,7 @@ namespace de4dot.blocks {
}
public override bool Equals(object obj) {
var other = obj as PropertyReferenceAndDeclaringTypeKey;
var other = obj as PropertyRefAndDeclaringTypeKey;
if (other == null)
return false;
return new SigComparer(SigComparerOptions.ComparePropertyDeclaringType).Equals(propRef, other.propRef);

View File

@ -1,81 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.IO;
namespace de4dot.PE {
public class Cor20Header : IFileLocation {
public uint cb;
public ushort majorRuntimeVersion;
public ushort minorRuntimeVersion;
public DataDirectory metadataDirectory;
public uint flags;
public uint entryPointToken;
public DataDirectory resources;
public DataDirectory strongNameSignature;
public DataDirectory codeManagerTable;
public DataDirectory vtableFixups;
public DataDirectory exportAddressTableJumps;
public DataDirectory managedNativeHeader;
public Metadata metadata;
BinaryReader reader;
public uint MetadataOffset {
get { return metadata.Offset; }
}
public uint MetadataHeaderLength {
get { return metadata.HeaderLength; }
}
uint offset;
public uint Offset {
get { return offset; }
}
public uint Length {
get { return 18 * 4; }
}
public Cor20Header(BinaryReader reader) {
this.reader = reader;
offset = (uint)reader.BaseStream.Position;
cb = reader.ReadUInt32();
majorRuntimeVersion = reader.ReadUInt16();
minorRuntimeVersion = reader.ReadUInt16();
metadataDirectory.read(reader);
flags = reader.ReadUInt32();
entryPointToken = reader.ReadUInt32();
resources.read(reader);
strongNameSignature.read(reader);
codeManagerTable.read(reader);
vtableFixups.read(reader);
exportAddressTableJumps.read(reader);
managedNativeHeader.read(reader);
}
internal void initMetadataTable() {
metadata = new Metadata(reader);
}
public MetadataTables createMetadataTables() {
return new MetadataTables(reader, metadata);
}
}
}

View File

@ -1,58 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.IO;
namespace de4dot.PE {
public enum Machine : ushort {
i386 = 0x14C,
ia64 = 0x200,
amd64 = 0x8664,
}
public class FileHeader : IFileLocation {
public Machine machine;
public ushort numberOfSections;
public uint timeDateStamp;
public uint pointerToSymbolTable;
public uint numberOfSymbols;
public ushort sizeOfOptionalHeader;
public ushort characteristics;
uint offset;
public uint Offset {
get { return offset; }
}
public uint Length {
get { return 5 * 4; }
}
public FileHeader(BinaryReader reader) {
offset = (uint)reader.BaseStream.Position;
machine = (Machine)reader.ReadUInt16();
numberOfSections = reader.ReadUInt16();
timeDateStamp = reader.ReadUInt32();
pointerToSymbolTable = reader.ReadUInt32();
numberOfSymbols = reader.ReadUInt32();
sizeOfOptionalHeader = reader.ReadUInt16();
characteristics = reader.ReadUInt16();
}
}
}

View File

@ -1,114 +0,0 @@
/*
Copyright (C) 2011-2012 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 System;
using System.IO;
using System.Text;
namespace de4dot.PE {
public class Metadata : IFileLocation {
uint magic;
ushort majorVersion, minorVersion;
uint reserved;
string versionString;
ushort flags;
DotNetStream[] streams;
uint offset, headerLength, length;
public DotNetStream[] Streams {
get { return streams; }
}
public uint Offset {
get { return offset; }
}
public uint Length {
get { return length; }
}
public uint HeaderLength {
get { return headerLength; }
}
public uint HeaderEnd {
get { return offset + headerLength; }
}
public Metadata(BinaryReader reader) {
magic = reader.ReadUInt32();
if (magic != 0x424A5342)
return;
offset = (uint)reader.BaseStream.Position - 4;
majorVersion = reader.ReadUInt16();
minorVersion = reader.ReadUInt16();
reserved = reader.ReadUInt32();
versionString = readString(reader, reader.ReadInt32());
flags = reader.ReadUInt16();
int numStreams = reader.ReadUInt16();
streams = new DotNetStream[numStreams];
uint lastOffset = offset;
for (int i = 0; i < numStreams; i++) {
uint fileOffset = offset + reader.ReadUInt32();
uint size = reader.ReadUInt32();
string name = readAsciizString(reader);
streams[i] = new DotNetStream(name, fileOffset, size);
lastOffset = Math.Max(lastOffset, fileOffset + size);
}
lastOffset = Math.Max(lastOffset, (uint)reader.BaseStream.Position);
length = lastOffset - offset;
headerLength = (uint)reader.BaseStream.Position - offset;
}
public DotNetStream getStream(string name) {
foreach (var stream in streams) {
if (stream.name == name)
return stream;
}
return null;
}
string readString(BinaryReader reader, int len) {
var sb = new StringBuilder(len);
var nextPos = reader.BaseStream.Position + len;
for (int i = 0; i < len; i++) {
byte b = reader.ReadByte();
if (b == 0)
break;
sb.Append((char)b);
}
reader.BaseStream.Position = nextPos;
return sb.ToString();
}
string readAsciizString(BinaryReader reader) {
var sb = new StringBuilder();
while (true) {
byte b = reader.ReadByte();
if (b == 0)
break;
sb.Append((char)b);
}
reader.BaseStream.Position = (reader.BaseStream.Position + 3) & ~3;
return sb.ToString();
}
}
}

View File

@ -1,152 +0,0 @@
/*
Copyright (C) 2011-2012 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 System;
using System.IO;
namespace de4dot.PE {
using MVT = MetadataVarType;
public class MetadataTables {
BinaryReader reader;
Metadata metadata;
byte heapOffsetSizes;
MetadataType[] metadataTypes = new MetadataType[64];
public MetadataTables(BinaryReader reader, Metadata metadata) {
this.reader = reader;
this.metadata = metadata;
init();
}
public MetadataType getMetadataType(MetadataIndex index) {
return metadataTypes[(int)index];
}
void seek(uint fileOffset) {
reader.BaseStream.Position = fileOffset;
}
// TODO: This table needs to be updated to support the other metadata tables.
static MetadataVarType[] metadataVarType = new MetadataVarType[] {
MVT.byte2, MVT.stringIndex, MVT.guidIndex, MVT.guidIndex, MVT.guidIndex, MVT.end, // 0
MVT.resolutionScope, MVT.stringIndex, MVT.stringIndex, MVT.end, // 1
MVT.byte4, MVT.stringIndex, MVT.stringIndex, MVT.typeDefOrRef, MVT.fieldIndex, MVT.methodDefIndex, MVT.end, // 2
MVT.end, // 3
MVT.byte2, MVT.stringIndex, MVT.blobIndex, MVT.end, // 4
MVT.methodDefIndex, MVT.end, // 5
MVT.byte4, MVT.byte2, MVT.byte2, MVT.stringIndex, MVT.blobIndex, MVT.paramIndex, MVT.end, // 6
MVT.end, // 7
MVT.byte2, MVT.byte2, MVT.stringIndex, MVT.end, // 8
MVT.typeDefIndex, MVT.typeDefOrRef, MVT.end, // 9
MVT.memberRefParent, MVT.stringIndex, MVT.blobIndex, MVT.end, // 10
MVT.byte1, MVT.byte1, MVT.hasConstant, MVT.blobIndex, MVT.end, // 11
MVT.hasCustomAttribute, MVT.customAttributeType, MVT.blobIndex, MVT.end,// 12
MVT.hasFieldMarshal, MVT.blobIndex, MVT.end, // 13
MVT.byte2, MVT.hasDeclSecurity, MVT.blobIndex, MVT.end, // 14
MVT.byte2, MVT.byte4, MVT.typeDefIndex, MVT.end, // 15
MVT.byte4, MVT.fieldIndex, MVT.end, // 16
MVT.blobIndex, MVT.end, // 17
MVT.typeDefIndex, MVT.eventIndex, MVT.end, // 18
MVT.end, // 19
MVT.byte2, MVT.stringIndex, MVT.typeDefOrRef, MVT.end, // 20
MVT.typeDefIndex, MVT.propertyIndex, MVT.end, // 21
MVT.end, // 22
MVT.byte2, MVT.stringIndex, MVT.blobIndex, MVT.end, // 23
MVT.byte2, MVT.methodDefIndex, MVT.hasSemantics, MVT.end, // 24
MVT.typeDefIndex, MVT.methodDefOrRef, MVT.methodDefOrRef, MVT.end, // 25
MVT.stringIndex, MVT.end, // 26
MVT.blobIndex, MVT.end, // 27
MVT.byte2, MVT.memberForwarded, MVT.stringIndex, MVT.moduleRefIndex, MVT.end, // 28
MVT.byte4, MVT.fieldIndex, MVT.end, // 29
MVT.end, // 30
MVT.end, // 31
MVT.byte4, MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte4, MVT.blobIndex, MVT.stringIndex, MVT.stringIndex, MVT.end, // 32
MVT.byte4, MVT.end, // 33
MVT.byte4, MVT.byte4, MVT.byte4, MVT.end, // 34
MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte4, MVT.blobIndex, MVT.stringIndex, MVT.stringIndex, MVT.blobIndex, MVT.end, // 35
MVT.byte4, MVT.assemblyRefIndex, MVT.end, // 36
MVT.byte4, MVT.byte4, MVT.byte4, MVT.assemblyRefIndex, MVT.end, // 37
MVT.byte4, MVT.stringIndex, MVT.blobIndex, MVT.end, // 38
MVT.byte4, MVT.byte4, MVT.stringIndex, MVT.stringIndex, MVT.implementation, MVT.end,// 39
MVT.byte4, MVT.byte4, MVT.stringIndex, MVT.implementation, MVT.end, // 40
MVT.typeDefIndex, MVT.typeDefIndex, MVT.end, // 41
MVT.byte2, MVT.byte2, MVT.typeOrMethodDef, MVT.stringIndex, MVT.end, // 42
MVT.end, // 43
MVT.genericParamIndex, MVT.typeDefOrRef, MVT.end, // 44
MVT.end, // 45
MVT.end, // 46
MVT.end, // 47
MVT.end, // 48
MVT.end, // 49
MVT.end, // 50
MVT.end, // 51
MVT.end, // 52
MVT.end, // 53
MVT.end, // 54
MVT.end, // 55
MVT.end, // 56
MVT.end, // 57
MVT.end, // 58
MVT.end, // 59
MVT.end, // 60
MVT.end, // 61
MVT.end, // 62
MVT.end, // 63
MVT.stop
};
void init() {
var streamTable = metadata.getStream("#~") ?? metadata.getStream("#-");
if (streamTable == null)
throw new ApplicationException("Could not find #~ stream");
seek(streamTable.Offset);
reader.ReadUInt32(); // reserved
reader.ReadUInt16(); // major + minor version
heapOffsetSizes = reader.ReadByte();
reader.ReadByte(); // always 1
ulong validMask = reader.ReadUInt64();
reader.ReadUInt64(); // sorted
var numRows = new uint[64];
for (int i = 0; validMask != 0; i++, validMask >>= 1) {
if ((validMask & 1) != 0)
numRows[i] = reader.ReadUInt32();
}
var builder = new MetadataTypeBuilder(heapOffsetSizes, numRows);
uint fileOffset = (uint)reader.BaseStream.Position;
for (int i = 0, j = 0; ; i++) {
if (metadataVarType[i] == MVT.end) {
var mdType = builder.create();
mdType.rows = numRows[j];
mdType.fileOffset = fileOffset;
fileOffset += mdType.rows * mdType.totalSize;
metadataTypes[j++] = mdType;
}
else if (metadataVarType[i] == MVT.stop)
break;
else
builder.field(metadataVarType[i]);
}
}
}
}

View File

@ -1,89 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.Collections.Generic;
namespace de4dot.PE {
public enum MetadataIndex {
iModule = 0,
iTypeRef = 1,
iTypeDef = 2,
iField = 4,
iMethodDef = 6,
iParam = 8,
iInterfaceImpl = 9,
iMemberRef = 10,
iConstant = 11,
iCustomAttribute = 12,
iFieldMarshal = 13,
iDeclSecurity = 14,
iClassLayout = 15,
iFieldLayout = 16,
iStandAloneSig = 17,
iEventMap = 18,
iEvent = 20,
iPropertyMap = 21,
iProperty = 23,
iMethodSemantics = 24,
iMethodImpl = 25,
iModuleRef = 26,
iTypeSpec = 27,
iImplMap = 28,
iFieldRVA = 29,
iAssembly = 32,
iAssemblyProcessor = 33,
iAssemblyOS = 34,
iAssemblyRef = 35,
iAssemblyRefProcessor = 36,
iAssemblyRefOS = 37,
iFile = 38,
iExportedType = 39,
iManifestResource = 40,
iNestedClass = 41,
iGenericParam = 42,
iGenericParamConstraint = 44,
};
public class MetadataType {
public uint fileOffset;
public uint rows;
public uint totalSize;
public List<MetadataField> fields;
public MetadataType(List<MetadataField> fields) {
this.fields = fields;
totalSize = 0;
foreach (var field in fields)
totalSize += (uint)field.size;
}
public override string ToString() {
return string.Format("MDType: {0:X8}, {1} rows, {2} bytes, {3} fields", fileOffset, rows, totalSize, fields.Count);
}
}
public struct MetadataField {
public int offset;
public int size;
public override string ToString() {
return string.Format("offset: {0}, size {1}", offset, size);
}
}
}

View File

@ -1,203 +0,0 @@
/*
Copyright (C) 2011-2012 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 System;
using System.Collections.Generic;
namespace de4dot.PE {
enum MetadataVarType {
end,
stop,
byte1,
byte2,
byte4,
stringIndex, // index into #String heap
guidIndex, // index into #GUID heap
blobIndex, // index into #Blob heap
resolutionScope,
typeDefOrRef,
fieldIndex,
methodDefIndex,
paramIndex,
typeDefIndex,
eventIndex,
propertyIndex,
moduleRefIndex,
assemblyRefIndex,
genericParamIndex,
memberRefParent,
hasConstant,
hasCustomAttribute,
customAttributeType,
hasFieldMarshal,
hasDeclSecurity,
hasSemantics,
methodDefOrRef,
memberForwarded,
implementation,
typeOrMethodDef,
};
class MetadataTypeBuilder {
byte heapOffsetSizes;
uint[] numRows;
List<MetadataField> fields;
int offset;
public MetadataTypeBuilder(byte heapOffsetSizes, uint[] numRows) {
this.heapOffsetSizes = heapOffsetSizes;
this.numRows = numRows;
reset();
}
void reset() {
offset = 0;
fields = new List<MetadataField>();
}
public MetadataType create() {
var type = new MetadataType(fields);
reset();
return type;
}
public void field(MetadataVarType type) {
int size;
switch (type) {
case MetadataVarType.byte1:
size = 1;
break;
case MetadataVarType.byte2:
size = 2;
break;
case MetadataVarType.byte4:
size = 4;
break;
case MetadataVarType.stringIndex:
size = (heapOffsetSizes & 1) != 0 ? 4 : 2;
break;
case MetadataVarType.guidIndex:
size = (heapOffsetSizes & 2) != 0 ? 4 : 2;
break;
case MetadataVarType.blobIndex:
size = (heapOffsetSizes & 4) != 0 ? 4 : 2;
break;
case MetadataVarType.resolutionScope:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iModule, MetadataIndex.iModuleRef, MetadataIndex.iAssemblyRef, MetadataIndex.iTypeRef });
break;
case MetadataVarType.typeDefOrRef:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iTypeRef, MetadataIndex.iTypeSpec });
break;
case MetadataVarType.memberRefParent:
size = getSize(13, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iTypeRef, MetadataIndex.iModuleRef, MetadataIndex.iMethodDef, MetadataIndex.iTypeSpec });
break;
case MetadataVarType.hasConstant:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iField, MetadataIndex.iParam, MetadataIndex.iProperty });
break;
case MetadataVarType.hasCustomAttribute:
size = getSize(11, new MetadataIndex[] {
MetadataIndex.iMethodDef, MetadataIndex.iField, MetadataIndex.iTypeRef,
MetadataIndex.iTypeDef, MetadataIndex.iParam, MetadataIndex.iInterfaceImpl,
MetadataIndex.iMemberRef, MetadataIndex.iModule /*TODO:, MetadataIndex.iPermission*/,
MetadataIndex.iProperty, MetadataIndex.iEvent, MetadataIndex.iStandAloneSig,
MetadataIndex.iModuleRef, MetadataIndex.iTypeSpec, MetadataIndex.iAssembly,
MetadataIndex.iAssemblyRef, MetadataIndex.iFile, MetadataIndex.iExportedType,
MetadataIndex.iManifestResource,
});
break;
case MetadataVarType.customAttributeType:
size = getSize(13, new MetadataIndex[] { MetadataIndex.iMethodDef, MetadataIndex.iMemberRef }); // others aren't used
break;
case MetadataVarType.hasFieldMarshal:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iField, MetadataIndex.iParam });
break;
case MetadataVarType.hasDeclSecurity:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iMethodDef, MetadataIndex.iAssembly });
break;
case MetadataVarType.hasSemantics:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iEvent, MetadataIndex.iProperty });
break;
case MetadataVarType.methodDefOrRef:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iMethodDef, MetadataIndex.iMemberRef });
break;
case MetadataVarType.memberForwarded:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iField, MetadataIndex.iMethodDef });
break;
case MetadataVarType.implementation:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iFile, MetadataIndex.iAssemblyRef, MetadataIndex.iExportedType });
break;
case MetadataVarType.typeOrMethodDef:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iMethodDef });
break;
case MetadataVarType.fieldIndex:
size = getSize(MetadataIndex.iField);
break;
case MetadataVarType.methodDefIndex:
size = getSize(MetadataIndex.iMethodDef);
break;
case MetadataVarType.paramIndex:
size = getSize(MetadataIndex.iParam);
break;
case MetadataVarType.typeDefIndex:
size = getSize(MetadataIndex.iTypeDef);
break;
case MetadataVarType.eventIndex:
size = getSize(MetadataIndex.iEvent);
break;
case MetadataVarType.propertyIndex:
size = getSize(MetadataIndex.iProperty);
break;
case MetadataVarType.moduleRefIndex:
size = getSize(MetadataIndex.iModuleRef);
break;
case MetadataVarType.assemblyRefIndex:
size = getSize(MetadataIndex.iAssemblyRef);
break;
case MetadataVarType.genericParamIndex:
size = getSize(MetadataIndex.iGenericParam);
break;
default:
throw new ApplicationException("Unknown type");
}
var field = new MetadataField();
field.offset = offset;
field.size = size;
fields.Add(field);
offset += size;
}
uint getMaxRows(MetadataIndex[] indexes) {
uint maxRows = 0;
for (int i = 0; i < indexes.Length; i++)
maxRows = Math.Max(maxRows, numRows[(int)indexes[i]]);
return maxRows;
}
int getSize(int bits, MetadataIndex[] indexes) {
uint maxNum = 1U << bits;
uint maxRows = getMaxRows(indexes);
return maxRows <= maxNum ? 2 : 4;
}
int getSize(MetadataIndex index) {
return getSize(16, new MetadataIndex[] { index });
}
}
}

View File

@ -1,119 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.IO;
namespace de4dot.PE {
public class OptionalHeader : IFileLocation {
public ushort magic;
public byte majorLinkerVersion;
public byte minorLinkerVersion;
public uint sizeOfCode;
public uint sizeOfInitializedData;
public uint sizeOfUninitializedData;
public uint addressOfEntryPoint;
public uint baseOfCode;
public uint baseOfData; // 32-bit only
public ulong imageBase;
public uint sectionAlignment;
public uint fileAlignment;
public ushort majorOperatingSystemVersion;
public ushort minorOperatingSystemVersion;
public ushort majorImageVersion;
public ushort minorImageVersion;
public ushort majorSubsystemVersion;
public ushort minorSubsystemVersion;
public uint win32VersionValue;
public uint sizeOfImage;
public uint sizeOfHeaders;
public uint checkSum;
public ushort subsystem;
public ushort dllCharacteristics;
public ulong sizeOfStackReserve;
public ulong sizeOfStackCommit;
public ulong sizeOfHeapReserve;
public ulong sizeOfHeapCommit;
public uint loaderFlags;
public uint numberOfRvaAndSizes;
public DataDirectory[] dataDirectories;
uint offset, length;
public uint Offset {
get { return offset; }
}
public uint Length {
get { return length; }
}
public OptionalHeader(BinaryReader reader) {
offset = (uint)reader.BaseStream.Position;
magic = reader.ReadUInt16();
majorLinkerVersion = reader.ReadByte();
minorLinkerVersion = reader.ReadByte();
sizeOfCode = reader.ReadUInt32();
sizeOfInitializedData = reader.ReadUInt32();
sizeOfUninitializedData = reader.ReadUInt32();
addressOfEntryPoint = reader.ReadUInt32();
baseOfCode = reader.ReadUInt32();
if (is32bit())
baseOfData = reader.ReadUInt32();
imageBase = read4Or8(reader);
sectionAlignment = reader.ReadUInt32();
fileAlignment = reader.ReadUInt32();
majorOperatingSystemVersion = reader.ReadUInt16();
minorOperatingSystemVersion = reader.ReadUInt16();
majorImageVersion = reader.ReadUInt16();
minorImageVersion = reader.ReadUInt16();
majorSubsystemVersion = reader.ReadUInt16();
minorSubsystemVersion = reader.ReadUInt16();
win32VersionValue = reader.ReadUInt32();
sizeOfImage = reader.ReadUInt32();
sizeOfHeaders = reader.ReadUInt32();
checkSum = reader.ReadUInt32();
subsystem = reader.ReadUInt16();
dllCharacteristics = reader.ReadUInt16();
sizeOfStackReserve = read4Or8(reader);
sizeOfStackCommit = read4Or8(reader);
sizeOfHeapReserve = read4Or8(reader);
sizeOfHeapCommit = read4Or8(reader);
loaderFlags = reader.ReadUInt32();
numberOfRvaAndSizes = reader.ReadUInt32();
dataDirectories = new DataDirectory[16];
for (int i = 0; i < dataDirectories.Length; i++)
dataDirectories[i].read(reader);
length = (uint)reader.BaseStream.Position - offset;
}
public uint offsetOfDataDirectory(int n) {
return offset + length - (uint)(16 - n) * 8;
}
ulong read4Or8(BinaryReader reader) {
if (is32bit())
return reader.ReadUInt32();
return reader.ReadUInt64();
}
public bool is32bit() {
return magic != 0x20B;
}
}
}

View File

@ -1,285 +0,0 @@
/*
Copyright (C) 2011-2012 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 System;
using System.IO;
namespace de4dot.PE {
public class PeImage {
BinaryReader reader;
BinaryWriter writer;
FileHeader fileHeader;
OptionalHeader optionalHeader;
SectionHeader[] sectionHeaders;
Cor20Header cor20Header;
SectionHeader dotNetSection;
Resources resources;
public BinaryReader Reader {
get { return reader; }
}
public uint ImageLength {
get { return (uint)reader.BaseStream.Length; }
}
public Cor20Header Cor20Header {
get { return cor20Header; }
}
public Resources Resources {
get { return resources; }
}
public FileHeader FileHeader {
get { return fileHeader; }
}
public OptionalHeader OptionalHeader {
get { return optionalHeader; }
}
public SectionHeader[] Sections {
get { return sectionHeaders; }
}
public uint FileHeaderOffset {
get { return fileHeader.Offset; }
}
public PeImage(byte[] data)
: this(new MemoryStream(data)) {
}
public PeImage(Stream stream) {
reader = new BinaryReader(stream);
if (stream.CanWrite)
writer = new BinaryWriter(stream);
init();
}
public SectionHeader findSection(string displayName) {
foreach (var section in sectionHeaders) {
if (section.displayName == displayName)
return section;
}
return null;
}
void seek(uint position) {
reader.BaseStream.Position = position;
}
void seekRva(uint rva) {
seek(rvaToOffset(rva));
}
void skip(int bytes) {
reader.BaseStream.Position += bytes;
}
void init() {
seek(0);
if (reader.ReadUInt16() != 0x5A4D)
throw new BadImageFormatException("Not a PE file");
skip(29 * 2);
seek(reader.ReadUInt32());
if (reader.ReadUInt32() != 0x4550)
throw new BadImageFormatException("Not a PE file");
fileHeader = new FileHeader(reader);
optionalHeader = new OptionalHeader(reader);
sectionHeaders = new SectionHeader[fileHeader.numberOfSections];
for (int i = 0; i < sectionHeaders.Length; i++)
sectionHeaders[i] = new SectionHeader(reader);
uint netRva = optionalHeader.dataDirectories[14].virtualAddress;
if (netRva != 0) {
seekRva(netRva);
cor20Header = new Cor20Header(reader);
dotNetSection = getSectionHeaderRva(netRva);
seekRva(cor20Header.metadataDirectory.virtualAddress);
cor20Header.initMetadataTable();
}
uint resourceRva = optionalHeader.dataDirectories[2].virtualAddress;
uint resourceOffset = 0;
if (resourceRva != 0)
resourceOffset = rvaToOffset(resourceRva);
resources = new Resources(reader, resourceOffset, optionalHeader.dataDirectories[2].size);
}
SectionHeader getSectionHeaderRva(uint rva) {
for (int i = 0; i < sectionHeaders.Length; i++) {
var section = sectionHeaders[i];
if (section.virtualAddress <= rva && rva < section.virtualAddress + Math.Max(section.virtualSize, section.sizeOfRawData))
return section;
}
return null;
}
SectionHeader getSectionHeaderOffset(uint offset) {
for (int i = 0; i < sectionHeaders.Length; i++) {
var section = sectionHeaders[i];
if (section.pointerToRawData <= offset && offset < section.pointerToRawData + section.sizeOfRawData)
return section;
}
return null;
}
public uint rvaToOffset(uint rva) {
var section = getSectionHeaderRva(rva);
if (section == null)
throw new ApplicationException(string.Format("Invalid RVA {0:X8}", rva));
return rva - section.virtualAddress + section.pointerToRawData;
}
public uint offsetToRva(uint offset) {
var section = getSectionHeaderOffset(offset);
if (section == null)
throw new ApplicationException(string.Format("Invalid offset {0:X8}", offset));
return offset - section.pointerToRawData + section.virtualAddress;
}
bool intersect(uint offset1, uint length1, uint offset2, uint length2) {
return !(offset1 + length1 <= offset2 || offset2 + length2 <= offset1);
}
bool intersect(uint offset, uint length, IFileLocation location) {
return intersect(offset, length, location.Offset, location.Length);
}
public bool dotNetSafeWriteOffset(uint offset, byte[] data) {
if (cor20Header != null) {
uint length = (uint)data.Length;
if (!dotNetSection.isInside(offset, length))
return false;
if (intersect(offset, length, cor20Header))
return false;
if (intersect(offset, length, cor20Header.MetadataOffset, cor20Header.MetadataHeaderLength))
return false;
}
offsetWrite(offset, data);
return true;
}
public bool dotNetSafeWrite(uint rva, byte[] data) {
return dotNetSafeWriteOffset(rvaToOffset(rva), data);
}
public void write(uint rva, byte[] data) {
seekRva(rva);
writer.Write(data);
}
public void writeUInt16(uint rva, ushort data) {
seekRva(rva);
writer.Write(data);
}
public void writeUInt32(uint rva, uint data) {
seekRva(rva);
writer.Write(data);
}
public byte readByte(uint rva) {
seekRva(rva);
return reader.ReadByte();
}
public ushort readUInt16(uint rva) {
seekRva(rva);
return reader.ReadUInt16();
}
public uint readUInt32(uint rva) {
seekRva(rva);
return reader.ReadUInt32();
}
public int readInt32(uint rva) {
seekRva(rva);
return reader.ReadInt32();
}
public byte[] readBytes(uint rva, int size) {
seekRva(rva);
return reader.ReadBytes(size);
}
public void offsetWrite(uint offset, byte[] data) {
seek(offset);
writer.Write(data);
}
public byte[] offsetReadBytes(uint offset, int size) {
seek(offset);
return reader.ReadBytes(size);
}
public uint offsetRead(uint offset, int size) {
if (size == 2) return offsetReadUInt16(offset);
if (size == 4) return offsetReadUInt32(offset);
throw new NotImplementedException();
}
public byte offsetReadByte(uint offset) {
seek(offset);
return reader.ReadByte();
}
public ushort offsetReadUInt16(uint offset) {
seek(offset);
return reader.ReadUInt16();
}
public uint offsetReadUInt32(uint offset) {
seek(offset);
return reader.ReadUInt32();
}
public void offsetWrite(uint offset, uint data, int size) {
if (size == 2)
offsetWriteUInt16(offset, (ushort)data);
else if (size == 4)
offsetWriteUInt32(offset, data);
else
throw new NotImplementedException();
}
public void offsetWriteUInt16(uint offset, ushort data) {
seek(offset);
writer.Write(data);
}
public void offsetWriteUInt32(uint offset, uint data) {
seek(offset);
writer.Write(data);
}
public byte[] readAllBytes() {
seek(0);
return reader.ReadBytes((int)reader.BaseStream.Length);
}
}
}

View File

@ -1,124 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.Collections.Generic;
namespace de4dot.PE {
public class ResourceDirectory : ResourceDirectoryEntry {
Resources resources;
int offset;
List<ResourceData> resourceDataList = new List<ResourceData>();
List<ResourceDirectory> resourceDirectoryList = new List<ResourceDirectory>();
public List<ResourceData> Data {
get { return resourceDataList; }
}
public List<ResourceDirectory> Directories {
get { return resourceDirectoryList; }
}
public ResourceDirectory(int id, Resources resources, int offset)
: base(id) {
init(resources, offset);
}
public ResourceDirectory(string name, Resources resources, int offset)
: base(name) {
init(resources, offset);
}
void init(Resources resources, int offset) {
this.resources = resources;
this.offset = offset;
initializeEntries();
}
public ResourceDirectory getDirectory(int id) {
return find(resourceDirectoryList, id);
}
public ResourceDirectory getDirectory(string name) {
return find(resourceDirectoryList, name);
}
public ResourceData getData(int id) {
return find(resourceDataList, id);
}
public ResourceData getData(string name) {
return find(resourceDataList, name);
}
void initializeEntries() {
if (offset < 0)
return;
if (!resources.isSizeAvailable(offset, 16))
return;
if (!resources.seek(offset + 12))
return;
int named = resources.readUInt16();
int ids = resources.readUInt16();
int total = named + ids;
if (!resources.isSizeAvailable(total * 8))
return;
for (int i = 0, entryOffset = offset + 16; i < total; i++, entryOffset += 8) {
resources.seek(entryOffset);
uint nameOrId = resources.readUInt32();
uint dataOrDirectory = resources.readUInt32();
string name = null;
int id = -1;
if ((nameOrId & 0x80000000) != 0) {
name = resources.readString((int)(nameOrId & 0x7FFFFFFF));
if (name == null)
break;
}
else
id = (int)nameOrId;
if ((dataOrDirectory & 0x80000000) == 0) {
if (!resources.seek((int)dataOrDirectory))
break;
if (!resources.isSizeAvailable(16))
break;
uint dataRva = resources.readUInt32();
uint dataSize = resources.readUInt32();
if (name == null)
resourceDataList.Add(new ResourceData(id, dataRva, dataSize));
else
resourceDataList.Add(new ResourceData(name, dataRva, dataSize));
}
else {
int directoryOffset = (int)(dataOrDirectory & 0x7FFFFFFF);
if (name == null)
resourceDirectoryList.Add(new ResourceDirectory(id, resources, directoryOffset));
else
resourceDirectoryList.Add(new ResourceDirectory(name, resources, directoryOffset));
}
}
}
public override string ToString() {
return string.Format("OFS: {0:X8}, NAME: {1}", offset, getName());
}
}
}

View File

@ -1,73 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.Collections.Generic;
namespace de4dot.PE {
public abstract class ResourceDirectoryEntry {
protected readonly string name;
protected readonly int id;
public bool HasStringName {
get { return name != null; }
}
public bool HasId {
get { return !HasStringName; }
}
public string Name {
get { return name; }
}
public int Id {
get { return id; }
}
public ResourceDirectoryEntry(int id) {
this.name = null;
this.id = id;
}
public ResourceDirectoryEntry(string name) {
this.name = name;
this.id = -1;
}
protected string getName() {
return HasStringName ? name : id.ToString();
}
protected static T find<T>(IEnumerable<T> list, int id) where T : ResourceDirectoryEntry {
foreach (var dirEntry in list) {
if (dirEntry.HasId && dirEntry.Id == id)
return dirEntry;
}
return null;
}
protected static T find<T>(IEnumerable<T> list, string name) where T : ResourceDirectoryEntry {
foreach (var dirEntry in list) {
if (dirEntry.HasStringName && dirEntry.Name == name)
return dirEntry;
}
return null;
}
}
}

View File

@ -1,93 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.IO;
using System.Text;
namespace de4dot.PE {
public class Resources {
BinaryReader reader;
uint startOffset;
uint totalSize;
ResourceDirectory root;
public BinaryReader Reader {
get { return reader; }
}
public Resources(BinaryReader reader, uint startOffset, uint totalSize) {
this.reader = reader;
this.startOffset = startOffset;
this.totalSize = totalSize;
}
public ResourceDirectory getRoot() {
if (root != null)
return root;
return root = new ResourceDirectory("root", this, startOffset == 0 ? -1 : 0);
}
public bool isSizeAvailable(int offset, int size) {
if (offset < 0 || offset + size < offset)
return false;
return (uint)(offset + size) <= totalSize;
}
public bool isSizeAvailable(int size) {
return isSizeAvailable((int)(reader.BaseStream.Position - startOffset), size);
}
public bool seek(int offset) {
if (!isSizeAvailable(offset, 0))
return false;
reader.BaseStream.Position = startOffset + offset;
return true;
}
public ushort readUInt16() {
return reader.ReadUInt16();
}
public uint readUInt32() {
return reader.ReadUInt32();
}
public byte[] readBytes(int size) {
return reader.ReadBytes(size);
}
public string readString(int offset) {
if (!seek(offset))
return null;
if (!isSizeAvailable(2))
return null;
int size = readUInt16();
int sizeInBytes = size * 2;
if (!isSizeAvailable(sizeInBytes))
return null;
var stringData = readBytes(sizeInBytes);
try {
return Encoding.Unicode.GetString(stringData);
}
catch {
return null;
}
}
}
}

View File

@ -1,76 +0,0 @@
/*
Copyright (C) 2011-2012 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 System.IO;
using System.Text;
namespace de4dot.PE {
public class SectionHeader : IFileLocation {
public byte[] name;
public uint virtualSize;
public uint virtualAddress;
public uint sizeOfRawData;
public uint pointerToRawData;
public uint pointerToRelocations;
public uint pointerToLinenumbers;
public ushort numberOfRelocations;
public ushort numberOfLinenumbers;
public uint characteristics;
public string displayName;
uint offset;
public uint Offset {
get { return offset; }
}
public uint Length {
get { return 10 * 4; }
}
public SectionHeader(BinaryReader reader) {
offset = (uint)reader.BaseStream.Position;
name = reader.ReadBytes(8);
virtualSize = reader.ReadUInt32();
virtualAddress = reader.ReadUInt32();
sizeOfRawData = reader.ReadUInt32();
pointerToRawData = reader.ReadUInt32();
pointerToRelocations = reader.ReadUInt32();
pointerToLinenumbers = reader.ReadUInt32();
numberOfRelocations = reader.ReadUInt16();
numberOfLinenumbers = reader.ReadUInt16();
characteristics = reader.ReadUInt32();
var sb = new StringBuilder(name.Length);
foreach (var c in name) {
if (c == 0)
break;
sb.Append((char)c);
}
displayName = sb.ToString();
}
public bool isInside(uint offset, uint length) {
return offset >= pointerToRawData && offset + length <= pointerToRawData + sizeOfRawData;
}
public override string ToString() {
return string.Format("{0:X8} {1:X8} {2:X8} - {3}", virtualAddress, virtualSize, sizeOfRawData, displayName);
}
}
}

View File

@ -21,7 +21,7 @@ using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("blocks")]
[assembly: AssemblyDescription("Modifies Mono.Cecil MethodDefinition bodies")]
[assembly: AssemblyDescription("Modifies dot10 MethodDef bodies")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("blocks")]

View File

@ -73,22 +73,6 @@
<Compile Include="InstructionListParser.cs" />
<Compile Include="MemberDefDict.cs" />
<Compile Include="MethodBlocks.cs" />
<Compile Include="PE\Cor20Header.cs" />
<Compile Include="PE\DataDirectory.cs" />
<Compile Include="PE\DotNetStream.cs" />
<Compile Include="PE\FileHeader.cs" />
<Compile Include="PE\IFileLocation.cs" />
<Compile Include="PE\Metadata.cs" />
<Compile Include="PE\MetadataTables.cs" />
<Compile Include="PE\MetadataType.cs" />
<Compile Include="PE\MetadataTypeBuilder.cs" />
<Compile Include="PE\OptionalHeader.cs" />
<Compile Include="PE\PeImage.cs" />
<Compile Include="PE\ResourceData.cs" />
<Compile Include="PE\ResourceDirectory.cs" />
<Compile Include="PE\ResourceDirectoryEntry.cs" />
<Compile Include="PE\Resources.cs" />
<Compile Include="PE\SectionHeader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScopeBlock.cs" />
<Compile Include="TryBlock.cs" />

View File

@ -35,8 +35,18 @@ namespace de4dot.code.AssemblyClient {
}
public class NewProcessAssemblyClientFactory : IAssemblyClientFactory {
ServerClrVersion serverVersion;
public NewProcessAssemblyClientFactory() {
this.serverVersion = ServerClrVersion.CLR_ANY_ANYCPU;
}
internal NewProcessAssemblyClientFactory(ServerClrVersion serverVersion) {
this.serverVersion = serverVersion;
}
public IAssemblyClient create() {
return new AssemblyClient(new NewProcessAssemblyServerLoader());
return new AssemblyClient(new NewProcessAssemblyServerLoader(serverVersion));
}
}
}

View File

@ -21,23 +21,45 @@ using System;
using AssemblyData;
namespace de4dot.code.AssemblyClient {
enum ServerClrVersion {
CLR_ANY_ANYCPU,
CLR_ANY_x86,
CLR_ANY_x64,
CLR_v20_x86,
CLR_v20_x64,
CLR_v40_x86,
CLR_v40_x64,
}
abstract class IpcAssemblyServerLoader : IAssemblyServerLoader {
const string ASSEMBLY_SERVER_FILENAME_X86 = "AssemblyServer.exe";
const string ASSEMBLY_SERVER_FILENAME_X64 = "AssemblyServer-x64.exe";
readonly string assemblyServerFilename;
protected string ipcName;
protected string ipcUri;
string url;
protected IpcAssemblyServerLoader() {
assemblyServerFilename = getServerName();
protected IpcAssemblyServerLoader()
: this(ServerClrVersion.CLR_ANY_ANYCPU) {
}
protected IpcAssemblyServerLoader(ServerClrVersion serverVersion) {
assemblyServerFilename = getServerName(serverVersion);
ipcName = Utils.randomName(15, 20);
ipcUri = Utils.randomName(15, 20);
url = string.Format("ipc://{0}/{1}", ipcName, ipcUri);
}
static string getServerName() {
return IntPtr.Size == 4 ? ASSEMBLY_SERVER_FILENAME_X86 : ASSEMBLY_SERVER_FILENAME_X64;
static string getServerName(ServerClrVersion serverVersion) {
if (serverVersion == ServerClrVersion.CLR_ANY_ANYCPU)
serverVersion = IntPtr.Size == 4 ? ServerClrVersion.CLR_ANY_x86 : ServerClrVersion.CLR_ANY_x64;
switch (serverVersion) {
case ServerClrVersion.CLR_ANY_x86: return "AssemblyServer.exe";
case ServerClrVersion.CLR_ANY_x64: return "AssemblyServer-x64.exe";
case ServerClrVersion.CLR_v20_x86: return "AssemblyServer-CLR20.exe";
case ServerClrVersion.CLR_v20_x64: return "AssemblyServer-CLR20-x64.exe";
case ServerClrVersion.CLR_v40_x86: return "AssemblyServer-CLR40.exe";
case ServerClrVersion.CLR_v40_x64: return "AssemblyServer-CLR40-x64.exe";
default: throw new ArgumentException(string.Format("Invalid server version: {0}", serverVersion));
}
}
public void loadServer() {

View File

@ -25,6 +25,13 @@ namespace de4dot.code.AssemblyClient {
class NewProcessAssemblyServerLoader : IpcAssemblyServerLoader {
Process process;
public NewProcessAssemblyServerLoader() {
}
public NewProcessAssemblyServerLoader(ServerClrVersion version)
: base(version) {
}
public override void loadServer(string filename) {
if (process != null)
throw new ApplicationException("Server is already loaded");

View File

@ -46,7 +46,7 @@ namespace de4dot.code {
dataDict.Remove(name);
}
static ITypeDefOrRef getNonGenericTypeReference(ITypeDefOrRef typeRef) {
static ITypeDefOrRef getNonGenericTypeRef(ITypeDefOrRef typeRef) {
var ts = typeRef as TypeSpec;
if (ts == null)
return typeRef;
@ -59,7 +59,7 @@ namespace de4dot.code {
public TypeDef resolveType(ITypeDefOrRef type) {
if (type == null)
return null;
type = getNonGenericTypeReference(type);
type = getNonGenericTypeRef(type);
var typeDef = type as TypeDef;
if (typeDef != null)

View File

@ -40,7 +40,7 @@ namespace de4dot.code {
void deobfuscateEnd();
void deobfuscateCleanUp();
void load(IEnumerable<IDeobfuscator> deobfuscators);
void load(IList<IDeobfuscator> deobfuscators);
void save();
}
}

View File

@ -133,11 +133,11 @@ namespace de4dot.code {
printExInfo(exInfo);
var instrString = instr.OpCode.Name;
var operandString = getOperandString(instr);
var memberReference = instr.Operand as ITokenOperand;
var memberRef = instr.Operand as ITokenOperand;
if (operandString == "")
Logger.log(loggerEvent, "{0}", instrString);
else if (memberReference != null)
Logger.log(loggerEvent, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberReference.MDToken.ToUInt32());
else if (memberRef != null)
Logger.log(loggerEvent, "{0,-9} {1} // {2:X8}", instrString, Utils.removeNewlines(operandString), memberRef.MDToken.ToUInt32());
else
Logger.log(loggerEvent, "{0,-9} {1}", instrString, Utils.removeNewlines(operandString));
}

View File

@ -165,7 +165,7 @@ namespace de4dot.code {
this.callEndIndex = callEndIndex;
}
public IMethod getMethodReference() {
public IMethod getMethodRef() {
return (IMethod)block.Instructions[callEndIndex].Operand;
}
}
@ -257,7 +257,7 @@ namespace de4dot.code {
bool findArgs(CallResult callResult) {
var block = callResult.block;
var method = callResult.getMethodReference();
var method = callResult.getMethodRef();
var methodArgs = DotNetUtils.getArgs(method);
int numArgs = methodArgs.Count;
var args = new object[numArgs];

View File

@ -160,14 +160,22 @@ namespace de4dot.code {
return noExt + "-cleaned" + ext;
}
public void load(IEnumerable<IDeobfuscator> deobfuscators) {
loadModule(deobfuscators);
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(Filename));
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(NewFilename));
detectObfuscator(deobfuscators);
if (deob == null)
throw new ApplicationException("Could not detect obfuscator!");
initializeDeobfuscator();
public void load(IList<IDeobfuscator> deobfuscators) {
try {
loadModule(deobfuscators);
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(Filename));
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(NewFilename));
detectObfuscator(deobfuscators);
if (deob == null)
throw new ApplicationException("Could not detect obfuscator!");
initializeDeobfuscator();
}
finally {
foreach (var d in deobfuscators) {
if (d != deob && d != null)
d.Dispose();
}
}
}
void loadModule(IEnumerable<IDeobfuscator> deobfuscators) {
@ -187,32 +195,32 @@ namespace de4dot.code {
}
bool unpackNativeImage(IEnumerable<IDeobfuscator> deobfuscators) {
var peImage = new PEImage(Filename);
using (var peImage = new PEImage(Filename)) {
foreach (var deob in deobfuscators) {
byte[] unpackedData = null;
try {
unpackedData = deob.unpackNativeFile(peImage);
}
catch {
}
if (unpackedData == null)
continue;
foreach (var deob in deobfuscators) {
byte[] unpackedData = null;
try {
unpackedData = deob.unpackNativeFile(peImage);
var oldModule = module;
try {
module = assemblyModule.load(unpackedData);
}
catch {
Logger.w("Could not load unpacked data. File: {0}, deobfuscator: {0}", peImage.FileName ?? "(unknown filename)", deob.TypeLong);
continue;
}
finally {
if (oldModule != null)
oldModule.Dispose();
}
this.deob = deob;
return true;
}
catch {
}
if (unpackedData == null)
continue;
var oldModule = module;
try {
module = assemblyModule.load(unpackedData);
}
catch {
Logger.w("Could not load unpacked data. File: {0}, deobfuscator: {0}", peImage.FileName ?? "(unknown filename)", deob.TypeLong);
continue;
}
finally {
if (oldModule != null)
oldModule.Dispose();
}
this.deob = deob;
return true;
}
return false;
@ -544,8 +552,6 @@ namespace de4dot.code {
deob.DeobfuscatedFile = null;
if (!options.ControlFlowDeobfuscation) {
// If it's the unknown type, we don't remove any types that could cause Mono.Cecil
// to throw an exception.
if (ShouldPreserveTokens())
return;
}
@ -778,9 +784,7 @@ namespace de4dot.code {
var baseDir = Utils.getDirName(options.NewFilename);
var newName = Path.Combine(baseDir, assemblyName + extension);
Logger.n("Creating file {0}", newName);
using (var writer = new BinaryWriter(new FileStream(newName, FileMode.Create))) {
writer.Write(data);
}
File.WriteAllBytes(newName, data);
}
void IDeobfuscatedFile.stringDecryptersAdded() {
@ -795,6 +799,8 @@ namespace de4dot.code {
deobfuscateCleanUp();
if (module != null)
module.Dispose();
if (deob != null)
deob.Dispose();
module = null;
deob = null;
}

View File

@ -128,7 +128,7 @@ namespace de4dot.code {
}
class StaticStringInliner : StringInlinerBase {
MethodDefinitionAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], string>> stringDecrypters = new MethodDefinitionAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], string>>();
MethodDefAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], string>> stringDecrypters = new MethodDefAndDeclaringTypeDict<Func<MethodDef, MethodSpec, object[], string>>();
public override bool HasHandlers {
get { return stringDecrypters.Count != 0; }

View File

@ -182,7 +182,7 @@
<Compile Include="deobfuscators\DeobUtils.cs" />
<Compile Include="deobfuscators\Dotfuscator\Deobfuscator.cs" />
<Compile Include="deobfuscators\Dotfuscator\StringDecrypter.cs" />
<Compile Include="deobfuscators\dotNET_Reactor\MyPEImage.cs" />
<Compile Include="deobfuscators\MyPEImage.cs" />
<Compile Include="deobfuscators\dotNET_Reactor\v3\AntiStrongName.cs" />
<Compile Include="deobfuscators\dotNET_Reactor\v3\ApplicationModeDecrypter.cs" />
<Compile Include="deobfuscators\dotNET_Reactor\v3\ApplicationModeUnpacker.cs" />

View File

@ -22,7 +22,6 @@ using System.Collections.Generic;
using System.IO;
using dot10.DotNet;
using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Agile_NET {
class CliSecureRtType {
@ -192,13 +191,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
bool findNativeCode(byte[] moduleBytes) {
var stream = moduleBytes != null ?
(Stream)new MemoryStream(moduleBytes) :
(Stream)new FileStream(module.Location, FileMode.Open, FileAccess.Read, FileShare.Read);
using (stream) {
var peImage = new PeImage(stream);
var bytes = moduleBytes != null ? moduleBytes : DeobUtils.readModule(module);
using (var peImage = new MyPEImage(bytes))
return foundSig = MethodsDecrypter.detect(peImage);
}
}
public bool isAtLeastVersion50() {

View File

@ -23,7 +23,6 @@ using dot10.IO;
using dot10.PE;
using dot10.DotNet;
using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.Agile_NET {
public class DeobfuscatorInfo : DeobfuscatorInfoBase {
@ -209,11 +208,11 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return false;
byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module);
var peImage = new PeImage(fileData);
if (!new MethodsDecrypter().decrypt(peImage, module, cliSecureRtType, ref dumpedMethods)) {
Logger.v("Methods aren't encrypted or invalid signature");
return false;
using (var peImage = new MyPEImage(fileData)) {
if (!new MethodsDecrypter().decrypt(peImage, module, cliSecureRtType, ref dumpedMethods)) {
Logger.v("Methods aren't encrypted or invalid signature");
return false;
}
}
newFileData = fileData;

View File

@ -20,9 +20,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.PE;
using dot10.DotNet;
using de4dot.PE;
using dot10.DotNet.MD;
using de4dot.blocks;
using de4dot.code.AssemblyClient;
namespace de4dot.code.deobfuscators.Agile_NET {
class CodeHeader {
@ -61,7 +64,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
Pro,
}
PeImage peImage;
MyPEImage peImage;
ModuleDefMD module;
CliSecureRtType csRtType;
CodeHeader codeHeader = new CodeHeader();
@ -73,35 +76,36 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
abstract class DecrypterBase : IDecrypter {
protected readonly PeImage peImage;
protected readonly MyPEImage peImage;
protected readonly CodeHeader codeHeader;
protected readonly uint endOfMetadata;
public DecrypterBase(PeImage peImage, CodeHeader codeHeader) {
public DecrypterBase(MyPEImage peImage, CodeHeader codeHeader) {
this.peImage = peImage;
this.codeHeader = codeHeader;
endOfMetadata = peImage.rvaToOffset(peImage.Cor20Header.metadataDirectory.virtualAddress + peImage.Cor20Header.metadataDirectory.size);
var mdDir = peImage.Cor20Header.MetaData;
endOfMetadata = peImage.rvaToOffset((uint)mdDir.VirtualAddress + mdDir.Size);
}
public abstract MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections);
protected MethodBodyHeader getCodeBytes(byte[] methodBody, out byte[] code, out byte[] extraSections) {
return MethodBodyParser.parseMethodBody(new BinaryReader(new MemoryStream(methodBody)), out code, out extraSections);
return MethodBodyParser.parseMethodBody(MemoryImageStream.Create(methodBody), out code, out extraSections);
}
}
// CS 1.1 (could be other versions too)
class Decrypter10 {
PeImage peImage;
MyPEImage peImage;
CsBlowfish blowfish;
public Decrypter10(PeImage peImage, byte[] key) {
public Decrypter10(MyPEImage peImage, byte[] key) {
this.peImage = peImage;
this.blowfish = new CsBlowfish(key);
}
public MethodBodyHeader decrypt(uint bodyOffset, out byte[] code, out byte[] extraSections) {
peImage.Reader.BaseStream.Position = bodyOffset;
peImage.Reader.Position = bodyOffset;
var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
blowfish.decrypt(code);
return mbHeader;
@ -110,31 +114,31 @@ namespace de4dot.code.deobfuscators.Agile_NET {
// CS 3.0 (could be other versions too)
class Decrypter30 : DecrypterBase {
public Decrypter30(PeImage peImage, CodeHeader codeHeader)
public Decrypter30(MyPEImage peImage, CodeHeader codeHeader)
: base(peImage, codeHeader) {
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
peImage.Reader.BaseStream.Position = peImage.rvaToOffset(methodInfo.codeOffs);
peImage.Reader.Position = peImage.rvaToOffset(methodInfo.codeOffs);
return MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
}
}
// CS 4.0 (could be other versions too)
class Decrypter40 : DecrypterBase {
public Decrypter40(PeImage peImage, CodeHeader codeHeader)
public Decrypter40(MyPEImage peImage, CodeHeader codeHeader)
: base(peImage, codeHeader) {
}
public override MethodBodyHeader decrypt(MethodInfo methodInfo, out byte[] code, out byte[] extraSections) {
peImage.Reader.BaseStream.Position = endOfMetadata + methodInfo.codeOffs;
peImage.Reader.Position = endOfMetadata + methodInfo.codeOffs;
return MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
}
}
// CS 4.5 (could be other versions too)
class Decrypter45 : DecrypterBase {
public Decrypter45(PeImage peImage, CodeHeader codeHeader)
public Decrypter45(MyPEImage peImage, CodeHeader codeHeader)
: base(peImage, codeHeader) {
}
@ -153,7 +157,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
class Decrypter5 : DecrypterBase {
readonly uint codeHeaderSize;
public Decrypter5(PeImage peImage, CodeHeader codeHeader, uint codeHeaderSize)
public Decrypter5(MyPEImage peImage, CodeHeader codeHeader, uint codeHeaderSize)
: base(peImage, codeHeader) {
this.codeHeaderSize = codeHeaderSize;
}
@ -174,7 +178,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
class ProDecrypter : DecrypterBase {
readonly uint[] key = new uint[4];
public ProDecrypter(PeImage peImage, CodeHeader codeHeader)
public ProDecrypter(MyPEImage peImage, CodeHeader codeHeader)
: base(peImage, codeHeader) {
for (int i = 0; i < 4; i++)
key[i] = be_readUInt32(codeHeader.decryptionKey, i * 4);
@ -222,7 +226,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
interface ICsHeader {
IDecrypter createDecrypter();
List<MethodInfo> getMethodInfos(uint codeHeaderOffset);
void patchMethodDefTable(MetadataType methodDefTable, IList<MethodInfo> methodInfos);
void patchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos);
}
abstract class CsHeaderBase : ICsHeader {
@ -236,7 +240,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
public abstract IDecrypter createDecrypter();
public virtual void patchMethodDefTable(MetadataType methodDefTable, IList<MethodInfo> methodInfos) {
public virtual void patchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos) {
}
public abstract List<MethodInfo> getMethodInfos(uint codeHeaderOffset);
@ -347,10 +351,10 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return getMethodInfos4(codeHeaderOffset);
}
public override void patchMethodDefTable(MetadataType methodDefTable, IList<MethodInfo> methodInfos) {
uint offset = methodDefTable.fileOffset - methodDefTable.totalSize;
public override void patchMethodTable(MDTable methodDefTable, IList<MethodInfo> methodInfos) {
uint offset = (uint)methodDefTable.StartOffset - methodDefTable.RowSize;
foreach (var methodInfo in methodInfos) {
offset += methodDefTable.totalSize;
offset += methodDefTable.RowSize;
if (methodInfo.flags == 0 || methodInfo.codeOffs == 0)
continue;
uint rva = methodsDecrypter.peImage.offsetReadUInt32(offset);
@ -370,7 +374,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
V52, // 5.2+ (or maybe 5.1+)
}
List<CsHeaderVersion> getCsHeaderVersions(uint codeHeaderOffset, MetadataType methodDefTable) {
List<CsHeaderVersion> getCsHeaderVersions(uint codeHeaderOffset, MDTable methodDefTable) {
if (sigType == SigType.Old)
return new List<CsHeaderVersion> { CsHeaderVersion.V10 };
if (!isOldHeader(methodDefTable))
@ -408,10 +412,10 @@ namespace de4dot.code.deobfuscators.Agile_NET {
}
}
bool isOldHeader(MetadataType methodDefTable) {
if (methodDefTable.totalSize != codeHeader.methodDefElemSize)
bool isOldHeader(MDTable methodDefTable) {
if (methodDefTable.RowSize != codeHeader.methodDefElemSize)
return true;
if (methodDefTable.fileOffset - peImage.rvaToOffset(peImage.Cor20Header.metadataDirectory.virtualAddress) != codeHeader.methodDefTableOffset)
if ((uint)methodDefTable.StartOffset - peImage.rvaToOffset((uint)peImage.Cor20Header.MetaData.VirtualAddress) != codeHeader.methodDefTableOffset)
return true;
return false;
@ -434,7 +438,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
Error,
}
public bool decrypt(PeImage peImage, ModuleDefMD module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) {
public bool decrypt(MyPEImage peImage, ModuleDefMD module, CliSecureRtType csRtType, ref DumpedMethods dumpedMethods) {
this.peImage = peImage;
this.csRtType = csRtType;
this.module = module;
@ -444,9 +448,9 @@ namespace de4dot.code.deobfuscators.Agile_NET {
case DecryptResult.NotEncrypted: return false;
case DecryptResult.Error:
Logger.w("Using dynamic method decryption");
Logger.n("Using dynamic method decryption");
byte[] moduleCctorBytes = getModuleCctorBytes(csRtType);
dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.decrypt(module.Location, moduleCctorBytes);
dumpedMethods = de4dot.code.deobfuscators.MethodsDecrypter.decrypt(module, moduleCctorBytes);
return true;
default:
@ -469,27 +473,27 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return moduleCctorBytes;
}
static uint getCodeHeaderOffset(PeImage peImage) {
return peImage.rvaToOffset(peImage.Cor20Header.metadataDirectory.virtualAddress + peImage.Cor20Header.metadataDirectory.size);
static uint getCodeHeaderOffset(MyPEImage peImage) {
return peImage.rvaToOffset((uint)peImage.Cor20Header.MetaData.VirtualAddress + peImage.Cor20Header.MetaData.Size);
}
static string[] sections = new string[] {
".text", ".rsrc", ".data", ".rdata",
};
static uint getOldCodeHeaderOffset(PeImage peImage) {
static uint getOldCodeHeaderOffset(MyPEImage peImage) {
var sect = getLastOf(peImage, sections);
if (sect == null || sect.virtualSize < 0x100)
if (sect == null || sect.VirtualSize < 0x100)
return 0;
return peImage.rvaToOffset(sect.virtualAddress + sect.virtualSize - 0x100);
return peImage.rvaToOffset((uint)sect.VirtualAddress + sect.VirtualSize - 0x100);
}
static SectionHeader getLastOf(PeImage peImage, string[] sections) {
SectionHeader sect = null;
static ImageSectionHeader getLastOf(MyPEImage peImage, string[] sections) {
ImageSectionHeader sect = null;
foreach (var name in sections) {
var sect2 = peImage.findSection(name);
if (sect2 == null)
continue;
if (sect == null || sect2.virtualAddress > sect.virtualAddress)
if (sect == null || sect2.VirtualAddress > sect.VirtualAddress)
sect = sect2;
}
return sect;
@ -500,8 +504,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
if (sigType == SigType.Unknown)
return DecryptResult.NotEncrypted;
var metadataTables = peImage.Cor20Header.createMetadataTables();
var methodDefTable = metadataTables.getMetadataType(MetadataIndex.iMethodDef);
var methodDefTable = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
foreach (var version in getCsHeaderVersions(codeHeaderOffset, methodDefTable)) {
try {
@ -534,66 +537,44 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return codeHeaderOffset;
}
void decryptMethodsOld(MetadataType methodDefTable, ref DumpedMethods dumpedMethods) {
void decryptMethodsOld(MDTable methodDefTable, ref DumpedMethods dumpedMethods) {
dumpedMethods = new DumpedMethods();
uint offset = methodDefTable.fileOffset;
var decrypter = new Decrypter10(peImage, codeHeader.decryptionKey);
for (int i = 0; i < methodDefTable.rows; i++, offset += methodDefTable.totalSize) {
for (uint rid = 1; rid <= methodDefTable.Rows; rid++) {
var dm = new DumpedMethod();
dm.token = 0x06000001 + (uint)i;
var method = (MethodDef)module.ResolveMethod(MDToken.ToRID(dm.token));
if (method == null || method.DeclaringType == DotNetUtils.getModuleType(module))
var method = (MethodDef)module.ResolveMethod(rid);
if (method == null || method.DeclaringType == module.GlobalType)
continue;
uint rva = peImage.offsetReadUInt32(offset + (uint)methodDefTable.fields[0].offset);
if (rva == 0)
peImage.readMethodTableRowTo(dm, rid);
if (dm.mdRVA == 0)
continue;
uint bodyOffset = peImage.rvaToOffset(rva);
dm.mdRVA = peImage.offsetRead(offset + (uint)methodDefTable.fields[0].offset, methodDefTable.fields[0].size);
dm.mdImplFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[1].offset);
dm.mdFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[2].offset);
dm.mdName = peImage.offsetRead(offset + (uint)methodDefTable.fields[3].offset, methodDefTable.fields[3].size);
dm.mdSignature = peImage.offsetRead(offset + (uint)methodDefTable.fields[4].offset, methodDefTable.fields[4].size);
dm.mdParamList = peImage.offsetRead(offset + (uint)methodDefTable.fields[5].offset, methodDefTable.fields[5].size);
uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
var mbHeader = decrypter.decrypt(bodyOffset, out dm.code, out dm.extraSections);
dm.mhFlags = mbHeader.flags;
dm.mhMaxStack = mbHeader.maxStack;
dm.mhCodeSize = (uint)dm.code.Length;
dm.mhLocalVarSigTok = mbHeader.localVarSigTok;
peImage.updateMethodHeaderInfo(dm, mbHeader);
dumpedMethods.add(dm);
}
}
void decryptMethods(uint codeHeaderOffset, MetadataType methodDefTable, ICsHeader csHeader, ref DumpedMethods dumpedMethods) {
void decryptMethods(uint codeHeaderOffset, MDTable methodDefTable, ICsHeader csHeader, ref DumpedMethods dumpedMethods) {
var methodInfos = csHeader.getMethodInfos(codeHeaderOffset);
csHeader.patchMethodDefTable(methodDefTable, methodInfos);
csHeader.patchMethodTable(methodDefTable, methodInfos);
dumpedMethods = new DumpedMethods();
uint offset = methodDefTable.fileOffset;
decrypter = csHeader.createDecrypter();
for (int i = 0; i < methodInfos.Count; i++, offset += methodDefTable.totalSize) {
var methodInfo = methodInfos[i];
for (uint rid = 1; rid <= (uint)methodInfos.Count; rid++) {
var methodInfo = methodInfos[(int)rid - 1];
if (methodInfo.codeOffs == 0)
continue;
var dm = new DumpedMethod();
dm.token = 0x06000001 + (uint)i;
dm.mdRVA = peImage.offsetRead(offset + (uint)methodDefTable.fields[0].offset, methodDefTable.fields[0].size);
dm.mdImplFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[1].offset);
dm.mdFlags = peImage.offsetReadUInt16(offset + (uint)methodDefTable.fields[2].offset);
dm.mdName = peImage.offsetRead(offset + (uint)methodDefTable.fields[3].offset, methodDefTable.fields[3].size);
dm.mdSignature = peImage.offsetRead(offset + (uint)methodDefTable.fields[4].offset, methodDefTable.fields[4].size);
dm.mdParamList = peImage.offsetRead(offset + (uint)methodDefTable.fields[5].offset, methodDefTable.fields[5].size);
peImage.readMethodTableRowTo(dm, rid);
var mbHeader = decrypter.decrypt(methodInfo, out dm.code, out dm.extraSections);
dm.mhFlags = mbHeader.flags;
dm.mhMaxStack = mbHeader.maxStack;
dm.mhCodeSize = (uint)dm.code.Length;
dm.mhLocalVarSigTok = mbHeader.localVarSigTok;
peImage.updateMethodHeaderInfo(dm, mbHeader);
dumpedMethods.add(dm);
}
@ -622,7 +603,7 @@ namespace de4dot.code.deobfuscators.Agile_NET {
return getSigType(signature) != SigType.Unknown;
}
public static bool detect(PeImage peImage) {
public static bool detect(MyPEImage peImage) {
try {
uint codeHeaderOffset = getCodeHeaderOffset(peImage);
if (isValidSignature(peImage.offsetReadBytes(codeHeaderOffset, 16)))

View File

@ -28,10 +28,10 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
IDeobfuscatorContext deobfuscatorContext;
ModuleDefMD module;
EmbeddedResource resource;
AssemblyRef vmAssemblyReference;
AssemblyRef vmAssemblyRef;
public bool Detected {
get { return resource != null && vmAssemblyReference != null; }
get { return resource != null && vmAssemblyRef != null; }
}
public EmbeddedResource Resource {
@ -48,16 +48,16 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
this.module = module;
if (oldOne.resource != null)
this.resource = (EmbeddedResource)module.Resources[oldOne.module.Resources.IndexOf(oldOne.resource)];
if (oldOne.vmAssemblyReference != null)
this.vmAssemblyReference = module.ResolveAssemblyRef(oldOne.vmAssemblyReference.Rid);
if (oldOne.vmAssemblyRef != null)
this.vmAssemblyRef = module.ResolveAssemblyRef(oldOne.vmAssemblyRef.Rid);
}
public void find() {
resource = findCsvmResource();
vmAssemblyReference = findVmAssemblyReference();
vmAssemblyRef = findVmAssemblyRef();
}
AssemblyRef findVmAssemblyReference() {
AssemblyRef findVmAssemblyRef() {
foreach (var memberRef in module.GetMemberRefs()) {
var sig = memberRef.MethodSig;
if (sig == null)
@ -132,7 +132,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
VmOpCodeHandlerDetector getVmOpCodeHandlerDetector() {
var vmFilename = vmAssemblyReference.Name + ".dll";
var vmFilename = vmAssemblyRef.Name + ".dll";
var vmModulePath = Path.Combine(Path.GetDirectoryName(module.Location), vmFilename);
Logger.v("CSVM filename: {0}", vmFilename);

View File

@ -234,12 +234,12 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
throw new ApplicationException("Invalid number of locals");
for (int i = 0; i < numLocals; i++)
locals.Add(new Local(readTypeReference(reader)));
locals.Add(new Local(readTypeRef(reader)));
return locals;
}
TypeSig readTypeReference(BinaryReader reader) {
TypeSig readTypeRef(BinaryReader reader) {
var etype = (ElementType)reader.ReadInt32();
switch (etype) {
case ElementType.Void: return module.CorLibTypes.Void;
@ -345,7 +345,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
object fixOperand(IList<Instruction> instrs, Instruction instr, IVmOperand vmOperand) {
if (vmOperand is TokenOperand)
return getMemberReference(((TokenOperand)vmOperand).token);
return getMemberRef(((TokenOperand)vmOperand).token);
if (vmOperand is TargetDisplOperand)
return getInstruction(instrs, instr, ((TargetDisplOperand)vmOperand).displacement);
@ -387,7 +387,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
return fieldRef;
}
ITokenOperand getMemberReference(int token) {
ITokenOperand getMemberRef(int token) {
var memberRef = module.ResolveToken(token) as ITokenOperand;
if (memberRef == null)
throw new ApplicationException(string.Format("Could not find member ref: {0:X8}", token));

View File

@ -75,7 +75,7 @@ namespace de4dot.code.deobfuscators.Agile_NET.vm {
}
static internal IEnumerable<FieldDef> getFields(TypeDef type) {
var typeFields = new FieldDefinitionAndDeclaringTypeDict<FieldDef>();
var typeFields = new FieldDefAndDeclaringTypeDict<FieldDef>();
foreach (var field in type.Fields)
typeFields.add(field, field);
var realFields = new Dictionary<FieldDef, bool>();

View File

@ -52,15 +52,15 @@ namespace de4dot.code.deobfuscators.Babel_NET {
string[] strings;
AssemblyRef[] assemblyNames;
Dictionary<string, int> methodOffsets;
List<TypeSig> typeReferences;
MemberReferenceConverter memberReferenceConverter;
List<TypeSig> 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.memberReferenceConverter = new MemberReferenceConverter(module);
this.memberRefConverter = new MemberRefConverter(module);
}
public bool initialize() {
@ -86,26 +86,26 @@ namespace de4dot.code.deobfuscators.Babel_NET {
void initializeV10() {
reader.ReadInt16();
int methodNamesOffset = (int)reader.ReadInt64();
int typeReferencesOffset = (int)reader.ReadInt64();
int assemblyReferencesOffset = (int)reader.ReadInt64();
int typeRefsOffset = (int)reader.ReadInt64();
int assemblyRefsOffset = (int)reader.ReadInt64();
int stringsOffset = (int)reader.ReadInt64();
initializeStrings(stringsOffset);
initializeAssemblyNames(assemblyReferencesOffset);
initializeAssemblyNames(assemblyRefsOffset);
initializeMethodNames(methodNamesOffset);
initializeTypeReferences(typeReferencesOffset);
initializeTypeRefs(typeRefsOffset);
}
void initializeV55() {
int methodNamesOffset = (int)reader.ReadInt64() ^ METADATA_SIG;
int typeReferencesOffset = (int)reader.ReadInt64() ^ (METADATA_SIG << 1);
int assemblyReferencesOffset = (int)reader.ReadInt64() ^ ((METADATA_SIG << 1) + 1);
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(assemblyReferencesOffset);
initializeAssemblyNames(assemblyRefsOffset);
initializeMethodNames(methodNamesOffset);
initializeTypeReferences(typeReferencesOffset);
initializeTypeRefs(typeRefsOffset);
}
public void restore(string name, MethodDef method) {
@ -138,11 +138,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
body.ExceptionHandlers.Add(eh);
}
BabelMethodDefinition getMethod(string name) {
BabelMethodDef getMethod(string name) {
int offset = methodOffsets[name];
methodOffsets.Remove(name);
reader.Position = offset;
return new MethodDefinitionReader(this, reader).read();
return new MethodDefReader(this, reader).read();
}
public string readString() {
@ -150,7 +150,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
public TypeSig readTypeSig() {
return typeReferences[readVariableLengthInt32()];
return typeRefs[readVariableLengthInt32()];
}
public TypeSig[] readTypeSigs() {
@ -160,7 +160,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return refs;
}
public IField readFieldReference() {
public IField readFieldRef() {
var name = readString();
var declaringType = readTypeSig();
@ -171,7 +171,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
Utils.removeNewlines(declaringType)));
}
return memberReferenceConverter.convert(fields[0]);
return memberRefConverter.convert(fields[0]);
}
static List<FieldDef> getFields(TypeDef type, string name) {
@ -180,10 +180,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return new List<FieldDef>(type.FindFields(name));
}
public IMethod readMethodReference() {
var babelMethodRef = new MethodReferenceReader(this, reader).read();
public IMethod readMethodRef() {
var babelMethodRef = new MethodRefReader(this, reader).read();
var method = getMethodReference(babelMethodRef);
var method = getMethodRef(babelMethodRef);
if (method == null) {
throw new ApplicationException(string.Format("Could not find method '{0}' in type '{1}'",
Utils.removeNewlines(babelMethodRef.Name),
@ -198,7 +198,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return module.UpdateRowId(mr);
}
IMethod getMethodReference(BabelMethodreference babelMethodRef) {
IMethod getMethodRef(BabelMethodreference babelMethodRef) {
var declaringType = resolve(babelMethodRef.DeclaringType);
if (declaringType == null)
return null;
@ -221,10 +221,10 @@ namespace de4dot.code.deobfuscators.Babel_NET {
foreach (var method in declaringType.Methods) {
if (compareMethod(GenericArgsSubstitutor.create(method, gis, gim), babelMethodRef)) {
if (!babelMethodRef.IsGenericMethod)
methods.Add(memberReferenceConverter.convert(method));
methods.Add(memberRefConverter.convert(method));
else {
var gim2 = new GenericInstMethodSig(babelMethodRef.GenericArguments);
var ms = module.UpdateRowId(new MethodSpecUser(memberReferenceConverter.convert(method), gim2));
var ms = module.UpdateRowId(new MethodSpecUser(memberRefConverter.convert(method), gim2));
methods.Add(ms);
}
}
@ -329,39 +329,39 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
void initializeTypeReferences(int headerOffset) {
void initializeTypeRefs(int headerOffset) {
reader.Position = headerOffset;
if (reader.ReadInt32() != TYPEREFS_SIG)
throw new ApplicationException("Invalid typerefs sig");
int numTypeRefs = reader.ReadInt32();
typeReferences = new List<TypeSig>(numTypeRefs + 1);
typeReferences.Add(null);
typeRefs = new List<TypeSig>(numTypeRefs + 1);
typeRefs.Add(null);
var genericArgFixes = new Dictionary<GenericInstSig, List<int>>();
for (int i = 0; i < numTypeRefs; i++) {
TypeId typeId = (TypeId)reader.ReadByte();
switch (typeId) {
case TypeId.TypeRef:
typeReferences.Add(readTypeRef());
typeRefs.Add(readTypeRef());
break;
case TypeId.GenericInstance:
List<int> genericArgs;
var git = readGenericInstanceType(out genericArgs);
typeReferences.Add(git);
typeRefs.Add(git);
genericArgFixes[git] = genericArgs;
break;
case TypeId.Pointer:
typeReferences.Add(readPointerType());
typeRefs.Add(readPointerType());
break;
case TypeId.Array:
typeReferences.Add(readArrayType());
typeRefs.Add(readArrayType());
break;
case TypeId.ByRef:
typeReferences.Add(readByReferenceType());
typeRefs.Add(readByRefType());
break;
default:
@ -372,7 +372,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
foreach (var kv in genericArgFixes) {
var git = kv.Key;
foreach (var typeNum in kv.Value)
git.GenericArguments.Add(typeReferences[typeNum]);
git.GenericArguments.Add(typeRefs[typeNum]);
}
}
@ -381,13 +381,13 @@ namespace de4dot.code.deobfuscators.Babel_NET {
parseReflectionTypeName(readString(), out ns, out name);
var asmRef = assemblyNames[readVariableLengthInt32()];
var declaringType = readTypeSig();
var typeReference = new TypeRefUser(module, ns, name);
var typeRef = new TypeRefUser(module, ns, name);
if (declaringType != null)
typeReference.ResolutionScope = getTypeRef(declaringType);
typeRef.ResolutionScope = getTypeRef(declaringType);
else
typeReference.ResolutionScope = asmRef;
typeRef.ResolutionScope = asmRef;
return memberReferenceConverter.convert(typeReference);
return memberRefConverter.convert(typeRef);
}
TypeRef getTypeRef(TypeSig type) {
@ -469,7 +469,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return new ArraySig(typeSig, rank);
}
ByRefSig readByReferenceType() {
ByRefSig readByRefType() {
return new ByRefSig(readTypeSig());
}

View File

@ -23,14 +23,14 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
// Converts type references/definitions in one module to this module
class MemberReferenceConverter {
class MemberRefConverter {
ModuleDefMD module;
public ModuleDefMD Module {
get { return module; }
}
public MemberReferenceConverter(ModuleDefMD module) {
public MemberRefConverter(ModuleDefMD module) {
this.module = module;
}
@ -60,7 +60,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
public IField convert(IField fieldRef) {
if (isInOurModule(fieldRef))
return tryGetFieldDefinition(fieldRef);
return tryGetFieldDef(fieldRef);
return createImporter().Import(fieldRef);
}
@ -68,11 +68,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
if (!(methodRef is MemberRef || methodRef is MethodDef) || methodRef.MethodSig == null)
throw new ApplicationException("Invalid method reference type");
if (isInOurModule(methodRef))
return (IMethodDefOrRef)tryGetMethodDefinition(methodRef);
return (IMethodDefOrRef)tryGetMethodDef(methodRef);
return (IMethodDefOrRef)createImporter().Import(methodRef);
}
public IField tryGetFieldDefinition(IField fieldRef) {
public IField tryGetFieldDef(IField fieldRef) {
var fieldDef = fieldRef as FieldDef;
if (fieldDef != null)
return fieldDef;
@ -83,7 +83,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return DotNetUtils.getField(declaringType, fieldRef);
}
public IMethod tryGetMethodDefinition(IMethod methodRef) {
public IMethod tryGetMethodDef(IMethod methodRef) {
var methodDef = methodRef as MethodDef;
if (methodDef != null)
return methodDef;

View File

@ -45,11 +45,11 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
protected override IField ReadInlineField(Instruction instr) {
return imageReader.readFieldReference();
return imageReader.readFieldRef();
}
protected override IMethod ReadInlineMethod(Instruction instr) {
return imageReader.readMethodReference();
return imageReader.readMethodRef();
}
protected override MethodSig ReadInlineSig(Instruction instr) {
@ -63,8 +63,8 @@ namespace de4dot.code.deobfuscators.Babel_NET {
protected override ITokenOperand ReadInlineTok(Instruction instr) {
switch (reader.ReadByte()) {
case 0: return imageReader.readTypeSig().ToTypeDefOrRef();
case 1: return imageReader.readFieldReference();
case 2: return imageReader.readMethodReference();
case 1: return imageReader.readFieldRef();
case 2: return imageReader.readMethodRef();
default: throw new ApplicationException("Unknown token type");
}
}

View File

@ -42,7 +42,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
class BabelMethodDefinition : BabelMethodreference {
class BabelMethodDef : BabelMethodreference {
Parameter thisParameter;
public int Flags2 { get; set; }
@ -95,16 +95,16 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
class MethodReferenceReader {
class MethodRefReader {
ImageReader imageReader;
IBinaryReader reader;
BabelMethodreference bmr;
public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader)
public MethodRefReader(ImageReader imageReader, IBinaryReader reader)
: this(imageReader, reader, new BabelMethodreference()) {
}
public MethodReferenceReader(ImageReader imageReader, IBinaryReader reader, BabelMethodreference bmr) {
public MethodRefReader(ImageReader imageReader, IBinaryReader reader, BabelMethodreference bmr) {
this.imageReader = imageReader;
this.reader = reader;
this.bmr = bmr;
@ -133,19 +133,19 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
class MethodDefinitionReader {
MethodReferenceReader methodReferenceReader;
class MethodDefReader {
MethodRefReader methodRefReader;
MethodBodyReader methodBodyReader;
BabelMethodDefinition bmd;
BabelMethodDef bmd;
public MethodDefinitionReader(ImageReader imageReader, IBinaryReader reader) {
this.bmd = new BabelMethodDefinition();
this.methodReferenceReader = new MethodReferenceReader(imageReader, reader, bmd);
public MethodDefReader(ImageReader imageReader, IBinaryReader reader) {
this.bmd = new BabelMethodDef();
this.methodRefReader = new MethodRefReader(imageReader, reader, bmd);
this.methodBodyReader = new MethodBodyReader(imageReader, reader);
}
public BabelMethodDefinition read() {
methodReferenceReader.read();
public BabelMethodDef read() {
methodRefReader.read();
methodBodyReader.read(bmd.getRealParameters());
bmd.setBody(methodBodyReader);
return bmd;

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Babel_NET {
class ProxyCallFixer : ProxyCallFixer2 {
MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType> methodToType = new MethodDefinitionAndDeclaringTypeDict<ProxyCreatorType>();
MethodDefAndDeclaringTypeDict<ProxyCreatorType> methodToType = new MethodDefAndDeclaringTypeDict<ProxyCreatorType>();
public ProxyCallFixer(ModuleDefMD module)
: base(module) {

View File

@ -309,7 +309,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
return null;
}
class ReflectionToCecilMethodCreator {
class ReflectionToDot10MethodCreator {
MethodDef method;
List<Instruction> instructions = new List<Instruction>();
InstructionEmulator emulator;
@ -331,7 +331,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
get { return instructions; }
}
public ReflectionToCecilMethodCreator(MethodDef method) {
public ReflectionToDot10MethodCreator(MethodDef method) {
this.method = method;
this.emulator = new InstructionEmulator(method);
}
@ -439,7 +439,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
emulator.pop(); // the this ptr
addInstruction(new Instruction {
OpCode = opcode,
Operand = createCecilOperand(opcode, operand),
Operand = createDot10Operand(opcode, operand),
});
return true;
}
@ -449,7 +449,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
}
object createCecilOperand(OpCode opcode, Value op) {
object createDot10Operand(OpCode opcode, Value op) {
if (op is Int32Value)
return ((Int32Value)op).value;
if (op is StringValue)
@ -470,7 +470,7 @@ namespace de4dot.code.deobfuscators.Babel_NET {
}
static List<Instruction> getOffsetCalcInstructions(MethodDef method) {
var creator = new ReflectionToCecilMethodCreator(method);
var creator = new ReflectionToDot10MethodCreator(method);
creator.create();
var instrs = creator.Instructions;

View File

@ -21,7 +21,6 @@ using System;
using System.Collections.Generic;
using dot10.DotNet;
using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.CodeFort {
public class DeobfuscatorInfo : DeobfuscatorInfoBase {

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeFort {
class ProxyCallFixer : ProxyCallFixer3 {
MethodDefinitionAndDeclaringTypeDict<bool> proxyTargetMethods = new MethodDefinitionAndDeclaringTypeDict<bool>();
MethodDefAndDeclaringTypeDict<bool> proxyTargetMethods = new MethodDefAndDeclaringTypeDict<bool>();
TypeDef proxyMethodsType;
public TypeDef ProxyMethodsType {

View File

@ -19,11 +19,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using dot10.IO;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.CodeVeil {
class MethodsDecrypter {
@ -32,23 +31,22 @@ namespace de4dot.code.deobfuscators.CodeVeil {
interface IDecrypter {
void initialize(byte[] methodsData);
bool decrypt(BinaryReader fileDataReader, DumpedMethod dm);
bool decrypt(IBinaryReader fileDataReader, DumpedMethod dm);
}
class Decrypter : IDecrypter {
BinaryReader methodsDataReader;
IBinaryReader methodsDataReader;
public virtual void initialize(byte[] methodsData) {
methodsDataReader = new BinaryReader(new MemoryStream(methodsData));
methodsDataReader = MemoryImageStream.Create(methodsData);
}
public virtual bool decrypt(BinaryReader fileDataReader, DumpedMethod dm) {
public virtual bool decrypt(IBinaryReader fileDataReader, DumpedMethod dm) {
if (fileDataReader.ReadByte() != 0x2A)
return false; // Not a RET
int methodsDataOffset = DeobUtils.readVariableLengthInt32(fileDataReader);
methodsDataReader.BaseStream.Position = methodsDataOffset;
methodsDataReader.Position = fileDataReader.ReadCompressedUInt32();
dm.mhCodeSize = (uint)DeobUtils.readVariableLengthInt32(methodsDataReader);
dm.mhCodeSize = methodsDataReader.ReadCompressedUInt32();
dm.code = methodsDataReader.ReadBytes((int)dm.mhCodeSize);
if ((dm.mhFlags & 8) != 0)
dm.extraSections = MethodBodyParser.readExtraSections(methodsDataReader);
@ -126,46 +124,38 @@ namespace de4dot.code.deobfuscators.CodeVeil {
if (decrypter == null)
return false;
var peImage = new PeImage(fileData);
if (peImage.Sections.Length <= 0)
return false;
using (var peImage = new MyPEImage(fileData)) {
if (peImage.Sections.Count <= 0)
return false;
var methodsData = findMethodsData(peImage, fileData);
if (methodsData == null)
return false;
var methodsData = findMethodsData(peImage, fileData);
if (methodsData == null)
return false;
decrypter.initialize(methodsData);
decrypter.initialize(methodsData);
dumpedMethods = createDumpedMethods(peImage, fileData, methodsData);
if (dumpedMethods == null)
return false;
dumpedMethods = createDumpedMethods(peImage, fileData, methodsData);
if (dumpedMethods == null)
return false;
}
return true;
}
DumpedMethods createDumpedMethods(PeImage peImage, byte[] fileData, byte[] methodsData) {
DumpedMethods createDumpedMethods(MyPEImage peImage, byte[] fileData, byte[] methodsData) {
var dumpedMethods = new DumpedMethods();
var methodsDataReader = new BinaryReader(new MemoryStream(methodsData));
var fileDataReader = new BinaryReader(new MemoryStream(fileData));
var metadataTables = peImage.Cor20Header.createMetadataTables();
var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef);
uint methodDefOffset = methodDef.fileOffset;
for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) {
uint bodyRva = peImage.offsetReadUInt32(methodDefOffset);
if (bodyRva == 0)
continue;
uint bodyOffset = peImage.rvaToOffset(bodyRva);
var methodsDataReader = MemoryImageStream.Create(methodsData);
var fileDataReader = MemoryImageStream.Create(fileData);
var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
for (uint rid = 1; rid <= methodDef.Rows; rid++) {
var dm = new DumpedMethod();
dm.token = (uint)(0x06000001 + i);
dm.mdRVA = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[0].offset, methodDef.fields[0].size);
dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset);
dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset);
dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size);
dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size);
dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size);
peImage.readMethodTableRowTo(dm, rid);
if (dm.mdRVA == 0)
continue;
uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
byte b = peImage.offsetReadByte(bodyOffset);
uint codeOffset;
@ -187,7 +177,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
dm.mhLocalVarSigTok = peImage.offsetReadUInt32(bodyOffset + 8);
codeOffset = bodyOffset + (uint)(dm.mhFlags >> 12) * 4;
}
fileDataReader.BaseStream.Position = codeOffset;
fileDataReader.Position = codeOffset;
if (!decrypter.decrypt(fileDataReader, dm))
continue;
@ -202,14 +192,14 @@ namespace de4dot.code.deobfuscators.CodeVeil {
static byte[] initializeMethodEnd = new byte[] {
0x33, 0xC0, 0x40, 0x5E, 0x5F, 0x5A, 0x59, 0x5B, 0xC9, 0xC2,
};
byte[] findMethodsData(PeImage peImage, byte[] fileData) {
byte[] findMethodsData(MyPEImage peImage, byte[] fileData) {
var section = peImage.Sections[0];
var reader = new BinaryReader(new MemoryStream(fileData));
var reader = MemoryImageStream.Create(fileData);
const int RVA_EXECUTIVE_OFFSET = 1 * 4;
const int ENC_CODE_OFFSET = 6 * 4;
int lastOffset = (int)(section.pointerToRawData + section.sizeOfRawData);
int lastOffset = (int)(section.PointerToRawData + section.SizeOfRawData);
for (int offset = getStartOffset(peImage); offset < lastOffset; ) {
offset = findSig(fileData, offset, lastOffset, initializeMethodEnd);
if (offset < 0)
@ -229,13 +219,13 @@ namespace de4dot.code.deobfuscators.CodeVeil {
continue;
int relOffs = BitConverter.ToInt32(fileData, offset + ENC_CODE_OFFSET);
if (relOffs <= 0 || relOffs >= section.sizeOfRawData)
if (relOffs <= 0 || relOffs >= section.SizeOfRawData)
continue;
reader.BaseStream.Position = section.pointerToRawData + relOffs;
reader.Position = section.PointerToRawData + relOffs;
int size = DeobUtils.readVariableLengthInt32(reader);
int size = (int)reader.ReadCompressedUInt32();
int endOffset = relOffs + size;
if (endOffset < relOffs || endOffset > section.sizeOfRawData)
if (endOffset < relOffs || endOffset > section.SizeOfRawData)
continue;
return reader.ReadBytes(size);
@ -244,7 +234,7 @@ namespace de4dot.code.deobfuscators.CodeVeil {
return null;
}
int getStartOffset(PeImage peImage) {
int getStartOffset(MyPEImage peImage) {
int minOffset = int.MaxValue;
foreach (var rva in mainType.Rvas) {
int rvaOffs = (int)peImage.rvaToOffset((uint)rva);

View File

@ -21,7 +21,6 @@ using System;
using System.Collections.Generic;
using dot10.DotNet;
using de4dot.blocks;
using de4dot.PE;
namespace de4dot.code.deobfuscators.CodeWall {
public class DeobfuscatorInfo : DeobfuscatorInfoBase {
@ -164,10 +163,10 @@ namespace de4dot.code.deobfuscators.CodeWall {
return false;
byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module);
var peImage = new PeImage(fileData);
if (!methodsDecrypter.decrypt(peImage, ref dumpedMethods))
return false;
using (var peImage = new MyPEImage(fileData)) {
if (!methodsDecrypter.decrypt(peImage, ref dumpedMethods))
return false;
}
newFileData = fileData;
return true;

View File

@ -20,7 +20,6 @@
using System;
using dot10.DotNet;
using dot10.DotNet.Emit;
using de4dot.PE;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeWall {
@ -67,50 +66,33 @@ namespace de4dot.code.deobfuscators.CodeWall {
return false;
}
public bool decrypt(PeImage peImage, ref DumpedMethods dumpedMethods) {
public bool decrypt(MyPEImage peImage, ref DumpedMethods dumpedMethods) {
dumpedMethods = new DumpedMethods();
bool decrypted = false;
var metadataTables = peImage.Cor20Header.createMetadataTables();
var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef);
uint methodDefOffset = methodDef.fileOffset;
for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) {
uint bodyRva = peImage.offsetReadUInt32(methodDefOffset);
if (bodyRva == 0)
continue;
uint bodyOffset = peImage.rvaToOffset(bodyRva);
var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
for (uint rid = 1; rid <= methodDef.Rows; rid++) {
var dm = new DumpedMethod();
dm.token = (uint)(0x06000001 + i);
peImage.readMethodTableRowTo(dm, rid);
byte[] code, extraSections;
peImage.Reader.BaseStream.Position = bodyOffset;
var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out code, out extraSections);
if (code.Length < 6 || code[0] != 0x2A || code[1] != 0x2A)
if (dm.mdRVA == 0)
continue;
dm.code = code;
dm.extraSections = extraSections;
uint bodyOffset = peImage.rvaToOffset(dm.mdRVA);
int seed = BitConverter.ToInt32(code, 2);
Array.Copy(newCodeHeader, code, newCodeHeader.Length);
peImage.Reader.Position = bodyOffset;
var mbHeader = MethodBodyParser.parseMethodBody(peImage.Reader, out dm.code, out dm.extraSections);
peImage.updateMethodHeaderInfo(dm, mbHeader);
if (dm.code.Length < 6 || dm.code[0] != 0x2A || dm.code[1] != 0x2A)
continue;
int seed = BitConverter.ToInt32(dm.code, 2);
Array.Copy(newCodeHeader, dm.code, newCodeHeader.Length);
if (seed == 0)
decrypt(code);
decrypt(dm.code);
else
decrypt(code, seed);
dm.mdRVA = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[0].offset, methodDef.fields[0].size);
dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset);
dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset);
dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size);
dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size);
dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size);
dm.mhFlags = mbHeader.flags;
dm.mhMaxStack = mbHeader.maxStack;
dm.mhCodeSize = (uint)dm.code.Length;
dm.mhLocalVarSigTok = mbHeader.localVarSigTok;
decrypt(dm.code, seed);
dumpedMethods.add(dm);
decrypted = true;

View File

@ -29,7 +29,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.CodeWall {
class StringDecrypter {
ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<StringEncrypterInfo> stringEncrypterInfos = new MethodDefinitionAndDeclaringTypeDict<StringEncrypterInfo>();
MethodDefAndDeclaringTypeDict<StringEncrypterInfo> stringEncrypterInfos = new MethodDefAndDeclaringTypeDict<StringEncrypterInfo>();
Version version;
public enum Version {

View File

@ -36,7 +36,7 @@ namespace de4dot.code.deobfuscators.CryptoObfuscator {
public void read(MethodDef method) {
this.parameters = method.Parameters;
this.locals = getLocals(method);
SetLocals(getLocals(method));
maxStackSize = (ushort)reader.ReadInt32();
ReadInstructionsNumBytes(reader.ReadUInt32());

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.DeepSea {
class ArrayBlockState {
ModuleDefMD module;
FieldDefinitionAndDeclaringTypeDict<FieldInfo> fieldToInfo = new FieldDefinitionAndDeclaringTypeDict<FieldInfo>();
FieldDefAndDeclaringTypeDict<FieldInfo> fieldToInfo = new FieldDefAndDeclaringTypeDict<FieldInfo>();
public class FieldInfo {
public readonly FieldDef field;

View File

@ -27,9 +27,9 @@ namespace de4dot.code.deobfuscators.DeepSea {
// DS 4.x can move fields from a class to a struct. This class restores the fields.
class FieldsRestorer {
ModuleDefMD module;
TypeDefinitionDict<List<TypeDef>> structToOwners = new TypeDefinitionDict<List<TypeDef>>();
FieldDefinitionAndDeclaringTypeDict<bool> structFieldsToFix = new FieldDefinitionAndDeclaringTypeDict<bool>();
TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDef>> typeToFieldsDict = new TypeDefinitionDict<FieldDefinitionAndDeclaringTypeDict<FieldDef>>();
TypeDefDict<List<TypeDef>> structToOwners = new TypeDefDict<List<TypeDef>>();
FieldDefAndDeclaringTypeDict<bool> structFieldsToFix = new FieldDefAndDeclaringTypeDict<bool>();
TypeDefDict<FieldDefAndDeclaringTypeDict<FieldDef>> typeToFieldsDict = new TypeDefDict<FieldDefAndDeclaringTypeDict<FieldDef>>();
public List<TypeDef> FieldStructs {
get {
@ -76,7 +76,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
break;
}
var fieldsDict = new FieldDefinitionAndDeclaringTypeDict<FieldDef>();
var fieldsDict = new FieldDefAndDeclaringTypeDict<FieldDef>();
typeToFieldsDict.add(ownerType, fieldsDict);
foreach (var structField in structType.Fields) {
var newField = module.UpdateRowId(new FieldDefUser(structField.Name, structField.FieldSig.Clone(), structField.Attributes));
@ -144,7 +144,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
IEnumerable<FieldDef> getPossibleFields(TypeDef type) {
var typeToFields = new TypeDefinitionDict<List<FieldDef>>();
var typeToFields = new TypeDefDict<List<FieldDef>>();
foreach (var field in type.Fields) {
if (field.Attributes != FieldAttributes.Private)
continue;

View File

@ -27,7 +27,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.DeepSea {
class StringDecrypter {
ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<IDecrypterInfo> methodToInfo = new MethodDefinitionAndDeclaringTypeDict<IDecrypterInfo>();
MethodDefAndDeclaringTypeDict<IDecrypterInfo> methodToInfo = new MethodDefAndDeclaringTypeDict<IDecrypterInfo>();
DecrypterVersion version = DecrypterVersion.Unknown;
public enum DecrypterVersion {
@ -45,12 +45,12 @@ namespace de4dot.code.deobfuscators.DeepSea {
}
static short[] findKey(MethodDef initMethod, FieldDef keyField) {
var fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
var fields = new FieldDefAndDeclaringTypeDict<bool>();
fields.add(keyField, true);
return findKey(initMethod, fields);
}
static short[] findKey(MethodDef initMethod, FieldDefinitionAndDeclaringTypeDict<bool> fields) {
static short[] findKey(MethodDef initMethod, FieldDefAndDeclaringTypeDict<bool> fields) {
var instrs = initMethod.Body.Instructions;
for (int i = 0; i < instrs.Count - 2; i++) {
var ldci4 = instrs[i];
@ -153,7 +153,7 @@ namespace de4dot.code.deobfuscators.DeepSea {
MethodDef cctor;
int magic;
int arg1, arg2;
FieldDefinitionAndDeclaringTypeDict<bool> fields;
FieldDefAndDeclaringTypeDict<bool> fields;
ArrayInfo arrayInfo;
ushort[] encryptedData;
short[] key;
@ -206,8 +206,8 @@ namespace de4dot.code.deobfuscators.DeepSea {
return count >= 2;
}
static FieldDefinitionAndDeclaringTypeDict<bool> getFields(MethodDef method) {
var fields = new FieldDefinitionAndDeclaringTypeDict<bool>();
static FieldDefAndDeclaringTypeDict<bool> getFields(MethodDef method) {
var fields = new FieldDefAndDeclaringTypeDict<bool>();
foreach (var instr in method.Body.Instructions) {
if (instr.OpCode.Code != Code.Ldsfld && instr.OpCode.Code != Code.Stsfld)
continue;

View File

@ -189,19 +189,6 @@ namespace de4dot.code.deobfuscators {
return null;
}
//TODO: Remove this method
public static int readVariableLengthInt32(BinaryReader reader) {
byte b = reader.ReadByte();
if ((b & 0x80) == 0)
return b;
if ((b & 0x40) == 0)
return (((int)b & 0x3F) << 8) + reader.ReadByte();
return (((int)b & 0x3F) << 24) +
((int)reader.ReadByte() << 16) +
((int)reader.ReadByte() << 8) +
reader.ReadByte();
}
public static int readVariableLengthInt32(byte[] data, ref int index) {
byte b = data[index++];
if ((b & 0x80) == 0)

View File

@ -229,8 +229,8 @@ namespace de4dot.code.deobfuscators {
public abstract IEnumerable<int> getStringDecrypterMethods();
class MethodCallRemover {
Dictionary<string, MethodDefinitionAndDeclaringTypeDict<bool>> methodNameInfos = new Dictionary<string, MethodDefinitionAndDeclaringTypeDict<bool>>();
MethodDefinitionAndDeclaringTypeDict<MethodDefinitionAndDeclaringTypeDict<bool>> methodRefInfos = new MethodDefinitionAndDeclaringTypeDict<MethodDefinitionAndDeclaringTypeDict<bool>>();
Dictionary<string, MethodDefAndDeclaringTypeDict<bool>> methodNameInfos = new Dictionary<string, MethodDefAndDeclaringTypeDict<bool>>();
MethodDefAndDeclaringTypeDict<MethodDefAndDeclaringTypeDict<bool>> methodRefInfos = new MethodDefAndDeclaringTypeDict<MethodDefAndDeclaringTypeDict<bool>>();
void checkMethod(IMethod methodToBeRemoved) {
var sig = methodToBeRemoved.MethodSig;
@ -245,9 +245,9 @@ namespace de4dot.code.deobfuscators {
return;
checkMethod(methodToBeRemoved);
MethodDefinitionAndDeclaringTypeDict<bool> dict;
MethodDefAndDeclaringTypeDict<bool> dict;
if (!methodNameInfos.TryGetValue(method, out dict))
methodNameInfos[method] = dict = new MethodDefinitionAndDeclaringTypeDict<bool>();
methodNameInfos[method] = dict = new MethodDefAndDeclaringTypeDict<bool>();
dict.add(methodToBeRemoved, true);
}
@ -258,7 +258,7 @@ namespace de4dot.code.deobfuscators {
var dict = methodRefInfos.find(method);
if (dict == null)
methodRefInfos.add(method, dict = new MethodDefinitionAndDeclaringTypeDict<bool>());
methodRefInfos.add(method, dict = new MethodDefAndDeclaringTypeDict<bool>());
dict.add(methodToBeRemoved, true);
}
@ -270,7 +270,7 @@ namespace de4dot.code.deobfuscators {
}
void removeAll(IList<Block> allBlocks, Blocks blocks, string method) {
MethodDefinitionAndDeclaringTypeDict<bool> info;
MethodDefAndDeclaringTypeDict<bool> info;
if (!methodNameInfos.TryGetValue(method, out info))
return;
@ -285,7 +285,7 @@ namespace de4dot.code.deobfuscators {
removeCalls(allBlocks, blocks, info);
}
void removeCalls(IList<Block> allBlocks, Blocks blocks, MethodDefinitionAndDeclaringTypeDict<bool> info) {
void removeCalls(IList<Block> allBlocks, Blocks blocks, MethodDefAndDeclaringTypeDict<bool> info) {
var instrsToDelete = new List<int>();
foreach (var block in allBlocks) {
instrsToDelete.Clear();
@ -782,5 +782,13 @@ namespace de4dot.code.deobfuscators {
protected static int toInt32(bool b) {
return b ? 1 : 0;
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
}
}
}

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Dotfuscator {
class StringDecrypter {
ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<StringDecrypterInfo> stringDecrypterMethods = new MethodDefinitionAndDeclaringTypeDict<StringDecrypterInfo>();
MethodDefAndDeclaringTypeDict<StringDecrypterInfo> stringDecrypterMethods = new MethodDefAndDeclaringTypeDict<StringDecrypterInfo>();
public class StringDecrypterInfo {
public MethodDef method;

View File

@ -24,7 +24,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators {
class ExceptionLoggerRemover {
MethodDefinitionAndDeclaringTypeDict<bool> exceptionLoggerMethods = new MethodDefinitionAndDeclaringTypeDict<bool>();
MethodDefAndDeclaringTypeDict<bool> exceptionLoggerMethods = new MethodDefAndDeclaringTypeDict<bool>();
public int NumRemovedExceptionLoggers { get; set; }

View File

@ -32,7 +32,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
TypeDef delegateType;
TypeDef delegateInitType;
protected BinaryReader decryptedReader;
MethodDefinitionAndDeclaringTypeDict<Info> decrypterMethods = new MethodDefinitionAndDeclaringTypeDict<Info>();
MethodDefAndDeclaringTypeDict<Info> decrypterMethods = new MethodDefAndDeclaringTypeDict<Info>();
protected class Info {
public MethodDef method;
@ -66,7 +66,7 @@ namespace de4dot.code.deobfuscators.Goliath_NET {
public IEnumerable<TypeDef> DecrypterTypes {
get {
var types = new TypeDefinitionDict<TypeDef>();
var types = new TypeDefDict<TypeDef>();
foreach (var info in decrypterMethods.getValues()) {
if (info.referenced)
types.add(info.method.DeclaringType, info.method.DeclaringType);

View File

@ -25,7 +25,7 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators.Goliath_NET {
class LocalsRestorer {
ModuleDefMD module;
TypeDefinitionDict<Info> typeToInfo = new TypeDefinitionDict<Info>();
TypeDefDict<Info> typeToInfo = new TypeDefDict<Info>();
class Info {
public TypeDef type;

View File

@ -52,7 +52,7 @@ namespace de4dot.code.deobfuscators {
RenameResourceKeys = 2,
}
public interface IDeobfuscator : INameChecker {
public interface IDeobfuscator : INameChecker, IDisposable {
string Type { get; }
string TypeLong { get; }
string Name { get; }

View File

@ -243,7 +243,7 @@ namespace de4dot.code.deobfuscators.ILProtector {
}
static void restoreMethod(MethodDef method, MethodReader methodReader) {
// body.MaxStackSize = <let Mono.Cecil calculate this>
// body.MaxStackSize = <let dot10 calculate this>
method.Body.InitLocals = methodReader.InitLocals;
methodReader.RestoreMethod(method);
}

View File

@ -44,9 +44,9 @@ namespace de4dot.code.deobfuscators {
MemberRef createInitializeArrayMethod() {
if (initializeArrayMethod == null) {
var runtimeHelpersType = DotNetUtils.findOrCreateTypeReference(module, module.CorLibTypes.AssemblyRef, "System.Runtime.CompilerServices", "RuntimeHelpers", false);
var systemArrayType = DotNetUtils.findOrCreateTypeReference(module, module.CorLibTypes.AssemblyRef, "System", "Array", false);
var runtimeFieldHandleType = DotNetUtils.findOrCreateTypeReference(module, module.CorLibTypes.AssemblyRef, "System", "RuntimeFieldHandle", true);
var runtimeHelpersType = DotNetUtils.findOrCreateTypeRef(module, module.CorLibTypes.AssemblyRef, "System.Runtime.CompilerServices", "RuntimeHelpers", false);
var systemArrayType = DotNetUtils.findOrCreateTypeRef(module, module.CorLibTypes.AssemblyRef, "System", "Array", false);
var runtimeFieldHandleType = DotNetUtils.findOrCreateTypeRef(module, module.CorLibTypes.AssemblyRef, "System", "RuntimeFieldHandle", true);
var methodSig = MethodSig.CreateStatic(module.CorLibTypes.Void, systemArrayType, runtimeFieldHandleType);
initializeArrayMethod = module.UpdateRowId(new MemberRefUser(module, "InitializeArray", methodSig, runtimeHelpersType.TypeDefOrRef));
}
@ -96,7 +96,7 @@ namespace de4dot.code.deobfuscators {
return arrayType;
if (valueType == null)
valueType = DotNetUtils.findOrCreateTypeReference(module, module.CorLibTypes.AssemblyRef, "System", "ValueType", false);
valueType = DotNetUtils.findOrCreateTypeRef(module, module.CorLibTypes.AssemblyRef, "System", "ValueType", false);
arrayType = new TypeDefUser("", string.Format("__StaticArrayInitTypeSize={0}", size), valueType.TypeDefOrRef);
module.UpdateRowId(arrayType);
arrayType.Attributes = TypeAttributes.NestedPrivate | TypeAttributes.ExplicitLayout |

View File

@ -21,8 +21,8 @@ using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using dot10.PE;
using dot10.DotNet;
using de4dot.PE;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.MPRESS {
@ -159,7 +159,7 @@ namespace de4dot.code.deobfuscators.MPRESS {
if (checkMethods(type, methods_v1x)) {
var lfMethod = DotNetUtils.getMethod(type, "System.Boolean", "(System.String,System.Byte[]&)");
if (lfMethod != null) {
if (DeobUtils.hasInteger(lfMethod, (int)Machine.amd64))
if (DeobUtils.hasInteger(lfMethod, (int)Machine.AMD64))
return Version.V218;
return Version.V1x_217;
}
@ -194,37 +194,39 @@ namespace de4dot.code.deobfuscators.MPRESS {
return false;
byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module);
var peImage = new PeImage(fileData);
var section = peImage.Sections[peImage.Sections.Length - 1];
var offset = section.pointerToRawData;
offset += 16;
byte[] decompressed;
using (var peImage = new MyPEImage(fileData)) {
var section = peImage.Sections[peImage.Sections.Count - 1];
var offset = section.PointerToRawData;
offset += 16;
byte[] decompressed, compressed;
int compressedLen;
switch (version) {
case Version.V0x:
compressedLen = fileData.Length - (int)offset;
compressed = peImage.offsetReadBytes(offset, compressedLen);
decompressed = Lzmat.decompress_old(compressed);
if (decompressed == null)
throw new ApplicationException("LZMAT decompression failed");
break;
byte[] compressed;
int compressedLen;
switch (version) {
case Version.V0x:
compressedLen = fileData.Length - (int)offset;
compressed = peImage.offsetReadBytes(offset, compressedLen);
decompressed = Lzmat.decompress_old(compressed);
if (decompressed == null)
throw new ApplicationException("LZMAT decompression failed");
break;
case Version.V1x_217:
case Version.V218:
if (peImage.FileHeader.machine == Machine.amd64 && version == Version.V218)
offset = section.pointerToRawData + section.virtualSize;
int decompressedLen = (int)peImage.offsetReadUInt32(offset);
compressedLen = fileData.Length - (int)offset - 4;
compressed = peImage.offsetReadBytes(offset + 4, compressedLen);
decompressed = new byte[decompressedLen];
uint decompressedLen2;
if (Lzmat.decompress(decompressed, out decompressedLen2, compressed) != LzmatStatus.OK)
throw new ApplicationException("LZMAT decompression failed");
break;
case Version.V1x_217:
case Version.V218:
if (peImage.PEImage.ImageNTHeaders.FileHeader.Machine == Machine.AMD64 && version == Version.V218)
offset = section.PointerToRawData + section.VirtualSize;
int decompressedLen = (int)peImage.offsetReadUInt32(offset);
compressedLen = fileData.Length - (int)offset - 4;
compressed = peImage.offsetReadBytes(offset + 4, compressedLen);
decompressed = new byte[decompressedLen];
uint decompressedLen2;
if (Lzmat.decompress(decompressed, out decompressedLen2, compressed) != LzmatStatus.OK)
throw new ApplicationException("LZMAT decompression failed");
break;
default:
throw new ApplicationException("Unknown MPRESS version");
default:
throw new ApplicationException("Unknown MPRESS version");
}
}
newFileData = decompressed;

View File

@ -17,22 +17,27 @@
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using de4dot.PE;
using System;
namespace de4dot.code.deobfuscators.MaxtoCode {
class DecrypterInfo {
class DecrypterInfo : IDisposable {
public MainType mainType;
public readonly PeImage peImage;
public readonly MyPEImage peImage;
public readonly PeHeader peHeader;
public readonly McKey mcKey;
public readonly byte[] fileData;
public DecrypterInfo(MainType mainType, byte[] fileData) {
this.mainType = mainType;
this.peImage = new PeImage(fileData);
this.peImage = new MyPEImage(fileData);
this.peHeader = new PeHeader(mainType, peImage);
this.mcKey = new McKey(peImage, peHeader);
this.fileData = fileData;
}
public void Dispose() {
if (peImage != null)
peImage.Dispose();
}
}
}

View File

@ -120,10 +120,18 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
newOne.setModule(module);
newOne.mainType = new MainType(module, mainType);
newOne.decrypterInfo = decrypterInfo;
newOne.decrypterInfo.mainType = newOne.mainType;
decrypterInfo = null;
if (newOne.decrypterInfo != null)
newOne.decrypterInfo.mainType = newOne.mainType;
return newOne;
}
void freePEImage() {
if (decrypterInfo != null)
decrypterInfo.Dispose();
decrypterInfo = null;
}
public override void deobfuscateBegin() {
base.deobfuscateBegin();
@ -134,6 +142,8 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
staticStringInliner.add(stringDecrypter.Method, (method, gim, args) => stringDecrypter.decrypt((uint)args[0]));
DeobfuscatedFile.stringDecryptersAdded();
}
else
freePEImage();
foreach (var method in mainType.InitMethods)
addCctorInitCallToBeRemoved(method);
@ -142,6 +152,11 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
removeInvalidResources();
}
public override void deobfuscateEnd() {
freePEImage();
base.deobfuscateEnd();
}
static Encoding getEncoding(int cp) {
try {
return Encoding.GetEncoding(cp);
@ -235,5 +250,11 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
list.Add(stringDecrypter.Method.MDToken.ToInt32());
return list;
}
protected override void Dispose(bool disposing) {
if (disposing)
freePEImage();
base.Dispose(disposing);
}
}
}

View File

@ -19,7 +19,6 @@
using System;
using System.IO;
using de4dot.PE;
namespace de4dot.code.deobfuscators.MaxtoCode {
class McKey {
@ -30,7 +29,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
get { return data[index]; }
}
public McKey(PeImage peImage, PeHeader peHeader) {
public McKey(MyPEImage peImage, PeHeader peHeader) {
this.peHeader = peHeader;
try {
this.data = peImage.readBytes(peHeader.getMcKeyRva(), 0x2000);

View File

@ -21,7 +21,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using de4dot.PE;
using dot10.IO;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.MaxtoCode {
@ -31,7 +31,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
class MethodInfos {
MainType mainType;
PeImage peImage;
MyPEImage peImage;
PeHeader peHeader;
McKey mcKey;
uint structSize;
@ -61,7 +61,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
}
}
public MethodInfos(MainType mainType, PeImage peImage, PeHeader peHeader, McKey mcKey) {
public MethodInfos(MainType mainType, MyPEImage peImage, PeHeader peHeader, McKey mcKey) {
this.mainType = mainType;
this.peImage = peImage;
this.peHeader = peHeader;
@ -463,55 +463,21 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
var methodInfos = new MethodInfos(decrypterInfo.mainType, peImage, decrypterInfo.peHeader, decrypterInfo.mcKey);
methodInfos.initializeInfos();
var metadataTables = peImage.Cor20Header.createMetadataTables();
var methodDef = metadataTables.getMetadataType(MetadataIndex.iMethodDef);
uint methodDefOffset = methodDef.fileOffset;
for (int i = 0; i < methodDef.rows; i++, methodDefOffset += methodDef.totalSize) {
uint bodyRva = peImage.offsetReadUInt32(methodDefOffset);
if (bodyRva == 0)
continue;
var methodDef = peImage.DotNetFile.MetaData.TablesStream.MethodTable;
for (uint rid = 1; rid <= methodDef.Rows; rid++) {
var dm = new DumpedMethod();
peImage.readMethodTableRowTo(dm, rid);
var info = methodInfos.lookup(bodyRva);
var info = methodInfos.lookup(dm.mdRVA);
if (info == null)
continue;
uint bodyOffset = peImage.rvaToOffset(bodyRva);
ushort magic = peImage.offsetReadUInt16(bodyOffset);
ushort magic = peImage.readUInt16(dm.mdRVA);
if (magic != 0xFFF3)
continue;
var dm = new DumpedMethod();
dm.token = (uint)(0x06000001 + i);
dm.mdRVA = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[0].offset, methodDef.fields[0].size);
dm.mdImplFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[1].offset);
dm.mdFlags = peImage.offsetReadUInt16(methodDefOffset + (uint)methodDef.fields[2].offset);
dm.mdName = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[3].offset, methodDef.fields[3].size);
dm.mdSignature = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[4].offset, methodDef.fields[4].size);
dm.mdParamList = peImage.offsetRead(methodDefOffset + (uint)methodDef.fields[5].offset, methodDef.fields[5].size);
var reader = new BinaryReader(new MemoryStream(info.body));
byte b = reader.ReadByte();
if ((b & 3) == 2) {
dm.mhFlags = 2;
dm.mhMaxStack = 8;
dm.mhCodeSize = (uint)(b >> 2);
dm.mhLocalVarSigTok = 0;
}
else {
reader.BaseStream.Position--;
dm.mhFlags = reader.ReadUInt16();
dm.mhMaxStack = reader.ReadUInt16();
dm.mhCodeSize = reader.ReadUInt32();
dm.mhLocalVarSigTok = reader.ReadUInt32();
uint codeOffset = (uint)(dm.mhFlags >> 12) * 4;
reader.BaseStream.Position += codeOffset - 12;
}
dm.code = reader.ReadBytes((int)dm.mhCodeSize);
if ((dm.mhFlags & 8) != 0) {
reader.BaseStream.Position = (reader.BaseStream.Position + 3) & ~3;
dm.extraSections = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
}
var mbHeader = MethodBodyParser.parseMethodBody(MemoryImageStream.Create(info.body), out dm.code, out dm.extraSections);
peImage.updateMethodHeaderInfo(dm, mbHeader);
dumpedMethods.add(dm);
}
@ -529,8 +495,8 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
uint resourceSize = peHeader.readUInt32(0x0E14) ^ mcKey.readUInt32(0x00AA);
if (resourceRva == 0 || resourceSize == 0)
return;
if (resourceRva != peImage.Cor20Header.resources.virtualAddress ||
resourceSize != peImage.Cor20Header.resources.size) {
if (resourceRva != (uint)peImage.Cor20Header.Resources.VirtualAddress ||
resourceSize != peImage.Cor20Header.Resources.Size) {
Logger.w("Invalid resource RVA and size found");
}
@ -551,10 +517,10 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
uint usHeapSize = peHeader.readUInt32(0x0E04) ^ mcKey.readUInt32(0x0082);
if (usHeapRva == 0 || usHeapSize == 0)
return;
var usHeap = peImage.Cor20Header.metadata.getStream("#US");
if (usHeap == null ||
peImage.rvaToOffset(usHeapRva) != usHeap.fileOffset ||
usHeapSize != usHeap.Length) {
var usHeap = peImage.DotNetFile.MetaData.USStream;
if (usHeap.StartOffset == 0 || // Start offset is 0 if it's not present in the file
peImage.rvaToOffset(usHeapRva) != (uint)usHeap.StartOffset ||
usHeapSize != (uint)(usHeap.EndOffset - usHeap.StartOffset)) {
Logger.w("Invalid #US heap RVA and size found");
}

View File

@ -18,7 +18,6 @@
*/
using System;
using de4dot.PE;
namespace de4dot.code.deobfuscators.MaxtoCode {
enum EncryptionVersion {
@ -40,7 +39,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
get { return version; }
}
public PeHeader(MainType mainType, PeImage peImage) {
public PeHeader(MainType mainType, MyPEImage peImage) {
uint headerOffset;
version = getHeaderOffsetAndVersion(peImage, out headerOffset);
headerData = peImage.offsetReadBytes(headerOffset, 0x1000);
@ -58,7 +57,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return BitConverter.ToUInt32(headerData, offset);
}
static EncryptionVersion getHeaderOffsetAndVersion(PeImage peImage, out uint headerOffset) {
static EncryptionVersion getHeaderOffsetAndVersion(MyPEImage peImage, out uint headerOffset) {
headerOffset = 0;
var version = getVersion(peImage, headerOffset);
@ -69,8 +68,8 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
if (section == null)
return EncryptionVersion.Unknown;
headerOffset = section.pointerToRawData;
uint end = section.pointerToRawData + section.sizeOfRawData - 0x1000 + 1;
headerOffset = section.PointerToRawData;
uint end = section.PointerToRawData + section.SizeOfRawData - 0x1000 + 1;
while (headerOffset < end) {
version = getVersion(peImage, headerOffset);
if (version != EncryptionVersion.Unknown)
@ -81,7 +80,7 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
return EncryptionVersion.Unknown;
}
static EncryptionVersion getVersion(PeImage peImage, uint headerOffset) {
static EncryptionVersion getVersion(MyPEImage peImage, uint headerOffset) {
uint m1lo = peImage.offsetReadUInt32(headerOffset + 0x900);
uint m1hi = peImage.offsetReadUInt32(headerOffset + 0x904);

View File

@ -23,11 +23,11 @@ using dot10.DotNet;
using de4dot.blocks;
namespace de4dot.code.deobfuscators {
class MemberReferenceBuilder {
class MemberRefBuilder {
ModuleDefMD module;
Dictionary<TypeSig, TypeSig> createdTypes = new Dictionary<TypeSig, TypeSig>(TypeEqualityComparer.Instance);
public MemberReferenceBuilder(ModuleDefMD module) {
public MemberRefBuilder(ModuleDefMD module) {
this.module = module;
}
@ -108,7 +108,7 @@ namespace de4dot.code.deobfuscators {
}
public ClassSig type(string ns, string name, string asmSimpleName) {
return type(ns, name, findAssemblyReference(asmSimpleName));
return type(ns, name, findAssemblyRef(asmSimpleName));
}
public ClassSig type(string ns, string name) {
@ -120,7 +120,7 @@ namespace de4dot.code.deobfuscators {
}
public ValueTypeSig valueType(string ns, string name, string asmSimpleName) {
return valueType(ns, name, findAssemblyReference(asmSimpleName));
return valueType(ns, name, findAssemblyRef(asmSimpleName));
}
public ValueTypeSig valueType(string ns, string name) {
@ -173,7 +173,7 @@ namespace de4dot.code.deobfuscators {
return module.UpdateRowId(new MemberRefUser(module, name, sig, declaringType));
}
AssemblyRef findAssemblyReference(string asmSimpleName) {
AssemblyRef findAssemblyRef(string asmSimpleName) {
var asmRef = module.GetAssemblyRef(asmSimpleName);
if (asmRef == null)
throw new ApplicationException(string.Format("Could not find assembly {0} in assembly references", asmSimpleName));

View File

@ -19,6 +19,7 @@
using System;
using System.IO;
using dot10.IO;
namespace de4dot.code.deobfuscators {
[Serializable]
@ -39,7 +40,7 @@ namespace de4dot.code.deobfuscators {
}
static class MethodBodyParser {
public static MethodBodyHeader parseMethodBody(BinaryReader reader, out byte[] code, out byte[] extraSections) {
public static MethodBodyHeader parseMethodBody(IBinaryReader reader, out byte[] code, out byte[] extraSections) {
try {
return parseMethodBody2(reader, out code, out extraSections);
}
@ -49,14 +50,10 @@ namespace de4dot.code.deobfuscators {
}
public static bool verify(byte[] data) {
return verify(new BinaryReader(new MemoryStream(data)));
return verify(MemoryImageStream.Create(data));
}
public static bool verify(Stream data) {
return verify(new BinaryReader(data));
}
public static bool verify(BinaryReader reader) {
public static bool verify(IBinaryReader reader) {
try {
byte[] code, extraSections;
parseMethodBody(reader, out code, out extraSections);
@ -67,7 +64,7 @@ namespace de4dot.code.deobfuscators {
}
}
static MethodBodyHeader parseMethodBody2(BinaryReader reader, out byte[] code, out byte[] extraSections) {
static MethodBodyHeader parseMethodBody2(IBinaryReader reader, out byte[] code, out byte[] extraSections) {
var mbHeader = new MethodBodyHeader();
uint codeOffset;
@ -95,7 +92,7 @@ namespace de4dot.code.deobfuscators {
else
throw new InvalidMethodBody();
if (mbHeader.codeSize + codeOffset > reader.BaseStream.Length)
if (mbHeader.codeSize + codeOffset > reader.Length)
throw new InvalidMethodBody();
code = reader.ReadBytes((int)mbHeader.codeSize);
@ -107,11 +104,11 @@ namespace de4dot.code.deobfuscators {
return mbHeader;
}
static void align(BinaryReader reader, int alignment) {
reader.BaseStream.Position = (reader.BaseStream.Position + alignment - 1) & ~(alignment - 1);
static void align(IBinaryReader reader, int alignment) {
reader.Position = (reader.Position + alignment - 1) & ~(alignment - 1);
}
public static byte[] readExtraSections(BinaryReader reader) {
public static byte[] readExtraSections(IBinaryReader reader) {
try {
return readExtraSections2(reader);
}
@ -120,16 +117,16 @@ namespace de4dot.code.deobfuscators {
}
}
static byte[] readExtraSections2(BinaryReader reader) {
static byte[] readExtraSections2(IBinaryReader reader) {
align(reader, 4);
int startPos = (int)reader.BaseStream.Position;
int startPos = (int)reader.Position;
parseSection(reader);
int size = (int)reader.BaseStream.Position - startPos;
reader.BaseStream.Position = startPos;
int size = (int)reader.Position - startPos;
reader.Position = startPos;
return reader.ReadBytes(size);
}
static void parseSection(BinaryReader reader) {
static void parseSection(IBinaryReader reader) {
byte flags;
do {
align(reader, 4);
@ -141,20 +138,20 @@ namespace de4dot.code.deobfuscators {
throw new InvalidMethodBody("Invalid bits set");
if ((flags & 0x40) != 0) {
reader.BaseStream.Position--;
reader.Position--;
int num = (int)(reader.ReadUInt32() >> 8) / 24;
reader.BaseStream.Position += num * 24;
reader.Position += num * 24;
}
else {
int num = reader.ReadByte() / 12;
reader.BaseStream.Position += 2 + num * 12;
reader.Position += 2 + num * 12;
}
} while ((flags & 0x80) != 0);
}
static byte peek(BinaryReader reader) {
static byte peek(IBinaryReader reader) {
byte b = reader.ReadByte();
reader.BaseStream.Position--;
reader.Position--;
return b;
}
}

View File

@ -24,9 +24,9 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators {
class MethodCallRestorerBase {
protected MemberReferenceBuilder builder;
protected MemberRefBuilder builder;
protected ModuleDefMD module;
MethodDefinitionAndDeclaringTypeDict<NewMethodInfo> oldToNewMethod = new MethodDefinitionAndDeclaringTypeDict<NewMethodInfo>();
MethodDefAndDeclaringTypeDict<NewMethodInfo> oldToNewMethod = new MethodDefAndDeclaringTypeDict<NewMethodInfo>();
class NewMethodInfo {
public OpCode opCode;
@ -40,7 +40,7 @@ namespace de4dot.code.deobfuscators {
public MethodCallRestorerBase(ModuleDefMD module) {
this.module = module;
this.builder = new MemberReferenceBuilder(module);
this.builder = new MemberRefBuilder(module);
}
public void createGetManifestResourceStream1(MethodDef oldMethod) {

View File

@ -23,8 +23,8 @@ using de4dot.blocks;
namespace de4dot.code.deobfuscators {
class MethodCollection {
TypeDefinitionDict<bool> types = new TypeDefinitionDict<bool>();
MethodDefinitionAndDeclaringTypeDict<bool> methods = new MethodDefinitionAndDeclaringTypeDict<bool>();
TypeDefDict<bool> types = new TypeDefDict<bool>();
MethodDefAndDeclaringTypeDict<bool> methods = new MethodDefAndDeclaringTypeDict<bool>();
public bool exists(IMethod method) {
if (method == null)

View File

@ -257,12 +257,12 @@ namespace de4dot.code.deobfuscators {
local = pushInstr.Operand as Local;
if (local == null)
return null;
type = createByReferenceType(local.Type.RemovePinned());
type = createByRefType(local.Type.RemovePinned());
break;
case Code.Ldarga:
case Code.Ldarga_S:
type = createByReferenceType(pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType));
type = createByRefType(pushInstr.GetArgumentType(method.MethodSig, method.DeclaringType));
break;
case Code.Ldfld:
@ -278,12 +278,12 @@ namespace de4dot.code.deobfuscators {
var field2 = pushInstr.Operand as IField;
if (field2 == null || field2.FieldSig == null)
return null;
type = createByReferenceType(field2.FieldSig.GetFieldType());
type = createByRefType(field2.FieldSig.GetFieldType());
break;
case Code.Ldelema:
case Code.Unbox:
type = createByReferenceType(pushInstr.Operand as ITypeDefOrRef);
type = createByRefType(pushInstr.Operand as ITypeDefOrRef);
break;
default:
@ -293,13 +293,13 @@ namespace de4dot.code.deobfuscators {
return type;
}
static ByRefSig createByReferenceType(ITypeDefOrRef elementType) {
static ByRefSig createByRefType(ITypeDefOrRef elementType) {
if (elementType == null)
return null;
return new ByRefSig(elementType.ToTypeSig());
}
static ByRefSig createByReferenceType(TypeSig elementType) {
static ByRefSig createByRefType(TypeSig elementType) {
if (elementType == null)
return null;
return new ByRefSig(elementType);

View File

@ -24,8 +24,12 @@ using de4dot.mdecrypt;
namespace de4dot.code.deobfuscators {
static class MethodsDecrypter {
public static DumpedMethods decrypt(string filename, byte[] moduleCctorBytes) {
using (var client = new NewProcessAssemblyClientFactory().create()) {
public static DumpedMethods decrypt(ModuleDef module, byte[] moduleCctorBytes) {
return decrypt(getServerClrVersion(module), module.Location, moduleCctorBytes);
}
public static DumpedMethods decrypt(ServerClrVersion serverVersion, string filename, byte[] moduleCctorBytes) {
using (var client = new NewProcessAssemblyClientFactory(serverVersion).create()) {
client.connect();
client.waitConnected();
var info = new DecryptMethodsInfo();
@ -35,5 +39,20 @@ namespace de4dot.code.deobfuscators {
return client.Service.decryptMethods();
}
}
static ServerClrVersion getServerClrVersion(ModuleDef module) {
switch (module.GetPointerSize()) {
default:
case 4:
if (module.IsClr40)
return ServerClrVersion.CLR_v40_x86;
return ServerClrVersion.CLR_v20_x86;
case 8:
if (module.IsClr40)
return ServerClrVersion.CLR_v40_x64;
return ServerClrVersion.CLR_v20_x64;
}
}
}
}

View File

@ -1,21 +1,59 @@
using System;
using System.Collections.Generic;
using dot10.IO;
using dot10.PE;
using dot10.DotNet.MD;
using de4dot.blocks;
namespace de4dot.code.deobfuscators.dotNET_Reactor {
namespace de4dot.code.deobfuscators {
sealed class MyPEImage : IDisposable {
IPEImage peImage;
byte[] peImageData;
IImageStream peStream;
DotNetFile dnFile;
bool dnFileInitialized;
ImageSectionHeader dotNetSection;
bool ownPeImage;
public DotNetFile DotNetFile {
get {
if (dnFileInitialized)
return dnFile;
dnFileInitialized = true;
var dotNetDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14];
if (dotNetDir.VirtualAddress != 0 && dotNetDir.Size >= 0x48) {
dnFile = DotNetFile.Load(peImage, false);
dotNetSection = findSection(dotNetDir.VirtualAddress);
}
return dnFile;
}
}
public ImageCor20Header Cor20Header {
get { return DotNetFile.MetaData.ImageCor20Header; }
}
public IBinaryReader Reader {
get { return peStream; }
}
public IPEImage PEImage {
get { return peImage; }
}
public ImageFileHeader FileHeader {
get { return peImage.ImageNTHeaders.FileHeader; }
}
public IImageOptionalHeader OptionalHeader {
get { return peImage.ImageNTHeaders.OptionalHeader; }
}
public IList<ImageSectionHeader> Sections {
get { return peImage.ImageSectionHeaders; }
}
public uint Length {
get { return (uint)peStream.Length; }
}
@ -33,13 +71,6 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor {
void initialize(IPEImage peImage) {
this.peImage = peImage;
this.peStream = peImage.CreateFullStream();
//TODO: Only init this if they use the .NET MD
var dotNetDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14];
if (dotNetDir.VirtualAddress != 0 && dotNetDir.Size >= 0x48) {
dnFile = DotNetFile.Load(peImage, false);
dotNetSection = findSection(dotNetDir.VirtualAddress);
}
}
ImageSectionHeader findSection(RVA rva) {
@ -50,10 +81,66 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor {
return null;
}
public ImageSectionHeader findSection(string name) {
foreach (var section in peImage.ImageSectionHeaders) {
if (section.DisplayName == name)
return section;
}
return null;
}
public void readMethodTableRowTo(DumpedMethod dm, uint rid) {
dm.token = 0x06000000 + rid;
var row = DotNetFile.MetaData.TablesStream.ReadMethodRow(rid);
if (row == null)
throw new ArgumentException("Invalid Method rid");
dm.mdRVA = row.RVA;
dm.mdImplFlags = row.ImplFlags;
dm.mdFlags = row.Flags;
dm.mdName = row.Name;
dm.mdSignature = row.Signature;
dm.mdParamList = row.ParamList;
}
public void updateMethodHeaderInfo(DumpedMethod dm, MethodBodyHeader mbHeader) {
dm.mhFlags = mbHeader.flags;
dm.mhMaxStack = mbHeader.maxStack;
dm.mhCodeSize = dm.code == null ? 0 : (uint)dm.code.Length;
dm.mhLocalVarSigTok = mbHeader.localVarSigTok;
}
public uint rvaToOffset(uint rva) {
return (uint)peImage.ToFileOffset((RVA)rva);
}
static bool isInside(ImageSectionHeader section, uint offset, uint length) {
return offset >= section.PointerToRawData && offset + length <= section.PointerToRawData + section.SizeOfRawData;
}
public void writeUInt32(uint rva, uint data) {
offsetWriteUInt32(rvaToOffset(rva), data);
}
public void writeUInt16(uint rva, ushort data) {
offsetWriteUInt16(rvaToOffset(rva), data);
}
public byte readByte(uint rva) {
return offsetReadByte(rvaToOffset(rva));
}
public int readInt32(uint rva) {
return (int)offsetReadUInt32(rvaToOffset(rva));
}
public ushort readUInt16(uint rva) {
return offsetReadUInt16(rvaToOffset(rva));
}
public byte[] readBytes(uint rva, int size) {
return offsetReadBytes(rvaToOffset(rva), size);
}
public void offsetWriteUInt32(uint offset, uint val) {
peImageData[offset + 0] = (byte)val;
peImageData[offset + 1] = (byte)(val >> 8);
@ -99,14 +186,14 @@ namespace de4dot.code.deobfuscators.dotNET_Reactor {
}
public bool dotNetSafeWriteOffset(uint offset, byte[] data) {
if (dnFile != null) {
if (DotNetFile != null) {
uint length = (uint)data.Length;
if (!isInside(dotNetSection, offset, length))
return false;
if (intersect(offset, length, dnFile.MetaData.ImageCor20Header))
if (intersect(offset, length, DotNetFile.MetaData.ImageCor20Header))
return false;
if (intersect(offset, length, dnFile.MetaData.MetaDataHeader))
if (intersect(offset, length, DotNetFile.MetaData.MetaDataHeader))
return false;
}

View File

@ -181,7 +181,7 @@ namespace de4dot.code.deobfuscators {
// ...push args...
// call Invoke
abstract class ProxyCallFixer1 : ProxyCallFixerBase {
FieldDefinitionAndDeclaringTypeDict<DelegateInfo> fieldToDelegateInfo = new FieldDefinitionAndDeclaringTypeDict<DelegateInfo>();
FieldDefAndDeclaringTypeDict<DelegateInfo> fieldToDelegateInfo = new FieldDefAndDeclaringTypeDict<DelegateInfo>();
protected ProxyCallFixer1(ModuleDefMD module)
: base(module) {
@ -369,7 +369,7 @@ namespace de4dot.code.deobfuscators {
// ...push args...
// call static method
abstract class ProxyCallFixer2 : ProxyCallFixerBase {
MethodDefinitionAndDeclaringTypeDict<DelegateInfo> proxyMethodToDelegateInfo = new MethodDefinitionAndDeclaringTypeDict<DelegateInfo>();
MethodDefAndDeclaringTypeDict<DelegateInfo> proxyMethodToDelegateInfo = new MethodDefAndDeclaringTypeDict<DelegateInfo>();
protected ProxyCallFixer2(ModuleDefMD module)
: base(module) {

View File

@ -29,7 +29,7 @@ namespace de4dot.code.deobfuscators.Rummage {
class StringDecrypter {
ModuleDefMD module;
MethodDef stringDecrypterMethod;
FieldDefinitionAndDeclaringTypeDict<StringInfo> stringInfos = new FieldDefinitionAndDeclaringTypeDict<StringInfo>();
FieldDefAndDeclaringTypeDict<StringInfo> stringInfos = new FieldDefAndDeclaringTypeDict<StringInfo>();
int fileDispl;
uint[] key;
BinaryReader reader;

View File

@ -85,11 +85,11 @@ namespace de4dot.code.deobfuscators.Skater_NET {
protected override void scanForObfuscator() {
stringDecrypter = new StringDecrypter(module);
if (hasAssemblyReference("Microsoft.VisualBasic"))
if (hasAssemblyRef("Microsoft.VisualBasic"))
stringDecrypter.find();
}
bool hasAssemblyReference(string name) {
bool hasAssemblyRef(string name) {
foreach (var asmRef in module.GetAssemblyRefs()) {
if (asmRef.Name == name)
return true;

View File

@ -32,7 +32,7 @@ namespace de4dot.code.deobfuscators.Skater_NET {
ModuleDefMD module;
TypeDef decrypterType;
MethodDef decrypterCctor;
FieldDefinitionAndDeclaringTypeDict<string> fieldToDecryptedString = new FieldDefinitionAndDeclaringTypeDict<string>();
FieldDefAndDeclaringTypeDict<string> fieldToDecryptedString = new FieldDefAndDeclaringTypeDict<string>();
bool canRemoveType;
IDecrypter decrypter;

View File

@ -416,8 +416,8 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
if (decrypter.CanDecrypt) {
var invokeMethod = info.GetStringDelegate == null ? null : info.GetStringDelegate.FindMethod("Invoke");
staticStringInliner.add(invokeMethod, (method, gim, args) => {
var fieldDefinition = DotNetUtils.getField(module, (IField)args[0]);
return decrypter.decrypt(fieldDefinition.MDToken.ToInt32(), (int)args[1]);
var fieldDef = DotNetUtils.getField(module, (IField)args[0]);
return decrypter.decrypt(fieldDef.MDToken.ToInt32(), (int)args[1]);
});
staticStringInliner.add(info.StringDecrypterMethod, (method, gim, args) => {
return decrypter.decrypt(0, (int)args[0]);

View File

@ -217,7 +217,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
// Find the string decrypter string offset value or null if none found
int? findOffsetValue(MethodDef method) {
var fieldDict = new FieldDefinitionAndDeclaringTypeDict<IField>();
var fieldDict = new FieldDefAndDeclaringTypeDict<IField>();
foreach (var field in method.DeclaringType.Fields)
fieldDict.add(field, field);
@ -253,7 +253,7 @@ namespace de4dot.code.deobfuscators.SmartAssembly {
return null;
}
int? findOffsetValue(MethodDef method, FieldDef offsetField, FieldDefinitionAndDeclaringTypeDict<IField> fields) {
int? findOffsetValue(MethodDef method, FieldDef offsetField, FieldDefAndDeclaringTypeDict<IField> fields) {
var instructions = method.Body.Instructions;
for (int i = 0; i <= instructions.Count - 2; i++) {
var ldstr = instructions[i];

Some files were not shown because too many files have changed in this diff Show More