DarthTon / Blackbone

Windows memory hacking library
MIT License
4.81k stars 1.33k forks source link

Why does NtQueryVirtualMemory fail? #88

Closed bonment closed 8 years ago

bonment commented 8 years ago

I am trying to hook NtQueryVirtualMemory as follows:

#include "stdafx.h"
#include "Blackbone/src/BlackBone/Process/Process.h"
#include "Blackbone/src/BlackBone/LocalHook/LocalHook.hpp"

using namespace blackbone;

typedef NTSTATUS(NTAPI* tNtQueryVirtualMemory)(HANDLE ProcessHandle,
    PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass,
    PVOID Buffer, ULONG Length, PULONG ResultLength);

Detour<tNtQueryVirtualMemory> detour;
tNtQueryVirtualMemory orig;

NTSTATUS NTAPI Hook(HANDLE& ProcessHandle,
    PVOID& BaseAddress, MEMORY_INFORMATION_CLASS& MemoryInformationClass,
    PVOID& Buffer, ULONG& Length, PULONG& ResultLength)
{
    detour.Restore();
    auto res = orig(ProcessHandle, BaseAddress, MemoryInformationClass, Buffer, Length, ResultLength);
    detour.Hook(orig, &Hook, HookType::Int3, CallOrder::NoOriginal, ReturnMethod::UseNew);
    return res;
}

int main()
{
    Process thisProc;
    thisProc.Attach(GetCurrentProcess());
    auto ntdll = GetModuleHandle(L"ntdll.dll");
    auto ntqvm = GetProcAddress(ntdll, "NtQueryVirtualMemory");
    orig = reinterpret_cast<tNtQueryVirtualMemory>(ntqvm);
    MEMORY_BASIC_INFORMATION mbi = {0}, mbi2 = {0};
    VirtualQuery(&Hook, &mbi, sizeof(mbi));
    detour.Hook(orig, &Hook, HookType::Int3, CallOrder::NoOriginal, ReturnMethod::UseNew);  
    VirtualQuery(&Hook, &mbi2, sizeof(mbi2));   
    return 0;
}

However I'm doing something wrong because it fails after ntqvm is hooked.. The mbi2 is just completely empty. I think, maybe some recursion is happening since the Detour class checks to see if it has write permissions before enabling/disabling? So do you have a suggestion how I can hook this function with blackbone.

Visual studio debugger is not helpful. It just says "program.exe has triggered a breakpoint."

Regards -b

DarthTon commented 8 years ago

Fix function prototype:

typedef NTSTATUS( NTAPI* tNtQueryVirtualMemory )(
    HANDLE ProcessHandle,
    PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass,
    PVOID Buffer, SIZE_T Length, PSIZE_T ResultLength
    );

Proper hook syntax would be:


NTSTATUS NTAPI Hook( 
    HANDLE& ProcessHandle, PVOID& BaseAddress, 
    MEMORY_INFORMATION_CLASS& MemoryInformationClass,
    PVOID& Buffer, SIZE_T& Length, PSIZE_T& ResultLength
    )
{
    auto pmbi = reinterpret_cast<PMEMORY_BASIC_INFORMATION>(Buffer);
    std::wcout << std::hex << L"Hook: mbi2.BaseAddress: 0x" << pmbi->BaseAddress << std::endl;
    pmbi->BaseAddress = (PVOID)0xDEADBEEF;
    return STATUS_SUCCESS;
}

int main()
{
    Process thisProc;
    thisProc.Attach( GetCurrentProcessId() );
    auto ntdll = GetModuleHandle( L"ntdll.dll" );
    auto ntqvm = GetProcAddress( ntdll, "NtQueryVirtualMemory" );
    orig = reinterpret_cast<tNtQueryVirtualMemory>(ntqvm);
    MEMORY_BASIC_INFORMATION mbi = { 0 }, mbi2 = { 0 };
    ULONG bytes = 0;
    VirtualQuery( &Hook, &mbi, sizeof( mbi ) );
    std::wcout << L"mbi.BaseAddress: " << std::hex << mbi.BaseAddress << std::endl;
    detour.Hook( orig, &Hook, HookType::Int3, CallOrder::HookLast, ReturnMethod::UseNew );
    VirtualQuery( &Hook, &mbi2, sizeof( mbi2 ) );
    std::wcout << L"mbi2.BaseAddress: " << std::hex << mbi2.BaseAddress << std::endl;
    return 0;
}

VS debugger can't handle Int3 hooks because of its own exception handler.