Я столкнулся с некоторыми проблемами при попытке ввести DLL в процесс. Я довольно новичок в этой теме, но я знаком с C #, поэтому чтение и понимание синтаксиса C ++ было не таким уж незнакомым, и я понимаю его по большей части.
То, что я пытаюсь, это только для обучения, и я пытаюсь это с помощью простых приложений, таких как notepad.exe и calc.exe.
Настройка проекта:
(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());
}
Неуправляемый dll успешно внедряется, когда не пытается загрузить clr и управляемый 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.
Я посмотрел на процесс в 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();
}
Первое сообщение показывает.
Я понял, что проблема в том, что код в DllMain не должен иметь доступ к CLR.
Код в DllMain не должен иметь доступ к CLR. Это означает, что DllMain не должен вызывать управляемые функции, прямо или косвенно; управляемый код не должен быть объявлен или реализован в DllMain; и никакая сборка мусора или автоматическая загрузка библиотеки не должны происходить в DllMain.
https://msdn.microsoft.com/en-us/library/ms173266.aspx
При создании нового потока код выполняется успешно
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;
}
И от чтения прокомментируйте еще один вопрос здесь на SO CreateThread должен быть безопасным в этом конкретном случае.
Других решений пока нет …