{"id":15003683,"url":"https://github.com/milabs/khook","last_synced_at":"2025-05-16T13:02:11.974Z","repository":{"id":45818146,"uuid":"147030504","full_name":"milabs/khook","owner":"milabs","description":"Linux Kernel hooking engine (x86)","archived":false,"fork":false,"pushed_at":"2024-12-04T23:42:47.000Z","size":62,"stargazers_count":340,"open_issues_count":2,"forks_count":51,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-09T08:04:39.543Z","etag":null,"topics":["hooking","linux-kernel","linux-kernel-module","x86"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/milabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-01T20:27:45.000Z","updated_at":"2025-04-03T05:54:22.000Z","dependencies_parsed_at":"2024-05-17T08:28:37.297Z","dependency_job_id":"4298cc35-e0e1-4b40-a38a-e7a067593e5e","html_url":"https://github.com/milabs/khook","commit_stats":{"total_commits":52,"total_committers":1,"mean_commits":52.0,"dds":0.0,"last_synced_commit":"bdead379ff8a7ad9ed0730fdfda8b11834fbc145"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milabs%2Fkhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milabs%2Fkhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milabs%2Fkhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/milabs%2Fkhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/milabs","download_url":"https://codeload.github.com/milabs/khook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254535787,"owners_count":22087394,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hooking","linux-kernel","linux-kernel-module","x86"],"created_at":"2024-09-24T19:00:18.048Z","updated_at":"2025-05-16T13:02:11.943Z","avatar_url":"https://github.com/milabs.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 0\n\nKHOOK (خوک) - Linux Kernel hooking engine.\n\n# Usage\n\nInclude `Makefile.khook` to your `Makefile/Kbuild` file:\n~~~\nMODNAME      ?= your-module-name\n...\ninclude      /path/to/khook/Makefile.khook\n...\n$(MODNAME)-y += $(KHOOK_GOALS)\nccflags-y    += $(KHOOK_CCFLAGS)\nldflags-y    += $(KHOOK_LDFLAGS) # use LDFLAGS for old kernels\n...\n~~~\n\nThen, include KHOOK engine header like follows:\n~~~\n#include \u003ckhook/engine.h\u003e\n~~~\n\nUse `khook_init(lookup)` and `khook_cleanup()` to initalize and de-initialize hooking engine.\n\nUse `khook_lookup_name(sym)` to resolve `sym` address.\n\nUse `khook_write_kernel(fn, arg)` to write kernel read-only data.\n\n# Examples\n\nSee the `khook_demo` folder for examples. Use `make` to build it.\n\n## Hooking of generic kernel functions \n\nAn example of hooking a kernel function with known prototype (function is defined in `linux/fs.h`):\n~~~\n#include \u003clinux/fs.h\u003e // has inode_permission() proto\nKHOOK(inode_permission);\nstatic int khook_inode_permission(struct inode *inode, int mask)\n{\n        int ret = 0;\n        ret = KHOOK_ORIGIN(inode_permission, inode, mask);\n        printk(\"%s(%p, %08x) = %d\\n\", __func__, inode, mask, ret);\n        return ret;\n}\n~~~\n\nAn example of hooking a kernel function with custom prototype (function is not defined in `linux/binfmts.h`):\n~~~\n#include \u003clinux/binfmts.h\u003e // has no load_elf_binary() proto\nKHOOK_EXT(int, load_elf_binary, struct linux_binprm *);\nstatic int khook_load_elf_binary(struct linux_binprm *bprm)\n{\n        int ret = 0;\n        ret = KHOOK_ORIGIN(load_elf_binary, bprm);\n        printk(\"%s(%p) = %d (%s)\\n\", __func__, bprm, ret, bprm-\u003efilename);\n        return ret;\n}\n~~~\n\nStarting from [a6e7f394](https://github.com/milabs/khook/commit/a6e7f3945a4eebb811818f62bd2cf2ea50f609c0) 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.\n\nAn example of hooking 12 argument function `scsi_execute` is shown below (see [#5](/../../issues/5) for details):\n\n~~~\n\n#include \u003cscsi/scsi_device.h\u003e\nKHOOK(scsi_execute);\nstatic 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)\n{\n        int ret = 0;\n        ret = KHOOK_ORIGIN(scsi_execute, sdev, cmd, data_direction, buffer, bufflen, sense, sshdr, timeout, retries, flags, rq_flags, resid);\n        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);\n        return ret;\n}\n\n~~~\n\nStarting from [f996ce39](https://github.com/milabs/khook/commit/f996ce39fbcb70ed3e6565808b2b76afe6b5e8ff) it's possible to hook `x86-32` kernels as correct trampoline has been implemented.\n\n## Hooking of system calls (handler functions)\n\nAn example of hooking `kill(2)` system call handler (see [#3](/../../issues/3) for the details):\n~~~\n// long sys_kill(pid_t pid, int sig)\nKHOOK_EXT(long, sys_kill, long, long);\nstatic long khook_sys_kill(long pid, long sig) {\n        printk(\"sys_kill -- %s pid %ld sig %ld\\n\", current-\u003ecomm, pid, sig);\n        return KHOOK_ORIGIN(sys_kill, pid, sig);\n}\n\n// long sys_kill(const struct pt_regs *regs) -- modern kernels\nKHOOK_EXT(long, __x64_sys_kill, const struct pt_regs *);\nstatic long khook___x64_sys_kill(const struct pt_regs *regs) {\n        printk(\"sys_kill -- %s pid %ld sig %ld\\n\", current-\u003ecomm, regs-\u003edi, regs-\u003esi);\n        return KHOOK_ORIGIN(__x64_sys_kill, regs);\n}\n~~~\n\n# Features\n\n- x86 only\n- 2.6.33+ kernels\n- use of in-kernel length disassembler\n- ready-to-use submodule with no external deps\n\n# How it works?\n\nThe diagram below illustrates the call to function `X` without hooking:\n\n~~~\nCALLER\n| ...\n| CALL X -(1)---\u003e X\n| ...  \u003c----.     | ...\n` RET       |     ` RET -.\n            `--------(2)-'\n~~~\n\nThe diagram below illustrates the call to function `X` when `KHOOK` is used:\n\n~~~\nCALLER\n| ...\n| CALL X -(1)---\u003e X\n| ...  \u003c----.     | JUMP -(2)----\u003e khook_X_stub\n` RET       |     | ???            | INCR use_count\n            |     | ...  \u003c----.    | CALL handler   -(3)----\u003e khook_X\n            |     | ...       |    | DECR use_count \u003c----.    | ...\n            |     ` RET -.    |    ` RET -.              |    | CALL origin -(4)----\u003e khook_X_orig\n            |            |    |           |              |    | ...  \u003c----.           | N bytes of X\n            |            |    |           |              |    ` RET -.    |           ` JMP X + N -.\n            `------------|----|-------(8)-'              '-------(7)-'    |                        |\n                         |    `-------------------------------------------|--------------------(5)-'\n                         `-(6)--------------------------------------------'\n~~~\n\n# License\n\nThis software is licensed under the GPL.\n\n# Author\n\n[Ilya V. Matveychikov](https://github.com/milabs)\n\n2018, 2019, 2020, 2022, 2023, 2024\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilabs%2Fkhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmilabs%2Fkhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmilabs%2Fkhook/lists"}