{"id":16839490,"url":"https://github.com/sigmasd/rhook","last_synced_at":"2025-09-13T16:48:29.530Z","repository":{"id":113562498,"uuid":"354387335","full_name":"sigmaSd/Rhook","owner":"sigmaSd","description":"Hook libc functions with super easy API","archived":false,"fork":false,"pushed_at":"2023-10-01T11:00:39.000Z","size":85,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T03:24:48.488Z","etag":null,"topics":["hook","libc","rust"],"latest_commit_sha":null,"homepage":"https://docs.rs/rhook","language":"Rust","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/sigmaSd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","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-03T20:25:13.000Z","updated_at":"2024-04-20T19:35:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"25c30017-8c9a-4e0c-972a-1af5496dcd16","html_url":"https://github.com/sigmaSd/Rhook","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/sigmaSd%2FRhook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigmaSd%2FRhook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigmaSd%2FRhook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sigmaSd%2FRhook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sigmaSd","download_url":"https://codeload.github.com/sigmaSd/Rhook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248346251,"owners_count":21088424,"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":["hook","libc","rust"],"created_at":"2024-10-13T12:32:31.719Z","updated_at":"2025-04-11T05:21:27.474Z","avatar_url":"https://github.com/sigmaSd.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rhook\n\nHook libc functions with an easy API\n\n### Usage\n\n1- Import the trait [RunHook]\n\n2- Create an [Command](std::process::Command) with [Command::new](std::process::Command::new) and add hooks to it via [add_hook](RunHook::add_hook) and [add_hooks](RunHook::add_hooks) methods\n\n3- Confirm the hooks with [set_hooks](Anchor::set_hooks) method this step is necessary\n\n3.1- Hooks are closures that takes no input and return an option of the libc function as output.\n\nIf the closure return `None` that is equivalent to returning `Some(original_function(args))` in\nother words it will run and use the original function output\n\nInside the closure you have access to the libc function input + some imports from std (see\nsrc/scaffold.rs)\n\n4- Now you can carry on with the usual [Command](std::process::Command) methods ([output](std::process::Command::output), [spawn](std::process::Command::spawn),[status](std::process::Command::status),..)\n\n\n**Tricks:**\n\nThe closure used for hooks have acess to many things: (imported by https://github.com/sigmaSd/Rhook/blob/master/src/scaffold.rs)\n- closure input (which is the libc function input)\n- closure output (which is the libc function output)\n- The original function with the following name `original_$libcfn` this is useful in particular to avoid recursion\n- Some varaibles to make coding easier: `transmute` `ManuallyDrop` `CString` and a static mut `COUNTER`\n- You can find the input/output of a function by looking it up here [libc](https://docs.rs/libc)\n- Add `.map_err(|e|println!(\"{}\",e))` after `set_hooks` in order to prettify the dynamic library compiling error while debugging\n- If you take ownership of an input value inside of the closure, be sure to use ManuallyDrop so you don't free it\n\n### Example\n\nSay you want to limit the bandwidth of a program\n\nUsually downloading calls `libc::recv` function\n\nSo our goal is to throttle it with a simple sleep\n\nTo do that with this crate: (taking speedtest program as an example)\n\n1- Look up its doc's here  [recv](https://docs.rs/libc/0.2.93/libc/fn.recv.html) to see what the\nfunction's input/output is\n\n2- use this crate\n```rust\nuse rhook::{Hook, RunHook};\n\nfn main() {\n    std::process::Command::new(\"speedtest\")\n        .add_hook(Hook::recv(stringify!(|| {\n            std::thread::sleep(std::time::Duration::from_millis(10));\n            // since we're not doing any modification to the output you can just return None here\n            Some(original_recv(socket, buf, len, flags))\n        })))\n        .set_hooks()\n        //  uncomment this line to get readable error in case of a panic\n        // .map_err(|e| println!(\"{}\", e))\n        .unwrap()\n        .spawn()\n        .unwrap();\n}\n```\n\nThats it!\nNote that you have acess inside the closure to the original function denoted by the prefix\n`original_` + the function name\n\nCheck out the examples for more info\n\nLicense: MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsigmasd%2Frhook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsigmasd%2Frhook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsigmasd%2Frhook/lists"}