我正在尝试将托管的 c# dll 注入本机可执行文件。我将以下代码注入可执行文件以加载 CLR。
我知道注入有效,因为当我将代码注入 cmd 时.exe它会正确输出。我知道CLRCreateInstance,pMetaHost->GetRuntime,pRuntimeInfo->GetInterface都返回S_OK,但pClrRuntimeHost->Start()返回E_FAIL。
仅当我将 dll 注入远程进程时,才会发生这种情况。如果我在自己的进程上加载 dll 并从那里调用 Main,则所有调用都将返回S_OK并且托管代码运行良好。
更新:我尝试将代码注入其他进程,如记事本.exe和资源管理器.exe。它在那些中运行良好。我仍然很好奇为什么它不能在 cmd .exe 中运行,但我只将其用于测试目的,因此它不再是问题。
GetLastError 返回"尝试引用不存在的令牌"
#include "stdafx.h"
#include "Bootstrap.h"
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
using namespace std;
//Forward declarations
void StartTheDotNetRuntime();
DllExport HRESULT Main(_In_ LPCTSTR lpCommand)
{
cout << "Starting .NET runtime" << endl;
StartTheDotNetRuntime();
return 0;
}
void StartTheDotNetRuntime()
{
wprintf(L"Press enter to load the .net runtime...");
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
// build runtime
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
// start runtime
hr = pClrRuntimeHost->Start();
cout << "RESULT: " << hr << endl;
wprintf(L".Net runtime is loaded.");
// Okay, the CLR is up and running in this (previously native) process.
// Now call a method on our managed C# class library.
DWORD dwReturn = 0;
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
L"F:\Client.dll",
L"Client.Main", L"Start", L"MyParameter", &dwReturn);
cout << dwReturn << endl;
}
我已经找到了问题的答案,至少对我来说,注入引导程序的过程需要具有管理员权限。我花了很长时间才意识到,因为默认情况下所有程序都具有管理员权限,一旦我开始以管理员身份注入的过程,它就起作用了!