Difference between revisions of "Lua:AOBScan"

From Cheat Engine
Jump to navigation Jump to search
m
(Added more in depth details for parameters, wildcards, example usage, performance, and returns. Also added related function refrences.)
Line 4: Line 4:
 
'''function''' AOBScan(''AOBString'', ''ProtectionFlags'' OPTIONAL, ''AlignmentType'' OPTIONAL, ''AlignmentParam'' HALFOPTIONAL)
 
'''function''' AOBScan(''AOBString'', ''ProtectionFlags'' OPTIONAL, ''AlignmentType'' OPTIONAL, ''AlignmentParam'' HALFOPTIONAL)
  
Scans the currently opened process and returns a [[Lua:Class:Stringlist|StringList]] object containing all the results.  
+
Scans the currently opened process memory for a byte pattern (Array of Bytes) and returns a [[Lua:Class:Stringlist|StringList]] object containing all matching addresses as hexadecimal strings.
Don't forget to free this list when done.
+
 
Byte value of higher than 255 or anything not an integer will be seen as a wildcard.
+
'''Returns:''' A [[Lua:Class:Stringlist|StringList]] containing the addresses found, or '''nil''' if no matches are found.
 +
 
 +
'''Important:''' Always call '''list.destroy()''' when done to free memory and prevent leaks.
 +
 
 +
=== Two Calling Modes ===
 +
 
 +
'''Mode 1: Pattern String''' - Provide an AOB pattern as a hex string with optional wildcards
 +
AOBScan(AOBString, ProtectionFlags, AlignmentType, AlignmentParam)
 +
 
 +
'''Mode 2: Varargs Bytes''' - Pass individual byte values as separate arguments
 +
AOBScan(byte1, byte2, byte3, ...)
 +
 +
In varargs mode:
 +
* Values 0-255 are treated as literal bytes
 +
* '''nil''', non-numeric values, or values > 255 become wildcards
 +
* Zero (0) is written as "00" if it's a number, or as a wildcard if nil/non-numeric
  
  
 
=== Function Parameters ===
 
=== Function Parameters ===
  
{|width="85%" cellpadding="10%" cellpadding="5%" cellspacing="0" border="0"
+
==== Mode 1: Pattern String ====
!align="left"|Parameter
 
!align="left"|Type
 
!style="width: 80%;" align="left"|Description
 
|-
 
|...
 
|'''...'''
 
|Bytes to scan for seperated as arguments
 
|}
 
 
 
  
 
{|width="85%" cellpadding="10%" cellpadding="5%" cellspacing="0" border="0"
 
{|width="85%" cellpadding="10%" cellpadding="5%" cellspacing="0" border="0"
Line 29: Line 35:
 
|AOBString
 
|AOBString
 
|string
 
|string
|A string of bytes, as hex, to scan for
+
|A hex byte pattern with space/comma/dash separators. Use '''??''' or '''*''' for full-byte wildcards. Supports nibble wildcards like '''7?''' or '''?A'''
 
|-
 
|-
 
|ProtectionFlags
 
|ProtectionFlags
 
|string
 
|string
|A string of flags used to set protection type of memory to be scanned
+
|'''Optional.''' Memory protection filter (see below). Default: "" (scan all memory)
 
|-
 
|-
 
|AlignmentType
 
|AlignmentType
 
|integer
 
|integer
|Used with 'AlignmentParam' to set scan alignment
+
|'''Optional.''' Alignment mode: 0=None, 1=Divisible, 2=Last digits. Default: 0
 
|-
 
|-
 
|AlignmentParam
 
|AlignmentParam
 
|string
 
|string
|A string which either holds the value the addresses must be dividable by or what the last digits of the address must be
+
|'''Optional.''' Hex value for alignment checking. Default: "1"
 
|}
 
|}
 +
 +
==== Mode 2: Varargs Bytes ====
 +
 +
{|width="85%" cellpadding="10%" cellpadding="5%" cellspacing="0" border="0"
 +
!align="left"|Parameter
 +
!align="left"|Type
 +
!style="width: 80%;" align="left"|Description
 +
|-
 +
|...
 +
|'''varargs'''
 +
|Individual byte values (0-255). Use '''nil''' or values > 255 for wildcards
 +
|}
 +
 +
 +
=== Protection Flags ===
 +
 +
The '''''ProtectionFlags''''' parameter is a string that filters which memory regions to scan based on their protection attributes:
 +
 +
'''Syntax:''' Prefix each flag with:
 +
* '''+''' = Region MUST have this flag set
 +
* '''-''' = Region MUST NOT have this flag set 
 +
* '''*''' = Don't care (default)
 +
 +
'''Flags:'''
 +
* '''X''' = Executable
 +
* '''W''' = Writable
 +
* '''C''' = Copy On Write
 +
* '''D''' = Dirty (macOS only)
 +
 +
'''Examples:'''
 +
  "+W-C"    Writable memory excluding copy-on-write (don't care about executable)
 +
  "+X-W-C"  Readonly executable memory (code sections)
 +
  "+X"      All executable memory (typical for code scanning)
 +
  "-W"      Non-writable memory only
 +
  ""        Scan everything (equivalent to "*X*W*C")
 +
  "*X*W*C"  Explicitly scan everything (don't care about any flags)
 +
 +
 +
=== Alignment Parameters ===
 +
 +
Use '''''AlignmentType''''' and '''''AlignmentParam''''' to constrain addresses and improve scan performance:
 +
 +
'''AlignmentType values:'''
 +
* '''0''' = fsmNotAligned - No alignment check (default)
 +
* '''1''' = fsmAligned - Address must be divisible by AlignmentParam
 +
* '''2''' = fsmLastDigits - Address must end with specific hex digits
 +
 +
'''AlignmentParam:'''
 +
* Interpreted as a '''hexadecimal''' value
 +
* For '''AlignmentType=1''': Alignment boundary (e.g., "10" = 16-byte aligned, "4" = 4-byte aligned)
 +
* For '''AlignmentType=2''': Required ending hex digits (e.g., "00" = addresses ending in ...00, "F0" = ending in ...F0)
 +
 +
'''Examples:'''
 +
  AlignmentType=1, AlignmentParam="10"  Only 16-byte aligned addresses (0x...0, 0x...10, 0x...20, etc.)
 +
  AlignmentType=1, AlignmentParam="4"    Only 4-byte aligned addresses
 +
  AlignmentType=2, AlignmentParam="00"  Only addresses ending with 00 (0x...00)
 +
  AlignmentType=2, AlignmentParam="F0"  Only addresses ending with F0 (0x...F0)
 +
 +
 +
=== Wildcard Syntax ===
 +
 +
'''Full-byte wildcards:''' Match any byte value
 +
* '''??''' - Most common notation
 +
* '''*''' - Alternative notation
 +
* Any non-hex characters in a byte position
 +
 +
'''Nibble wildcards:''' Match specific half-byte (4 bits)
 +
* '''7?''' - High nibble is 7, low nibble can be anything (matches 70-7F)
 +
* '''?A''' - High nibble can be anything, low nibble is A (matches 0A, 1A, 2A, ..., FA)
 +
 +
'''Examples:'''
 +
  "48 8B ?? ?? ?? 89"        Full wildcards for bytes 3-5
 +
  "DE AD ?? EF"              Wildcard for byte 3
 +
  "7? A? ?3"                Nibble wildcards: 7x, Ax, x3
 +
 +
 +
=== Usage Examples ===
 +
 +
'''Basic scan - find all matches:'''
 +
local results = AOBScan("48 8B 05 ?? ?? ?? 89")
 +
if results then
 +
  print("Found " .. results.Count .. " matches")
 +
  for i = 0, results.Count - 1 do
 +
    print(string.format("%X", results[i]))
 +
  end
 +
  results.destroy()
 +
else
 +
  print("Pattern not found")
 +
end
 +
 +
'''Scan executable memory only (faster for code patterns):'''
 +
local results = AOBScan("55 8B EC", "+X")
 +
if results then
 +
  print("First match: " .. results[0])
 +
  results.destroy()
 +
end
 +
 +
'''Scan with alignment (16-byte aligned addresses):'''
 +
local results = AOBScan("FF 15 ?? ?? ?? ??", "+X", 1, "10")
 +
if results then
 +
  results.destroy()
 +
end
 +
 +
'''Scan for addresses ending in 00:'''
 +
local results = AOBScan("DE AD BE EF", "", 2, "00")
 +
if results then
 +
  results.destroy()
 +
end
 +
 +
'''Varargs mode with wildcards:'''
 +
local results = AOBScan(0x48, 0x8B, nil, nil, nil, 0x89)  -- nil = wildcard
 +
if results then
 +
  results.destroy()
 +
end
 +
 +
'''Helper function to get first match:'''
 +
function findAOB(pattern, flags)
 +
  local results = AOBScan(pattern, flags or "+X")
 +
  if results and results.Count > 0 then
 +
    local addr = results[0]
 +
    results.destroy()
 +
    return addr
 +
  end
 +
  return nil
 +
end
 +
 +
local address = findAOB("48 8B ?? ?? ?? 89")
 +
if address then
 +
  print("Found at: " .. address)
 +
end
 +
 +
 +
=== Performance Tips ===
 +
 +
* Use '''+X''' protection flag when scanning for code to dramatically reduce scan time
 +
* Use alignment when you know the address characteristics (e.g., function pointers are often aligned)
 +
* Keep patterns as specific as possible - avoid excessive wildcards
 +
* For single-result scans, consider using '''AOBScanUnique''' or module-specific variants
 +
* Always destroy the StringList after use to prevent memory leaks
  
  
* '''''protectionflags''''' is a string:
+
=== Return Value ===
** Add a + to indicate that flag MUST be set and a - to indicate that that flag MUST NOT be set. (* sets it to don't care)
 
** X = Executable
 
** W = Writable memory
 
** C = Copy On Write.
 
Examples:
 
  +W-C = Writable memory exluding copy on write and doesn't care about the Executable flag
 
  +X-C-W = Find readonly executable memory
 
  +W = Finds all writable memory and don't care about copy on write or execute
 
  "" = Find everything (is the same as "*X*C*W" )
 
  
 +
* '''Success:''' Returns a [[Lua:Class:Stringlist|StringList]] object containing hex address strings
 +
* '''Failure:''' Returns '''nil''' (no matches found or invalid pattern)
  
* '''''alignmenttype''''' is an integer:
+
'''Note:''' The returned addresses are strings in hexadecimal format (e.g., "7FF12340"). Convert with tonumber(addr, 16) if you need numeric values.
** 0 = No alignment check
 
** 1 = Address must be dividable by alignmentparam
 
** 2 = Address must end with alignmentparam
 
  
  
{{LuaSeeAlso}}
+
=== See Also ===
  
=== Related Functions ===
+
* [[Lua:AOBScanUnique|AOBScanUnique]] - Returns a single address or nil (no cleanup needed)
* [[Lua:autoAssemble|autoAssemble]]
+
* [[Lua:AOBScanModule|AOBScanModule]] - Scan within a specific module
* [[Lua:disassemble|disassemble]]
+
* [[Lua:AOBScanModuleUnique|AOBScanModuleUnique]] - Find unique pattern in a module
* [[Lua:getInstructionSize|getInstructionSize]]
+
* [[Lua:Class:Stringlist|StringList]] - String list object documentation
* [[Lua:getPreviousOpcode|getPreviousOpcode]]
 
* [[Lua:allocateSharedMemory|allocateSharedMemory]]
 
* [[Lua:mapMemory|mapMemory]]
 
* [[Lua:unmapMemory|unmapMemory]]
 
* [[Lua:readBytes|readBytes]]
 
* [[Lua:readPointer|readPointer]]
 
* [[Lua:writeBytes|writeBytes]]
 
* [[Lua:readBytesLocal|readBytesLocal]]
 
* [[Lua:readPointerLocal|readPointerLocal]]
 
* [[Lua:writeBytesLocal|writeBytesLocal]]
 
* [[Lua:wordToByteTable|wordToByteTable]]
 
* [[Lua:dwordToByteTable|dwordToByteTable]]
 
* [[Lua:qwordToByteTable|qwordToByteTable]]
 
* [[Lua:floatToByteTable|floatToByteTable]]
 
* [[Lua:doubleToByteTable|doubleToByteTable]]
 
* [[Lua:stringToByteTable|stringToByteTable]]
 
* [[Lua:wideStringToByteTable|wideStringToByteTable]]
 
* [[Lua:byteTableToWord|byteTableToWord]]
 
* [[Lua:byteTableToDword|byteTableToDword]]
 
* [[Lua:byteTableToQword|byteTableToQword]]
 
* [[Lua:byteTableToFloat|byteTableToFloat]]
 
* [[Lua:byteTableToDouble|byteTableToDouble]]
 
* [[Lua:byteTableToString|byteTableToString]]
 
* [[Lua:byteTableToWideString|byteTableToWideString]]
 

Revision as of 21:40, 20 October 2025

function AOBScan(...)

function AOBScan(AOBString, ProtectionFlags OPTIONAL, AlignmentType OPTIONAL, AlignmentParam HALFOPTIONAL)

Scans the currently opened process memory for a byte pattern (Array of Bytes) and returns a StringList object containing all matching addresses as hexadecimal strings.

Returns: A StringList containing the addresses found, or nil if no matches are found.

Important: Always call list.destroy() when done to free memory and prevent leaks.

Two Calling Modes

Mode 1: Pattern String - Provide an AOB pattern as a hex string with optional wildcards

AOBScan(AOBString, ProtectionFlags, AlignmentType, AlignmentParam)

Mode 2: Varargs Bytes - Pass individual byte values as separate arguments

AOBScan(byte1, byte2, byte3, ...)

In varargs mode:

  • Values 0-255 are treated as literal bytes
  • nil, non-numeric values, or values > 255 become wildcards
  • Zero (0) is written as "00" if it's a number, or as a wildcard if nil/non-numeric


Function Parameters

Mode 1: Pattern String

Parameter Type Description
AOBString string A hex byte pattern with space/comma/dash separators. Use ?? or * for full-byte wildcards. Supports nibble wildcards like 7? or ?A
ProtectionFlags string Optional. Memory protection filter (see below). Default: "" (scan all memory)
AlignmentType integer Optional. Alignment mode: 0=None, 1=Divisible, 2=Last digits. Default: 0
AlignmentParam string Optional. Hex value for alignment checking. Default: "1"

Mode 2: Varargs Bytes

Parameter Type Description
... varargs Individual byte values (0-255). Use nil or values > 255 for wildcards


Protection Flags

The ProtectionFlags parameter is a string that filters which memory regions to scan based on their protection attributes:

Syntax: Prefix each flag with:

  • + = Region MUST have this flag set
  • - = Region MUST NOT have this flag set
  • * = Don't care (default)

Flags:

  • X = Executable
  • W = Writable
  • C = Copy On Write
  • D = Dirty (macOS only)

Examples:

 "+W-C"     Writable memory excluding copy-on-write (don't care about executable)
 "+X-W-C"   Readonly executable memory (code sections)
 "+X"       All executable memory (typical for code scanning)
 "-W"       Non-writable memory only
 ""         Scan everything (equivalent to "*X*W*C")
 "*X*W*C"   Explicitly scan everything (don't care about any flags)


Alignment Parameters

Use AlignmentType and AlignmentParam to constrain addresses and improve scan performance:

AlignmentType values:

  • 0 = fsmNotAligned - No alignment check (default)
  • 1 = fsmAligned - Address must be divisible by AlignmentParam
  • 2 = fsmLastDigits - Address must end with specific hex digits

AlignmentParam:

  • Interpreted as a hexadecimal value
  • For AlignmentType=1: Alignment boundary (e.g., "10" = 16-byte aligned, "4" = 4-byte aligned)
  • For AlignmentType=2: Required ending hex digits (e.g., "00" = addresses ending in ...00, "F0" = ending in ...F0)

Examples:

 AlignmentType=1, AlignmentParam="10"   Only 16-byte aligned addresses (0x...0, 0x...10, 0x...20, etc.)
 AlignmentType=1, AlignmentParam="4"    Only 4-byte aligned addresses
 AlignmentType=2, AlignmentParam="00"   Only addresses ending with 00 (0x...00)
 AlignmentType=2, AlignmentParam="F0"   Only addresses ending with F0 (0x...F0)


Wildcard Syntax

Full-byte wildcards: Match any byte value

  • ?? - Most common notation
  • * - Alternative notation
  • Any non-hex characters in a byte position

Nibble wildcards: Match specific half-byte (4 bits)

  • 7? - High nibble is 7, low nibble can be anything (matches 70-7F)
  • ?A - High nibble can be anything, low nibble is A (matches 0A, 1A, 2A, ..., FA)

Examples:

 "48 8B ?? ?? ?? 89"        Full wildcards for bytes 3-5
 "DE AD ?? EF"              Wildcard for byte 3
 "7? A? ?3"                 Nibble wildcards: 7x, Ax, x3


Usage Examples

Basic scan - find all matches:

local results = AOBScan("48 8B 05 ?? ?? ?? 89")
if results then
  print("Found " .. results.Count .. " matches")
  for i = 0, results.Count - 1 do
    print(string.format("%X", results[i]))
  end
  results.destroy()
else
  print("Pattern not found")
end

Scan executable memory only (faster for code patterns):

local results = AOBScan("55 8B EC", "+X")
if results then
  print("First match: " .. results[0])
  results.destroy()
end

Scan with alignment (16-byte aligned addresses):

local results = AOBScan("FF 15 ?? ?? ?? ??", "+X", 1, "10")
if results then
  results.destroy()
end

Scan for addresses ending in 00:

local results = AOBScan("DE AD BE EF", "", 2, "00")
if results then
  results.destroy()
end

Varargs mode with wildcards:

local results = AOBScan(0x48, 0x8B, nil, nil, nil, 0x89)  -- nil = wildcard
if results then
  results.destroy()
end

Helper function to get first match:

function findAOB(pattern, flags)
  local results = AOBScan(pattern, flags or "+X")
  if results and results.Count > 0 then
    local addr = results[0]
    results.destroy()
    return addr
  end
  return nil
end

local address = findAOB("48 8B ?? ?? ?? 89")
if address then
  print("Found at: " .. address)
end


Performance Tips

  • Use +X protection flag when scanning for code to dramatically reduce scan time
  • Use alignment when you know the address characteristics (e.g., function pointers are often aligned)
  • Keep patterns as specific as possible - avoid excessive wildcards
  • For single-result scans, consider using AOBScanUnique or module-specific variants
  • Always destroy the StringList after use to prevent memory leaks


Return Value

  • Success: Returns a StringList object containing hex address strings
  • Failure: Returns nil (no matches found or invalid pattern)

Note: The returned addresses are strings in hexadecimal format (e.g., "7FF12340"). Convert with tonumber(addr, 16) if you need numeric values.


See Also