Skip to content

Commit b3c1780

Browse files
committed
Initial commit.
1 parent ff9acb9 commit b3c1780

File tree

8 files changed

+611
-0
lines changed

8 files changed

+611
-0
lines changed

LoadBinaryPlugin.csproj

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
7+
<ProjectGuid>{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>LoadBinaryPlugin</RootNamespace>
11+
<AssemblyName>LoadBinaryPlugin</AssemblyName>
12+
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
</PropertyGroup>
15+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
16+
<PlatformTarget>x86</PlatformTarget>
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\x86\</OutputPath>
21+
<DefineConstants>TRACE;DEBUG;WIN32</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
27+
<PlatformTarget>x86</PlatformTarget>
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>..\bin\Release\x86\</OutputPath>
31+
<DefineConstants>TRACE;WIN32;RELEASE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
34+
</PropertyGroup>
35+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
36+
<PlatformTarget>x64</PlatformTarget>
37+
<DebugSymbols>true</DebugSymbols>
38+
<DebugType>full</DebugType>
39+
<Optimize>false</Optimize>
40+
<OutputPath>bin\Debug\x64\</OutputPath>
41+
<DefineConstants>TRACE;DEBUG;WIN64</DefineConstants>
42+
<ErrorReport>prompt</ErrorReport>
43+
<WarningLevel>4</WarningLevel>
44+
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
45+
</PropertyGroup>
46+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
47+
<PlatformTarget>x64</PlatformTarget>
48+
<DebugType>pdbonly</DebugType>
49+
<Optimize>true</Optimize>
50+
<OutputPath>..\bin\Release\x64\</OutputPath>
51+
<DefineConstants>TRACE;WIN64;RELEASE</DefineConstants>
52+
<ErrorReport>prompt</ErrorReport>
53+
<WarningLevel>4</WarningLevel>
54+
</PropertyGroup>
55+
<PropertyGroup>
56+
<StartupObject />
57+
</PropertyGroup>
58+
<ItemGroup>
59+
<Reference Include="RGiesecke.DllExport.Metadata, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8f52d83c1a22df51, processorArchitecture=MSIL">
60+
<HintPath>packages\UnmanagedExports.1.2.7\lib\net\RGiesecke.DllExport.Metadata.dll</HintPath>
61+
<Private>False</Private>
62+
</Reference>
63+
<Reference Include="System" />
64+
<Reference Include="System.Core" />
65+
<Reference Include="System.Drawing" />
66+
<Reference Include="System.Windows.Forms" />
67+
<Reference Include="System.Xml.Linq" />
68+
<Reference Include="System.Data.DataSetExtensions" />
69+
<Reference Include="Microsoft.CSharp" />
70+
<Reference Include="System.Data" />
71+
<Reference Include="System.Net.Http" />
72+
<Reference Include="System.Xml" />
73+
</ItemGroup>
74+
<ItemGroup>
75+
<Compile Include="LoadBinaryPluginExt.cs" />
76+
<Compile Include="Properties\AssemblyInfo.cs" />
77+
<Compile Include="Properties\Resources.Designer.cs">
78+
<AutoGen>True</AutoGen>
79+
<DesignTime>True</DesignTime>
80+
<DependentUpon>Resources.resx</DependentUpon>
81+
</Compile>
82+
</ItemGroup>
83+
<ItemGroup>
84+
<ProjectReference Include="..\ReClass.NET\ReClass.NET.csproj">
85+
<Project>{BFB8917D-E9B4-463F-A6E8-612C35728C78}</Project>
86+
<Name>ReClass.NET</Name>
87+
</ProjectReference>
88+
</ItemGroup>
89+
<ItemGroup>
90+
<EmbeddedResource Include="Properties\Resources.resx">
91+
<Generator>ResXFileCodeGenerator</Generator>
92+
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
93+
<SubType>Designer</SubType>
94+
</EmbeddedResource>
95+
</ItemGroup>
96+
<ItemGroup>
97+
<None Include="packages.config" />
98+
</ItemGroup>
99+
<ItemGroup>
100+
<None Include="Resources\icon.png" />
101+
</ItemGroup>
102+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
103+
<Import Project="packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets" Condition="Exists('packages/UnmanagedExports.1.2.7/tools/RGiesecke.DllExport.targets')" />
104+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
105+
Other similar extension points exist, see Microsoft.Common.targets.
106+
<Target Name="BeforeBuild">
107+
</Target>
108+
<Target Name="AfterBuild">
109+
</Target>
110+
-->
111+
</Project>

LoadBinaryPlugin.sln

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25420.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoadBinaryPlugin", "LoadBinaryPlugin.csproj", "{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReClass.NET", "..\ReClass.NET\ReClass.NET.csproj", "{BFB8917D-E9B4-463F-A6E8-612C35728C78}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|x64 = Debug|x64
13+
Debug|x86 = Debug|x86
14+
Release|x64 = Release|x64
15+
Release|x86 = Release|x86
16+
EndGlobalSection
17+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Debug|x64.ActiveCfg = Debug|x64
19+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Debug|x64.Build.0 = Debug|x64
20+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Debug|x86.ActiveCfg = Debug|x86
21+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Debug|x86.Build.0 = Debug|x86
22+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Release|x64.ActiveCfg = Release|x64
23+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Release|x64.Build.0 = Release|x64
24+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Release|x86.ActiveCfg = Release|x86
25+
{CA79BA0B-0D80-476A-B793-FC7EF7DCEAD8}.Release|x86.Build.0 = Release|x86
26+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Debug|x64.ActiveCfg = Debug|x64
27+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Debug|x64.Build.0 = Debug|x64
28+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Debug|x86.ActiveCfg = Debug|x86
29+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Debug|x86.Build.0 = Debug|x86
30+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Release|x64.ActiveCfg = Release|x64
31+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Release|x64.Build.0 = Release|x64
32+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Release|x86.ActiveCfg = Release|x86
33+
{BFB8917D-E9B4-463F-A6E8-612C35728C78}.Release|x86.Build.0 = Release|x86
34+
EndGlobalSection
35+
GlobalSection(SolutionProperties) = preSolution
36+
HideSolutionNode = FALSE
37+
EndGlobalSection
38+
EndGlobal

LoadBinaryPluginExt.cs

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics.Contracts;
4+
using System.Drawing;
5+
using System.IO.MemoryMappedFiles;
6+
using System.Runtime.InteropServices;
7+
using System.Windows.Forms;
8+
using ReClassNET.Plugins;
9+
using RGiesecke.DllExport;
10+
using static ReClassNET.Memory.NativeHelper;
11+
12+
namespace LoadBinaryPlugin
13+
{
14+
public class LoadBinaryPluginExt : Plugin
15+
{
16+
private static object sync = new object();
17+
18+
private static IPluginHost host;
19+
20+
private static string currentFile;
21+
22+
private static Dictionary<IntPtr, MemoryMappedFile> openFiles;
23+
24+
public override Image Icon => Properties.Resources.icon;
25+
26+
public override bool Initialize(IPluginHost host)
27+
{
28+
Contract.Requires(host != null);
29+
30+
System.Diagnostics.Debugger.Launch();
31+
32+
if (host == null)
33+
{
34+
throw new ArgumentNullException(nameof(host));
35+
}
36+
37+
openFiles = new Dictionary<IntPtr, MemoryMappedFile>();
38+
39+
return true;
40+
}
41+
42+
public override void Terminate()
43+
{
44+
foreach (var kv in openFiles)
45+
{
46+
kv.Value.Dispose();
47+
}
48+
openFiles.Clear();
49+
50+
host = null;
51+
}
52+
53+
/// <summary>Gets a <see cref="MemoryMappedFile"/> by its plugin internal identifier.</summary>
54+
/// <param name="id">The identifier.</param>
55+
/// <returns>The file or null if the identifier doesn't exist.</returns>
56+
private static MemoryMappedFile GetMappedFileById(IntPtr id)
57+
{
58+
MemoryMappedFile file;
59+
openFiles.TryGetValue(id, out file);
60+
return file;
61+
}
62+
63+
/// <summary>Logs the exception and removes the file.</summary>
64+
/// <param name="id">The identifier.</param>
65+
/// <param name="ex">The exception.</param>
66+
private static void LogErrorAndRemoveFile(IntPtr id, Exception ex)
67+
{
68+
Contract.Requires(ex != null);
69+
70+
MemoryMappedFile file;
71+
if (openFiles.TryGetValue(id, out file))
72+
{
73+
file.Dispose();
74+
}
75+
76+
openFiles.Remove(id);
77+
78+
host.Logger.Log(ex);
79+
}
80+
81+
/// <summary>Queries if the file is valid.</summary>
82+
/// <param name="process">The file to check.</param>
83+
/// <returns>True if the file is valid, false if not.</returns>
84+
[DllExport(CallingConvention = CallingConvention.StdCall)]
85+
public static bool IsProcessValid(IntPtr process)
86+
{
87+
lock (sync)
88+
{
89+
return GetMappedFileById(process) != null;
90+
}
91+
}
92+
93+
/// <summary>Opens the file.</summary>
94+
/// <param name="pid">The file id.</param>
95+
/// <param name="desiredAccess">The desired access. (ignored)</param>
96+
/// <returns>A plugin internal handle to the file.</returns>
97+
[DllExport(CallingConvention = CallingConvention.StdCall)]
98+
private static IntPtr OpenRemoteProcess(int pid, int desiredAccess)
99+
{
100+
lock (sync)
101+
{
102+
try
103+
{
104+
var file = MemoryMappedFile.CreateFromFile(currentFile);
105+
106+
var handle = file.SafeMemoryMappedFileHandle.DangerousGetHandle();
107+
108+
openFiles.Add(handle, file);
109+
110+
return handle;
111+
}
112+
catch (Exception ex)
113+
{
114+
host.Logger.Log(ex);
115+
}
116+
}
117+
118+
return IntPtr.Zero;
119+
}
120+
121+
/// <summary>Closes the file.</summary>
122+
/// <param name="process">The file to close.</param>
123+
[DllExport(CallingConvention = CallingConvention.StdCall)]
124+
private static void CloseRemoteProcess(IntPtr process)
125+
{
126+
lock (sync)
127+
{
128+
MemoryMappedFile file;
129+
if (openFiles.TryGetValue(process, out file))
130+
{
131+
openFiles.Remove(process);
132+
133+
file.Dispose();
134+
}
135+
}
136+
}
137+
138+
/// <summary>Reads memory of the file.</summary>
139+
/// <param name="process">The process to read from.</param>
140+
/// <param name="address">The address to read from.</param>
141+
/// <param name="buffer">The buffer to read into.</param>
142+
/// <param name="size">The size of the memory to read.</param>
143+
/// <returns>True if it succeeds, false if it fails.</returns>
144+
[DllExport(CallingConvention = CallingConvention.StdCall)]
145+
private static bool ReadRemoteMemory(IntPtr process, IntPtr address, IntPtr buffer, int size)
146+
{
147+
lock (sync)
148+
{
149+
var file = GetMappedFileById(process);
150+
if (file != null)
151+
{
152+
try
153+
{
154+
using (var stream = file.CreateViewStream(address.ToInt64(), size))
155+
{
156+
var tempBuffer = new byte[size];
157+
stream.Read(tempBuffer, 0, size);
158+
159+
Marshal.Copy(tempBuffer, 0, buffer, size);
160+
161+
return true;
162+
}
163+
}
164+
catch (UnauthorizedAccessException)
165+
{
166+
// address + size >= file size
167+
}
168+
catch (Exception ex)
169+
{
170+
LogErrorAndRemoveFile(process, ex);
171+
}
172+
}
173+
174+
return false;
175+
}
176+
}
177+
178+
/// <summary>Not supported.</summary>
179+
/// <param name="process">The file to write to.</param>
180+
/// <param name="address">The address to write to.</param>
181+
/// <param name="buffer">The memory to write.</param>
182+
/// <param name="size">The size of the memory to write.</param>
183+
/// <returns>True if it succeeds, false if it fails.</returns>
184+
[DllExport(CallingConvention = CallingConvention.StdCall)]
185+
private static bool WriteRemoteMemory(IntPtr process, IntPtr address, IntPtr buffer, int size)
186+
{
187+
// No write support.
188+
189+
return false;
190+
}
191+
192+
/// <summary>Opens a file browser dialog and reports the selected file.</summary>
193+
/// <param name="callbackProcess">The callback which gets called for the selected file.</param>
194+
[DllExport(CallingConvention = CallingConvention.StdCall)]
195+
private static void EnumerateProcesses(EnumerateProcessCallback callbackProcess)
196+
{
197+
if (callbackProcess == null)
198+
{
199+
return;
200+
}
201+
202+
using (var ofd = new OpenFileDialog())
203+
{
204+
ofd.Filter = "All|*.*";
205+
206+
if (ofd.ShowDialog() == DialogResult.OK)
207+
{
208+
currentFile = ofd.FileName;
209+
210+
callbackProcess(currentFile.GetHashCode(), currentFile);
211+
}
212+
}
213+
}
214+
215+
/// <summary>Not supported.</summary>
216+
/// <param name="process">The process.</param>
217+
/// <param name="callbackSection">The callback which gets called for every section.</param>
218+
/// <param name="callbackModule">The callback which gets called for every module.</param>
219+
[DllExport(CallingConvention = CallingConvention.StdCall)]
220+
private static void EnumerateRemoteSectionsAndModules(IntPtr process, EnumerateRemoteSectionCallback callbackSection, EnumerateRemoteModuleCallback callbackModule)
221+
{
222+
// No modules and sections here.
223+
}
224+
}
225+
}

0 commit comments

Comments
 (0)