Difference between revisions of "Lua Debugging"

From Cheat Engine
Jump to navigation Jump to search
(Created page with '== Lua Debugging == There are functions exposed to LUA that enable scripts to control the debugger: * '''openProcess(name)''' - Open a running process * '''debugProcess()''' - …')
 
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 +
[[Category:Lua]]
 
== Lua Debugging ==
 
== Lua Debugging ==
  
Line 5: Line 6:
 
* '''openProcess(name)''' - Open a running process
 
* '''openProcess(name)''' - Open a running process
 
* '''debugProcess()''' - Start debugging the open process
 
* '''debugProcess()''' - Start debugging the open process
* '''debug_setBreakpoint(address)''' - Add a breakpoint at an address
+
* '''debug_setBreakpoint(address)''' - Add a breakpoint at an address, optional parameters are size and type
 
* '''debug_continueFromBreakpoint(method)''' - Continue execution, methods are "co_run", "co_stepinto" and "co_stepover"
 
* '''debug_continueFromBreakpoint(method)''' - Continue execution, methods are "co_run", "co_stepinto" and "co_stepover"
(and possibly "co_runtill" which is in TContinueOption but not shown in main.lua).
+
("co_runtill" is in TContinueOption but not shown in main.lua, probably because it needs to know what address to run to).
  
 
In addition, you can create the event function '''debugger_onBreakpoint()''' that will
 
In addition, you can create the event function '''debugger_onBreakpoint()''' that will
Line 25: Line 26:
 
         if (EIP ~= 0x00406002) then return 0 end -- ignore user-set breakpoints
 
         if (EIP ~= 0x00406002) then return 0 end -- ignore user-set breakpoints
 
         armors[ECX] = readFloat(ECX+0x60) -- store armor in table
 
         armors[ECX] = readFloat(ECX+0x60) -- store armor in table
         debug_continueFromBreakpoint(":co_run") -- continue execution
+
         debug_continueFromBreakpoint(co_run) -- continue execution
 
         return 1 -- let CE know we handled breakpoint, no need to update debugger form
 
         return 1 -- let CE know we handled breakpoint, no need to update debugger form
 
end
 
end
Line 33: Line 34:
 
debug_setBreakpoint(0x00406002)
 
debug_setBreakpoint(0x00406002)
 
</pre>
 
</pre>
 +
 +
=== debug_setBreakpoint() ===
 +
 +
Add a breakpoint at an address, optional parameters are size and type.
 +
* size: number of bytes to break for counting from the address (default: 1, not used if type is bptExecute)
 +
* type: type of breakpoint (default bptExecute)
 +
** bptExecute: break when the instruction pointer EIP is in the area
 +
** bptAccess: break when memory in the area is accessed
 +
** bptWrite: break when memory in the area is written to
 +
 +
Types from debuggertypedefinitions.pas[https://github.com/cheat-engine/cheat-engine/blob/master/Cheat%20Engine/debuggertypedefinitions.pas#L27]:
 +
<pre>
 +
type
 +
  TContinueOption = (co_run=0, co_stepinto=1, co_stepover=2, co_runtill=3); 
 +
 +
type
 +
  TBreakpointTrigger = (bptExecute=0, bptAccess=1, bptWrite=2);
 +
</pre>
 +
 +
 +
== Available variables ==
 +
 +
These variables can be used in your <code>debugger_onBreakpoint()</code> event function.
 +
 +
Changes to these variables will only take effect if the process is break'd and there's no (other) current <code>debug_setBreakpoint</code> method running.
 +
 +
'''Assembly registers:'''<sup>[[https://github.com/cheat-engine/cheat-engine/blob/21393be5766a4787ea6d58a9240820212dd4e944/Cheat%20Engine/LuaHandler.pas#L590 source]]</sup> Holds the current value of the registers.
 +
* (All CE versions:) <code>EAX</code>, <code>EBX</code>, <code>ECX</code>, <code>EDX</code>, <code>EDI</code>, <code>ESI</code>, <code>EBP</code>, <code>ESP</code>, <code>EIP</code>
 +
* (CE 64-bit only:) <code>RAX</code>, <code>RBX</code>, <code>RCX</code>, <code>RDX</code>, <code>RDI</code>, <code>RSI</code>, <code>RBP</code>, <code>RSP</code>, <code>RIP</code>, <code>R8</code>, <code>R9</code>, <code>R10</code>, <code>R11</code>, <code>R12</code>, <code>R13</code>, <code>R14</code>, <code>R15</code>
 +
* If <code>extraregs</code>(?):
 +
** Floating point registers: <code>FP0</code>, <code>FP1</code>, <code>FP2</code>, <code>FP3</code>, <code>FP4</code>, <code>FP5</code>, <code>FP6</code>, <code>FP7</code>
 +
** [https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions#Registers XMM] registers: <code>XMM0</code>, <code>XMM1</code>, <code>XMM2</code>, <code>XMM3</code>, <code>XMM4</code>, <code>XMM5</code>, <code>XMM6</code>, <code>XMM7</code>
 +
** If CE 64-bit: <code>XMM8</code>, <code>XMM9</code>, <code>XMM10</code>, <code>XMM11</code>, <code>XMM12</code>, <code>XMM13</code>, <code>XMM14</code>, <code>XMM15</code>
 +
* <code>EFLAGS</code>

Latest revision as of 11:51, 19 March 2017

Lua Debugging[edit]

There are functions exposed to LUA that enable scripts to control the debugger:

  • openProcess(name) - Open a running process
  • debugProcess() - Start debugging the open process
  • debug_setBreakpoint(address) - Add a breakpoint at an address, optional parameters are size and type
  • debug_continueFromBreakpoint(method) - Continue execution, methods are "co_run", "co_stepinto" and "co_stepover"

("co_runtill" is in TContinueOption but not shown in main.lua, probably because it needs to know what address to run to).

In addition, you can create the event function debugger_onBreakpoint() that will be called by Cheat Engine whenever a breakpoint is hit.

Here's an example for Space Pirates and Zomies that tracks ships that have their armor decreased. By debugging I found that at 0x406002, ECX has a pointer to a structure with the armor float at 0x60. This code will track those values in the armors table with the key being the address and the value being the actual armor value:

if not armors then
   armors = { }
end

function debugger_onBreakpoint()
         if (EIP ~= 0x00406002) then return 0 end -- ignore user-set breakpoints
         armors[ECX] = readFloat(ECX+0x60) -- store armor in table
         debug_continueFromBreakpoint(co_run) -- continue execution
         return 1 -- let CE know we handled breakpoint, no need to update debugger form
end

openProcess("SpazGame.exe")
debugProcess()
debug_setBreakpoint(0x00406002)

debug_setBreakpoint()[edit]

Add a breakpoint at an address, optional parameters are size and type.

  • size: number of bytes to break for counting from the address (default: 1, not used if type is bptExecute)
  • type: type of breakpoint (default bptExecute)
    • bptExecute: break when the instruction pointer EIP is in the area
    • bptAccess: break when memory in the area is accessed
    • bptWrite: break when memory in the area is written to

Types from debuggertypedefinitions.pas[1]:

type
  TContinueOption = (co_run=0, co_stepinto=1, co_stepover=2, co_runtill=3);  

type
  TBreakpointTrigger = (bptExecute=0, bptAccess=1, bptWrite=2); 


Available variables[edit]

These variables can be used in your debugger_onBreakpoint() event function.

Changes to these variables will only take effect if the process is break'd and there's no (other) current debug_setBreakpoint method running.

Assembly registers:[source] Holds the current value of the registers.

  • (All CE versions:) EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP, EIP
  • (CE 64-bit only:) RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, RIP, R8, R9, R10, R11, R12, R13, R14, R15
  • If extraregs(?):
    • Floating point registers: FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7
    • XMM registers: XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7
    • If CE 64-bit: XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15
  • EFLAGS