| name | read-write-memory |
| description | Read and write process memory — all data types, safety rules, and concrete examples via CLI, TCP, or bridge |
/probe:rw
Read and write process memory. Covers every data type, all three command delivery methods, safety rules, and copy-paste examples.
How to Send Commands
ARC Probe commands can be sent three ways. Use whichever is available:
1. CLI (simplest)
probe.exe <command>
Returns JSON to stdout. Exit code 0 = success, 1 = error.
probe.exe "read_int 0x7FFB0A8D0000+0x354"
probe.exe "write_int 0x055EA1C28FE8+0x50 1"
If probe.exe is not in PATH, use the full path to the build directory.
2. TCP (direct)
Connect to 127.0.0.1:9998 and send commands as newline-terminated strings:
$tcp = New-Object System.Net.Sockets.TcpClient('127.0.0.1', 9998)
$s = $tcp.GetStream()
$w = New-Object System.IO.StreamWriter($s); $w.AutoFlush = $true
$r = New-Object System.IO.StreamReader($s)
$w.WriteLine('read_int 0x7FFB0A8D0000+0x354')
$r.ReadLine()
$tcp.Close()
3. HTTP Bridge (when GUI is running)
curl -s -X POST http://localhost:9996 \
-H "Content-Type: application/json" \
-d '{"action":"probe","command":"read_int 0x7FFB0A8D0000+0x354"}'
The bridge wraps the response: {"ok":true,"data":{"ok":true,"data":{...}}}. Outer ok = bridge status, inner = probe response.
Address Formats
All addresses are hexadecimal. Accepted formats:
| Format | Example |
|---|
| With 0x prefix | 0x7FF612340000 |
| Without prefix | 7FF612340000 |
| Module-relative | client.dll+0x2E76FE8 |
| Offset arithmetic | 0x055EA1C28FE8+0x50 |
To get module bases: modules list
Reading Memory
read — Raw bytes (hex string)
read <addr> <size>
Returns up to 4096 bytes as a hex string. Use for opcode bytes, raw binary data, or when you need exact byte values.
probe.exe "read 0x7FFB0A8D0000 16"
read_ptr — 8-byte pointer
read_ptr <addr>
Reads an 8-byte (64-bit) pointer value. Use for following pointer fields in structs, reading vtable pointers, or any 8-byte address.
probe.exe "read_ptr 0x055EA1C28FE8"
read_int — 32-bit integer
read_int <addr>
Reads a signed 32-bit integer. Use for health, team numbers, enum values, counts, flags.
probe.exe "read_int 0x055EA1C28FE8+0x354"
read_float — 32-bit float
read_float <addr>
Reads a 32-bit float. Use for positions, angles, speed, cooldown timers.
probe.exe "read_float 0x055EA1C28FE8+0x40"
read_string — Null-terminated string
read_string <addr> [max_length]
Reads a null-terminated ASCII string. Default max 256 bytes. Use for entity names, class names, debug text.
probe.exe "read_string 0x7FFB22EA4098"
read_chain — Follow pointer chain
read_chain <addr> <off1> <off2> ...
Each offset: add to current address, dereference (read 8-byte pointer), move to result. Last value is the final read. Use for navigating nested structs.
probe.exe "read_chain client.dll+0x3862C28 0x10 0x0"
dump — Hex dump with ASCII
dump <addr> <size>
Max 256 bytes. Returns formatted hex dump with ASCII sidebar. Use for visual inspection of unknown memory.
probe.exe "dump 0x055EA1C28FE8 64"
Writing Memory
CRITICAL SAFETY RULES:
- Always read before writing. Record the original value so you can restore it.
- Never write to code sections unless intentionally patching instructions.
- Verify the address is valid — read it first. If the read fails, do not write.
- Prefer data sections (heap, globals, stack) over code sections.
- Small writes only — write the minimum bytes needed.
write — Raw hex bytes
write <addr> <hex_bytes>
Writes raw bytes. Use for patching instructions (NOP = 90, INT3 = CC), writing arbitrary byte sequences.
probe.exe "read 0x7FFB21234000 5"
probe.exe "write 0x7FFB21234000 9090909090"
probe.exe "write 0x7FFB21234000 E8AB123400"
write_int — 32-bit integer
write_int <addr> <value>
Writes a signed 32-bit integer. Use for health, flags, counters, enum values.
probe.exe "read_int 0x055EA1C28FE8+0x354"
probe.exe "write_int 0x055EA1C28FE8+0x354 999"
probe.exe "write_int 0x055EA1C29038 1"
write_float — 32-bit float
write_float <addr> <value>
Writes a 32-bit float. Use for positions, speed multipliers, timers.
probe.exe "read_float 0x055EA1C28FE8+0x40"
probe.exe "write_float 0x055EA1C28FE8+0x40 5000.0"
write_ptr — 8-byte pointer
write_ptr <addr> <value>
Writes an 8-byte pointer value. Use for redirecting pointers, modifying vtable entries (dangerous).
probe.exe "read_ptr 0x055EA1C28FE8+0x330"
probe.exe "write_ptr 0x055EA1C28FE8+0x330 0x055EB2350000"
Common Recipes
Toggle a boolean field
probe.exe "read_int 0x055EA1C29038"
probe.exe "write_int 0x055EA1C29038 1"
probe.exe "write_int 0x055EA1C29038 0"
Set health to max
probe.exe "read_int 0x055EA1C28FE8+0x350"
probe.exe "read_int 0x055EA1C28FE8+0x354"
probe.exe "write_int 0x055EA1C28FE8+0x354 625"
NOP a function call (skip it)
probe.exe "read 0x7FFB21234000 5"
probe.exe "write 0x7FFB21234000 9090909090"
probe.exe "write 0x7FFB21234000 E8AB123400"
Modify a float via bridge batch
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" -d '{
"action":"batch","actions":[
{"action":"activity","status":"working","message":"Writing memory..."},
{"action":"probe","command":"read_float 0x055EA1C28FE8+0x40"},
{"action":"probe","command":"write_float 0x055EA1C28FE8+0x40 5000.0"},
{"action":"probe","command":"read_float 0x055EA1C28FE8+0x40"},
{"action":"activity","status":"idle","message":"Done"}
]
}'
Error Handling
| Error | Cause | Fix |
|---|
"error":"Invalid address" | Address format wrong | Use hex with or without 0x prefix |
"error":"Read failed" | Address not readable | Verify with dump first; entity may be dead or freed |
"error":"Write failed" | Address not writable | Code sections are read-only; data/heap is writable |
"error":"Connection refused" | Probe not running | Inject DLL first, or check port 9998 |
"error":"Size exceeds maximum" | Read >4096 bytes | Split into multiple reads |
Tips
modules list gives you base addresses — add offsets to get absolute addresses
- Entity addresses change every match — use pointer chains, not hardcoded addresses
- Writing to networked values (health, position) may be overwritten by the server on the next tick
- Hardware breakpoints (
hwbp set <addr> w 4) let you find what code writes to an address — useful for finding where to patch
watch <addr> <size> polls for changes — use this to verify your writes are sticking
- Bool fields in Source 2 are sometimes stored as
int32 (4 bytes) and sometimes as uint8 (1 byte) — check the schema dump