Skip to content

Address Table and Sessions

brkzlr edited this page Jun 25, 2026 · 5 revisions

The address table is where useful scan results go after you find them. It lets you watch values, edit them, freeze them, group them and save them into a .pct table for later.

Scanning finds possible addresses. The address table is where you figure out which ones are actually worth keeping.

Address Table Basics

The table has five columns:

  • Freeze: checkbox for freezing a value or toggling a script entry
  • Description: your label, like Health, Ammo, Money
  • Address: address, expression or pointer chain
  • Type: how PINCE reads and writes the value
  • Value: the current value read from the target

Double click a normal row to edit it. Which editor opens depends on the column:

  • Description: rename the row
  • Address: edit the address or pointer chain
  • Type: change value type, length, signed/hex display or endianness
  • Value: write a new value to memory

Rows can also have children. This is mostly for groups, structures and keeping related values together.

Adding Entries

The common ways to add entries are:

  • Double click a scan result
  • Select scan results and press the down arrow button to copy them to the address table
  • Click Add Address Manually
  • Send a script from Libpince Engine with Send to cheat table
  • Add a structure from the Structures window
  • Paste rows copied from another table

The fastest beginner workflow is usually:

  1. Scan until the result count is small
  2. Add a few likely results to the table
  3. Change or freeze them one by one
  4. Delete the ones that do nothing
  5. Rename the good ones

Do not keep every scan result. A small table with tested entries is much nicer than a huge table full of random values.

Address Expressions

The Address column does not have to be a raw address.

It can be:

  • A plain address, like 0x7ffff1234560
  • A module expression, like libgame.so+0x1234
  • A GDB-style expression, like $rax+0x20
  • A pointer chain made with the Pointer checkbox in Add Address Manually
  • A relative child address, like +0x4, when the row is under a parent with a resolved address

If an address resolves cleanly, PINCE reads the value and updates the Value column. If it cannot resolve or read it, you will usually see ?? or an unchanged value.

Green addresses are static according to PINCE. Static is usually better than heap, but it does not automatically mean the value is useful. It can still be a display copy or some temporary cached value.

For more expression examples, see GDB Expressions. For pointer chains, see Pointers.

Value Types

Type decides how PINCE interprets the bytes at the address.

The normal types are:

  • Int8, Int16, Int32, Int64: whole numbers with 1, 2, 4 or 8 bytes
  • Float32, Float64: decimal/float values
  • String_ASCII, String_UTF8, String_UTF16, String_UTF32: text with a chosen encoding
  • ByteArray: raw bytes with a length

Integer rows can be displayed as unsigned, signed or hexadecimal. This only changes display/write parsing, not where the value lives.

Strings and ByteArray entries have a length. If you edit a string or byte array value with a different length, PINCE may update the stored length for that row.

Struct rows are special. They are created by the Structures tool, carry an address and group fields below them. A struct parent has no readable value of its own.

Testing Entries

Finding an address is only the first half. You still need to test it.

Good tests:

  • Change the value and see if the game reacts
  • Freeze it and see if the game stops changing it
  • Let the game change it naturally and see if the row updates
  • Go through a loading screen, menu, death, respawn or level change
  • Restart the game if you are checking if an entry survives between runs

Bad signs:

  • Editing it changes the table but not the game
  • It works once then stops updating
  • It changes a UI number but gameplay does not care
  • Freezing it breaks unrelated values
  • The address becomes unreadable after a scene change

If the value only works until restart, you probably need a pointer chain or code injection instead of keeping the raw address.

Freezing Values

Freezing does not magically lock the game variable. PINCE reads the current shown value when you enable freeze, stores that value and writes it back every freeze interval.

The default freeze interval is 100 ms. You can change it in Settings -> General -> Freeze Interval. The range is 100 ms to 10000 ms.

This means freeze is not instant. If the game changes and checks the value before PINCE writes it back, the game can still react first.

Example:

  • You have 50 health frozen
  • The enemy does 100 damage in one hit
  • The game checks death right after applying damage
  • PINCE writes 50 back a moment later, but you are already dead

For simple ammo/money values, normal freeze usually works fine. For fast logic like health, timers or physics, finding the code that writes the value can be better.

Freeze Modes

The small area just to the right of the freeze checkbox cycles freeze modes while the row is frozen.

Modes are:

  • No arrow: keep the captured value exactly
  • up arrow: allow increases, block decreases
  • down arrow: allow decreases, block increases

The arrow modes are ratchets.

With up arrow, PINCE lets the value rise. When it sees a higher value, it updates the frozen value to that higher number and keeps freezing from there. This is good for money or score where gains should stay but spending should not.

With down arrow, PINCE lets the value fall. When it sees a lower value, it updates the frozen value to that lower number and keeps freezing from there. This is useful for values where bigger is bad.

Script entries do not use freeze modes. Their checkbox runs script code instead.

Script Entries

Script entries are address table rows backed by Libpince Engine code.

They are created from Libpince Engine with Send to cheat table or Ctrl+Shift+T. When you toggle the row, PINCE runs the script instead of freezing a memory address.

Scripts can have sections:

[ENABLE]
# code that runs when checked
[DISABLE]
# code that runs when unchecked

The tags are case-insensitive and surrounding whitespace is ignored. If a script has no tags, the whole script runs when enabled and nothing runs when disabled.

The script namespace is created the first time you enable it and kept for that table entry. Variables made in [ENABLE] can be used later in [DISABLE] during the same PINCE session.

If [ENABLE] fails, PINCE unchecks the row again.

Groups

Groups are for keeping the table readable.

Useful group ideas:

  • Player
  • Inventory
  • Position
  • Timers
  • Debug scripts
  • Broken / needs update

Right click selected rows and use Add to a new group to move them into a new group. Use Create a new group to create an empty group.

Toggle including children is useful when a group contains multiple freezes or scripts you want to enable together.

Useful Context Menu Actions

Right click an address table row for actions.

Editing:

  • Description: rename selected rows
  • Address: edit address, expression or pointer chain
  • Type: change how the row is read
  • Value: write a new value
  • Edit script: open a script entry in Libpince Engine

Display:

  • Show as hexadecimal: display integer values in hex
  • Show as unsigned: display integer values as unsigned decimal
  • Show as signed: display integer values as signed decimal
  • View as structure: view the selected address using a saved structure

Debugging:

  • Browse this memory region: open Memory Viewer hex view at this address
  • Disassemble this address: open Memory Viewer disassembly at this address
  • Find out what writes to this address: catch code that changes it
  • Find out what reads this address: catch code that reads it
  • Find out what accesses this address: catch reads and writes

Pointers:

  • Pointer scan for this address: start a pointer scan from this value
  • Open pointer scanner: open the pointer scanner window when available

Table editing:

  • Cut, Copy, Paste: move rows around
  • Paste inside: paste rows as children of the selected row
  • Delete: remove rows
  • Add to a new group: group selected rows
  • Create a new group: create an empty group

Some actions only appear when they make sense. For example, integer display actions only appear for integer rows, script rows only show script-related actions and debugger actions need an attached process.

Shortcuts

Common shortcuts:

  • Enter: edit value
  • Ctrl+Enter: edit description
  • Ctrl+Alt+Enter: edit address
  • Alt+Enter: edit type
  • Space: toggle selected rows
  • Ctrl+Space: toggle selected rows and their children
  • Ctrl+B: browse memory region
  • Ctrl+D: disassemble address
  • Del: delete selected rows
  • Ctrl+C, Ctrl+X, Ctrl+V: copy, cut and paste rows
  • V: paste inside selected row
  • R: refresh the address table

Refreshing and Auto Update

The address table updates periodically when auto-update is enabled. You can change this from settings.

The refresh button forces an update and clears PINCE's expression cache. Use it if a pointer, expression or symbol looks stale.

If the target process is not attached, rows can still exist in the table, but live values cannot be read.

Sessions

A session is a .pct cheat table file.

It saves:

  • Address table rows, including groups, pointer chains, types, values, freeze states and script entries
  • Bookmarks and comments
  • Session notes
  • Structure definitions
  • Process name

It does not save a live process snapshot. It does not keep the game running, restore memory, restore allocated code caves or magically make heap addresses valid again.

Loading a .pct restores the table data. You still need to attach to the right process for values to resolve and update.

Use the folder button or Ctrl+O to load a session. Use the disk button or Ctrl+S to save one.

PINCE tracks unsaved changes and asks before closing or loading another table.

Session files have a version number. Current sessions are version 3. Older sessions are migrated when loaded if PINCE still understands their format.

What To Save

A good table usually has:

  • Clear descriptions
  • Working pointer chains or stable expressions instead of temporary heap addresses
  • Groups for related entries
  • Notes explaining anything non-obvious
  • Scripts only when a normal value edit/freeze is not enough

A bad table usually has hundreds of untested scan results named No Description.

If you are making a table to share, test it after restarting the game. If it only works in the same run where you scanned it, it is probably not ready yet.

Clone this wiki locally