Невозможно вызвать метод в управляемой dll после загрузки CLR. Зачем?

Я столкнулся с некоторыми проблемами при попытке ввести 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());
}

Неуправляемый dll успешно внедряется, когда не пытается загрузить 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.

Я посмотрел на процесс в 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();
}

Первое сообщение показывает.

-1

Решение

Я понял, что проблема в том, что код в 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 должен быть безопасным в этом конкретном случае.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]