|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Wed Jul 28, 2021 5:59 am Post subject: Edit table entry's offsets with Lua? |
|
|
I've got no idea how to go about my problem..
I'm detecting the version of a game and need to either alter the offsets of multiple table entries if it's one version over another, or simply make copies with the correct offset and delete them when detecting version.
If I were to delete them, can I get a memrec's offset value to test against with lua, or would I be better off just changing the description after deleting the incorrect offsets?
Both approaches work, but I have no idea how to do either:
Delete/Rename specific memrecs by name or offset
Change Offsets
So far I've got a function to iterate through the table's entries and match based on the DropDownList's text, but I don't know where I'd explore the rest of the memrec object's properties. Just need to read documentation I suppose, but it's a long read haha
They're all pointers [[base]+18]+?] where ? may change between versions, if that helps.
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Wed Jul 28, 2021 7:23 am Post subject: |
|
|
Memory record class:
Code: |
MemoryRecord Class:
The memoryrecord objects are the entries you see in the addresslist
properties
ID: Integer - Unique ID
Index: Integer - The index ID for this record. 0 is top. (ReadOnly)
Description: string- The description of the memory record
Address: string - Get/set the interpretable address string. Useful for simple address settings.
AddressString: string - Get the address string shown in CE (ReadOnly)
OffsetCount: integer - The number of offsets. Set to 0 for a normal address
Offset[] : integer - Array to access each offset
OffsetText[] : string - Array to access each offset using the interpretable text style
CurrentAddress: integer - The address the memoryrecord points to
VarType: ValueType (string) - The variable type of this record. See vtByte to vtCustom
Type: ValueType (number) - The variable type of this record. See vtByte to vtCustom
If the type is vtString then the following properties are available:
String.Size: Number of characters in the string
String.Unicode: boolean
String.Codepage: boolean
If the type is vtBinary then the following properties are available
Binary.Startbit: First bit to start reading from
Binary.Size : Number of bits
If the type is vtByteArray then the following properties are available
Aob.Size : Number of bytes
CustomTypeName: String - If the type is vtCustom this will contain the name of the CustomType
Script: String - If the type is vtAutoAssembler this will contain the auto assembler script
Value: string - The value in stringform.
NumericalValue: number - The value in numerical form. nil if it can not be parsed to a number
Selected: boolean - Set to true if selected (ReadOnly)
Active: boolean - Set to true to activate/freeze, false to deactivate/unfreeze
Color: integer
ShowAsHex: boolean - Self explanatory
ShowAsSigned: boolean - Self explanatory
AllowIncrease: boolean - Allow value increasing, unfreeze will reset it to false
AllowDecrease: boolean - Allow value decreasing, unfreeze will reset it to false
Collapsed: boolean - Set to true to collapse this record or false to expand it. Use expand/collapse methods for recursive operations.
IsGroupHeader: boolean - Set to true if the record was created as a Group Header with no address or value info.
IsAddressGroupHeader: boolean - Set to true if the record was created as a Group Header with address.
IsReadable: boolean - Set to false if record contains an unreadable address. NOTE: This property will not be set until the value property is accessed at least once. (ReadOnly)
Options: String set - a string enclosed by square brackets filled with the options seperated by a comma. Valid options are: moHideChildren, moActivateChildrenAsWell, moDeactivateChildrenAsWell, moRecursiveSetValue, moAllowManualCollapseAndExpand, moManualExpandCollapse, moAlwaysHideChildren
DropDownLinked: boolean - if dropdown list refers to list of another memory record eg. (memrec name)
DropDownLinkedMemrec: string - Description of linked memrec or emptystring if not linked
DropDownList : StringList - list of "value:description" lines, lists are still separate objects when linked, read-write
DropDownReadOnly: boolean - true if 'Disallow manual user input' is set
DropDownDescriptionOnly: boolean - self explanatory
DisplayAsDropDownListItem: boolean - self explanatory
DropDownCount: integer - equivalent to .DropDownList.Count
DropDownValue[index] : Array to access values in DropDownList (ReadOnly)
DropDownDescription[index] : Array to access Descriptions in DropDownList (ReadOnly)
Count: Number of children
Child[index] : Array to access the child records
[index] = Child[index]
Parent: MemoryRecord - The parent of the memory record
HotkeyCount: integer - Number of hotkeys attached to this memory record
Hotkey[] : Array to index the hotkeys
Async: Boolean - Set to true if activating this entry will be asynchronious. (only for AA/Lua scripts)
AsyncProcessing: Boolean - True when async is true and it's being processed
AsyncProcessingTime: qword - The time that it has been processing in milliseconds
HasMouseOver: boolean - True if the mouse is currently over it
OnActivate: function(memoryrecord,before,currentstate):boolean - The function to call when the memoryrecord will change (or changed) Active to true. If before is true, not returning true will cause the activation to stop.
OnDeactivate: function(memoryrecord,before,currentstate):boolean - The function to call when the memoryrecord will change (or changed) Active to false. If before is true, not returning true will cause the deactivation to stop.
OnDestroy: function() - Called when the memoryrecord is destroyed.
OnGetDisplayValue: function(memoryrecord,valuestring):boolean,string - This function gets called when rendering the value of a memory record. Return true and a new string to override the value shown
DontSave: boolean - Don't save this memoryrecord and it's children
methods
getDescription()
setDescription()
getAddress() : Returns the interpretable addressstring of this record. If it is a pointer, it returns a second result as a table filled with the offsets
setAddress(string) : Sets the interpretable address string, and if offsets are provided make it a pointer
getOffsetCount(): Returns the number of offsets for this memoryrecord
setOffsetCount(integer): Lets you set the number of offsets
getOffset(index) : Gets the offset at the given index
setOffset(index, value) : Sets the offset at the given index
getCurrentAddress(): Returns the current address as an integer (the final result of the interpretable address and pointer offsets)
appendToEntry(memrec): Appends the current memory record to the given memory record
getHotkey(index): Returns the hotkey from the hotkey array
getHotkeyByID(integer): Returns the hotkey with the given id
reinterpret()
createHotkey({keys}, action, value OPTIONAL, description OPTIONAL): Returns a hotkey object
disableWithoutExecute(): Sets the entry to disabled without executing the disable section
beginEdit() : Call when you wish to take a long time to edit a record. (e.g external editor) It prevents the record from getting deleted
endEdit() : to mark the end of your long edit sequence
global events
function onMemRecPreExecute(memoryrecord, newstate BOOLEAN):
If above function is defined it will be called before action* has been performed.
Active property is about to change to newState.
function onMemRecPostExecute(memoryrecord, newState BOOLEAN, succeeded BOOLEAN):
If above function is defined it will be called after action*.
Active property was supposed to change to newState.
If 'succeeded' is true it means that Active state has changed and is newState.
newState and succeeded are read only.
*action can be: running auto assembler script (ENABLE or DISABLE section), freezing and unfreezing
|
But here is some code to loop through the address list and update the very last offset of the memory record based on the description given. It skips over entries that do not have offsets. Hopefully this will put you in the right direction
Code: |
function updateOffsets(memRecord, newOffset)
local al = getAddressList()
local c = al.Count - 1
for i=0, c do
local offsetToSet = newOffset
local mr = al.getMemoryRecordByDescription(memRecord)
if mr == nil then break end
if mr ~= nil and mr.OffsetCount > 1 then
local oc = mr.OffsetCount
local endOffset = oc
mr.Offset[oc-endOffset] = newOffset
end
end
end
updateOffsets('test', 0xE)
|
Note: make sure you assign the new offsets in hex notation
|
|
Back to top |
|
|
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Wed Jul 28, 2021 7:27 am Post subject: |
|
|
Crazy how useful Lua can be.. I figured it had access to every part of the memrec but never really looked through much to find all the proper syntax. Many thanks!
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Wed Jul 28, 2021 7:57 am Post subject: |
|
|
You're welcome. Feel free to hit the reputation button if I helped you .
|
|
Back to top |
|
|
Birdi Expert Cheater Reputation: 0
Joined: 08 Jun 2020 Posts: 122 Location: Migrating
|
Posted: Wed Jul 28, 2021 8:27 pm Post subject: |
|
|
I just get an SQL error when I try, otherwise I would sorry :<
Also, here's my final script for anyone who might want it:
Code: |
local function updateOffsets(memRecord, adjustment, memAddress, offsetNumber, alteration)
local al = getAddressList()
for i=0, al.Count-1 do
if al[i].Description == memRecord and al[i].Address:match(memAddress) and al[i].OffsetCount > 0 then
if alteration == 'add' then
local mO = al[i].Offset[offsetNumber]
--print("\nCurrent Description: "..al[i].Description.."\nCurrent Offset: "..mO.."\nCurrent Address: "..al[i].Address)
al[i].Offset[offsetNumber] = mO + adjustment
elseif alteration == 'sub' then
local mO = al[i].Offset[offsetNumber]
--print("\nCurrent Description: "..al[i].Description.."\nCurrent Offset: "..mO.."\nCurrent Address: "..al[i].Address)
al[i].Offset[offsetNumber] = mO - adjustment
else --Set to the Adjustment instead of arithmetic
local mO = al[i].Offset[offsetNumber]
--print("\nCurrent Description: "..al[i].Description.."\nCurrent Offset: "..mO.."\nCurrent Address: "..al[i].Address)
al[i].Offset[offsetNumber] = adjustment
end
local mO = al[i].Offset[offsetNumber]
--print("New Offset: "..mO)
end
end
end
-- (Description, Offset Adjustment, Memory Address, Offset#, Add/Sub/Set)
updateOffsets('Health', 0x60, 'p_vms', 0x0, 'set')
|
You can probably expand this to include offsets around the offsetNumber, or up until/after it by n... and omit the memAddress in the if-check if you're not using symbols since it'll be dynamic.
|
|
Back to top |
|
|
LeFiXER Grandmaster Cheater Supreme Reputation: 20
Joined: 02 Sep 2011 Posts: 1055 Location: 0x90
|
Posted: Thu Jul 29, 2021 4:59 am Post subject: |
|
|
That's a shame. Not to worry, thank you anyway and thank you for sharing your complete script.
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|