Skip to content

Instantly share code, notes, and snippets.

@fakuivan
Last active January 9, 2019 06:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fakuivan/61b3bb9e59d8ac724cedf1e8910de8e3 to your computer and use it in GitHub Desktop.
Save fakuivan/61b3bb9e59d8ac724cedf1e8910de8e3 to your computer and use it in GitHub Desktop.
Use Cheat Engine's LUA engine to walk a struct to find offsets that match a given value and recursively walk potential structure pointers found within
function scanTree(address, maxOffset, comparator, structValidator, maxDepth)
local offsetTree = {}
address = getAddress(address)
for currentOffset = 0, maxOffset, 1 do
local currentAddress = address + currentOffset
if comparator(currentAddress) then
offsetTree[currentOffset] = true
end
if maxDepth > 0 then
local nextNode = readPointer(currentAddress)
if structValidator(nextNode) then
-- If this is a valid offset, then we'll overwrite it
offsetTree[currentOffset] = scanTree(nextNode,
maxOffset,
comparator,
structValidator,
maxDepth - 1)
end
end
end
return offsetTree
end
function compareFloat(float1, float2, radius)
local lowerLimit = float2 - radius
local upperLimit = float2 + radius
return float1 <= upperLimit and float1 >= lowerLimit
end
function floatMemComparator(address, value, radius)
local toCompare = readFloat(address)
if not toCompare then return false else
return compareFloat(toCompare, value, radius)
end
end
function usableAddress(address)
--return not (address == 0 or address == nil)
return not (address == 0 or address == nil or readBytes(address, 1) == nil)
end
function formatOffset(symbol, offset, dontDereference)
dontDereference = (dontDereference or false)
local repr = string.format("%s+0x%X", symbol, offset)
if not dontDereference then
repr = string.format("[%s]", repr)
end
return repr
end
function printOffsets(currentOffsets, baseName, previusOffsets)
previusOffsets = previusOffsets or {}
for offset, structure in pairs(currentOffsets) do
if structure == true then
local offsetRepr = baseName
for _,previusOffset in ipairs(previusOffsets) do
offsetRepr = formatOffset(offsetRepr, previusOffset, false)
end
offsetRepr = formatOffset(offsetRepr, offset, true)
print(offsetRepr)
else
table.insert(previusOffsets, offset)
printOffsets(structure, baseName, previusOffsets)
table.remove(previusOffsets, #previusOffsets)
end
end
end
-- Example usage:
beginTime = os.time()
symbol = "[[[[[[[[PlayerBase]+10]+28]+338]+38]+28]+48]+148]"
maxOffset = 0x400
comparator = function(address) return floatMemComparator(address, -133.9868927, 0.0001) end
depth = 3
result = scanTree(getAddress(symbol), maxOffset, comparator, usableAddress, depth)
print("Finished")
printOffsets(result, symbol)
print("Finished")
print(string.format("Scan took %d second(s)", os.time() - beginTime))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment