Merge branch 'port' into confuser
This commit is contained in:
commit
c3608908c5
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
9
AssemblyServer-CLR20-x64/App.config
Normal file
9
AssemblyServer-CLR20-x64/App.config
Normal 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>
|
65
AssemblyServer-CLR20-x64/AssemblyServer-CLR20-x64.csproj
Normal file
65
AssemblyServer-CLR20-x64/AssemblyServer-CLR20-x64.csproj
Normal 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>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
33
AssemblyServer-CLR20-x64/Properties/AssemblyInfo.cs
Normal file
33
AssemblyServer-CLR20-x64/Properties/AssemblyInfo.cs
Normal 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")]
|
9
AssemblyServer-CLR20/App.config
Normal file
9
AssemblyServer-CLR20/App.config
Normal 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>
|
59
AssemblyServer-CLR20/AssemblyServer-CLR20.csproj
Normal file
59
AssemblyServer-CLR20/AssemblyServer-CLR20.csproj
Normal 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>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
33
AssemblyServer-CLR20/Properties/AssemblyInfo.cs
Normal file
33
AssemblyServer-CLR20/Properties/AssemblyInfo.cs
Normal 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")]
|
9
AssemblyServer-CLR40-x64/App.config
Normal file
9
AssemblyServer-CLR40-x64/App.config
Normal 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>
|
67
AssemblyServer-CLR40-x64/AssemblyServer-CLR40-x64.csproj
Normal file
67
AssemblyServer-CLR40-x64/AssemblyServer-CLR40-x64.csproj
Normal 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>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
33
AssemblyServer-CLR40-x64/Properties/AssemblyInfo.cs
Normal file
33
AssemblyServer-CLR40-x64/Properties/AssemblyInfo.cs
Normal 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")]
|
9
AssemblyServer-CLR40/App.config
Normal file
9
AssemblyServer-CLR40/App.config
Normal 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>
|
59
AssemblyServer-CLR40/AssemblyServer-CLR40.csproj
Normal file
59
AssemblyServer-CLR40/AssemblyServer-CLR40.csproj
Normal 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>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
33
AssemblyServer-CLR40/Properties/AssemblyInfo.cs
Normal file
33
AssemblyServer-CLR40/Properties/AssemblyInfo.cs
Normal 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")]
|
|
@ -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")]
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")]
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace de4dot.code {
|
|||
void deobfuscateEnd();
|
||||
void deobfuscateCleanUp();
|
||||
|
||||
void load(IEnumerable<IDeobfuscator> deobfuscators);
|
||||
void load(IList<IDeobfuscator> deobfuscators);
|
||||
void save();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -160,7 +160,8 @@ namespace de4dot.code {
|
|||
return noExt + "-cleaned" + ext;
|
||||
}
|
||||
|
||||
public void load(IEnumerable<IDeobfuscator> deobfuscators) {
|
||||
public void load(IList<IDeobfuscator> deobfuscators) {
|
||||
try {
|
||||
loadModule(deobfuscators);
|
||||
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(Filename));
|
||||
TheAssemblyResolver.Instance.addSearchDirectory(Utils.getDirName(NewFilename));
|
||||
|
@ -169,6 +170,13 @@ namespace de4dot.code {
|
|||
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) {
|
||||
ModuleDefMD oldModule = module;
|
||||
|
@ -187,8 +195,7 @@ 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 {
|
||||
|
@ -214,6 +221,7 @@ namespace de4dot.code {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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,14 +191,10 @@ 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() {
|
||||
return DotNetUtils.hasPinvokeMethod(cliSecureRtType, "LoadLibraryA");
|
||||
|
|
|
@ -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,12 +208,12 @@ namespace de4dot.code.deobfuscators.Agile_NET {
|
|||
return false;
|
||||
|
||||
byte[] fileData = ModuleBytes ?? DeobUtils.readModule(module);
|
||||
var peImage = new PeImage(fileData);
|
||||
|
||||
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;
|
||||
return true;
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,8 +124,8 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
|||
if (decrypter == null)
|
||||
return false;
|
||||
|
||||
var peImage = new PeImage(fileData);
|
||||
if (peImage.Sections.Length <= 0)
|
||||
using (var peImage = new MyPEImage(fileData)) {
|
||||
if (peImage.Sections.Count <= 0)
|
||||
return false;
|
||||
|
||||
var methodsData = findMethodsData(peImage, fileData);
|
||||
|
@ -139,33 +137,25 @@ namespace de4dot.code.deobfuscators.CodeVeil {
|
|||
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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
using (var peImage = new MyPEImage(fileData)) {
|
||||
if (!methodsDecrypter.decrypt(peImage, ref dumpedMethods))
|
||||
return false;
|
||||
}
|
||||
|
||||
newFileData = fileData;
|
||||
return true;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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,12 +194,13 @@ 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;
|
||||
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;
|
||||
byte[] compressed;
|
||||
int compressedLen;
|
||||
switch (version) {
|
||||
case Version.V0x:
|
||||
|
@ -212,8 +213,8 @@ namespace de4dot.code.deobfuscators.MPRESS {
|
|||
|
||||
case Version.V1x_217:
|
||||
case Version.V218:
|
||||
if (peImage.FileHeader.machine == Machine.amd64 && version == Version.V218)
|
||||
offset = section.pointerToRawData + section.virtualSize;
|
||||
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);
|
||||
|
@ -226,6 +227,7 @@ namespace de4dot.code.deobfuscators.MPRESS {
|
|||
default:
|
||||
throw new ApplicationException("Unknown MPRESS version");
|
||||
}
|
||||
}
|
||||
|
||||
newFileData = decompressed;
|
||||
return true;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,10 +120,18 @@ namespace de4dot.code.deobfuscators.MaxtoCode {
|
|||
newOne.setModule(module);
|
||||
newOne.mainType = new MainType(module, mainType);
|
||||
newOne.decrypterInfo = decrypterInfo;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue
Block a user