All Projects → theXappy → RemoteNET

theXappy / RemoteNET

Licence: MIT license
Examine, create and interact with remote objects in other .NET processes.

Programming Languages

C#
18002 projects
C++
36643 projects - #6 most used programming language
c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to RemoteNET

SQLCallStackResolver
Utility to resolve SQL Server callstacks to their correct symbolic form using just PDBs and without a dump file
Stars: ✭ 55 (+89.66%)
Mutual labels:  debugging, clrmd
Timber Elixir
🌲 Great Elixir logging made easy
Stars: ✭ 226 (+679.31%)
Mutual labels:  debugging, instrumentation
contech
The Contech analysis framework provides the means for generating and analyzing task graphs that enable computer architects and programmers to gain a deeper understanding of parallel programs.
Stars: ✭ 43 (+48.28%)
Mutual labels:  instrumentation
Linux-Kernel-Driver-Programming
Implementation of PCI drivers, kprobe, sysfs, devfs, sensor driver, miscdevices, synchronization
Stars: ✭ 43 (+48.28%)
Mutual labels:  debugging
AppmemDumper
Forensics triage tool relying on Volatility and Foremost
Stars: ✭ 22 (-24.14%)
Mutual labels:  forensics
dwarf import
This loads DWARF info from an open binary and propagates function names, arguments, and type info
Stars: ✭ 18 (-37.93%)
Mutual labels:  debugging
stacktrace
Atom package to navigate stacktraces.
Stars: ✭ 35 (+20.69%)
Mutual labels:  debugging
arduino-printf
Add printf support to the Arduino SDK
Stars: ✭ 64 (+120.69%)
Mutual labels:  debugging
PowerPreference
💾 A Powerful library to control and simplify the usage of shared preference in Android.
Stars: ✭ 95 (+227.59%)
Mutual labels:  debugging
ducky
Chrome extension to overlay a (super adorable) rubber duck, as a virtual companion during rubber duck debugging.
Stars: ✭ 80 (+175.86%)
Mutual labels:  debugging
heaptrace
helps visualize heap operations for pwn and debugging
Stars: ✭ 252 (+768.97%)
Mutual labels:  debugging
TweakIt-Desktop
An Android Debugging Application
Stars: ✭ 33 (+13.79%)
Mutual labels:  debugging
urlRecon
📝 urlRecon - Info Gathering or Recon tool for Urls -> Retrieves * Whois information of the domain * DNS Details of the domain * Server Fingerprint * IP geolocation of the server
Stars: ✭ 31 (+6.9%)
Mutual labels:  forensics
Specter
Super simple debugging for PocketMine.
Stars: ✭ 73 (+151.72%)
Mutual labels:  debugging
stack-inspector
A gdb command to inspect the size of objects on the stack
Stars: ✭ 57 (+96.55%)
Mutual labels:  debugging
harvest
Tool to sort large collections of files according to common typologies
Stars: ✭ 32 (+10.34%)
Mutual labels:  forensics
RdpCacheStitcher
RdpCacheStitcher is a tool that supports forensic analysts in reconstructing useful images out of RDP cache bitmaps.
Stars: ✭ 176 (+506.9%)
Mutual labels:  forensics
node-ray
Debug your NodeJS & web code with Ray to fix problems faster
Stars: ✭ 39 (+34.48%)
Mutual labels:  debugging
MEAT
This toolkit aims to help forensicators perform different kinds of acquisitions on iOS devices
Stars: ✭ 101 (+248.28%)
Mutual labels:  forensics
debuggable-windows
This repository contains Ansible scripts which will install and configure tools necessary to effectively debug and profile applications on Windows.
Stars: ✭ 19 (-34.48%)
Mutual labels:  debugging

icon

RemoteNET NuGet

This library lets you examine, create and interact with remote objects in other .NET processes.
The target app doesn't need to be explicitly compiled (or consent) to support it.

Basically this library lets you mess with objects of any other .NET app without asking for permissions :)

Tested versions:

  • .NET 5/6
  • .NET Core 3.0/3.1
  • .NET Framework 4.5/4.6/4.7/4.8 (incl. subversions)

Including the library in your project

There are 2 ways to get the library:

  1. Get it from NuGet
    -or-
  2. Clone this repo, compile then reference RemoteNET.dll and ScubaDiver.API.dll in your project.

Minimal Working Example

To get the essence of how easy and usefull this library can be, see below a re-implementation of denandz/KeeFarce.
This example interacts with an open KeePass process and makes it export all credentials to a CSV file.

// Gain foothold within the target process
RemoteApp remoteApp = RemoteApp.Connect("KeePass.exe");
RemoteActivator rActivator = remoteApp.Activator;

// Get a remote DocumentManagerEx object
IEnumerable<CandidateObject> candidates = remoteApp.QueryInstances("KeePass.UI.DocumentManagerEx");
RemoteObject remoteDocumentManagerEx = remoteApp.GetRemoteObject(candidates.Single());
dynamic dynamicDocumentManagerEx = remoteDocumentManagerEx.Dynamify();

// Get sensitive properties to dump
dynamic activeDb = dynamicDocumentManagerEx.ActiveDatabase;
dynamic rootGroup = activeDb.RootGroup;

// Create remote PwExportInfo object (Call Ctor)
RemoteObject pwExportInfo = rActivator.CreateInstance("KeePass.DataExchange.PwExportInfo", rootGroup, activeDb, true);

// Create remote KeePassCsv1x (Call Ctor)
RemoteObject keePassCsv1x = rActivator.CreateInstance("KeePass.DataExchange.Formats.KeePassCsv1x");
dynamic dynamicCsvFormatter = keePassCsv1x.Dynamify();

// Creating a remote FileStream object
string tempOutputFile = Path.ChangeExtension(Path.GetTempFileName(), "csv");
RemoteObject exportFileStream = rActivator.CreateInstance(typeof(FileStream), tempOutputFile, FileMode.Create);

// Calling Export method of exporter
dynamicCsvFormatter.Export(pwExportInfo, exportFileStream, null);

// Showing results in default CSV editor.
Console.WriteLine($"Output written to: {tempOutputFile}");
Process.Start(tempOutputFile);

How To Use

This section documents most parts of the library's API which you'll likely need.

✳️ Setup

To start playing with a remote process you need to create a RemoteApp object like so:

RemoteApp remoteApp = RemoteApp.Connect("OtherDotNetAppName");

If you have multiple processes with such name you can use the overload Connect(System.Diagnostics.Process p);

✳️ Getting Existing Remote Objects

First and foremost RemoteNET allows you to find existing objects in the remote app.
To do so you'll need to search the remote heap.
Use RemoteApp.QueryInstances() to find possible candidate for the desired object and RemoteApp.GetRemoteObject() to get a handle of a candidate.

IEnumerable<CandidateObject> candidates = remoteApp.QueryInstances("MyApp.PasswordContainer");
RemoteObject passwordContainer = remoteApp.GetRemoteObject(candidates.Single());

✳️ Creating New Remote Objects

Sometimes the existing objects in the remote app are not enough to do what you want.
For this reason you can also create new objects remotely.
Use the Activator-lookalike for that cause:

// Creating a remote StringBuilder with default constructor
RemoteObject remoteSb1 = remoteApp.Activator.CreateInstance(typeof(StringBuilder));

// Creating a remote StringBuilder with the "StringBuilder(string, int)" ctor
RemoteObject remoteSb2 = remoteApp.Activator.CreateInstance(typeof(StringBuilder), "Hello", 100);

Note how we used constructor arguments in the second CreateInstance call. Those could also be other RemoteObjects:

// Constructing a bew StringBuilder
RemoteObject remoteStringBuilder = remoteApp.Activator.CreateInstance(typeof(StringBuilder));
// Constructing a new StringWriter using the "StringWriter(StringBuilder sb)" ctor
RemoteObject remoteStringWriter = remoteApp.Activator.CreateInstance(typeof(StringWriter), remoteStringBuilder);

✳️ Reading Remote Fields/Properties

To allow a smooth coding expereince RemoteNET is utilizing a special dynamic object which any RemoteObject can turn into.
This object can be used to access field/properties just if they were field/properties of a local object:

// Reading the 'Capacity' property of a newly created StringBuilder
RemoteObject remoteStringBuilder = remoteApp.Activator.CreateInstance(typeof(StringBuilder));
dynamic dynamicStringBuilder = remoteStringBuilder.Dynamify();
Console.WriteLine("Remote StringBuilder's Capacity: " + dynamicStringBuilder.Capacity)

A more interesting example would be retrieving the ConnectionStrings of every SqlConnection instance:

var sqlConCandidates = remoteApp.QueryInstances(typeof(SqlConnection));
foreach (CandidateObject candidate in sqlConCandidates)
{
    RemoteObject remoteSqlConnection = remoteApp.GetRemoteObject(candidate);
    dynamic dynamicSqlConnection = remoteSqlConnection.Dynamify();
    Console.WriteLine("ConnectionString: " + dynamicSqlConnection.ConnectionString);
}

✳️ Invoking Remote Methods

Just like accessing fields, invoking methods can be done on the dynamic objects.
This fun example dumps all private RSA keys (which are stored in RSACryptoServiceProviders) found in the target's memory:

Func<byte[], string> ToHex = ba => BitConverter.ToString(ba).Replace("-", "");

// Finding every RSACryptoServiceProvider instance
var rsaProviderCandidates = remoteApp.QueryInstances(typeof(RSACryptoServiceProvider));
foreach (CandidateObject candidateRsa in rsaProviderCandidates)
{
    RemoteObject rsaProv = remoteApp.GetRemoteObject(candidateRsa);
    dynamic dynamicRsaProv = rsaProv.Dynamify();
    // Calling remote `ExportParameters`.
    // First parameter (true) indicates we want the private key.
    Console.WriteLine(" * Key found:");
    dynamic parameters = dynamicRsaProv.ExportParameters(true);
    Console.WriteLine("Modulus: " + ToHex(parameters.Modulus));
    Console.WriteLine("Exponent: " + ToHex(parameters.Exponent));
    Console.WriteLine("D: " + ToHex(parameters.D));
    Console.WriteLine("P: " + ToHex(parameters.P));
    Console.WriteLine("Q: " + ToHex(parameters.Q));
    Console.WriteLine("DP: " + ToHex(parameters.DP));
    Console.WriteLine("DQ: " + ToHex(parameters.DQ));
    Console.WriteLine("InverseQ: " + ToHex(parameters.InverseQ));
}

✳️ Remote Events

You can also subscribe to/unsubscribe from remote events. The syntax is similar to "normal C#" although not exact:

CandidateObject cand = remoteApp.QueryInstances("System.IO.FileSystemWatcher").Single();
RemoteObject remoteFileSysWatcher = remoteApp.GetRemoteObject(cand);
dynamic dynFileSysWatcher = remoteFileSysWatcher.Dynamify();
Action<dynamic, dynamic> callback = (dynamic o, dynamic e) => Console.WriteLine("Event Invoked!");
dynFileSysWatcher.Changed += callback;
/* ... Somewhere further ... */
dynFileSysWatcher.Changed -= callback;

The limitations:

  1. The parameters for the callback must be dynamics
  2. The callback must define the exact number of parameters for that event
  3. Lambda expression are not allowed. The callback must be cast to an Action<...>.

TODOs

  1. Static members
  2. Document "Reflection API" (RemoteType, RemoteMethodInfo, ... )
  3. Support other .NET framework CLR versions (Before .NET 4). Currently supports v4.0.30319
  4. Document Harmony (prefix/postfix/finalizer hooks)
  5. Support more Harmony features

Thanks

denandz for his interesting project KeeFarce which was a major inspiration for this project.
Also, multiple parts of this project are directly taken from KeeFarce (DLL Injection, Bootstrap, IntPtr-to-Object converter).

icons8 for the "Puppet" icon

Raymond Chen for stating this project shouldn't be done in this blog post from 2010.
I really like this qoute from the post:

If you could obtain all instances of a type, the fundamental logic behind computer programming breaks down. It effectively becomes impossible to reason about code because anything could happen to your objects at any time.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].