# 15. IAT hooking

Note

See sample IAT hooking

## 15.1. Putting an IAT hook

To setup your IAT hook you just need:

> - A callback that respect the Hook protocol
> - The `windows.pe_parse.IATEntry` to hook

You just need to use the function `windows.pe_parse.IATEntry.set_hook()`

Putting a hook:

    import windows
    from windows.hooks import *

    @CreateFileACallback
    def createfile_callback(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, real_function):
        print("Trying to open {0}".format(lpFileName))
        if "secret" in lpFileName:
            return 0xffffffff
        return real_function()

    my_exe = windows.current_process.peb.modules[0]
    imp = my_exe.pe.imports

    iat_create_file = [entry for entry in imp['kernel32.dll'] if entry.name == "CreateFileA"]
    iat_create_file.set_hook(createfile_callback)

## 15.2. Hook protocol

### 15.2.1. Callback arguments

A hook callback must have the same number of argument as the hooked API, PLUS a last argument `real_function`.

The `real_function` argument is a callable that represent the hooked API, it can be called in two ways:

> - Without argument, the call will be done with the argument originaly passed to your callback. This allows simple redirection to the real API.
> - With arguments it will simply call the API with these.

Example:

    def createfile_callback(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, real_function):
        print("Trying to open {0}".format(lpFileName))
        if "secret" in lpFileName:
            return 0xffffffff
        # Perform the real call
        return real_function()

A hook callback must also embed some Type Information

### 15.2.2. Callback type information

In order make the magic behind hook callback, `ctypes` needs to have type information about the API parameters.

There is (again) two ways to give those informations to your hook callback. Both techniques use a decorator to setup type information to the callback.

> - Giving the type manualy using the decorator `windows.hooks.Callback`:

>       from windows.hooks import *
>       # First type is return type, others are parameters types
>       @Callback(ctypes.c_void_p, ctypes.c_ulong)
>       def exit_callback(x, real_function):
>           print("Try to quit with {0} | {1}".format(x, type(x)))
>           if x == 3:
>               print("TRYING TO REAL EXIT")
>               return real_function(1234)
>           return 0x4242424243444546

> - Using the Callback decorator generated from known functions:

>       from windows.hooks import *
>       # Decorator name is always API_NAME + "CallBack"
>       @CreateFileACallback
>       def createfile_callback(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, real_function):
>           print("Trying to open {0}".format(lpFileName))
>           if "secret" in lpFileName:
>               return 0xffffffff
>           return real_function()

> Note

> See the list of known functions

## 15.3. `windows.hooks`

class `windows.hooks.``Callback`(*types)

  Give type information to hook callback

class `windows.hooks.``IATHook`(IAT_entry, callback, types=None)

  Look at my hook <3

  `disable`()

    Disable the IAT hook

  `enable`()

    Enable the IAT hook: you MUST keep a reference to the IATHook while the hook is enabled