Dynamic load a static value address into user defined symbol by using lua script

A forum dedicated to use and support LUA for Cheat Engine.


Post Reply
User avatar
bbfox
Table Master
Table Master
Journeyman Hacker
Journeyman Hacker
Posts: 367
Joined: Sat Jul 23, 2022 8:59 am
Answers: 0
x 777

Dynamic load a static value address into user defined symbol by using lua script

Post by bbfox »

In some tables, there will be some static address values, like HP/MP/STR/DEF/DEX. Usually the address format will be:

  1. Only a static address. i.e. 305EC74D
  2. Defined by "module name"+offset. i.e. Game.exe+30FF23E7
    Method 2 usually works. If the game executable is updated, the address may be changed. So, I have to search these static addresses again. This will become a burden if games are updated frequently.
  3. Get the static address into a user-defined symbol from the OP code ==> There may be an easy way to do this. I use a lua script to parse the address.
    For example:
    Let's say there is a static address: Game.exe+71957EC. First, I will try to find what addresses access this value. i.e., we have an address that accesses the value in Game.exe+357EE95. Now, try to get the static value address from this OP code:

Image

  • The machine code is F3 0F5D 0D 4F69C103 (OP code length = 8), disassembly the OP code into assembly ==>

    Code: Select all

    minss xmm1,DWORD PTR [rip+03C1694F] #03C16957
    
  • We need to calculate address [rip+03C1694F+8 (OP code offset)] = [rip+03C16957]. In this example, the [rip = Game.exe+357EE95]. So, final address = [Game.exe+357EE95+03C16957] = [Game.exe+71957EC]

  • Lua code:

    • Pre-request: lua AOBScanModule https://opencheattables.com/viewtopic.php?t=345
    • main lua script code example. Explanation:
    • First Define 2 AOBs. Each AOB should only map to one result only:
      • Example AOB explained above: F3 0F 5D 0D ?? ?? ?? ?? F3 48 0F 2C C9: name: damage, Static address offset position = 4, Effective AOB length = 8 (used to calculate rip offset), symbol name = damage_base
      • Example 2: F3 0F 5D 0D ?? ?? ?? ?? 48 8B 83: name: defense, Static address offset position = 4, Effective AOB length = 8, symbol name = defense_base
    • Replace AOBs array with your AOBs:
    • Replace module name (usually game executable name) in line 34
    • Replace disable_array symbol name in [DISABLE] section
    • The code is not optimized. I'm not familiar with lua, but it's functional. I don't care if it's optimized or not because it just ran once. Revise yourself if you're familiar with lua.

Code: Select all

[ENABLE]
{$lua}
if syntaxcheck then return end
if memrec then print(memrec.Description) end
  AOBs = {
    {["name"]="damage", ["aob"]="F3 0F 5D 0D ?? ?? ?? ?? F3 48 0F 2C C9", ["pos"]= 4,  ["aoblen"]= 8 , ["symbol"]="damage_base"},
    {["name"]="defense", ["aob"]="F3 0F 5D 0D ?? ?? ?? ?? 48 8B 83", ["pos"]= 4,  ["aoblen"]= 8 , ["symbol"]="defense_base"},
  }
 
  local a1 = 'n/a'
  local a2 = 'n/a'
  local a3 = 0
  local a4 = 0
  local a5 = 'n/a'
 
  for k,v in pairs(AOBs) do
    for k1,v1 in pairs(v) do
      if (k1 == 'name') then
        a1 = v1
      end
      if (k1 == 'aob') then
        a2 = v1
      end
      if (k1 == 'pos') then
        a3 = v1
      end
      if (k1 == 'aoblen') then
        a4 = v1
      end
      if (k1 == 'symbol') then
        a5 = v1
      end
    end
    local aob_addr_str = AOBScanModule('Game.exe', a2, '+X-C-W')
    local name_addr_str = getAddressSafe(aob_addr_str[0])+a3
    local name_addr_val = readInteger(name_addr_str)
    local aob_addr_val = tonumber(aob_addr_str[0], 16)
    local final_addr_val = name_addr_val + aob_addr_val + a4
    registerSymbol(a5, final_addr_val)
  end
getLuaEngine().Close()
 
[DISABLE]
{$lua}
if syntaxcheck then return end
if memrec then print(memrec.Description) end
local disable_array = {"damage_base", "defense_base"}
local a_len = #(disable_array)
local i = 0
for i = 1, a_len do
  unregisterSymbol(disable_array[i])
end
getLuaEngine().Close()

Pastbin format:

Spoiler

  • Drawback: if one of the AOBs failed to scan, script will raise an error.

Output Example: Define an sith user defined symbol item in CE
Image





Example 2:
Image

  • OP Code = 8B 15 30A26D01
  • AOB = 8B 15 ?? ?? ?? ?? 83 CB FF
  • Static address offset position = 2, Effective AOB length = 6, symbol name = base_addr
  • Array in lua: {["name"]="base", ["aob"]="8B 15 ?? ?? ?? ?? 83 CB FF", ["pos"]= 2, ["aoblen"]= 6 , ["symbol"]="base_addr"},
  • Disassembly

Code: Select all

mov edx,DWORD PTR [rip+16da230] #16da236
Last edited by bbfox on Tue Apr 15, 2025 7:02 am, edited 3 times in total.

Table is free to use, but need to leave the author's name and source URL: https://opencheattables.com.
Table will not be up-to-date. Feel free to modify it, but leave credit to the source.
Tip me a coffee? https://ko-fi.com/bbfoxmodding


User avatar
justNOPing
Novice Hacker
Novice Hacker
Posts: 26
Joined: Mon Aug 08, 2022 10:02 am
Answers: 0
Location: newmem
x 19

Re: Dynamic load a static value address into user defined symbol by using lua script

Post by justNOPing »

bbfox wrote: Fri Aug 19, 2022 12:36 am

Let's say there is a static address: Game.exe+71957EC. First, I will try to find what addresses access this value. i.e. we have an address that access the value in Game.exe+357EE95. Now, try to get static value address from this OP Code:

Image

  • The machine code is F3 0F5D 0D 4F69C103 (OP code length = 8), disassembly the OP code into assembly ==>
  • We need to calculate address [rip+03C1694F+8 (OP code offset)] = [rip+03C16957]. In this example, the [rip = Game.exe+357EE95]. So, final address = [Game.exe+357EE95+03C16957] = [Game.exe+71957EC]

Alright, I get the [rip+03C1694F+8] calculation, but I don't get the link between Game.exe+7198B8 and Game.exe+357EE95. How does he even calculate the rip value (03C1694F)? Does "rip" represent the static address, which is then defined by Game.exe+357EE95?


User avatar
bbfox
Table Master
Table Master
Journeyman Hacker
Journeyman Hacker
Posts: 367
Joined: Sat Jul 23, 2022 8:59 am
Answers: 0
x 777

Re: Dynamic load a static value address into user defined symbol by using lua script

Post by bbfox »

justNOPing wrote: Fri Aug 19, 2022 4:57 am
bbfox wrote: Fri Aug 19, 2022 12:36 am

Let's say there is a static address: Game.exe+71957EC. First, I will try to find what addresses access this value. i.e. we have an address that access the value in Game.exe+357EE95. Now, try to get static value address from this OP Code:

Image

  • The machine code is F3 0F5D 0D 4F69C103 (OP code length = 8), disassembly the OP code into assembly ==>
  • We need to calculate address [rip+03C1694F+8 (OP code offset)] = [rip+03C16957]. In this example, the [rip = Game.exe+357EE95]. So, final address = [Game.exe+357EE95+03C16957] = [Game.exe+71957EC]

Alright, I get the [rip+03C1694F+8] calculation, but I don't get the link between Game.exe+7198B8 and Game.exe+357EE95. How does he even calculate the rip value (03C1694F)? Does "rip" represent the static address, which is then defined by Game.exe+357EE95?

Ignore Game.exe+7198B8. It's not in AOB range. I just markup the game executable name.

OK, I may miss some explanations. rip (or formally in uppercase RIP) is one of x64 CPU registers like RAX, RBX...etc. RIP is the instruction pointer (address of next instruction to run).

So, in memory address Game.exe+357EE95 == OP Code (or machine code): minss xmm1, [Game.exe+71957EC]. The RIP address will be equal to Game.exe+357EE95 before this OP code executed
After the OP code executed, it will equal to address Game.exe+357EE9D

03C1694F is an offset from machine code. It stored in OP Code F3 0F5D 0D 4F69C103. For x86 CPU, we need to perform a byte / word swap in memory to get correct value, if the width of value is Word, Integer, LongInt...etc. CE/lua functions will handle this. If we need to view memory structure by eye, we need to swap ourself. Please refer related X86 CPU documents.


Table is free to use, but need to leave the author's name and source URL: https://opencheattables.com.
Table will not be up-to-date. Feel free to modify it, but leave credit to the source.
Tip me a coffee? https://ko-fi.com/bbfoxmodding


User avatar
justNOPing
Novice Hacker
Novice Hacker
Posts: 26
Joined: Mon Aug 08, 2022 10:02 am
Answers: 0
Location: newmem
x 19

Re: Dynamic load a static value address into user defined symbol by using lua script

Post by justNOPing »

bbfox wrote: Fri Aug 19, 2022 12:36 am

Ignore Game.exe+7198B8. It's not in AOB range. I just markup the game executable name.

OK, I may miss some explanations. rip (or formally in uppercase RIP) is one of x64 CPU registers like RAX, RBX...etc. RIP is the instruction pointer (address of next instruction to run).

So, in memory address Game.exe+357EE95 == OP Code (or machine code): minss xmm1, [Game.exe+71957EC]. The RIP address will be equal to Game.exe+357EE95 before this OP code executed
After the OP code executed, it will equal to address Game.exe+357EE9D

03C1694F is an offset from machine code. It stored in OP Code F3 0F5D 0D 4F69C103. For x86 CPU, we need to perform a byte / word swap in memory to get correct value, if the width of value is Word, Integer, LongInt...etc. CE/lua functions will handle this. If we need to view memory structure by eye, we need to swap ourself. Please refer related X86 CPU documents.

Thanks for a detailed explanation, much love.


Post Reply