Create, populate, and inspect structs in the ARC Probe GUI from live process memory. Reads memory via the probe, builds struct definitions in the GUI, and navigates to view them. Use when the user wants to map out a data structure visually.
Build struct definitions in the ARC Probe GUI backed by live memory reads from an injected process.
pnpm tauri dev in arc-probe/gui/)127.0.0.1:9996, probe on TCP (usually 9998)address (required): Base address of the struct instance (hex, e.g., 0x2E6C0389400)class_name (optional): Name for the struct (default: attempts RTTI identification)size (optional): Struct size in bytes (default: 256, use 1024 for large game objects)curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"ping"}'
If the address is a C++ object, the first 8 bytes are usually a vtable pointer:
# Read vtable pointer
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"read_ptr <address>"}'
# Read RTTI Complete Object Locator (vtable - 8)
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"read_ptr <vtable>-8"}'
# Read TypeDescriptor RVA (COL + 0xC)
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"read_int <col>+0xC"}'
# Read mangled class name (module_base + rva + 0x10)
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"read_string <module_base>+<rva>+0x10"}'
Use the class name (strip .?AV prefix and @@ suffix) as the struct name.
# Hex dump first 256 bytes
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"dump <address> 256"}'
Look for:
0x7FF... or 0x0000_02...)Use a batch to create the struct and add all fields at once. Field offsets must be decimal.
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" -d '{
"action":"batch","actions":[
{"action":"activity","status":"working","message":"Creating <ClassName>..."},
{"action":"store","store":"struct","method":"createStruct","args":["<ClassName>","<address>",<size>]},
{"action":"store","store":"struct","method":"addField","args":["<ClassName>",0,"pointer","vtable"]},
{"action":"store","store":"struct","method":"addField","args":["<ClassName>",816,"pointer","m_pGameSceneNode"]},
{"action":"store","store":"struct","method":"addField","args":["<ClassName>",852,"int32","m_iHealth"]},
{"action":"store","store":"struct","method":"setActiveStruct","args":["<ClassName>"]},
{"action":"navigate","tab":"structs"},
{"action":"activity","status":"idle","message":"<ClassName> ready"}
]
}'
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"store","store":"label","method":"setLabel","args":["<address>","<ClassName> instance"]}'
Read specific fields to confirm the struct is correct:
# Read health
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"read_int <address>+0x354"}'
# Read team
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"read <address>+0x3F3 1"}'
Compare with what the GUI shows. Enable "Live" mode in the toolbar for auto-refresh.
| Hex | Decimal | Common Field |
|---|---|---|
| 0x000 | 0 | vtable |
| 0x330 | 816 | m_pGameSceneNode |
| 0x350 | 848 | m_iMaxHealth |
| 0x354 | 852 | m_iHealth |
| 0x35C | 860 | m_lifeState |
| 0x3C0 | 960 | m_flSimulationTime |
| 0x3F3 | 1011 | m_iTeamNum |
| Type | Size | Use for |
|---|---|---|
pointer | 8 | Pointers, vtables, scene nodes |
int32 | 4 | Health, team, counts, enums |
uint32 | 4 | Unsigned values, raw flags |
float | 4 | Single coordinate, speed |
bool | 1 | Flags (click to toggle in GUI) |
uint8 | 1 | Small enums, team number |
int64 | 8 | Steam IDs, large counters |
uint64 | 8 | Bitmasks |
vec2 | 8 | 2D vectors (2 floats: X, Y) |
vec3 | 12 | 3D positions/velocities (3 floats: X, Y, Z) |
qangle | 12 | Angles (3 floats: Pitch, Yaw, Roll) |
color32 | 4 | RGBA color (4 bytes, has color picker in GUI) |
colorf | 16 | RGBA color (4 floats 0.0-1.0, has color picker) |
matrix3x4 | 48 | Transform matrix (12 floats) |
flags | 4 | Bitmask flags (displayed as hex 0x00000000) |
enum32 | 4 | Named enum values (int32 display) |
handle | 4 | Entity handle (#index extracted via val & 0x7FFF) |
gametime | 4 | GameTime_t (float displayed as seconds, e.g., 12.5s) |
string_ptr | 8 | Pointer to null-terminated string |
All scalar and compound values are editable in the GUI — click any value to enter edit mode:
Writes are sent via the probe's write_int/write_float/write TCP commands.
totalSize of 1024 for game entity structs (C_BaseEntity is ~4000+ bytes but 1024 covers the most useful fields)?, the probe isn't connected or the address is invalid