C++ 加载CLR后无法在托管dll中调用方法。为什么?
我在尝试将dll注入进程时遇到了一些问题。我在这个话题上很新,但是我对C语言很熟悉,所以阅读和理解C++的语法并不陌生,我大部分理解。p> 我所尝试的只是为了学习,我正在使用一些简单的应用程序,比如notepad.exe和calc.exe 项目设置:C++ 加载CLR后无法在托管dll中调用方法。为什么?,c++,.net,dll,clr,inject,C++,.net,Dll,Clr,Inject,我在尝试将dll注入进程时遇到了一些问题。我在这个话题上很新,但是我对C语言很熟悉,所以阅读和理解C++的语法并不陌生,我大部分理解。p> 我所尝试的只是为了学习,我正在使用一些简单的应用程序,比如notepad.exe和calc.exe 项目设置: WPF应用程序-选择我想要修补的进程并注入非托管dll CppDLL.dll-用于加载CLR、托管dll和托管dll上的调用方法的非托管dll SharpDLL.dll-托管dll (wpf)c#感兴趣的 dllToInject = fileD
- WPF应用程序-选择我想要修补的进程并注入非托管dll
- CppDLL.dll-用于加载CLR、托管dll和托管dll上的调用方法的非托管dll
- SharpDLL.dll-托管dll
dllToInject = fileDialog.FileName;
Process targetProcess = Process.GetProcessById(processToInject.ID);
var dllInjector = DllInjector.GetInstance;
DllInjectionResult injectResult;
if ((injectResult = dllInjector.Inject(processToInject.Name,dllToInject)) == DllInjectionResult.Success)
{
MessageBox.Show("Success");
} else
{
MessageBox.Show("Error: " + injectResult.ToString());
}
当不尝试加载clr和托管dll时,非托管dll被成功注入,如下所示
但当我尝试加载CLR和托管dll时,它失败了
CppDLL.dlldllmain.cpp:
#include "stdafx.h"
#include <Windows.h>
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
#import "mscorlib.tlb" raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
rename("ReportEvent", "InteropServices_ReportEvent")
void LoadDotNet()
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
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));
hr = pClrRuntimeHost->Start();
DWORD pReturnValue;
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
L"C:\\Users\\DanHovedPC\\Desktop\\inject\\SharpDLL.dll",
L"SharpDLL.Injected",
L"Start",
L"Hello from .NET",
&pReturnValue);
pMetaHost->Release();
pRuntimeInfo->Release();
pClrRuntimeHost->Release();
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
MessageBox(NULL, L"Hi!", L"From cpp DLL", NULL);
//LoadDotNet();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
在CppDLL.dll中,如果取消对函数的注释并对messagebox进行注释,则会失败。SharpDLL.dll不会被注入。当我试图关闭记事本时,进程仍然显示在process Explorer中
我在前面已经看过了这个过程,默认情况下不会加载clr.dll,但是在函数运行时会加载它。也许是.NET版本?我正在运行Windows10x64
更新
代码一直运行,直到我尝试实际启动运行时为止
void LoadDotNet()
{
HRESULT hr;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pClrRuntimeHost = NULL;
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
MessageBox(NULL, L"Runs up to here...", L"DEBUG", NULL);
hr = pClrRuntimeHost->Start();
MessageBox(NULL,(LPCWSTR)GetLastError(),L"DEBUG",NULL);
pMetaHost->Release();
pRuntimeInfo->Release();
pClrRuntimeHost->Release();
}
第一个消息框显示。我发现问题在于DllMain中的代码不能访问CLR DllMain中的代码不得访问CLR。这意味着DllMain不应直接或间接调用托管函数;DllMain中不应声明或实现托管代码;DllMain中不应进行垃圾收集或自动加载库 创建新线程时,代码将成功运行
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//printf("DLL Loaded!");
CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)LoadDotNet, NULL, 0, NULL);
}
return TRUE;
}
在这种特殊情况下,读取CreateThread应该是安全的
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//printf("DLL Loaded!");
CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)LoadDotNet, NULL, 0, NULL);
}
return TRUE;
}