Page 1 of 1

Hooking RtlCopyMemory crash

Posted: Mon Nov 18, 2019 9:54 pm
by wineggdrop
VOID (WINAPI *Real_RtlCopyMemory)(PVOID pDestination,const PVOID pSource,SIZE_T iSize);
VOID WINAPI Detour_RtlCopyMemory(PVOID pDestination,const PVOID pSource,SIZE_T iSize);

void InstallHook()
{
LPTSTR lpModule = "ntdll.dll";
LPTSTR lpAPIToHook = "RtlCopyMemory";
HookAPI(lpModule,lpAPIToHook,Detour_RtlCopyMemory,(PVOID*)&Real_RtlCopyMemory);
}

VOID Detour_RtlCopyMemory(PVOID pDestination,const PVOID pSource,SIZE_T iSize)
{
OutputDebugPrintf("RtlCopyMemory Called");
return Real_RtlCopyMemory(pDestination,pSource,iSize);
}

when the dll injects into any process(tested on notepad.exe,mstsc.exe or other application),the process crashes with c0000005 error.no problem Hooking RtlCompareMemory.
test platform: windows 7 x64 and windows server 2012 R2

Re: Hooking RtlCopyMemory crash

Posted: Mon Nov 18, 2019 10:05 pm
by iconic
Your detour callback is missing WINAPI (__stdcall) calling convention

--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 12:39 am
by wineggdrop
VOID (WINAPI *Real_RtlCopyMemory)(PVOID pDestination,const PVOID pSource,SIZE_T iSize);
VOID WINAPI Detour_RtlCopyMemory(PVOID pDestination,const PVOID pSource,SIZE_T iSize);

void InstallHook()
{
LPTSTR lpModule = "ntdll.dll";
LPTSTR lpAPIToHook = "RtlCopyMemory";
HookAPI(lpModule,lpAPIToHook,Detour_RtlCopyMemory,(PVOID*)&Real_RtlCopyMemory);
}

VOID WINAPI Detour_RtlCopyMemory(PVOID pDestination,const PVOID pSource,SIZE_T iSize)
{
OutputDebugPrintf("RtlCopyMemory Called");
return Real_RtlCopyMemory(pDestination,pSource,iSize);
}

same result with the WINAPI convention.

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 12:45 am
by iconic
Does Real_RtlCopyMemory have WINAPI? Both callback and real hook definitions need the same calling convention, otherwise you crash

--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 1:01 am
by wineggdrop
iconic wrote:Does Real_RtlCopyMemory have WINAPI? Both callback and real hook definitions need the same calling convention, otherwise you crash

--Iconic
I have tried both with/without WINAPI conversion,same result.I even tried the __cdecl conversion,same result.BTW,it won't only happen in madcodehook,it happens in microsoft's Detours,and minhook library.

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 1:51 am
by iconic
Make sure you're calling InitializeMadCHook() before anything else. My quick test code worked fine here with a hook on ntdll RtlCopyMemory
RtlCopyMemory.png
RtlCopyMemory.png (41.83 KiB) Viewed 16771 times

Code: Select all

typedef void (WINAPI *_RtlCopyMemory)(PVOID Destination, PVOID Source, SIZE_T Length);

void (WINAPI *Real_RtlCopyMemory)(PVOID Destination, PVOID Source, SIZE_T Length);

void WINAPI Detour_RtlCopyMemory(PVOID Destination, PVOID Source, SIZE_T Length)
{
	Real_RtlCopyMemory(Destination, Source, Length);
	if (Length == 5 && lstrcmpA((char *)Source, "Hello") == 0)
	{
		printf("Calling RtlCopyMemory(0x%p, 0x%p, 0x%x) <-----\n", Destination, Source, Length);
	}
	else
	{
		printf("Calling RtlCopyMemory(0x%p, 0x%p, 0x%x)\n", Destination, Source, Length);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	InitializeMadCHook();
	char a1[MAX_PATH] = {0};
	char a2[MAX_PATH] = {0};
	_RtlCopyMemory pRtlCopyMemory = (_RtlCopyMemory)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCopyMemory");
	lstrcpyA(a1, "Hello");
	HookAPI("ntdll.dll", "RtlCopyMemory", Detour_RtlCopyMemory, (PVOID*)&Real_RtlCopyMemory);
	pRtlCopyMemory(&a2, &a1, 5);
	getchar();
	return 0;
}
--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 2:19 am
by iconic
Just tested a 32-bit build of the same code on Win7 x64. The WOW64 version of ntdll does *not* export RtlCopyMemory at all. RtlCompareMemory() however *is* exported

--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 3:17 am
by wineggdrop
your code works fine,but it's an exe file,I am talking about the hook in dll,inject the dll into a running process like notepad.exe,mstsc.exe and etc.

64 bit ntdll.dll exports RtlCopyMemory,and 32 bit ntdll.dll won't export that api,I am sure about it.

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 3:25 am
by iconic
Please upload “your” library project code. I’ll test as soon as I receive it.

—Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 3:32 am
by wineggdrop
#pragma warning(disable : 4995)
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include "MadHook.h"


#if defined _M_X64
#pragma comment(lib,"madHookx64.lib")
#elif defined _M_IX86
#pragma comment(lib,"madHookx32.lib")
#endif

VOID (WINAPI *Real_RtlCopyMemory)(PVOID pDestination,const PVOID pSource,SIZE_T iSize);
VOID WINAPI Detour_RtlCopyMemory(PVOID pDestination,const PVOID pSource,SIZE_T iSize);

void InstallHook();
void OutputDebugPrintf(const char* strOutputString, ...);

extern "C" __declspec(dllexport) void MadCodeHookTest(){return;}

BOOL WINAPI DllMain(HINSTANCE hDLL,DWORD fdwReason,LPVOID lpReserved)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
InstallHook();
break;
case DLL_PROCESS_DETACH:
FinalizeMadCHook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}

void InstallHook()
{
InitializeMadCHook();

LPTSTR lpModule = NULL;
LPTSTR lpAPIToHook = NULL;

lpModule = "ntdll.dll";
lpAPIToHook = "RtlCopyMemory";
if (HookAPI(lpModule,lpAPIToHook,Detour_RtlCopyMemory,(PVOID*)&Real_RtlCopyMemory))
{
OutputDebugPrintf("Mad Hook %s Successful",lpAPIToHook);
}
else
{
OutputDebugPrintf("Mad Hook %s Failure",lpAPIToHook);
}

}

VOID WINAPI Detour_RtlCopyMemory(PVOID pDestination,const PVOID pSource,SIZE_T iSize)
{
OutputDebugPrintf("RtlCopyMemory Called");
return Real_RtlCopyMemory(pDestination,pSource,iSize);
}

void OutputDebugPrintf(const char* strOutputString, ...)
{
char strBuffer[4096] = { 0 };
va_list vlArgs;
va_start(vlArgs, strOutputString);
_vsnprintf(strBuffer, sizeof(strBuffer)-1, strOutputString, vlArgs);
va_end(vlArgs);
OutputDebugString(strBuffer);
}

tested on X64 version of windows 7 and windows server 2012 R2(compiled DLL is 64 bit)

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 3:42 am
by iconic
If you remove the variable arg functionality in your code (which use CDECL and can be very bad inside an STDCALL hook callback) to use the normal WIN32 API OutputDebugStringW("RtlCopyMemory Called"); which is also STDCALL does the issue continue to persist? I'd advise you do not use c run-time functions inside DLL hook callbacks, sometimes you can get away with them, other times you can't.

--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 4:20 am
by iconic
Alright, I can confirm the issue, but as you mentioned previously this happens with any other hooking library you have tried so it's not an MCH issue directly.
If you simply just call the *real* function inside your callback the issue disappears here. I've tested with Notepad. To make sure it was being called I
created a secondary thread to poll a global counter to see how often RtlCopyMemory() was being called for 60 seconds, updating the value output every
5 seconds and then sleeping. You'll need a different method for letting other code know that the callback has been called, most other methods I've tried
will actually deadlock.
Internal_Hook_Callback_Count.png
Internal_Hook_Callback_Count.png (69.54 KiB) Viewed 16750 times
--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 8:11 pm
by iconic
@wineggdrop

Can you please confirm that simply calling the *real* function inside your callback works without trouble?

Code: Select all


VOID WINAPI Detour_RtlCopyMemory(PVOID pDestination, const PVOID pSource, SIZE_T iSize)
{
    return Real_RtlCopyMemory(pDestination, pSource, iSize);
}
I ran some further tests today and was able to pass all params (dest, src, size) to another worker thread just fine via APCs and then used WriteFile to create a log.
Unsurprisingly, due to the heavy API call volume, the log became rather large quickly here but nonetheless worked fine. OutputDebugString, SendIpcMessage,
mailslots etc. all locked up for me so I turned to APCs (NtQueueApcThread) which allowed all 3 parameters to be effortlessly passed on and logged from a different
thread context. Hopefully that can be helpful to you in some way.

--Iconic

Re: Hooking RtlCopyMemory crash

Posted: Tue Nov 19, 2019 10:18 pm
by wineggdrop
it works if removing the OutputDebugPrintf("RtlCopyMemory Called");