Libmem.NET
2.0.0-preview.1
See the version list below for details.
dotnet add package Libmem.NET --version 2.0.0-preview.1
NuGet\Install-Package Libmem.NET -Version 2.0.0-preview.1
<PackageReference Include="Libmem.NET" Version="2.0.0-preview.1" />
<PackageVersion Include="Libmem.NET" Version="2.0.0-preview.1" />
<PackageReference Include="Libmem.NET" />
paket add Libmem.NET --version 2.0.0-preview.1
#r "nuget: Libmem.NET, 2.0.0-preview.1"
#:package Libmem.NET@2.0.0-preview.1
#addin nuget:?package=Libmem.NET&version=2.0.0-preview.1&prerelease
#tool nuget:?package=Libmem.NET&version=2.0.0-preview.1&prerelease
Libmem.NET
Libmem.NET is a Windows C++/CLI wrapper around rdbo/libmem, exposing process, thread, module, memory, scanning, symbol, assembly/disassembly, Hook, VMT, and DLL injection capabilities to C# / .NET.
Author and maintainer: xiaohei7972. Project organization: CardResearchLab.
Current source uses the Libmem.NET identity; the prepared version is 2.0.0-preview.1, pending public release validation. Historical stable v1.0.0 uses LibmemCli. Consumers must update references and recompile; see the migration guide.
Official support target:
- Windows x64
- .NET 8
- C# / .NET consumers
- a pinned rdbo/libmem native backend
x86 source/build configuration is retained but is outside the current stable support and official Release scope. The local NuGet PackageReference path is CI-validated; account-side Trusted Publishing configuration must still be verified before publication.
Download
Build current Libmem.NET from source or download an artifact from a successful Build workflow run.
Historical v1.0.0 still provides these old-name assets. They do not support the new-name examples below:
Historical ZIP SHA-256: 647f93c73bbd9fc77e2eb84dc2d5530953b12212c75c09d97b19388e4b331b99.
See the Release & Versioning Guide for release and integrity information.
Quick start
Build current source or extract a current Build artifact, then reference this assembly from an x64 .NET 8 project:
Libmem.NET.dll
and keep at least these files beside the application:
Libmem.NET.dll
libmem.dll
Ijwhost.dll
Keep Libmem.NET.xml as well for IntelliSense documentation.
Basic example
using Libmem.NET;
using NativeApi = global::Libmem.NET.Libmem;
var process = NativeApi.CurrentProcess()
?? throw new InvalidOperationException("Current process not found.");
using var session = ProcessSession.Open(process)
?? throw new InvalidOperationException("Failed to open process session.");
Console.WriteLine(
$"{session.Name} PID={session.Pid} Arch={session.Architecture} Bits={session.Bits}");
foreach (var module in session.Modules.Enumerate())
{
Console.WriteLine(
$"{module.Name} Base=0x{module.Base:X} Size=0x{module.Size:X}");
}
Memory example
using Libmem.NET;
using NativeApi = global::Libmem.NET.Libmem;
using var session = ProcessSession.Open((uint)Environment.ProcessId)
?? throw new InvalidOperationException("Failed to open process session.");
using var allocation = session.Memory.Allocate(
4096,
MemoryProtection.ReadWrite);
session.Memory.Write(allocation.Address, [1, 2, 3, 4]);
var data = session.Memory.Read(allocation.Address, 4);
Console.WriteLine(string.Join(", ", data));
RemoteAllocation implements IDisposable; use using for deterministic cleanup.
API structure
New code should generally use ProcessSession as the process-scoped entry point:
| ProcessSession property | Manager |
|---|---|
Memory |
MemoryManager |
Modules |
ModuleManager |
Threads |
ThreadManager |
Scanner |
ScanManager |
Symbols |
SymbolManager |
Assembly |
AssemblyManager |
Hooks |
HookManager |
Injector |
InjectorManager |
The lower-level static NativeApi.* (global::Libmem.NET.Libmem) surface remains available for one-shot calls and native-style compatibility.
Process / Thread
- process enumeration, lookup, and current-process access
- process liveness checks
- PID + start-time identity validation
- thread enumeration and main-thread lookup
Modules / Symbols
- module enumeration, lookup, load, and unload
- exported symbol enumeration
- symbol address lookup
- symbol demangling
Memory / Scanning
- Read / Write
- Set / Protect
- Allocate / Free
- owned
RemoteAllocation - DeepPointer
- DataScan
- PatternScan
- SigScan
Assembly
- Assemble
- Disassemble
- CodeLength
AssemblyManager defaults to the target process architecture.
Hook / VMT
- native code Hook
- trampoline metadata
- Hook Remove / Dispose
- VMT Hook / Unhook / Reset
HookHandle and VmtManager provide explicit lifetime management.
Injection
InjectorManager.InjectLibrary(...) returns an InjectedModuleHandle representing one owned load reference.
Cross-bitness injection is not supported.
Lifetime model
Resources that require ownership use explicit IDisposable semantics:
ProcessSessionRemoteAllocationHookHandleVmtManagerInjectedModuleHandle
Explicit Dispose() performs deterministic cleanup. When native cleanup definitively fails, the ownership API surfaces that failure instead of silently discarding still-live resource state.
Finalizers never perform dangerous remote memory release, remote code restoration, VMT restoration, or remote module unload operations on the GC thread.
Results and exceptions
v1.0 distinguishes normal misses from actual operation failures.
| Case | Behavior |
|---|---|
| Process / Module / Segment miss | null |
| Symbol / Scan / DeepPointer miss | libmem bad-address sentinel |
| Definite Manager native failure | LibmemException |
| Invalid arguments | standard .NET Argument* exceptions |
| Manager use after disposal | ObjectDisposedException |
See API Reference for the full contract.
Build from source
Requirements:
- Windows x64
- Visual Studio 2022
- Desktop development with C++
- C++/CLI support for v143 build tools
- Windows SDK
- .NET 8 SDK
- CMake
- Git
Clone recursively:
git clone --recursive https://github.com/CardResearchLab/Libmem.NET.git
cd Libmem.NET
.\build.ps1 -Configuration Release -Platform x64
The build initializes Git submodules, builds the pinned native libmem revision, builds the C++/CLI assembly, generates XML documentation, and writes outputs under artifacts/.
Primary outputs:
artifacts/native/x64/Release/bin/libmem.dll
artifacts/managed/x64/Release/Libmem.NET.dll
artifacts/managed/x64/Release/Libmem.NET.xml
artifacts/managed/x64/Release/Ijwhost.dll
Runtime package
The prepared version is 2.0.0-preview.1. Namespace and assembly identity changes break the former v1.0.0 identity and require consumer recompilation. VERSION, NuGet and informational version use 2.0.0-preview.1; numeric assembly/file versions use 2.0.0.0. Build downloads include the runtime ZIP, SHA-256 and Libmem.NET.2.0.0-preview.1.nupkg, with changelog and migration documentation inside the packages. Preparation does not imply public availability; GitHub preview downloads and the later manual NuGet push are separate steps.
Build the release-style runtime ZIP locally:
.\build.ps1 -Configuration Release -Platform x64
.\eng\package-runtime.ps1 -Configuration Release -Platform x64
Outputs:
artifacts/package/Libmem.NET-windows-x64/
artifacts/package/Libmem.NET-windows-x64.zip
artifacts/package/Libmem.NET-windows-x64.zip.sha256
manifest.json records version, repository commit, pinned libmem commit, target framework, platform, build configuration, and per-file SHA-256.
Git submodule integration
For source-level reproducible integration:
git submodule add https://github.com/CardResearchLab/Libmem.NET.git external/Libmem.NET
git submodule update --init --recursive
Then reference:
external/Libmem.NET/src/Libmem.NET.vcxproj
from the consuming solution.
The repository also provides a reusable GitHub Actions build workflow.
jobs:
build-libmem:
uses: CardResearchLab/Libmem.NET/.github/workflows/reusable-build.yml@main
with:
ref: main
configuration: Release
platform: x64
artifact-name: Libmem.NET-windows-x64
For reproducible builds, pin both the workflow reference and ref to a reviewed commit.
NuGet status
The package ID is Libmem.NET, targeting Windows x64 / .NET 8. CI validates pack, independent PackageReference restore/build/run/publish, native runtime asset copy, and rejection of non-x64 consumers.
Create local packages with eng/package-nuget.ps1; development versions include the commit identifier. v* tags create GitHub downloads, marking preview versions as prereleases. A later manual run on the published tag with publish-nuget enabled performs NuGet OIDC login and push. release/v* branches validate packages and render release notes without publication.
The identity migration creates no new tag or public package. Verify the nuget.org Trusted Publishing policy and GitHub NUGET_USER secret before a formal release. See the Consumption Guide and release checklist.
Tests and CI
The repository uses layered validation:
- Build + Runtime Smoke
- Hook / VMT Runtime Tests
- Injector Runtime Tests
- External Process Runtime Tests
- NuGet Consumer Tests
- Public API baseline validation
- pinned libmem public API coverage validation
- runtime package integrity validation
Build is the single automatic PR gate. It builds and tests Release x64 by default, retaining all Release suites and package checks above. Enable debug under Actions → Build → Run workflow to additionally build Debug x64 and run Debug smoke tests.
Specialized workflows remain manual entry points:
- Hook/VMT
- Injector
- External Process, using the independent
Libmem.NET.TestTarget - NuGet Consumer
Public API stability
The baseline enforces public member contracts. The current LibmemCli → Libmem.NET identity migration is an intentional breaking change requiring recompilation; member signatures, ownership, and error semantics are preserved. Historical v1.x compatibility does not imply that the new assembly can replace the old DLL.
The repository freezes namespace, public types, methods, properties, and enums through:
api/Libmem.NET.PublicApi.txt
Any intentional breaking change requires an explicit API baseline update, CHANGELOG entry, semantic-versioning review, and relevant validation.
Pinned upstream
The native backend is currently pinned to:
rdbo/libmem
a07c9942bf1358dabcc83eb0cd072736c749d7f8
See UPSTREAM.txt.
Documentation
- API Reference
- Migration Guide
- Release Checklist
- Consumption Guide
- Release & Versioning Guide
- v1.0.0 Release Notes
- CHANGELOG
- ROADMAP
- 简体中文 README
License
Libmem.NET is licensed under GNU AGPL-3.0-only.
See THIRD_PARTY_NOTICES.md for third-party components and licenses.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.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.