Need help with khook?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

milabs
137 Stars 31 Forks GNU General Public License v2.0 33 Commits 1 Opened issues

Description

Linux Kernel hooking engine (x86)

Services available

!
?

Need anything else?

Contributors list

# 96,106
Objecti...
C
Qt
Linux
33 commits

0

KHOOK (خوک) - Linux Kernel hooking engine.

Usage

Include KHOOK engine: ~~~

include "khook/engine.c"

Add the following line to the KBuild/Makefile:

ldflags-y += -T$(src)/khook/engine.lds (use LDFLAGS for old kernels) ~~~

Use

khook_init()
and
khook_cleanup()
to initalize and de-initialize hooking engine.

Examples

Hooking of generic kernel functions

An example of hooking a kernel function with known prototype (function is defined in

linux/fs.h
): ~~~

include // has inode_permission() proto

KHOOK(inodepermission); static int khookinodepermission(struct inode *inode, int mask) { int ret = 0; ret = KHOOKORIGIN(inodepermission, inode, mask); printk("%s(%p, %08x) = %d\n", _func__, inode, mask, ret); return ret; } ~~~

An example of hooking a kernel function with custom prototype (function is not defined in

linux/binfmts.h
): ~~~

include // has no loadelfbinary() proto

KHOOKEXT(int, loadelfbinary, struct linuxbinprm *); static int khookloadelfbinary(struct linuxbinprm *bprm) { int ret = 0; ret = KHOOKORIGIN(loadelfbinary, bprm); printk("%s(%p) = %d (%s)\n", _func__, bprm, ret, bprm->filename); return ret; } ~~~

Starting from a6e7f394 it's possible to hook a function with big amount of arguments. This requires for

KHOOK
to make a local copy of N (hardcoded as 8) arguments which are passed through the stack before calling the handler function.

An example of hooking 12 argument function

scsi_execute
is shown below (see #5 for details):
#include 
KHOOK(scsi_execute);
static int khook_scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, unsigned char *sense, struct scsi_sense_hdr *sshdr, int timeout, int retries, u64 flags, req_flags_t rq_flags, int *resid)
{
        int ret = 0;
        ret = KHOOK_ORIGIN(scsi_execute, sdev, cmd, data_direction, buffer, bufflen, sense, sshdr, timeout, retries, flags, rq_flags, resid);
        printk("%s(%lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx) = %d\n", __func__, (long)sdev, (long)cmd, (long)data_direction, (long)buffer, (long)bufflen, (long)sense, (long)sshdr, (long)timeout, (long)retries, (long)flags, (long)rq_flags, (long)resid ,ret);
        return ret;
}

Hooking of system calls (handler functions)

An example of hooking

kill(2)
system call handler (see #3 for the details): ~~~ // long syskill(pidt pid, int sig) KHOOKEXT(long, syskill, long, long); static long khooksyskill(long pid, long sig) { printk("syskill -- %s pid %ld sig %ld\n", current->comm, pid, sig); return KHOOKORIGIN(sys_kill, pid, sig); }

// long syskill(const struct ptregs *regs) -- modern kernels KHOOKEXT(long, _x64syskill, const struct ptregs *); static long khookx64syskill(const struct ptregs *regs) { printk("syskill -- %s pid %ld sig %ld\n", current->comm, regs->di, regs->si); return KHOOK_ORIGIN(x64syskill, regs); } ~~~

Features

  • x86 only
  • 2.6.33+ kernels
  • use of in-kernel length disassembler

How it works?

The diagram below illustrates the call to function

X
without hooking:
CALLER
| ...
| CALL X -(1)---> X
| ...  

The diagram below illustrates the call to function

X
when
KHOOK
is used:
CALLER
| ...
| CALL X -(1)---> X
| ...   STUB.hook
` RET       |     | ???            | INCR use_count
            |     | ...   HOOK.fn
            |     | ...       |    | DECR use_count  STUB.orig
            |            |    |           |              |    | ...  

License

This software is licensed under the GPL.

Author

Ilya V. Matveychikov

2018, 2019, 2020

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.