Jump to content

MemorySharp logo

MemorySharp

MemorySharp is a C# based memory editing library targeting Windows applications, offering various functions to extract and inject data and codes into remote processes to allow interoperability.

The goal of this library is to provide a safe, powerful and easy to use API, keeping the remote process as clean as possible. This library is said Out-of-Process, in other words it does not need to be injected within the target process. Only your application loads MemorySharp, ensuring that only the requested operations are executed in the opened process. For the moment, the library only supports 32-bit development.

MemorySharp is licensed under the MIT License. The license is simple and easy to understand and it places almost no restrictions on what you can do with a project using MemorySharp. You are free to use any MemorySharp project in any other project (even commercial projects) as long as the copyright header is left intact.

Feel free to join the community to submit your feebacks, ideas of improvement, a bug or simply to ask a question on the official board.

Features

MemorySharp is divided into several parts. Here is list the all the features available.

  • Process interactions
    • Check if the process is debugged
    • Gather information of the process
    • Interact with the PEB (Process Environment Block)
  • Memory interactions
    • Allocate and free a chunk of memory
    • Change the protection of allocated regions
    • Get an absolute/relative address from a pointer
    • Query the memory allocated
    • Read and write primitive and complex data types
  • Module interactions
    • Enumerate all modules loaded
    • Find functions inside a module
    • Get the main module
    • Inject and eject modules
  • Thread interactions
    • Create and terminate threads
    • Get the exit code of terminated threads
    • Get the main thread
    • Get the segments addresses
    • Get threads by identifier
    • Interact with the TEB (Thread Environment Block)
    • Join threads
    • Manage the context of threads
    • Query the state of threads
    • Suspend and resume threads
  • Window interactions
    • Enumerate the windows of the process
    • Enumerate the child windows of the process
    • Enumerate the child windows of another window
    • Flash the window (once or repeatedly)
    • Get a window by its class name
    • Get a window by its title (or a part of its title)
    • Get the attached thread of a window
    • Get the main window
    • Interact with the keyboard with a window (press and release keys, write texts) without activate it
    • Interact with the mouse with the window (clicks, movement)
    • Post and send message
    • Query the class name
    • Query and modify the title
    • Query and modify the size (height, width) and the position (X, Y)
  • Assembly interactions
    • Assemble mnemonics
    • Embed FASM compiler (Fasm.NET)
    • Execute remote codes (such as functions) with/without parameter(s) synchronously and asynchronously
    • Inject mnemonics
    • Support several calling conventions
  • Data types manipulations
    • Extract useful information from data types
    • Convert a byte array to a managed object
    • Convert a managed object to a byte array
    • Convert a pointer to a managed object
    • Store data in the remote process in safe (collected when unused)
  • Helpers available
    • ApplicationFinder: Find the right process to interact
    • HandleManipulator: Convert an handle to a process or a thread
    • Generic singleton: Implement a singleton on any of your class
    • Randomizer: Generate random numbers, strings and Guid
    • SerializationHelper: Serialize and deserialize managed object into XML
  • PE Format Analysis (not available yet, coming soon)
  • Executor Mechanism (not available yet, coming soon)
  • Hook Mechanism (not available yet, coming soon)
  • Pattern Mechanism (not available yet, coming soon)
  • Patching Mechanism (not available yet, coming soon)

Quick Overview

Here are some examples that use MemorySharp to interact with a third-party process.

Reading/Write data

These are basically two ways to read/write data. The first one is to use the the MemorySharp class :

var address = IntPtr.Zero; var sharp = new MemorySharp(Process.GetCurrentProcess());

// Read an array of 3 integers 
int[] integers = sharp.Read<int>(address, 3);
// Write a string
sharp.WriteString(address, "I love managed languages.");

The second way is to use RemotePointer objects. These objects are instanciated using the indexer on MemorySharp objects :

var address = IntPtr.Zero;
var offset = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

// Read an array of 3 integers 
int[] integers = sharp[address].Read(offset, 3);
// Write a string
sharp[address].WriteString("I love managed languages.");

Execute/Inject code

Executing code is very similar to read and write memory. The Assembly factory can be used :

var address = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

// Execute code and get the return value as boolean
var ret = sharp.Assembly.Execute<bool>(address);

Using RemotePointer is also possible :

var address = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

// Execute code and get the return value as a Vector3 structure
var vector = sharp[address].Execute<Vector3>(CallingConventions.Stdcall, "a parameter", "another one");

The parameters like string are dynamically allocated in the remote process memory and freed as soon as the execution of the code terminated. Here, some FASM mnemonics are injected at a given address :

var address = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

// Inject mnemonics
sharp.Assembly.Inject(
    new[]
        {
            "push 0",
            "add esp, 4",
            "retn"
        },
    address);

Lazy people will enjoy the assembly transactions to remote inject and execute code :

var address = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

// Inject and execute code lazily
using(var t = sharp.Assembly.BeginTransaction())
{
	t.AddLine("mov eax, {0}", address);
	t.AddLine("call eax");
	t.AddLine("retn");
}

The code is then automatically executed in the remote process.

Thread-and-play

Here are some examples to show how it's easy to play with remote threads. Hijacking a thread :

var sharp = new MemorySharp(Process.GetCurrentProcess());

sharp.Threads.MainThread.Context.Eip = address;

What ? Yes of course... the code suspends and resumes the thread when changing its context. Freeze the application :

var sharp = new MemorySharp(Process.GetCurrentProcess());

sharp.Threads.SuspendAll();

Extract specific information from the TEB :

var sharp = new MemorySharp(Process.GetCurrentProcess());

var tlsPtr = sharp.Threads.MainThread.Teb.Tls;

TLS cloning (only for the demo, it would be quite evil to really do that) :

var sharp = new MemorySharp(Process.GetCurrentProcess());

sharp.Threads.RemoteThreads.First().Teb.TlsSlots = sharp.Threads.RemoteThreads.Last().Teb.TlsSlots;

Inject/eject Modules

Here a module is injected and ejected using the `IDisposable` interface :

string path = [..];
var sharp = new MemorySharp(Process.GetCurrentProcess());

using (var module = sharp.Modules.Inject(path))
{
    module.FindFunction("MessageBoxW").Execute(0, "Hey", "Title", 0);
}

One more time, using indexer here is interesting :

var address = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

// It's in[dexer]ception !
sharp["kernel32"]["MessageBoxW"].Execute(0, "Hey", "Title", 0);

The traditional way is also available :

var address = IntPtr.Zero;
var sharp = new MemorySharp(Process.GetCurrentProcess());

var module = sharp.Modules.Inject(path);
module.Eject();

Query/interact with windows

Resize and move a window :

var sharp = new MemorySharp(Process.GetCurrentProcess());

// Move and resize
sharp.MainWindow.X = 200;
sharp.MainWindow.Y = 200;
sharp.MainWindow.Height = 200;
sharp.MainWindow.Width = 200;

Write a text in Notepad++ :

var sharp = new MemorySharp(Process.GetCurrentProcess());

// Find Scintilla
var scintilla = sharp.Windows.GetWindowsByClassName("Scintilla").FirstOrDefault();
// If scintilla was found
if(scintilla != null)
{
	// Write something
	scintilla.Keyboard.Write("Hello, World!");
}

Click on the top left corner of a window :

var sharp = new MemorySharp(Process.GetCurrentProcess());

// Get the window
var window = sharp.Windows.MainWindow;
// Activate it to be in foreground
window.Activate();
// Move the cursor
window.Mouse.MoveTo(0, 0);
// Perform a left click
window.Mouse.ClickLeft();

How about pressing a key ?

var sharp = new MemorySharp(Process.GetCurrentProcess());

// Get the window
var window = sharp.Windows.MainWindow;
// Press the bottom arrow down and repeat the message every 20ms
window.Keyboard.Press(Keys.Down, TimeSpan.FromMilliseconds(20));
// Wait 3 seconds
Thread.Sleep(3000);
// Release the key
window.Keyboard.Release(Keys.Down);