{"id":16078210,"url":"https://github.com/edouardpoitras/process_injection_example","last_synced_at":"2025-10-15T10:45:05.187Z","repository":{"id":137413389,"uuid":"363011504","full_name":"edouardpoitras/process_injection_example","owner":"edouardpoitras","description":"Linux Remote Process Injection and Hooking Example - htop","archived":false,"fork":false,"pushed_at":"2021-04-30T13:16:08.000Z","size":5,"stargazers_count":9,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T04:41:34.365Z","etag":null,"topics":["example","hook","hooking","linux","remote-process-injection"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/edouardpoitras.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":"2021-04-30T03:06:12.000Z","updated_at":"2025-02-24T16:20:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"8efff280-1003-44e8-ace4-e67d537a5a4f","html_url":"https://github.com/edouardpoitras/process_injection_example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edouardpoitras%2Fprocess_injection_example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edouardpoitras%2Fprocess_injection_example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edouardpoitras%2Fprocess_injection_example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edouardpoitras%2Fprocess_injection_example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edouardpoitras","download_url":"https://codeload.github.com/edouardpoitras/process_injection_example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248358548,"owners_count":21090401,"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":["example","hook","hooking","linux","remote-process-injection"],"created_at":"2024-10-09T10:09:12.304Z","updated_at":"2025-10-15T10:45:00.169Z","avatar_url":"https://github.com/edouardpoitras.png","language":"C","readme":"# Linux Remote Process Injection and Hooking - htop\n\nI was very curious how someone would go about doing this.\nThere seems to be plenty of tools ([Detours](https://github.com/Microsoft/Detours), [EasyHook](https://easyhook.github.io/), etc) and documentation online on how to hook into running processes in Windows, but I had a hard time finding a concrete example online on how to do it in Linux.\nThis is the repository I wish I had found 3 days ago.\n\n## Overview\n\nFor the sake of this exercise, we are going to assume that `htop` is not open-source.\n\nWe want be able to change the uptime value displayed by `htop` while it's running.\n\nFor this we need the name and signature of the function responsible.\n\nFire up `htop` in a terminal window and get it's PID while you're in there.\n\nYou can also get the PID with something like this: `ps aux | grep htop | head -n 1`\n\nIn another terminal window, start a debug session with the `htop` process using it's PID:\n\n    gdb --pid \u003cpid\u003e\n\nOnce attached to the running process, we want to find the function.\nLet's start by searching for a function that has the word `uptime` in it:\n\n    (gdb) set case-sensitive off\n    (gdb) info functions uptime\n    All functions matching regular expression \"uptime\":\n\n    Non-debugging symbols:\n    0x000055caa45ceba0  Platform_getUptime\n\nLooks like `Platform_getUptime` is what we're looking for.\nLet's add a breakpoint on that function call so we can see examine it's return value:\n\n    (gdb) break Platform_getUptime\n    Breakpoint 1 at 0x55caa45ceba0\n    (gdb) continue\n    Continuing.\n\n    Breakpoint 1, 0x000055caa45ceba0 in Platform_getUptime ()\n\nLooks like we hit it immediately. Now let's get it's return value:\n\n    (gdb) finish\n    Run till exit from #0  0x000055caa45ceba0 in Platform_getUptime ()\n    0x000055caa45c654d in ?? ()\n    (gdb) print $rax\n    $1 = 50689\n\nNOTE: You may need to use the 32-bit $eax register instead. Also this may not work on some CPUs.\n\nIt returned the value 50689, which is roughly the number of seconds my machine has been on.\n\nAs a proof of concept, let's return the value 1 directly and see what that does.\n\n    (gdb) return (int)1\n    Make selected stack frame return now? (y or n) y\n    #0  0x000055caa45c654d in ?? ()\n    (gdb) continue\n    Continuing.\n\n    Breakpoint 1, 0x000055caa45ceba0 in Platform_getUptime ()\n\nWe've come back around to our breakpoint and you should now see an uptime of `00:00:01` in `htop`.\n\nAt this point we have enough information to write our hook.\n\n### htop_hook.c\n\nCode is short and well documented, but essentially we're using the [subhook](https://github.com/Zeex/subhook) library to hook `htop`'s `Platform_getUptime()` function so that it always returns 0. This results in the htop process always displaying an uptime value or 0.\n\n### inject.py\n\nA very simple script to find the PID of a running process by name and inject a shared library.\n\nWe are injecting our hook using the [pyinjector](https://github.com/kmaork/pyinjector) python library which is a wrapper around [kubo/injector](https://github.com/kubo/injector).\n\n## Prerequisites\n\nYou'll need a C compiler, cmake, python + pip, and `htop`.\n\nDon't forget to clone recursively to pull in the [subhook](https://github.com/Zeex/subhook) dependency.\n\n    git clone --recursive https://github.com/edouardpoitras/process_injection_example.git\n\n### Building\n\nShould be as simple as:\n\n    cmake .\n    make\n\nAlso need the python dependency:\n\n    pip install pyinjector\n\n### Kernel ptrace\n\nThe Linux kernel makes this possible through the use of [ptrace](https://man7.org/linux/man-pages/man2/ptrace.2.html). Because this is a rather sketchy thing to do usually only performed by debuggers, anti-virus', or malicious actors, the Linux Security Module (yama) will give you a hard time unless your system is configured to allow it.\n\nYou can temporarily disable the [ptrace](https://man7.org/linux/man-pages/man2/ptrace.2.html) restriction (until reboot) by modifying the ptrace_scope value:\n\n    echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope\n\nMore information can be found [here](https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama.html).\n\n## Running\n\nEnsure `htop` is running in a terminal on your machine, then inject the hook with the command:\n\n    python inject.py htop libhtop_hook.so\n\nYou should notice the `uptime` value change to `00:00:00`.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedouardpoitras%2Fprocess_injection_example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedouardpoitras%2Fprocess_injection_example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedouardpoitras%2Fprocess_injection_example/lists"}