Skip to content

Instantly share code, notes, and snippets.

@JasonGoemaat
Last active May 28, 2018 03:47
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 JasonGoemaat/6e879ba3cd46b79a2208093541bae331 to your computer and use it in GitHub Desktop.
Save JasonGoemaat/6e879ba3cd46b79a2208093541bae331 to your computer and use it in GitHub Desktop.
Address class for Cheat Engine LUA
local Address = {}
--[[ Return either a number or null for an address. If the address is
already a number, return it. If a string, do a symbol lookup.
--]]
local ValueToNumber = function(value)
if type(value) == 'string' then value = getAddressSafe(value) end
if type(value) ~= 'number' then return nil end
return value
end
--[[ Constructor to return a new Address object given a value.
Usage:
local address1 = Address.new('[modifiers_ptr]+80')
local address2 = Address.new(0x717335200)
--]]
function Address.new(value)
local obj = {}
if type(value) == 'string' then
obj.symbol = value
value = getAddressSafe(value)
end
if type(value) ~= 'number' then return nil end
obj.address = value
obj.hex = string.format('%X', value)
return setmetatable(obj, Address)
end
--[[ Alternate constructor can be called just by Address()
Usage:
local address1 = Address('[modifiers_ptr]+80')
local address2 = Address(0x717335200)
--]]
setmetatable(Address, { __call = function(tbl, value) return Address.new(value) end })
--[[ For output as a string, just output hex value
--]]
function Address:__tostring()
return self.hex
end
--[[ For concatenation, mostly for debug purposes use hex value
--]]
function Address:__concat(a)
return tostring(self)..tostring(a)
end
--[[ Add an offset (number, Address, or string evaluated by CE) to the address
and return a new instance.
--]]
function Address:offset(value)
if type(value) == 'string' then value = Address(value) end
if type(value) == 'table' and value.address ~= nil then value = value.address end
if type(value) ~= 'number' then return nil end
return Address(self.address + value)
end
--[[ __add is an operator so you can do the following:
local address = Address('modifiers_ptr')
address = address + 0x1c
--]]
function Address:__add(value)
-- handle if we are the second operand, i.e. '0x18 + address'
if getmetatable(value) == Address then return value:offset(self) end
return self:offset(value)
end
--[[ __index method to access properties that aren't there
--]]
function Address:__index(key)
local original = key
key = key:lower()
if key == 'byte' then
local b = readBytes(self.address, 1)
return b
end
if key == 'smallinteger' then return readSmallInteger(self.address) end
if key == 'integer' then return readInteger(self.address) end
if key == 'qword' then return readQword(self.address) end
if key == 'pointer' then return readPointer(self.address) end
if key == 'float' then return readFloat(self.address) end
if key == 'double' then return readDouble(self.address) end
if key == 'string' then return readString(self.address, MAX_STRING_LENGTH) end
return getmetatable(self)[original]
end
--[[ __newindex method to write properties that aren't there, for writing
values to memory at the address
--]]
function Address:__newindex(key, value)
local original = key
key = key:lower()
if key == 'byte' then return writeBytes(self.address, 1, value) end
if key == 'smallinteger' then return writeSmallInteger(self.address, value) end
if key == 'integer' then return writeInteger(self.address, value) end
if key == 'qword' then return writeQword(self.address, value) end
if key == 'pointer' then return writePointer(self.address, value) end
if key == 'float' then return writeFloat(self.address, value) end
if key == 'double' then return writeDouble(self.address, value) end
if key == 'string' then return writeString(self.address, value) end
self[key] = value
return value
end
--[[ Function to read a number of bytes
--]]
function Address:readBytes(count)
return readBytes(self.address, count, true)
end
--[[ Function to write a number of bytes
--]]
function Address:writeBytes(bytes)
return readBytes(self.address, bytes)
end
--[[ Function to read a number of bytes as an AOB string
--]]
function Address:readAOB(count)
local bytes = readBytes(self.address, count, true)
local strings = {}
for i,b in ipairs(bytes) do
table.insert(strings, string.format('%02X', b))
end
return table.concat(strings, ' ')
end
--[[ Function to write a number of bytes from an AOB string
TODO: write this function to parse the string as AOB
function Address:writeBytes(bytes)
return readBytes(self.address, bytes)
end
--]]
return Address
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment