#include "stdafx.h"
#include <CorHdr.h>
#include "corinfo.h"
#include "corjit.h"
#include <tchar.h>
extern "C" __declspec(dllexport) void HookJIT();
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD dwReason,
LPVOID lpReserved
)
{
HookJIT();
return TRUE;
}
BOOL bHooked = FALSE;
ULONG_PTR *(__stdcall *p_getJit)();
typedef int (__stdcall *compileMethod_def)(ULONG_PTR classthis, ICorJitInfo *comp,
CORINFO_METHOD_INFO *info, unsigned flags,
BYTE **nativeEntry, ULONG *nativeSizeOfCode);
struct JIT
{
compileMethod_def compileMethod;
};
compileMethod_def compileMethod;
//
// native code to inject
//
#define CODE_SIZE 15
BYTE Code[CODE_SIZE] =
{
0x8B, 0x0D, 0x00, 0x00, 0x00, 0x00, // mov ecx, [addr]
0xFF, 0x15, 0x00, 0x00, 0x00, 0x00, // call [msgbox]
0xC2, 0x04, 0x00 // ret 4
};
int __stdcall my_compileMethod(ULONG_PTR classthis, ICorJitInfo *comp, CORINFO_METHOD_INFO *info,
unsigned flags, BYTE **nativeEntry, ULONG *nativeSizeOfCode)
{
//
// Very lazy way to identify the method to inject
//
const char *szMethodName = NULL;
const char *szClassName = NULL;
szMethodName = comp->getMethodName(info->ftn, &szClassName);
if (strcmp(szMethodName, "button1_Click") == 0)
{
//
// Retrieve string
//
unsigned int strToken = 0x70000063; // "Right password!"
void* literalHnd = NULL;
comp->constructStringLiteral(info->scope, strToken, &literalHnd);
//
// Retrieve method
//
/*
* misused to activate the method's assembly
* (we don't care about that)
*
CORINFO_CALL_INFO callInfo;
comp->getCallInfo(info->ftn,
info->scope,
0x0A00001E,
0, // constraintToken
info->ftn,
CORINFO_CALLINFO_KINDONLY,
&callInfo);
*/
CORINFO_METHOD_HANDLE targetMethod = comp->findMethod(info->scope,
0x0A00001E, info->ftn);
CORINFO_CONST_LOOKUP addrInfo;
comp->getFunctionEntryPoint(targetMethod, IAT_VALUE, &addrInfo);
//
// Set up native code
//
/*
* This is basically what we're doing
*
__asm
{
mov ecx, [literalHnd]
call [addrInfo.addr]
}
*/
BYTE *pCode = Code;
pCode += 2;
*((ULONG_PTR *) pCode) = (ULONG_PTR) literalHnd;
pCode += 6;
*((ULONG_PTR *) pCode) = (ULONG_PTR) addrInfo.addr;
DWORD dwOldProtect;
VirtualProtect(Code, CODE_SIZE, PAGE_EXECUTE_READWRITE, &dwOldProtect);
*nativeEntry = Code;
*nativeSizeOfCode = CODE_SIZE;
return CORJIT_OK; // it's 0 as usual
}
int nRet = compileMethod(classthis, comp, info, flags, nativeEntry, nativeSizeOfCode);
return nRet;
}
//
// Hooks compileMethod
//
extern "C" __declspec(dllexport)
void HookJIT()
{
if (bHooked) return;
LoadLibrary(_T("mscoree.dll"));
HMODULE hJitMod = LoadLibrary(_T("mscorjit.dll"));
if (!hJitMod)
return;
p_getJit = (ULONG_PTR *(__stdcall *)()) GetProcAddress(hJitMod, "getJit");
if (p_getJit)
{
JIT *pJit = (JIT *) *((ULONG_PTR *) p_getJit());
if (pJit)
{
DWORD OldProtect;
VirtualProtect(pJit, sizeof (ULONG_PTR), PAGE_READWRITE, &OldProtect);
compileMethod = pJit->compileMethod;
pJit->compileMethod = &my_compileMethod;
VirtualProtect(pJit, sizeof (ULONG_PTR), OldProtect, &OldProtect);
bHooked = TRUE;
}
}
}