JamesMenetrey / MemorySharp

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.
Other
634 stars 135 forks source link

MemorySharp

Synopsis

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. 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.

The project is made by Binarysharp and can be downloaded on the official website.

Features

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

Community

Join the community to submit your feebacks, ideas of improvement, a bug or simply to ask a question of the official board: MemorySharp Community.

Examples

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<int>(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>(address, "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("YourFunctionName").Execute(parameters);
}

One more time, using indexer here is interesting :

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

// It's in[dexer]ception !
sharp["user32"]["MessageBoxA"].Execute(CallingConventions.Stdcall, 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);

Git flow

The branching strategy of the repository is based on the git flow proposed by Vincent Driessen, as depicted at the end of this part.

The central repo holds two main branches with an infinite lifetime:

Next to the main branches master and develop, our development model uses a variety of supporting branches to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.

The different types of branches we may use are:

Branch type Prefix
Feature feature-
Release release-
Hotfix hotfix-

Git flow diagram

Credits

At the beginning, I thank my Notepad++ app, because it suffered so many crashes due to bad injections and wrong codes of my part.

More seriously, I thank the entire Ownedcore community, which allows me to learn the art of the Memory Editing. Especially Apoc, who is a very inspirational person for me with his posts giving so well-written pieces of code without asking anything in return (this includes examples / offsets / guides /libraries), Cypher for his very critical mind about coding practices, Bananenbrot for giving nice advices in a lot of threads of the board, TOM_RUS for his very high-skilled eyes to read asm, making very comprehensive wrappers and Shynd, who gave me the idea of creating my own library. I certainly forget tons of people here.

This is because there are so many people ready to share their skills that I decided to publish a GPL-licensed version of MemorySharp.

Author

This developer and the copyright holder of this library is ZenLulz (Jämes Ménétrey).
The official website of MemorySharp is www.binarysharp.com.