Devlooped.Injector 1.0.0-beta

Prefix Reserved
This is a prerelease version of Devlooped.Injector.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Devlooped.Injector --version 1.0.0-beta                
NuGet\Install-Package Devlooped.Injector -Version 1.0.0-beta                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Devlooped.Injector" Version="1.0.0-beta" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Devlooped.Injector --version 1.0.0-beta                
#r "nuget: Devlooped.Injector, 1.0.0-beta"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Devlooped.Injector as a Cake Addin
#addin nuget:?package=Devlooped.Injector&version=1.0.0-beta&prerelease

// Install Devlooped.Injector as a Cake Tool
#tool nuget:?package=Devlooped.Injector&version=1.0.0-beta&prerelease                

Allows injecting .NET code into any Windows process.

Heavily based on Cory Plott's Snoop.

Usage:

  • Install:
install-package Devlooped.Injector

The $(PlatformTarget) or $(Platform) properties of the referencing project are used to determine which version (x86 or x64) of the boostrap.dll assembly will be referenced. If any of those specify either x86 or x64, the assembly will be automatically referenced.

The targets automatically include as content both the assembly as well as a helper Injector.exe executable which you can use to inject into processes that have a different bitness than the calling one.

  • Launch:
var targetProcess = System.Diagnostics.Process.GetProcessesByName("notepad.exe")[0];

Injector.Launch(
    // IntPtr of the main window handle of the process to inject
    targetProcess.MainWindowHandle,
    // The full path to the .NET assembly to load in the remote process
    Assembly.GetExecutingAssembly().Location,
    // Full type name of the public static class to invoke in the remote process
    "MyApp.Startup",
    // Name of the static method in that class to invoke in the remote process
    "Start");

When referencing the package from an AnyCPU project, a helper Injector.exe is provided in both x86 and x64 bitness versions and included in the referencing project as content, copied automatically to the output under Injector\[x86|x64]\Injector.exe. This allows you to run the relevant executable that matches the target process bitness. This executable receives the same parameters as the Launch method shown above.

For example, to detect a target process bitness, you could use the following interop code:

static class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
}

And then use the following code (note it's similar to the API-based one above) to inject into it:

var targetProcess = System.Diagnostics.Process.GetProcessesByName("notepad.exe")[0];

NativeMethods.IsWow64Process(targetProcess.Handle, out var isWow);
var platform = isWow ? "x86" : "x64";

Process.Start(Path.Combine("Injector", platform, "Injector.exe"),
    targetProcess.MainWindowHandle + " " +
    Assembly.GetExecutingAssembly().Location + " " +
    typeof(Startup).FullName + " " +
    $"{nameof(Startup.Start)}:hello:42:true");

Optionally, the injected method call can also receive parameters, in a {method}:arg1:arg2:argN format:

var targetProcess = System.Diagnostics.Process.GetProcessesByName("notepad.exe")[0];

Injector.Launch(
    // IntPtr of the main window handle of the process to inject
    targetProcess.MainWindowHandle,
    // The full path to the .NET assembly to load in the remote process
    Assembly.GetExecutingAssembly().Location,
    // Full type name of the public static class to invoke in the remote process
    "MyApp.Startup",
    // Name of the static method in that class to invoke in the remote process
    "Start:hello:42:true");

See Program.cs for complete example.

NOTE: parameter type conversion is supported and happens via the TypeConverter associated with the parameter type.

Sponsors

Clarius Org Christian Findlay C. Augusto Proiete Kirill Osenkov MFB Technologies, Inc. Amazon Web Services SandRock David Pallmann

Sponsor this project  

Learn more about GitHub Sponsors

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Devlooped.Injector:

Package Downloads
xunit.vsix

Allows creating reliable, flexible and fast VS SDK integration (VSIX) tests that run using any xUnit capable runner, such as Visual Studio built-in Test Explorer or TestDriven.NET.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.0 1,202 9/23/2022
1.0.1 456 9/9/2022
1.0.0-rc 257 9/9/2022
1.0.0-beta 276 9/9/2022