Skip to content

Commit

Permalink
GetMmdTransformationPlugin: x64 版 MMM に対応
Browse files Browse the repository at this point in the history
  • Loading branch information
mfakane committed Jun 6, 2017
1 parent 8f33709 commit a271944
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 141 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -32,4 +32,5 @@ ipch/
*.opensdf
*.ide
packages/
_*
_*
.localhistory/
6 changes: 6 additions & 0 deletions GetMmdTransformationContainer/App.config
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
73 changes: 73 additions & 0 deletions GetMmdTransformationContainer/GetMmdTransformationContainer.csproj
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8DC503A7-C9C6-4CED-B0B5-8A15D72F73C3}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GetMmdTransformationContainer</RootNamespace>
<AssemblyName>GetMmdTransformationContainer</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\GetMmdTransformationContainer64\Program.cs">
<Link>Program.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>copy $(TargetPath) $(SolutionDir)GetMmdTransformationPlugin\Resources</PostBuildEvent>
</PropertyGroup>
<!-- 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>
36 changes: 36 additions & 0 deletions GetMmdTransformationContainer/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
// アセンブリに関連付けられている情報を変更するには、
// これらの属性値を変更してください。
[assembly: AssemblyTitle("GetMmdTransformationContainer32")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GetMmdTransformationContainer32")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから
// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、
// その型の ComVisible 属性を true に設定してください。
[assembly: ComVisible(false)]

// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります
[assembly: Guid("8dc503a7-c9c6-4ced-b0b5-8a15d72f73c3")]

// アセンブリのバージョン情報は次の 4 つの値で構成されています:
//
// メジャー バージョン
// マイナー バージョン
// ビルド番号
// Revision
//
// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を
// 既定値にすることができます:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
4 changes: 2 additions & 2 deletions GetMmdTransformationContainer64/Program.cs
Expand Up @@ -6,7 +6,7 @@
using System.Security;
using System.Text;

namespace GetMmdTransformationContainer64
namespace GetMmdTransformationContainer
{
class Program
{
Expand Down Expand Up @@ -77,7 +77,7 @@ static void Main(string[] args)
WaitForSingleObject(hThread, unchecked((uint)-1));
CloseHandle(hThread);
}

// if finished, unload the library.
FreeLibraryRemote(hProcess, kernelModule, hModule);
FreeLibrary(localModule);
Expand Down
5 changes: 3 additions & 2 deletions GetMmdTransformationPlugin/GetMmdTransformationPlugin.csproj
Expand Up @@ -22,7 +22,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
Expand All @@ -32,7 +32,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<PropertyGroup>
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
Expand Down Expand Up @@ -90,6 +90,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Resources\GetMmdTransformation20.png" />
<Content Include="Resources\GetMmdTransformation32.png" />
<Content Include="Resources\GetMmdTransformationContainer.exe" />
<None Include="Resources\GetMmdTransformationProxy64.dll" />
<None Include="Resources\GetMmdTransformationContainer64.exe" />
<None Include="Resources\GetMmdTransformationProxy.dll" />
Expand Down
4 changes: 4 additions & 0 deletions GetMmdTransformationPlugin/GetMmdTransformationPlugin.txt
Expand Up @@ -25,6 +25,10 @@ MikuMikuMoving.exe のあるフォルダの Plugins フォルダに本 dll を

◆更新履歴

Version 0.6, Sun, 24 Jul 2016

x64 版 MMM に対応

Version 0.5, Sat, 22 Sep 2012

x64 版 MMD に対応
Expand Down
138 changes: 7 additions & 131 deletions GetMmdTransformationPlugin/Mmd/MmdImport.cs
Expand Up @@ -6,7 +6,6 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using Linearstar.MikuMikuMoving.GetMmdTransformationPlugin.Properties;

Expand Down Expand Up @@ -49,13 +48,7 @@ public MmdImport(Process process)

pipe = new NamedPipeServerStream(namedPipePrefix + this.Handle.ToString());

ThreadPool.QueueUserWorkItem(_ =>
{
if (this.IsPlatform64)
InvokeRemote64(process, this.Handle);
else
InvokeRemote(process, this.Handle);
});
ThreadPool.QueueUserWorkItem(_ => InvokeRemote(process, this.Handle));

pipe.WaitForConnection();
protocol = new MmdPipeProtocol(pipe);
Expand Down Expand Up @@ -83,12 +76,12 @@ static T GetDelegate<T>(IntPtr hModule, string entryPoint)
return (T)(object)Marshal.GetDelegateForFunctionPointer(proc, typeof(T));
}

bool IsWow64Process(IntPtr hProcess)
static bool IsWow64Process(IntPtr hProcess)
{
var proc = GetProcAddress(GetModuleHandle("kernel32"), "IsWow64Process");

if (proc == IntPtr.Zero)
return false;
return true;

bool rt;

Expand All @@ -102,36 +95,15 @@ bool IsWow64Process(IntPtr hProcess)
static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern IntPtr GetModuleHandle(string lpModuleName);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern IntPtr VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint dwFreeType);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out uint lpNumberOfBytesWritten);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, out uint lpThreadId);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern uint CloseHandle(IntPtr hHandle);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern bool GetExitCodeThread(IntPtr hThread, out IntPtr lpExitCode);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern IntPtr LoadLibrary(string lpFileName);
[SuppressUnmanagedCodeSecurity, DllImport("kernel32")]
static extern bool FreeLibrary(IntPtr hModule);

const uint MEM_COMMIT = 0x1000;
const uint MEM_RELEASE = 0x8000;
const uint PAGE_READWRITE = 0x4;

static void InvokeRemote64(Process process, IntPtr parameter)
static void InvokeRemote(Process process, IntPtr parameter)
{
var remoteProxy = Path.GetTempFileName();
var remoteContainer = Path.GetTempFileName();
var isPlatform64 = !IsWow64Process(process.Handle);

File.WriteAllBytes(remoteContainer, Resources.GetMmdTransformationContainer64);
File.WriteAllBytes(remoteProxy, Resources.GetMmdTransformationProxy64);
File.WriteAllBytes(remoteContainer, isPlatform64 ? Resources.GetMmdTransformationContainer64 : Resources.GetMmdTransformationContainer);
File.WriteAllBytes(remoteProxy, isPlatform64 ? Resources.GetMmdTransformationProxy64 : Resources.GetMmdTransformationProxy);

using (var p = Process.Start(new ProcessStartInfo
{
Expand Down Expand Up @@ -165,102 +137,6 @@ static void InvokeRemote64(Process process, IntPtr parameter)
}
}

static void InvokeRemote(Process process, IntPtr parameter)
{
var remoteProxy = Path.GetTempFileName();

File.WriteAllBytes(remoteProxy, Resources.GetMmdTransformationProxy);

var localModule = LoadLibrary(remoteProxy);
var hProcess = process.Handle;
var kernelModule = GetModuleHandle("kernel32");
IntPtr hModule;

// check if the assembly is already loaded.
{
var moduleName = Encoding.Unicode.GetBytes(Path.GetFileName(remoteProxy)).Concat(new[] { (byte)0 }).ToArray();
var alloc = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)moduleName.Length, MEM_COMMIT, PAGE_READWRITE);
uint writtenBytes;

WriteProcessMemory(hProcess, alloc, moduleName, (uint)moduleName.Length, out writtenBytes);

{
uint lpThreadId;
var getModuleHandle = GetProcAddress(kernelModule, "GetModuleHandleW");
var hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, getModuleHandle, alloc, 0, out lpThreadId);

WaitForSingleObject(hThread, unchecked((uint)-1));
GetExitCodeThread(hThread, out hModule);
CloseHandle(hThread);
}

VirtualFreeEx(hProcess, alloc, writtenBytes, MEM_RELEASE);
}

// if not loaded, use LoadLibraryW.
if (hModule == IntPtr.Zero)
hModule = LoadLibraryRemote(remoteProxy, hProcess, kernelModule);

// the main action.
{
uint lpThreadId;
var localEntryPointAddr = GetProcAddress(localModule, remoteEntryPoint);

// while hModule is just an address of the module, you can get the remote proc address by doing this :)
var remoteEntryPointAddr = hModule + (localEntryPointAddr.ToInt32() - localModule.ToInt32());
var hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, remoteEntryPointAddr, parameter, 0, out lpThreadId);

WaitForSingleObject(hThread, unchecked((uint)-1));
CloseHandle(hThread);
}

// if finished, unload the library.
FreeLibraryRemote(hProcess, kernelModule, hModule);
FreeLibrary(localModule);

try
{
File.Delete(remoteProxy);
}
catch
{
}
}

static IntPtr LoadLibraryRemote(string location, IntPtr hProcess, IntPtr kernelModule)
{
IntPtr hModule;
var path = Encoding.Unicode.GetBytes(location).Concat(new[] { (byte)0 }).ToArray();
var alloc = VirtualAllocEx(hProcess, IntPtr.Zero, (uint)path.Length, MEM_COMMIT, PAGE_READWRITE);
uint writtenBytes;

WriteProcessMemory(hProcess, alloc, path, (uint)path.Length, out writtenBytes);

{
uint lpThreadId;
var loadLibrary = GetProcAddress(kernelModule, "LoadLibraryW");
var hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, loadLibrary, alloc, 0, out lpThreadId);

WaitForSingleObject(hThread, unchecked((uint)-1));
GetExitCodeThread(hThread, out hModule);
CloseHandle(hThread);
}

VirtualFreeEx(hProcess, alloc, writtenBytes, MEM_RELEASE);

return hModule;
}

static void FreeLibraryRemote(IntPtr hProcess, IntPtr kernelModule, IntPtr hModule)
{
uint lpThreadId;
var freeLibrary = GetProcAddress(kernelModule, "FreeLibrary");
var hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, freeLibrary, hModule, 0, out lpThreadId);

WaitForSingleObject(hThread, unchecked((uint)-1));
CloseHandle(hThread);
}

T InvokeRemote<T>(string entryPoint, int[] parameters)
{
return protocol.InvokeRemote<T>(entryPoint, parameters);
Expand Down
2 changes: 1 addition & 1 deletion GetMmdTransformationPlugin/Properties/AssemblyInfo.cs
Expand Up @@ -7,5 +7,5 @@
[assembly: AssemblyCopyright("Copyright © mfakane 2012")]
[assembly: ComVisible(false)]
[assembly: Guid("2c309851-7f3e-4b62-87f9-44e5c492a0f8")]
[assembly: AssemblyVersion("0.5.*")]
[assembly: AssemblyVersion("0.6.*")]

12 changes: 11 additions & 1 deletion GetMmdTransformationPlugin/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a271944

Please sign in to comment.