A forum for reverse engineering, OS internals and malware analysis 

 #1970  by Mehdi
 Sat Aug 14, 2010 11:25 am
Hello everyone
I want to call ZwQueryVirtualMemory in Windows XP SP2 (This syscall is not exported from ntoskrnl.exe in Win XP)
I've succeeded with using the hard-coded address (for proof of concept), now I want a better and more stable solution.
Code: Select all
MyZwQueryVirtualMemory zwQVM = (MyZwQueryVirtualMemory)0x805ACD0E;
How I can reliably find the address of ZwQueryVirtualMemory and call it ?
(I've read that using unexported system calls from kernel mode is not recommended, but for my utility which is a Kernel mode memory dumper I need it)

Thank you very much
 #1972  by Mehdi
 Sat Aug 14, 2010 11:43 am
Thanks, but
1- my code is kernel mode.
2- And ZW* functions are in ntoskrnl (not ntdll)
 #1973  by GamingMasteR
 Sat Aug 14, 2010 11:45 am
Code: Select all
#define SYSCALL_INDEX(_address) *(PULONG)((PUCHAR)_address+1)

VOID GetNtQueryVirtualMemory(VOID)
{
    ASSERT(Irql <= APC_LEVEL)
    Ntdll = GetNtdllImageBase(); // Ntdll.dll is mapped into all processes VM by default
    if (Ntdll == NULL)
        return;
    lpNtQueryVirtualMemory =  KeServiceDescriptorTable[SYSCALL_INDEX(GetProcAddress(NtDll, "ZwQueryVirtualMemory"))].ServiceRoutine;
}
Or you can send the service index from the application to the driver while initializing .
Last edited by GamingMasteR on Sat Aug 14, 2010 1:48 pm, edited 1 time in total. Reason: Zw -> Nt, thanks EP for correction
 #1974  by Mehdi
 Sat Aug 14, 2010 1:09 pm
Thanks. Your post was very helpful
First I tried using MmGetSystemRoutineAddress, but it returns NULL for ZwQueryVirtualMemory.
Now I'm using this code (I've hardcoded the index, because it only runs on XP SP0-SP2) and it works.
Code: Select all
DWORD* systemCallTable              = (DWORD*)KeServiceDescriptorTable.KiServiceTable;
MyZwQueryVirtualMemory	zwQVM = (MyZwQueryVirtualMemory)(systemCallTable[0xB2]);
One question: GetProcAddress is a user mode function. How can we run it in kernel ?
 #1975  by EP_X0FF
 Sat Aug 14, 2010 1:15 pm
For a beginner, more efficient solution is to hardcode NtQueryVirtualMemory SSDT index inside driver.