.NETライブラリに対応
Opened this issue · 10 comments
RecottePluginManagerに.NETのホストをさせて、NativeDLLと一緒にManagedDLLも呼び出すようにする
DLLMainから呼ぶと、WaitForSingleObject
が帰ってこない…
スタックトレース自体wmain
から呼んだ時と同じ(こっちはsyscallが即時帰ってくる)
00007FF879F6CDD8 0F 1F 84 00 00 00 00 00 nop dword ptr [rax+rax]
00007FF879F6CDE0 4C 8B D1 mov r10,rcx
00007FF879F6CDE3 B8 04 00 00 00 mov eax,4
00007FF879F6CDE8 F6 04 25 08 03 FE 7F 01 test byte ptr [7FFE0308h],1
00007FF879F6CDF0 75 03 jne NtWaitForSingleObject+15h (07FF879F6CDF5h)
00007FF879F6CDF2 0F 05 syscall
00007FF879F6CDF4 C3 ret
WinMainの呼出し部分に遅延させた(もちろんうまくいく)
28b4daf#diff-01f5f0a4a10786db073a26a3680f98c83f1f39069fbf6b31266334a26e99dc73R353
C++/CLIでビルドすると、Ijwhost.dll
が生成されてしまう。この補助DLLがないと実行時エラーになるが、本体のDLLに以下の関数をExportさせるとIjwhost.dll
消してもでも動く。
(ロード時に本体以外のDLLが必要だと、Recotte本体ディレクトリに d3d11.dll
のリンク以外を置かないといけないのはどうしても避けたい)
// https://docs.microsoft.com/ja-jp/dotnet/framework/unmanaged-api/hosting/cordllmain-function
extern "C" __declspec(dllexport) BOOL STDMETHODCALLTYPE _CorDllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpReserved)
Ijwhostに関する情報
- https://github.com/dotnet/runtime/blob/main/docs/design/features/IJW-activation.md
- https://docs.microsoft.com/ja-jp/cpp/dotnet/calling-native-functions-from-managed-code?view=msvc-160#advantages-of-ijw
ただ、結局のところ、ijwhostを消せたところで、.NETRuntime本体を同梱できているわけではない、シングルファイルはあきらめるべき…🤔(最悪でもRecotteディレクトには d3d11.dll
以外置きたくないという要件はどちらでも満たせる)
究極的にはこれができればうれしい
REM https://github.com/wallstudio/WindowsExeHackSample/blob/master/Synthesize/Extract/build.bat
dotnet publish ^
--output .. ^
--runtime win-x64 ^
--self-contained=true ^
-p:Configuration=Release ^
/p:PublishSingleFile=true ^
/p:IncludeNativeLibrariesForSelfExtract=true ^
/p:DebugType=None ^
/p:DebugSymbols=false ^
https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md
単一ファイルにかんする調査
CoreCRLのホスティングAPIについて(hostfxrから呼ばれるやつ)
https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-interface
hostfxr側でincludeするInterface(ICLRRuntimeHost4
)
https://github.com/dotnet/runtime/blob/v6.0.0-rc.2.21480.5/src/coreclr/pal/prebuilt/inc/mscoree.h#L607
coreclr側のCOM実体(CorHost2
)のヘッダ
https://github.com/dotnet/runtime/blob/v6.0.0-rc.2.21480.5/src/coreclr/inc/corhost.h#L39
coreclr側のCOM実体(CorHost2
)の実装
https://github.com/dotnet/runtime/blob/v6.0.0-rc.2.21480.5/src/coreclr/vm/corhost.cpp#L50
余計なDLLを作らないようにするには、Runtimeを魔改造&リンクしてビルドするか、Resourceとして持ってPELoaderを実装するしかなさそう
いつかやってみたいのはあるけど、今回はそこまでするのはやめておこう
https://snoozy.hatenablog.com/entry/2020/01/20/033114
RecottePlugin
├ PluginManager
│ ├ ManagedLoader.dll (managed)
│ ├ PluginManager.dll (native)
│ │
│ ├ hostfxr.dll (native; dotnet runtime)
│ ├ coreclr.dll (native; dotnet runtime)
│ ├ clrjit.dll (native; dotnet runtime)
│ ├ clrcompression.dll (native; dotnet runtime)
│ └ stdibs (managed; dotnet runtime)
│ ├ mscorlib.dll
│ ├ System.Core.dll
│ └ ...
├ PluginX
...
https://github.com/dotnet/runtime/blob/v6.0.0/docs/project/dotnet-filenames.md