【发布时间】:2016-05-06 23:26:17
【问题描述】:
我在尝试将 dll 注入进程时遇到了一些问题。我对这个话题很陌生,但对 C# 很熟悉,所以阅读和理解 C++ 的语法并不是那么陌生,而且我大部分都理解它。
我正在尝试的只是为了学习,我正在尝试使用 notepad.exe 和 calc.exe 等简单的应用程序。
项目设置:
- WPF 应用程序 - 选择我想要修改的进程并注入非托管 dll。
- CppDLL.dll - 非托管 dll 加载 CLR、托管 dll 并调用托管 dll 上的方法。
- SharpDLL.dll - 托管 dll。
(wpf) 感兴趣的 c#
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.dll dllmain.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;
}
SharpDLL.dll Injected.cs
using System.Windows;
namespace SharpDLL
{
class Injected
{
public static int Start(string arg)
{
MessageBox.Show(arg);
return 0;
}
}
}
在 CppDLL.dll 中,如果我取消注释函数并注释消息框,它会失败。 SharpDLL.dll 不会被注入。当我尝试关闭记事本时,进程仍然显示在进程资源管理器中。
我事先查看了Process Explorer 中的进程,默认情况下不加载 clr.dll,但在函数运行时会加载它。也许它可能是 .NET 版本?我正在运行 Windows 10 x64。
更新
代码一直运行,直到我尝试实际启动运行时
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();
}
显示第一个消息框。
【问题讨论】: