Lua:getAddress

From Cheat Engine
Revision as of 02:47, 21 October 2025 by Mr millchick (talk | contribs) (fixed formatting errors, reverted param name)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

function getAddress(AddressString, Local OPTIONAL) : Integer

Resolves a symbol name (symbol, module, export, address, or expression) to a memory address. Raises an error if the symbol cannot be resolved.

This resolver supports module bases, module+offset expressions, registered symbols, labels from auto-assembler scripts, exported/debug symbols, and pointer arithmetic (e.g., "[module+offset]+8"). If the first argument is already a number, it is returned unchanged.


Function Parameters[edit]

Parameter Type Description
AddressString string or number The symbol, module name, export, label, or expression to resolve to an address. If a number is provided, it's returned unchanged
Local boolean Optional. If true, uses Cheat Engine's self symbol handler instead of the target process. Default: false


Returns[edit]

An integer representing the resolved memory address.

Important: This function raises an exception if symbol resolution fails. For safe resolution that returns nil on failure, use getAddressSafe instead.


Description[edit]

The function resolves various types of address expressions:

Module names:

  • "game.exe" → Base address of game.exe
  • "kernel32.dll" → Base address of kernel32.dll

Module + offset:

  • "game.exe+1234" → Base address + 0x1234
  • "game.exe+ABC" → Hex offsets automatically recognized

Symbol names:

  • Function names from debug symbols
  • Exported function names
  • Registered symbols from registerSymbol()

Labels:

  • Auto-assembler script labels
  • Custom registered labels

Expressions:

  • "[game.exe+100]+8" → Pointer arithmetic
  • "game.exe+100+4" → Multi-level pointers


Behavior[edit]

  • If AddressString is already a number, it's returned unchanged
  • Symbol resolution waits for symbols to load if necessary
  • On 64-bit Windows: Raises a Lua error with the exception message


Usage Examples[edit]

Get the address of a registered symbol in the target process:

registerSymbol("MySymbol", 0x401000)
local symAddr = getAddress("MySymbol")
print(string.format("MySymbol = 0x%X", symAddr))

Get the address of a symbol in the target process:

local ceAddr = getAddress("cheatengine-x86_64-SSE4-AVX2.exe+5000")
print(string.format("CE process address = 0x%X", ceAddr))

Basic module resolution:

local baseAddress = getAddress("game.exe")
print(string.format("Game base: %X", baseAddress))

Module with offset:

local address = getAddress("game.exe+12345")
print(string.format("Address: %X", address))

Using registered symbols:

registerSymbol("PlayerHealth", "game.exe+ABCD")
local healthAddr = getAddress("PlayerHealth")
print("Health at: " .. healthAddr)

Numeric input (pass-through):

local addr = getAddress(0x12345678)
-- Returns 0x12345678 unchanged

With error handling:

local success, result = pcall(function()
  return getAddress("NonExistentModule")
end)

if success then
  print("Address: " .. result)
else
  print("Error: " .. result)
end

Reading from resolved address:

local playerBase = getAddress("game.exe+100000")
local health = readInteger(playerBase + 0x50)
print("Health: " .. health)

Using local symbol handler:

-- Resolve symbols from Cheat Engine itself
local ceFunction = getAddress("SomeCEFunction", true)


Error Handling[edit]

Since getAddress raises exceptions on failure, wrap calls in pcall for safe execution:

Safe wrapper pattern:

function safeGetAddress(symbol, local)
  local success, result = pcall(getAddress, symbol, local)
  if success then
    return result
  else
    print("Failed to resolve: " .. symbol)
    return nil
  end
end

local addr = safeGetAddress("game.exe+1234")
if addr then
  -- Use address
end

Alternative - Use getAddressSafe:

-- Recommended for code that expects possible failures
local addr = getAddressSafe("game.exe+1234")
if addr then
  -- Symbol resolved
else
  -- Symbol failed, no exception raised
end


Advanced Examples[edit]

Resolve and register multiple symbols:

local symbols = {
  PlayerHealth = "game.exe+10000",
  PlayerMana = "game.exe+10004",
  PlayerExp = "game.exe+10008"
}

for name, expr in pairs(symbols) do
  local addr = getAddress(expr)
  registerSymbol(name, addr)
  print(string.format("%s = %X", name, addr))
end

Dynamic offset calculation:

local base = getAddress("game.exe")
local patternAddr = AOBScanUnique("48 8B 05 ?? ?? ?? ??", "+X")

if patternAddr then
  local offset = patternAddr - base
  print(string.format("Pattern at game.exe+%X", offset))
end

Multi-level pointer resolution:

-- Note: For complex pointers, use readPointer or pointer notation
local base = getAddress("game.exe+100000")
local ptr1 = readPointer(base)
local ptr2 = readPointer(ptr1 + 0x10)
local value = readInteger(ptr2 + 0x20)


Symbol Resolution Process[edit]

When you call getAddress("game.exe+1234"), the function:

  1. Checks if input is already a number → return it
  2. Parses the expression ("game.exe+1234")
  3. Looks up "game.exe" in the module list
  4. Gets the base address of the module
  5. Adds the offset (0x1234)
  6. Returns the final address

For complex expressions, the symbol handler evaluates:

  • Module bases
  • Registered symbols
  • Debug symbols (PDB/DWARF)
  • Exported functions
  • Mathematical operations


When to Use getAddress vs getAddressSafe[edit]

Use getAddress when:

  • The symbol MUST exist (critical for script functionality)
  • You want the script to fail loudly if something is wrong
  • You're in a protected call context (pcall)

Use getAddressSafe when:

  • Symbol might not exist (e.g., version-dependent features)
  • You want to handle failure gracefully
  • You're checking for optional features


See Also[edit]