Skip to content

m3vond/rawcall

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

rawcall

rawcall is a single-header C++ library that lets you call the original implementation of any x64 Windows function hooked at its prologue. It reads clean function bytes directly from the DLL file on disk, builds an executable trampoline in memory, and returns a callable function pointer. Since virtually all hook engines (MinHook, Detours, etc.) patch the function prologue, this covers the vast majority of real-world cases. This was written around 2 years ago and I have recently found it on an old drive. Published it with minor cleanup.

Usage

// By RVA
NTSTATUS status = CALL( "ntdll.dll", 0x69E20, NTSTATUS, __stdcall, PRTL_OSVERSIONINFOW )( &info );

// By export name
DWORD tick = CALLF( "kernel32.dll", "GetTickCount", DWORD, __stdcall )();

How it works

Hook engines patch the first few bytes of a function in loaded memory with a JMP to their handler. rawcall reads the DLL directly from disk. It decodes up to 10 instructions (#define RAWCALL_MAX_INSTRUCTIONS 10) using Zydis, copying clean bytes into a shellcode buffer allocated near the target DLL. RIP-relative instructions are fixed up so they still point to the correct absolute addresses at the new shellcode location. Once all instructions are copied, rawcall appends an absolute JMP back into loaded memory past the hook, and execution continues from there as normal.

Example

typedef int( __stdcall* MessageBoxA_t )( HWND, LPCSTR, LPCSTR, UINT );
MessageBoxA_t orig_msgbox;

__declspec( noinline ) int __stdcall MessageBoxAHook( HWND hwnd, LPCSTR text, LPCSTR caption, UINT type ) {
    printf( "messageboxa blocked\n" );
    return 1;
}

int main( ) {
    if ( MH_Initialize( ) != MH_OK ) return 1;
    if ( MH_CreateHook( &MessageBoxA, &MessageBoxAHook, reinterpret_cast< LPVOID* >( &orig_msgbox ) ) != MH_OK ) return 1;
    if ( MH_EnableHook( &MessageBoxA ) != MH_OK ) return 1;

    // blocked
    MessageBoxA( nullptr, "you should NOT see this", "rawcall demo", MB_OK );

    // works normally
    CALLF( "user32.dll", "MessageBoxA", int, __stdcall, HWND, LPCSTR, LPCSTR, UINT )(
        nullptr, "rawcall bypassed the hook!", "rawcall demo", MB_OK );

    return 0;
}

Prerequisites

  • Zydis

License

The project is licensed under Apache License 2.0.

About

x64 trampoline that sources clean function bytes from disk, bypassing in-memory hooks.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages