Hooking RtlCopyMemory crash

c++ / delphi package - dll injection and api hooking

Hooking RtlCopyMemory crash

Postby wineggdrop » Mon Nov 18, 2019 9:54 pm

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
Last edited by wineggdrop on Tue Nov 19, 2019 12:39 am, edited 1 time in total.
wineggdrop
 
Posts: 15
Joined: Mon Nov 18, 2019 6:18 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Mon Nov 18, 2019 10:05 pm

Your detour callback is missing WINAPI (__stdcall) calling convention

--Iconic
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby wineggdrop » Tue Nov 19, 2019 12:39 am

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.
wineggdrop
 
Posts: 15
Joined: Mon Nov 18, 2019 6:18 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 12:45 am

Does Real_RtlCopyMemory have WINAPI? Both callback and real hook definitions need the same calling convention, otherwise you crash

--Iconic
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby wineggdrop » Tue Nov 19, 2019 1:01 am

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.
wineggdrop
 
Posts: 15
Joined: Mon Nov 18, 2019 6:18 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 1:51 am

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.97 KiB) Viewed 306 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
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 2:19 am

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
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby wineggdrop » Tue Nov 19, 2019 3:17 am

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.
wineggdrop
 
Posts: 15
Joined: Mon Nov 18, 2019 6:18 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 3:25 am

Please upload “your” library project code. I’ll test as soon as I receive it.

—Iconic
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby wineggdrop » Tue Nov 19, 2019 3:32 am

#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)
wineggdrop
 
Posts: 15
Joined: Mon Nov 18, 2019 6:18 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 3:42 am

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
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 4:20 am

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.8 KiB) Viewed 285 times


--Iconic
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby iconic » Tue Nov 19, 2019 8:11 pm

@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
iconic
Site Admin
 
Posts: 929
Joined: Wed Jun 08, 2005 5:08 am

Re: Hooking RtlCopyMemory crash

Postby wineggdrop » Tue Nov 19, 2019 10:18 pm

it works if removing the OutputDebugPrintf("RtlCopyMemory Called");
wineggdrop
 
Posts: 15
Joined: Mon Nov 18, 2019 6:18 am


Return to madCodeHook

Who is online

Users browsing this forum: Google [Bot] and 11 guests

cron