AnyProcess.Net 1.0 unifica le funzionalità di Swed32 e Swed64 in una sola
libreria AnyCPU per Windows, Linux e macOS. L'architettura viene rilevata dal
processo target: una stessa applicazione a 64 bit può quindi gestire processi x86,
x64, ARM e ARM64 senza scegliere un assembly differente.
Il progetto nasce dalle API dei progetti MIT Swed32 (Massivetwat, 2023) e Swed64 (Swedz, 2022), sostituendone l'implementazione Windows-only con backend nativi distinti dietro la stessa API.
Richiede .NET 8 o una versione successiva compatibile:
dotnet add package AnyProcess.Net --version 1.0.0Il pacchetto include assembly AnyCPU, documentazione XML per IntelliSense,
README, changelog, licenza MIT e tutte le guide. Il pacchetto simboli .snupkg
contiene PDB portabili con SourceLink verso l'esatto commit GitHub.
- lettura e scrittura di byte, numeri, booleani, caratteri, stringhe UTF-8,
Vector3, matrici e puntatori; - API generiche per tipi
unmanaged, overloadTryRead/TryWritee accesso diretto tramiteSpan<byte>/ReadOnlySpan<byte>; - lifecycle osservabile e thread safety durante accessi concorrenti,
SetProcesseDispose; - pooling dei buffer interni nei percorsi ad alta frequenza e benchmark riproducibili con BenchmarkDotNet;
- pointer chain basate sulla dimensione puntatore del processo target;
- enumerazione dei moduli e ricerca del loro indirizzo base;
- enumerazione delle regioni di memoria con protezioni e tipo portabili;
- scansione della memoria mappata con wildcard complete o per nibble;
- signature scan compatibile con
ScanForBytes32di Swed32; - test su processi reali, non soltanto su buffer simulati;
- CI su Windows x64, Linux x64/ARM64 e macOS Intel/Apple Silicon.
using AnyProcess.Net;
using var memory = new ProcessMemory("my-process");
Console.WriteLine($"{memory.Architecture}, puntatori da {memory.PointerSize} byte");
var moduleBase = memory.GetModuleBase(
OperatingSystem.IsWindows() ? "my-process.exe" : "my-process");
var health = memory.ReadInt(moduleBase + 0x1234);
memory.WriteInt(moduleBase + 0x1234, health + 10);È possibile collegarsi anche tramite PID o System.Diagnostics.Process:
using var byPid = new ProcessMemory(1234);
using var byProcess = new ProcessMemory(System.Diagnostics.Process.GetCurrentProcess());using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct PlayerState
{
public int Health;
public float Speed;
}
var state = memory.Read<PlayerState>(address);
state.Health = 100;
memory.Write(address, state);
Span<byte> header = stackalloc byte[16];
if (!memory.TryRead(address, header, out var error))
{
Console.Error.WriteLine(
$"{error!.Operation} PID {error.ProcessId}, errore nativo {error.NativeErrorCode}: " +
error.NativeErrorMessage);
}Le API Read e Write generano una ProcessMemoryException dettagliata se il
sistema operativo rifiuta l'accesso. Le corrispondenti API TryRead e TryWrite
restituiscono false e possono fornire la stessa diagnostica tramite un parametro
out. Gli errori di programmazione, come l'uso di un oggetto già eliminato o un
argomento non valido, continuano invece a generare un'eccezione.
La guida API robusta descrive layout dei tipi, span, compatibilità con le API storiche e proprietà diagnostiche.
Console.WriteLine($"PID {memory.ProcessId}: {memory.LifecycleState}");
Parallel.For(0, 8, worker =>
{
var value = memory.Read<int>(addresses[worker]);
memory.Write(addresses[worker], value + 1);
});
if (!memory.IsAlive)
{
Console.WriteLine("Il target non è più disponibile.");
}Le operazioni indipendenti possono avanzare in parallelo. SetProcess e
Dispose impediscono l'avvio di nuove operazioni, attendono quelle già in corso e
solo dopo sostituiscono o chiudono le risorse native. La guida
Lifecycle, thread safety e performance documenta
ownership, pooling e benchmark.
var regions = memory.GetMemoryRegions();
var matches = memory.ScanMemory(
"48 8B ?? A? ?F 89",
new MemoryScanOptions
{
RequireExecutable = true,
MaxResults = 20
});Lo scanner legge soltanto regioni committed, leggibili e non guard. Lavora a blocchi mantenendo la sovrapposizione necessaria per trovare firme a cavallo tra due letture. La guida Regioni e scansione della memoria descrive wildcard, filtri, intervalli e differenze tra i sistemi operativi.
La compatibilità dell'API non elimina le protezioni del sistema operativo. Windows applica i diritti sugli handle di processo, Linux applica ptrace/Yama e macOS applica task port, code signing, Hardened Runtime e SIP.
La guida Permessi e protezioni descrive requisiti, diagnostica e limiti per ciascun sistema operativo.
Nop usa l'istruzione corretta per x86/x64 e ARM64. Su ARM32 l'esecuzione può
essere ARM o Thumb, quindi va usato WriteBytes con l'encoding appropriato.
Un controller a 32 bit non può rappresentare tutti gli indirizzi di un target a 64 bit. Pubblicando l'applicazione chiamante come AnyCPU/64 bit, lo stesso assembly può controllare sia target a 32 bit sia target a 64 bit.
La superficie pubblica della 1.0 è registrata in
PublicAPI.Shipped.txt. Ogni build segnala
come errore API aggiunte o rimosse senza un aggiornamento esplicito del contratto.
Dalle versioni successive, dotnet pack confronta inoltre la compatibilità
binaria del pacchetto con AnyProcess.Net 1.0.0 tramite Package Validation.
La guida Compatibilità dell'API descrive le regole per release patch, minor e major. La guida Pubblicazione documenta la checklist, SourceLink e la configurazione OIDC/Trusted Publishing di nuget.org.
Richiede .NET 8 SDK:
dotnet restore AnyProcess.Net.sln
dotnet build AnyProcess.Net.sln --configuration Release --no-restore
dotnet test AnyProcess.Net.sln --configuration Release --no-build --no-restoreIl progetto AnyProcess.Net.TestTarget viene compilato con la solution ed è
avviato dai test d'integrazione per verificare che le modifiche alla memoria siano
osservate da un processo separato.
Per produrre il pacchetto NuGet 1.0.0 e il relativo .snupkg:
dotnet pack AnyProcess.Net/AnyProcess.Net.csproj --configuration Release
pwsh ./eng/Validate-NuGetPackage.ps1 -PackageDirectory AnyProcess.Net/bin/Release -Version 1.0.0Per eseguire una sessione benchmark breve:
dotnet run --project AnyProcess.Net.Benchmarks -c Release -- --job short