{"id":19851858,"url":"https://github.com/stackoverflowexcept1on/net-core-injector","last_synced_at":"2025-10-08T18:35:12.806Z","repository":{"id":138029503,"uuid":"537577706","full_name":"StackOverflowExcept1on/net-core-injector","owner":"StackOverflowExcept1on","description":"CLI tool that can replace C# methods in .NET Core applications","archived":false,"fork":false,"pushed_at":"2025-06-12T12:08:06.000Z","size":196,"stargazers_count":67,"open_issues_count":1,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-12T12:36:05.123Z","etag":null,"topics":["charp","dll-injector","dotnet","frida","reverse-engineering"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StackOverflowExcept1on.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-09-16T18:33:20.000Z","updated_at":"2025-06-12T12:08:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"21538fd9-33bb-4c41-bef9-74199735f91e","html_url":"https://github.com/StackOverflowExcept1on/net-core-injector","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/StackOverflowExcept1on/net-core-injector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StackOverflowExcept1on%2Fnet-core-injector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StackOverflowExcept1on%2Fnet-core-injector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StackOverflowExcept1on%2Fnet-core-injector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StackOverflowExcept1on%2Fnet-core-injector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StackOverflowExcept1on","download_url":"https://codeload.github.com/StackOverflowExcept1on/net-core-injector/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StackOverflowExcept1on%2Fnet-core-injector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278991668,"owners_count":26081398,"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","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["charp","dll-injector","dotnet","frida","reverse-engineering"],"created_at":"2024-11-12T13:33:02.203Z","updated_at":"2025-10-08T18:35:12.770Z","avatar_url":"https://github.com/StackOverflowExcept1on.png","language":"C","readme":"### net-core-injector\n\n[![Build Status](https://github.com/StackOverflowExcept1on/net-core-injector/actions/workflows/ci.yml/badge.svg)](https://github.com/StackOverflowExcept1on/net-core-injector/actions/workflows/ci.yml)\n\nIn the following GIF, you can see how the code on the right intercepts the `static void F(int i)` function.\nAfter injecting, the original program starts outputting `1337` to the console instead of the default behavior.\n\n![banner](https://i.imgur.com/PzaC0br.gif)\n\nCLI tool that can replace C# methods in .NET Core applications\n\n### Requirements\n\n- C++ \u0026 C#\n  - Linux: g++, .NET 8: https://dotnet.microsoft.com/en-us/download/dotnet/8.0\n  - Windows: Visual Studio 2022 with installed C++ \u0026 C# build tools: https://visualstudio.microsoft.com/en/vs/\n- Node.js: https://nodejs.org/en/download/\n- frida: https://frida.re\n\n### Building\n\nOpen command line and run this script\n\n- `_build.sh` on Linux\n- `_build.bat` on Windows\n\nIt will build\n\n- Node.js package [net-core-injector](package.json) - DLL-injector written in TypeScript\n- [Bootstrapper](Bootstrapper) - helper native library written in C++ to interact with .NET Core runtime\n- [DemoApplication](DemoApplication) - test application to demonstrate how it works\n- [RuntimePatcher](RuntimePatcher) - code that attaches to [DemoApplication](DemoApplication)\n\n### Running\n\nThis script should produce output like the GIF above\n\n- `_run.sh` on Linux\n\n  Note: If you want to attach to an existing process on Linux, this requires root privileges. In this case, use\n  `_run.sh -a` (attach).\n\n- `_run.bat` on Windows\n\n### Internal documentation\n\nIt's mostly based on Microsoft documentation:\n[Write a custom .NET host to control the .NET runtime from your native code](https://learn.microsoft.com/en-us/dotnet/core/tutorials/netcore-hosting)\n\nTL;DR: each process that runs on .NET Core uses `hostfxr.dll` or `libhostfxr.so`. This library is loaded in its memory.\n\nTo load a custom C# assembly (also known as a DLL), you need to manipulate with `hostfxr` first.\nI did it in [`Bootstrapper/src/library.cpp`](Bootstrapper/src/library.cpp).\n\n[`net-core-injector/src/main.ts`](src/main.ts) injects `Bootstrapper.dll` into C# process and loads custom assembly\n\nThe following command runs `DemoApplication.exe` on another thread and injects code.\n\n```\nstart DemoApplication\\dist\\DemoApplication.exe\n\nnpm start -- inject ^\nDemoApplication.exe ^\nBootstrapper\\build\\Release\\Bootstrapper.dll ^\nRuntimePatcher\\dist\\RuntimePatcher.runtimeconfig.json ^\nRuntimePatcher\\dist\\RuntimePatcher.dll ^\n\"RuntimePatcher.Main, RuntimePatcher\" \"InitializePatches\"\n```\n\nThen the execution happens in this order:\n\n1. get into `DemoApplication.exe` process memory via DLL-injection of `Bootstrapper.dll`\n2. call native C++ code\n   ```cpp\n   bootstrapper_load_assembly(\n       /*runtime_config_path = */\"RuntimePatcher\\\\dist\\\\RuntimePatcher.runtimeconfig.json\",\n       /*assembly_path = */\"RuntimePatcher\\\\dist\\\\RuntimePatcher.dll\",\n       /*type_name = */\"RuntimePatcher.Main, RuntimePatcher\",\n       /*method_name = */\"InitializePatches\"\n   )\n   ```\n3. [`RuntimePatcher/Lib.cs`](RuntimePatcher/RuntimePatcher/Lib.cs) attaches to code of `DemoApplication.exe`\n\n### Application in real world\n\nI injected my DLL into the GitHub Actions security system and received money and a t-shirt from HackerOne\n\nAlso see: https://github.com/StackOverflowExcept1on/how-to-hack-github-actions\n\nYou can use this to mod games written in C# or to patch any software\n\n### TODO\n\n- I don't have macOS device so it's supported for now. External contributors are welcome.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackoverflowexcept1on%2Fnet-core-injector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstackoverflowexcept1on%2Fnet-core-injector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackoverflowexcept1on%2Fnet-core-injector/lists"}