External.Memory 1.0.0

dotnet add package External.Memory --version 1.0.0
NuGet\Install-Package External.Memory -Version 1.0.0
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="External.Memory" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add External.Memory --version 1.0.0
#r "nuget: External.Memory, 1.0.0"
#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 External.Memory as a Cake Addin
#addin nuget:?package=External.Memory&version=1.0.0

// Install External.Memory as a Cake Tool
#tool nuget:?package=External.Memory&version=1.0.0

C# library on netstandard 2.0 (supports .NET Framework 4.6.1 and higher), that allows you to externally read and write memory into the process, if you have the required access.

Initialization

When initializing process, you have 3 choices how to do so.

Using process ID
using External.Memory;
using System; // for console

// imaginary process id
var myProcessId = 1234;
var processMemory = new ProcessMemory(myProcessId);

Console.WriteLine("Process has been accessed");
Using process name
using External.Memory;
using System; // for console

// .exe IS REQUIRED
var myProcessName = "mygame.exe";
var processMemory = new ProcessMemory(myProcessName);

Console.WriteLine("Process has been accessed");
Or the very last option, if you already have the process handle with all permissions (Full Access Flag: 0x001F0FFF)
using External.Memory;
using System; // for console

// imaginary process handle
var myProcessHandle = new IntPtr(0x1488);
var processMemory = new ProcessMemory(myProcessHandle);

Console.WriteLine("Process has been accessed");

Reading process memory

When it comes to reading, you need only 2 things:

  • Address in memory (and the offset if needed).
  • Value type that you want to read.

Value type is important because it has to read right amount of bytes at that address. In our test-case we will try to obtain imaginary health in the our imagined game.

using External.Memory;
using System; // for console

// we will use process name in our test case
var processMemory = new ProcessMemory("mygame.exe")

// some imaginary health offsets
nint healthOffset = 0x00001337;

// reading the "health" of type uint (unsigned int, 4 bytes)
var health = processMemory.Read<uint>(healthOffset);

// then logging the health into the console
Console.WriteLine($"Health: {health}");

Writing process memory

Writing memory is basically the same, but beside the address and value-type, you need the values itself obviously, so provide it in the second argument. Now lets try to change the health in our game.

using External.Memory;
using System; // for console

// we will use process name in our test case
var processMemory = new ProcessMemory("mygame.exe")

// some imaginary health offsets
nint healthOffset = 0x00001337;

// reading the "health" of type uint (unsigned int)
var health = processMemory.Read<uint>(healthOffset);

// then logging the health into the console
Console.WriteLine($"Health: {health}");

// now lets change the health
processMemory.Write<uint>(healthOffset, 100);

// displaying new health
health = processMemory.Read<uint>(healthOffset)
Console.WriteLine($"New health: {health}");

Additions

If you need, you can read a byte array with your desired length, and then manipulate the buffer.

using External.Memory;
using System; // for console

// we will use process name in our test case
var processMemory = new ProcessMemory("mygame.exe")

// some imaginary health offsets
nint healthOffset = 0x00001337;

// reading the "health" as byte array
var healthArray = processMemory.ReadBytes(healthOffset, 4);

// now we can manually transform our buffer to a uint value using BitConverter class
var health = BitConverter.ToUInt32(healthArray, 0); // 0 is a start index

The result should stay the same.

Other features

  • Getting Module Handle and/or Module Base Address in your process.
using External.Memory;
using System; // for console

// we will use process name in our test case
var processMemory = new ProcessMemory("mygame.exe")

// imagined module
var moduleName = "client.dll";
var clientDllHandle = processMemory.GetModuleHandle(moduleName); // type: IntPtr
var clientDllBaseAddress = processMemory.GetModuleBaseAddress(moduleName); // type: IntPtr
  • Getting Proc Address in your process (Address of an exported function or variable from the specified dynamic-link-library (DLL))
using External.Memory;
using System; // for console

// we will use process name in our test case
var processMemory = new ProcessMemory("mygame.exe")

// imagined exported function
var functionName = "myExportedFunction";
var myExportedFunctionAddress = processMemory.GetProcAddress(functionName);

// or you can even get proc address of a different handle
// for example if you need an exported function from certain module that you might have obtained earlier
// you can provide it as function is overloaded

var anotherFunctionName = "myAnotherExportedFunction";
var myModuleHandle = new IntPtr(0x12345);
var myAnotherExportedFunction = processMemory.GetProcAddress(myModuleHandle, anotherFunctionName);

TODO

  • Add signature scans
  • Add tests as i am a lazy ass
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 74 4/17/2024