Thanks Virusman for posting the offset information, and method signature.
I am currently researching dll injection techniques that are viable for .net (c#)
I believe that I might be able to inject a dll into the nwmain process, and then have that dll (a c++ bootstrapper) execute a method contained in a c# dll, for triggering the method discussed above.
I've already got it working to the point where a dll can be injected into the process, however, I soon learned that I need to inject a c++ dll, which initiates the .net framework (CLR) within the NWN Process, and then have the bootstrapper make a further call to my 'actual' dll, which will contain the instructions to execute the delegate for the method pointer/address above.
Don't suppose you have any experience with c++ bootstrapping and .net?
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Bootstrap();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
which then calls
#include "stdafx.h"
#include <stdio.h>
#include "objbase.h"
#include "MSCorEE.h"
#import "C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb" raw_interfaces_only
using namespace mscorlib;
void Bootstrap() {
OutputDebugString(L"MceFM Bootstrap Started");
CoInitializeEx(0, COINIT_MULTITHREADED );
ICorRuntimeHost* pICorRuntimeHost = 0;
HRESULT st = CoCreateInstance(CLSID_CorRuntimeHost, 0, CLSCTX_ALL,
IID_ICorRuntimeHost, (void**)&pICorRuntimeHost);
if(!pICorRuntimeHost) return; // Clean up and log errror ...
HDOMAINENUM hEnum = NULL;
pICorRuntimeHost->EnumDomains(&hEnum);
if(!hEnum) return; // Clean up and log errror ...
IUnknown* pUunk = 0;
st = pICorRuntimeHost->NextDomain(hEnum, &pUunk);
if(!pUunk) return; // Clean up and log errror ...
_AppDomain * pCurDomain = NULL;
st = pUunk->QueryInterface(__uuidof(_AppDomain), (VOID**)&pCurDomain);
if(!pCurDomain) return; // Clean up and log errror ...
_bstr_t assemblyName =
"Last, Version=1.1.0.0, Culture=neutral, PublicKeyToken=792d614cdf38e9ce";
_bstr_t typeName = "MceFM.Last.Inject.Injectee";
_ObjectHandle* pObjectHandle = 0;
pCurDomain->CreateInstance(assemblyName, typeName, &pObjectHandle);
}
I've never worked on making a c++ dll from scratch before, so the bootstrapper is my current challenge.
From what I understand, I should be able to get the .net DLL to execute a delegate for the memory location you posted above... if I can get the code to execute under the context of the nwmain process.
To do that, I need to inject into the process, so its the Process firing the method, and not my external application. (although it will be my external application that triggers it)
Am I right that when the dll is injected, DLLMain is executed automatically for the c++ dll, and then I need to use that to spawn off my .net dll, and then execute methods within it?
Even if I don't get it finished, its still interesting, cause I am learning more about Injection etc