This repository contains two projects that are designed to be used together:
- InjectorCli: A .NET Framework 4.8 console injector built on frida-clr (
Frida.dll) - ManagedHookHostProj: A .NET Framework 4.8 helper DLL with native exports (via 3F .NET DllExport) used to resolve managed methods to native entrypoints so Frida can attach
- TestTarget32: An example .NET Framework 4.8 program to test the hooking against.
These projects target Windows and assume you are instrumenting processes you own or have permission to test.
Frida hooks native code addresses. On .NET Framework, managed methods are JIT-compiled into native code, but:
- Frida does not ship a stable “hook managed method by name” API for .NET Framework
- Method addresses are not known until the JIT compiles the method
So the overall pattern is:
- Use
InjectorClito attach/spawn a target and load a Frida JavaScript agent. - Inside the target, use
ManagedHookHostProj.dllto:- Find a managed method by reflection
- Force it to JIT (
RuntimeHelpers.PrepareMethod) - Return the method’s native entrypoint (
GetFunctionPointer)
- Back in the agent, call
Interceptor.attach(entrypoint, ...)to trace calls/ log args/ (optionally) alter behavior.
InjectorCli (C#)
- creates
Frida.DeviceManagerand selects a device - spawns or attaches to a process
- creates a
Frida.Scriptfrom your JavaScript file and loads it - prints messages from the agent via
script.Message
Agent (JavaScript)
- can hook normal Win32 APIs directly (e.g.
CreateFileW,MessageBoxW) - can optionally
Module.load()the managed helper DLL - calls exported helpers (e.g.
ResolveMethod) viaNativeFunction - uses helper-managed UTF-16 buffers (
DescribeObjectUtf16+FreeUtf16) instead of CLR string layout parsing - can query helper diagnostics using
GetLastErrorUtf16when resolution fails - uses returned addresses to attach hooks
ManagedHookHostProj (C# class library with exports)
- runs inside the target’s CLR
- uses reflection to locate the method you want by name (+ optional overload signature)
- forces JIT compilation and returns the native entrypoint address
- provides safe primitive read/write exports for by-ref values (
ReadInt32/WriteInt32/WriteBool) - exposes thread-local helper diagnostics (
GetLastErrorUtf16,ClearLastError)
To illustrate how all these work, we will assume that the target process is compiled to target 32-bit (WoW64) CPU architecture.
- You need an x86
Frida.dllto inject into an x86 target process. - Example commands (from a Visual Studio Developer Command Prompt):
cd C:\path\to\frida-clr
configure.bat --prefix="%CD%\dist-x86" --build=windows-x86-md
cd build
make.bat
make.bat installConfirm you have:
dist-x86\bin\Frida.dll(PE32)
-
You need to open InjectorCli.sln in Visual Studio, and set build target to
Release | x86. -
Or from a Developer Command Prompt:
msbuild \InjectorCli\InjectorCli.sln /p:Configuration=Release /p:Platform=x86- If your
Frida.dllis not atdist-x86\bin\Frida.dll, update the reference in InjectorCli.csproj accordingly.
-
You need to open ManagedHookHostProj.sln in Visual Studio, and set build target to
Release | x86. -
Or from a Developer Command Prompt:
msbuild \ManagedHookHostProj\ManagedHookHostProj.sln /p:Configuration=Release /p:Platform=x86- You can then verify exports by running the following command in the Developer Command Prompt:
dumpbin /exports examples\ManagedHookHostProj\bin\Release\ManagedHookHostProj.dllNote: on x86 + StdCall you may see decorated export names (e.g. _ResolveMethod@16). The provided agent script includes a fallback that locates decorated names.
- Attach to an existing PID:
FridaClrInjector.exe --pid 1234 --script hooks\hook_createfilew.js- Spawn suspended, inject, resume:
FridaClrInjector.exe --spawn "C:\Windows\SysWOW64\notepad.exe" --script hooks\hook_messagebox.js-
You should first edit hook_managed.js, by setting:
helperDllPathto the builtManagedHookHostProj.dlltargetAssemblyPath,targetTypeName,targetMethodName,paramSig
-
Then run:
FridaClrInjector.exe --pid 1234 --script "C:\path\to\hook_managed.js"- Inlining: small methods may be inlined in Release builds, and your hook won’t trigger.
- Overloads: use
paramSigto select the correct overload, otherwise you may hook the wrong one. - Bitness must match: x86 target requires x86 injector + x86
Frida.dll+ x86 helper DLL. - Raw managed refs are fragile: legacy helper exports (
MakeString/Box*/DescribeObject) should be treated as compatibility-only.
-
Injector docs:
-
Helper DLL docs:
-
Example Test Target docs: