In the following GIF, you can see how the code on the right intercepts the static void F(int i) function.
After injecting, the original program starts outputting 1337 to the console instead of the default behavior.
CLI tool that can replace C# methods in .NET Core applications
- C++ & C#
- Linux: g++, .NET 8: https://dotnet.microsoft.com/en-us/download/dotnet/8.0
- Windows: Visual Studio 2022 with installed C++ & C# build tools: https://visualstudio.microsoft.com/en/vs/
- Node.js: https://nodejs.org/en/download/
- frida: https://frida.re
Open command line and run this script
_build.shon Linux_build.baton Windows
It will build
- Node.js package net-core-injector - DLL-injector written in TypeScript
- Bootstrapper - helper native library written in C++ to interact with .NET Core runtime
- DemoApplication - test application to demonstrate how it works
- RuntimePatcher - code that attaches to DemoApplication
This script should produce output like the GIF above
-
_run.shon LinuxNote: If you want to attach to an existing process on Linux, this requires root privileges. In this case, use
_run.sh -a(attach). -
_run.baton Windows
It's mostly based on Microsoft documentation: Write a custom .NET host to control the .NET runtime from your native code
TL;DR: each process that runs on .NET Core uses hostfxr.dll or libhostfxr.so. This library is loaded in its memory.
To load a custom C# assembly (also known as a DLL), you need to manipulate with hostfxr first.
I did it in Bootstrapper/src/library.cpp.
net-core-injector/src/main.ts injects Bootstrapper.dll into C# process and loads custom assembly
The following command runs DemoApplication.exe on another thread and injects code.
start DemoApplication\dist\DemoApplication.exe
npm start -- inject ^
DemoApplication.exe ^
Bootstrapper\build\Release\Bootstrapper.dll ^
RuntimePatcher\dist\RuntimePatcher.runtimeconfig.json ^
RuntimePatcher\dist\RuntimePatcher.dll ^
"RuntimePatcher.Main, RuntimePatcher" "InitializePatches"
Then the execution happens in this order:
- get into
DemoApplication.exeprocess memory via DLL-injection ofBootstrapper.dll - call native C++ code
bootstrapper_load_assembly( /*runtime_config_path = */"RuntimePatcher\\dist\\RuntimePatcher.runtimeconfig.json", /*assembly_path = */"RuntimePatcher\\dist\\RuntimePatcher.dll", /*type_name = */"RuntimePatcher.Main, RuntimePatcher", /*method_name = */"InitializePatches" )
RuntimePatcher/Lib.csattaches to code ofDemoApplication.exe
I injected my DLL into the GitHub Actions security system and received money and a t-shirt from HackerOne
Also see: https://github.com/StackOverflowExcept1on/how-to-hack-github-actions
You can use this to mod games written in C# or to patch any software
- I don't have macOS device so it's supported for now. External contributors are welcome.
