{"id":21820468,"url":"https://github.com/smx-smx/ezinject","last_synced_at":"2025-09-11T00:34:30.792Z","repository":{"id":42614921,"uuid":"232076747","full_name":"smx-smx/ezinject","owner":"smx-smx","description":"Modular binary injection framework, successor of libhooker","archived":false,"fork":false,"pushed_at":"2025-03-20T02:00:40.000Z","size":2122,"stargazers_count":94,"open_issues_count":6,"forks_count":18,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-30T03:04:58.186Z","etag":null,"topics":["binary","cross-platform","hook","injection","modular","native","shared-library"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smx-smx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-06T10:25:18.000Z","updated_at":"2025-03-27T13:40:50.000Z","dependencies_parsed_at":"2023-10-13T13:00:34.776Z","dependency_job_id":"1d07116e-7f30-47b1-9550-1425d99adcd5","html_url":"https://github.com/smx-smx/ezinject","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smx-smx%2Fezinject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smx-smx%2Fezinject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smx-smx%2Fezinject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smx-smx%2Fezinject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smx-smx","download_url":"https://codeload.github.com/smx-smx/ezinject/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430870,"owners_count":20937874,"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":["binary","cross-platform","hook","injection","modular","native","shared-library"],"created_at":"2024-11-27T16:34:35.523Z","updated_at":"2025-09-11T00:34:30.779Z","avatar_url":"https://github.com/smx-smx.png","language":"C","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=K58G5YC9M76QN"],"categories":[],"sub_categories":[],"readme":"# ezinject\n\n![poc](doc/ezinject_w95.gif)\n\nModular binary injection framework [![Join us on Discord](https://img.shields.io/static/v1?link=https://discord.gg/wsZhBCEJsX\u0026message=Join%20Discord\u0026logo=discord\u0026style=flat\u0026color=107090\u0026labelColor=5E5E5E\u0026label=\u0026logoColor=white)](https://discord.gg/wsZhBCEJsX)\n\n## What is ezinject\nezinject is a **lightweight** and **flexible** binary injection framework.\nit can be thought as a lightweight and less featured version of frida.\n\nIt's main and primary goal is to load a user module (.dll, .so, .dylib) inside a target process.\nThese modules can augment ezinject by providing additional features, such as hooks, scripting languages, RPC servers, and so on.\nThey can also be written in multiple languages such as C, C++, Rust, etc... as long as the ABI is respected.\n\n**NOTE**: ezinject core is purposedly small, and only implements the \"kernel-mode\" (debugger) features it needs to run the \"user-mode\" program, aka the user module.\n\nIt requires **no dependencies** other than the OS C library (capstone is optionally used only by user modules)\n\nPorting ezinejct is **simple**: No assembly code is required other than a few inline assembly statements, and an abstraction layer separates multiple OSes implementations.\n\nAs proof, it has been ported and battle-tested on a wild variety of Linux devices such as:\n\n- Asus DSL-N55U D1, a Mips BE DSL modem running uClibc and Linux 2.6\n- ADB/DLink DVA-5592, an ARM v7 FPU-less xDSL modem running uClibc and Linux 3.0\n- Samsung GT-i9003 (latona), an Android 2.3 smartphone running Linux 2.6\n- Samsung GT-i9070 (janice), running Android 4\n- Samsung GT-i9300 (smdk4x12), running Android 7\n- pocophone F1 (beryllium), running Android 10\n- TomTom GO 910, a standalone GPS nav running glibc 2.3 and Linux 2.6\n\nas well as wildly different (both POSIX and non-POSIX OSes) such as\n\n- Windows\n- FreeBSD\n- Darwin (macOS)\n\n## Example of modules:\n- hooks example ([libdummy](https://github.com/smx-smx/ezinject/tree/master/samples/dummy))\n- run Python scripts ([pyloader](https://github.com/smx-smx/ezinject/tree/master/samples/pyloader))\n- run PHP scripts ([php](https://github.com/smx-smx/ezinject/tree/master/samples/php))\n- run .NET programs ([mono](https://github.com/smx-smx/ezinject/tree/master/samples/mono), [dotnetcore](https://github.com/smx-smx/ezinject/tree/master/samples/dotnetcore), [EzDotNet](https://github.com/smx-smx/EzDotnet))\n- turn the remote process into an RPC ([ezinject-webapi](https://github.com/smx-smx/ezinject-webapi))\n\nand so on...\n\n## Modules ABI\nShared modules must implement the following 2 functions:\n\n#### `int lib_preinit(struct injcode_user *user)`\nThis function is provided to let the user control the module lifecycle.\n\nFor example, by setting `user-\u003epersist` to 1, the module can be kept persistent in memory once `lib_main` returns.\n\nThis function should always return 0 to signal success.\n\n#### `int lib_main(int argc, char *argv[])`\nIt works just like a typical `main` function in C.\n\n`argv[0]` holds the name of the module, while `argv[1]` onwards are user arguments that you passed to the `ezinject` binary (they are passed to the module as user supplied arguments)\n\n**NOTE**: `lib_main` is executed synchronously, and `ezinject` will not complete until this function has returned. If you need to perform background work, you will need to **make a copy of `argv`** (important, as it will be freed upon return) and start a new thread.\nSee the php module for an example\n\n\n## Supported Architectures:\n- Linux:\n  - arm (arm+thumb)\n  - aarch64\n  - mips\n  - x86\n  - amd64\n  - powerpc32\n  - powerpc64\n  - riscv64\n  - hppa1.1\n\n- Windows: x86, x64\n- FreeBSD: x86, x64\n- Darwin: x64\n\n## Supported C Libraries:\n- Linux\n  - glibc\n  - uClibc (tested on ARM, MIPS)\n  - Android (tested on Android 2.x - 10.x)\n- FreeBSD (tested on FreeBSD 12)\n- Windows\n  - Win32 (tested on Windows 95)\n  - NT (tested on Windows NT 3.51, Windows XP, Windows 10 64bit)\n- Darwin (tested on macOS 11)\n\n## How does it work\n\nezinject implements a single instrumentation primitive: remote calls\n\nWe proceed as following:\n\n- Create a remote memory segment that will hold the payload\n  - If using shared memory, use remote syscalls to attach the shared memory in the target process\n- Invoke the payload remotely.\n\nThe stack at entry will contain a pointer to the context, and a pointer to the function to call.\n- The payload pops the parameters and the function to call from the stack, then calls the function in C (thus emitting a proper call with a stack frame)\n- The payload implementation creates a mutex/event, then opens the target library and awaits for the thread to be created.\n- The ezinject's crt (linked in the library) creates a local copy of the context, then creates a new thread.\n- The crt signals that the thread is ready to be awaited\n- The newly created thread prepares argv, then invokes `lib_preinit` and `lib_main` functions in the library\n- The user code is invoked. It can call any function inside the target, replace or hook functions (with libhooker as part of the CRT, in userland)\n\n## Build\n\nThe following is an example on Debian and derivates, needs to be adjusted for each platform.\n\n1. Install dependencies\n- build-essential\n- cmake\n- libcapstone-dev\n- pkg-config\n\n2. Build the project\n```sh\n./build.sh\n```\n\n## Sample usage\n\n### Linux .so injection\n\nOn Terminal 1\n```sh\n$ cd build/samples/dummy\n$ ./target\n```\n\nOn Terminal 2\n```sh\n$ cd build\n$ sudo ./ezinject `pidof target` samples/dummy/libdummy.so\n```\n\nExpected output\n```text\nreturn1() = 1\n```\nchanges to\n```\nreturn1() = 13370\n```\n\n### Python injection\n\n```sh\necho \"print('hello ' * 3 + 'from python')\" \u003e hello.py\nexport EZPY=`python -c \"import sys; import os; print(os.pathsep.join(sys.path))\"`\necho \"python path: $EZPY\"\n```\n\nFind libpython:\n```\nfind /usr/lib -name \"libpython*\"\n```\n\nPut correct libpython and paths in example below:\n```\nsudo ./ezinject `pidof target` samples/pyloader/libpyloader.so /usr/lib/x86_64-linux-gnu/libpython2.7.so.1 /usr/lib/python2.7 \"$EZPY\" hello.py\n```\n\n## Credits\nThis project has initially been created for the openlgtv community, of which i'm a member. It has since evolved to be a generic tool\n\nThanks to all members of the [openlgtv](https://github.com/openlgtv) and [webosbrew](https://github.com/webosbrew) community for supporting the development by adopting and testing ezinject.\n\nSpecial thanks to:\n- [irsl](https://github.com/irsl), for the initial work on libhooker, which inspired me to get involved\n- [mudkip908](https://github.com/mudkip908), for the preliminar ezinject proof of concept and code review\n\nIf you would like to support the ezinject development, you can\n- use it and spread the word\n- submit issues, suggestions, or pull requests\n- if you feel like, you can donate to me: \u003ca href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=K58G5YC9M76QN\"\u003e\u003cimg src=\"https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif\" alt=\"[paypal]\" /\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmx-smx%2Fezinject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmx-smx%2Fezinject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmx-smx%2Fezinject/lists"}