Home > Programming, Reverse Engineering, Windows > Windows 7 API Hooking

Windows 7 API Hooking

February 25th, 2009

Just wanted to give a heads up to anyone who utilizes API hooking heavily and wants their code to be compatible with Windows 7. Assuming things stay the way they are (which they probably will, this is the first time I’ve seen this before, so its not standard ‘beta build’ practice — checked with Vista and XP) then you will need to modify some of your API hooks.

Kernel32.dll now just ‘wraps’ a lot of APIs and the implementation is actually stored in KernelBase.dll.  This means if you want your code to work properly you’ll have to do this (example given with CreateProcessInternalW — unrelated code removed):

// Hook CreateProcessInternalW in KernelBase if it exists, or in Kernel32 otherwise.
// Needed because API moved to KernelBase in Windows 7.
// TODO: Implement alternative using NTDLL hooks. Priority: 2
FARPROC pCreateProcessInternalW = (hKernelBase) ? (GetProcAddress(hKernelBase,
“CreateProcessInternalW”)) : (GetProcAddress(hKernel32,”CreateProcessInternalW”));
CreateProcessInternalW_Trampoline = reinterpret_cast<tCreateProcessInternalW>(pCreateProcessInternalW);

// Perform the actual API hooking if the pointers are valid
if (pCreateProcessInternalW)

So basically, most of your code can stay the same, it’s just the retrieval of the API pointer that needs to be updated. Whether you’re using GPA, EAT, whatever, you’ll need to check for KernelBase.dll first. Tested and working on XP through Windows 7. Please note I have NOT verified that IAT hooking will work without modifications, but I’m assuming it should.

If you end up testing IAT hooking in Windows 7 please let me know how you go. Also, I haven’t compiled a list yet of all redirected functions, I will if I get the time, otherwise just test your code with CreateProcessInternalW.

Cypher Programming, Reverse Engineering, Windows , , , , ,

  1. DarkPressure
    February 26th, 2009 at 09:02 | #1

    No big change for me at all.
    You shouldn’t make assumptions when coding such stuff, it might always be different. That’s why my functions always took ForwarderRVA into consideration, since my GetProcAddr is custom anywayz.
    But thank you for the info

  2. February 26th, 2009 at 11:50 | #2

    When you’re working at the level I am you can’t help but make assumptions. Most of my hooks are in NTDLL and hence subject to change. Furthermore, I’m doing things like manually unlinking my module, which could easily break in new versions of Windows if they change undocumented structures.

    The fact of the matter is, whilst normally you shouldn’t make assumptions, when you’re working on a very low level project it’s usually impossible because you need to use undocumented structures/functions/features/etc.

  3. February 26th, 2009 at 12:00 | #3

    And oh, just wanted to point out, the forwarding is done like this:

    .text:77E6E8FB public CreateProcessInternalW
    .text:77E6E8FB CreateProcessInternalW proc near
    .text:77E6E8FB ; FUNCTION CHUNK AT .text:77E889DD SIZE 00000006 BYTES
    .text:77E6E8FB mov edi, edi
    .text:77E6E8FD push ebp
    .text:77E6E8FE mov ebp, esp
    .text:77E6E900 pop ebp
    .text:77E6E901 jmp loc_77E889DD
    .text:77E6E901 CreateProcessInternalW endp

    .text:77E889DD ; —————————————————————————
    .text:77E889DD ; START OF FUNCTION CHUNK FOR CreateProcessInternalW
    .text:77E889DD loc_77E889DD: ; CODE XREF: CreateProcessInternalW+6j
    .text:77E889DD jmp ds:CreateProcessInternalW_0
    .text:77E889DD ; END OF FUNCTION CHUNK FOR CreateProcessInternalW
    .text:77E889DD ; —————————————————————————

    So I dunno how sophisticated your tool is but it’s not picked up as a regular forward. Example:
    168 A6 0007E8FB CreateProcessInternalW <- not detected
    237 EB EnterCriticalSection (forwarded to NTDLL.RtlEnterCriticalSection) <- detected

  1. No trackbacks yet.