Difference between revisions of "Lua:getAddress"

From Cheat Engine
Jump to navigation Jump to search
(Added more detailed documentation with useful examples)
m (fixed formatting errors, reverted param name)
 
Line 1: Line 1:
 
[[Category:Lua]]
 
[[Category:Lua]]
'''function''' getAddress(''SymbolName'', ''Local'' OPTIONAL) ''':''' Integer
+
'''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.
 
Resolves a symbol name (symbol, module, export, address, or expression) to a memory address. Raises an error if the symbol cannot be resolved.
Line 14: Line 14:
 
!style="width: 80%;" align="left"|Description
 
!style="width: 80%;" align="left"|Description
 
|-
 
|-
|SymbolName
+
|AddressString
 
|string or number
 
|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
 
|The symbol, module name, export, label, or expression to resolve to an address. If a number is provided, it's returned unchanged
Line 58: Line 58:
 
=== Behavior ===
 
=== Behavior ===
  
* If '''SymbolName''' is already a number, it's returned unchanged
+
* If '''AddressString''' is already a number, it's returned unchanged
 
* Symbol resolution waits for symbols to load if necessary
 
* Symbol resolution waits for symbols to load if necessary
 
* On '''64-bit Windows''': Raises a Lua error with the exception message
 
* On '''64-bit Windows''': Raises a Lua error with the exception message
Line 66: Line 66:
  
 
'''Get the address of a registered symbol in the target process:'''
 
'''Get the address of a registered symbol in the target process:'''
registerSymbol("MySymbol", 0x401000)
+
registerSymbol("MySymbol", 0x401000)
local symAddr = getAddress("MySymbol")
+
local symAddr = getAddress("MySymbol")
print(string.format("MySymbol = 0x%X", symAddr))
+
print(string.format("MySymbol = 0x%X", symAddr))
  
 
'''Get the address of a symbol in the target process:'''
 
'''Get the address of a symbol in the target process:'''
local ceAddr = getAddress("cheatengine-x86_64-SSE4-AVX2.exe+5000")
+
local ceAddr = getAddress("cheatengine-x86_64-SSE4-AVX2.exe+5000")
print(string.format("CE process address = 0x%X", ceAddr))
+
print(string.format("CE process address = 0x%X", ceAddr))
  
 
'''Basic module resolution:'''
 
'''Basic module resolution:'''
Line 139: Line 139:
 
  else
 
  else
 
   -- Symbol failed, no exception raised
 
   -- Symbol failed, no exception raised
end
 
 
 
=== Platform-Specific Behavior ===
 
 
'''Windows 64-bit:'''
 
local addr = getAddress("InvalidSymbol")
 
-- Raises Lua error, can be caught with pcall
 
 
'''Windows 32-bit:'''
 
local addr = getAddress("InvalidSymbol")
 
-- Re-raises original exception (harder to catch in Lua)
 
 
'''Linux/macOS:'''
 
local addr, errMsg = getAddress("InvalidSymbol")
 
-- Returns: nil, "error message"
 
if not addr then
 
  print("Error: " .. errMsg)
 
 
  end
 
  end
  
Line 196: Line 178:
 
When you call getAddress("game.exe+1234"), the function:
 
When you call getAddress("game.exe+1234"), the function:
  
1. Checks if input is already a number → return it
+
<ol>
2. Parses the expression ("game.exe+1234")
+
<li>Checks if input is already a number → return it</li>
3. Looks up "game.exe" in the module list
+
<li>Parses the expression ("game.exe+1234")</li>
4. Gets the base address of the module
+
<li>Looks up "game.exe" in the module list</li>
5. Adds the offset (0x1234)
+
<li>Gets the base address of the module</li>
6. Returns the final address
+
<li>Adds the offset (0x1234)</li>
 +
<li>Returns the final address</li>
 +
</ol>
  
 
For complex expressions, the symbol handler evaluates:
 
For complex expressions, the symbol handler evaluates:

Latest revision as of 02:47, 21 October 2025

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]