|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
mindoff Advanced Cheater Reputation: 0
Joined: 12 Jun 2016 Posts: 96
|
Posted: Sat Jul 27, 2019 10:05 pm Post subject: Is there a way to add many addresses to cheat table by lua? |
|
|
Right now i'm working on a kenshi ralations modify.
The problem is I can get the relation asm code and debug to get the address of each one,and if I modify that code,it will modify all the relation to some value like 50.
But I don't want all the relation to 50,I just want some one specify to be 50.
I can modify it myself,but I still want to list all the relation from that code.
the code is something like below
movss xmm6,[rax+04]
[rax+04] is float value and rax + 04 is the address
the number of relations are not fixed I think.
I may be 5 or 20 or anything.
So I need to record these address and add these address into cheat table dynamicly.
My idea is this,the address is a loop if you set a break point.
Let's say first break point rax will be
11223340,
next may be
11223350,
and so on.
this seems infinite.But it will always be
11223340 address if you keep running debug.
and this whole loop should be all the relation address I need.
In some high level language like C#,I may code like
Code: |
bool bOnce = false;
bool bFinishList = false;
int firstAddress = 0;
List<int> addressList = new List<int>();
void update()
{
if(!bFinishList)
{
if(!bOnce)
{
firstAddress = getRaxAddr();
}
if(firstAddress != 0 && getRaxAddr() != firstAddress)
{
addressList.Add(getRaxAddr());
}
if(getRaxAddr() == firstAddress)
{
bFinishList = true;
}
}
}
|
Then addressList should have all the relation address I need.
So is there any way to do silimar thing with Lua and list these address to cheat table dynamicly?
|
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8517 Location: 127.0.0.1
|
Posted: Sun Jul 28, 2019 3:08 am Post subject: |
|
|
The Lua function: getAddressList() will return the main address list object from the CE window. From there you would use the AddressList and MemoryRecord objects:
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.
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. (ReadOnly)
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
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 - self explanatory
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
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): Returns a hotkey object
disableWithoutExecute(): Sets the entry to disabled without executing the disable section
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.
Addresslist Class: (Inheritance: Panel->WinControl->Control->Component->Object)
properties
Count: Integer - The number of records in the table
SelCount: integer- The number of records that are selected
SelectedRecord: MemoryRecord - The main selected record
MemoryRecord[]: MemoryRecord - Array to access the individial memory records
[] = MemoryRecord - Default accessor
CheckboxActiveSelectedColor: color
CheckboxActiveColor: color
CheckboxSelectedColor: color
CheckboxColor: color
SelectedBackgroundColor: color
SelectedSecondaryBackgroundColor: color
ExpandSignColor: color
IncreaseArrowColor: color
DecreaseArrowColor: color
OnDescriptionChange: function(addresslist,memrec):boolean - called when the user initiates a description column change on a record. Return true if you handle it, false for normal behaviour
OnAddressChange: function(addresslist,memrec):boolean - called when the user initiates an address column change on a record. Return true if you handle it, false for normal behaviour
OnTypeChange: function(addresslist,memrec):boolean - called when the user initiates a type column change on a record. Return true if you handle it, false for normal behaviour
OnValueChange: function(addresslist,memrec):boolean - called when the user initiates a value column change on a record. Return true if you handle it, false for normal behaviour
methods
getCount()
getMemoryRecord(index)
getMemoryRecordByDescription(description): returns a MemoryRecord object
getMemoryRecordByID(ID)
createMemoryRecord() : creates an generic cheat table entry and add it to the list
getSelectedRecords(): Returns a table containing all the selected records
doDescriptionChange() : Will show the GUI window to change the description of the selected entry
doAddressChange() : Will show the GUI window to change the address of the selected entry
doTypeChange() : Will show the GUI window to change the type of the selected entries
doValueChange() : Will show the GUI window to change the value of the selected entries
getSelectedRecord() : Gets the main selected memoryrecord
setSelectedRecord(memrec) : Sets the currently selected memoryrecord. This will unselect all other entries
disableAllWithoutExecute(): Disables all memory records without executing their [Disable] section
|
Other information regarding CE's Lua setup can be found in the celua.txt file in CE's directory.
_________________
- Retired. |
|
Back to top |
|
|
FreeER Grandmaster Cheater Supreme Reputation: 53
Joined: 09 Aug 2013 Posts: 1091
|
Posted: Sun Jul 28, 2019 8:25 am Post subject: |
|
|
besides the addresslist / memory record stuff it also has some debugging stuff
Code: | -debugging
debug variables
EFLAGS
32/64-bit: EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, EIP
64-bit only: RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, RIP, R8, R9, R10, R11, R12, R13, R14, R15 : The value of the register
Debug related routines:
function debugger_onBreakpoint():
When a breaking breakpoint hits (that includes single stepping) and the lua function debugger_onBreakpoint() is defined it will be called and the global variables EAX, EBX, .... will be filled in
Return 0 if you want the userinterface to be updated and anything else if not (e.g: You continued from the breakpoint in your script)
createProcess(path, parameters OPTIONAL, debug OPTIONAL, breakonentrypoint OPTIONAL) : Creates a process. If debug is true it will be created using the windows debugger and if breakonentry is true it will cause a breakpoint to occur on entrypoint
debugProcess(interface OPT): starts the debugger for the currently opened process (won't ask the user) Optional interface: 0=default, 1=windows debug, 2=VEHDebug, 3=Kerneldebug
debug_isDebugging(): Returns true if the debugger has been started
debug_getCurrentDebuggerInterface() : Returns the current debuggerinterface used (1=windows, 2=VEH 3=Kernel, nil=no debugging active)
debug_canBreak(): Returns true if there is a possibility the target can stop on a breakpoint. 6.4+
debug_isBroken(): Returns true if the debugger is currently halted on a thread
debug_getBreakpointList(): Returns a lua table containing all the breakpoint addresses
debug_addThreadToNoBreakList(threadid): This will cause breakpoints on the provided thread to be ignored
debug_removeThreadFromNoBreakList(threadid): removed the threadid from the list
debug_setBreakpoint(address, size OPTIONAL, trigger OPTIONAL, breakpointmethod OPTIONAL, functiontocall() OPTIONAL) : sets a breakpoint of a specific size at the given address. if trigger is bptExecute then size is ignored. If trigger is ignored then it will be of type bptExecute, which obviously also ignores the size then as well. (Other triggers are bptAccess and bptWrite)
debug_setBreakpoint(address, size OPTIONAL, trigger OPTIONAL, functiontocall() OPTIONAL)
debug_setBreakpoint(address, functiontocall() OPTIONAL)
debug_removeBreakpoint(address) : if the given address is a part of a breakpoint it will be removed
debug_continueFromBreakpoint(continueMethod) : if the debugger is currently waiting to continue you can continue with this. Valid parameters are :co_run (just continue), co_stepinto(when on top of a call, follow it), co_stepover (when on top of a call run till after the call)
debug_getXMMPointer(xmmregnr) :
Returns the address of the specified xmm register of the thread that is currently broken
This is a LOCAL Cheat Engine address. Use Local memory access functions to read and modify
xmmregnr can be 0 to 15 (0 to 7 on 32-bit)
The following routines describe last branch recording. These functions only work when kernelmode debugging is used and using windows XP (vista and later work less effective or not at all because the operating system interferes. Might also be intel specific. A dbvm upgrade in the future might make this work for windows vista and later)
debug_setLastBranchRecording(boolean): When set the Kernel debugger will try to record the last branch(es) taken before a breakpoint happens
debug_getMaxLastBranchRecord() : Returns the maximum branch record your cpu can store (-1 if none)
debug_getLastBranchRecord(index): Returns the value of the Last Branch Record at the given index (when handling a breakpoint)
function debugger_onModuleLoad(modulename, baseaddress) :
this routine is called when a module is loaded. Only works for the windows debugger
return 1 if you want to cause the debugger to break
Changing registers:
When the debugger is waiting to continue you can change the register variables. When you continue those register values will be set in the thread's context
If the target is currently stopped on a breakpoint, but not done through an onBreakpoint function. The context won't be set.
You can get and set the context back with these functions before execution continues"
debug_getContext(BOOL extraregs) - Fills the global variables for the regular registers. If extraregs is true, it will also set FP0 to FP7 and XMM0 to XMM15
debug_setContext(BOOL extraregs)
debug_updateGUI() - Will refresh the userinterface to reflect the new context if the debugger was broken
detachIfPossible() : Detaches the debugger from the target process (if it was attached)
|
Though I don't believe there's any trivial way to open the "find what accesses" or "find what addresses this instruction accesses" windows or the list they create. You can of course recreate the functionality yourself.
_________________
|
|
Back to top |
|
|
mindoff Advanced Cheater Reputation: 0
Joined: 12 Jun 2016 Posts: 96
|
Posted: Sun Jul 28, 2019 7:51 pm Post subject: |
|
|
Thanks,figure out how to use
getAddressList() and createMemoryRecord()
now the problem is how to mix asm and lua code together.
I test some code in Darkest Dungeon main update function,suppose lua could print number every frame and increase one by one.
But it only run once.What's the problem?
Is lua only run once in [enable]?
do I need to call lua function from asm?
if so how?
How could I record eax value from asm and add this value to memoryrecord from lua?
Code: |
define(address,"Darkest.exe"+11711CF)
define(bytes,8B 34 C8 0F 84 3F 07 00 00)
{$lua}
gCount = 0
{$asm}
[ENABLE]
assert(address,bytes)
alloc(newmem,$1000)
label(code)
label(return)
newmem:
code:
{$lua}
//I want to print value every time asm code running here as asm code
print(gCount)
gCount = gCount + 1
//But it only run once and gCount is not global var,every time print will return 0...
{$asm}
mov esi,[eax+ecx*8]
je Darkest.exe+1171917
jmp return
address:
jmp newmem
nop
nop
nop
nop
return:
[DISABLE]
address:
db bytes
// mov esi,[eax+ecx*8]
// je Darkest.exe+1171917
dealloc(newmem)
|
|
|
Back to top |
|
|
predprey Master Cheater Reputation: 24
Joined: 08 Oct 2015 Posts: 486
|
Posted: Mon Jul 29, 2019 7:45 am Post subject: |
|
|
mindoff wrote: | Thanks,figure out how to use
getAddressList() and createMemoryRecord()
now the problem is how to mix asm and lua code together.
I test some code in Darkest Dungeon main update function,suppose lua could print number every frame and increase one by one.
But it only run once.What's the problem?
Is lua only run once in [enable]?
do I need to call lua function from asm?
if so how?
How could I record eax value from asm and add this value to memoryrecord from lua?
Code: |
define(address,"Darkest.exe"+11711CF)
define(bytes,8B 34 C8 0F 84 3F 07 00 00)
{$lua}
gCount = 0
{$asm}
[ENABLE]
assert(address,bytes)
alloc(newmem,$1000)
label(code)
label(return)
newmem:
code:
{$lua}
//I want to print value every time asm code running here as asm code
print(gCount)
gCount = gCount + 1
//But it only run once and gCount is not global var,every time print will return 0...
{$asm}
mov esi,[eax+ecx*8]
je Darkest.exe+1171917
jmp return
address:
jmp newmem
nop
nop
nop
nop
return:
[DISABLE]
address:
db bytes
// mov esi,[eax+ecx*8]
// je Darkest.exe+1171917
dealloc(newmem)
|
|
there is a lua server template in the AA script form. but depending on how often the hooked code runs, calling CE’s lua server from within the game through ASM might create some lag, due to interprocess communication
|
|
Back to top |
|
|
FreeER Grandmaster Cheater Supreme Reputation: 53
Joined: 09 Aug 2013 Posts: 1091
|
Posted: Mon Jul 29, 2019 7:55 am Post subject: |
|
|
Quote: | now the problem is how to mix asm and lua code together. ...
Is lua only run once in [enable]?
do I need to call lua function from asm? |
yes, it's really more of a metaprogramming feature where you can run lua code before the asm is even really looked at and return a string of more AA code (which could include more {$lua} blocks that return more AA code etc lol)
As predprey mentions there's a template that lets you run lua from assembly but it can cause some lag, that can be mitigated some by precompiling the lua script and using a function reference. I have a couple basic examples here: https://github.com/FreeER/CE-Examples/blob/master/Tutorial-i386.ct#L2534-L2655 which include commented links to some more info here on the forums
_________________
|
|
Back to top |
|
|
mindoff Advanced Cheater Reputation: 0
Joined: 12 Jun 2016 Posts: 96
|
Posted: Wed Jul 31, 2019 6:51 pm Post subject: |
|
|
Thanks for the tutorial,almost done.
Now what I want to know is how to set a global lua variable which can share between multi places.
On my test,Cheat Table Lua Script can't even share a variable when run some code like this
Code: |
n = 0
print(n)
n = n + 1
|
This will always print 0
what I need is a global var which can count how many times I have run.
|
|
Back to top |
|
|
atom0s Moderator Reputation: 198
Joined: 25 Jan 2006 Posts: 8517 Location: 127.0.0.1
|
Posted: Wed Jul 31, 2019 7:23 pm Post subject: |
|
|
You are setting n to 0 then printing it, it'll always print 0 in that case.
_________________
- Retired. |
|
Back to top |
|
|
mindoff Advanced Cheater Reputation: 0
Joined: 12 Jun 2016 Posts: 96
|
Posted: Wed Jul 31, 2019 7:28 pm Post subject: |
|
|
OK,all done.
Thank you all for the replies
|
|
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
|
|