 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
nexnex Newbie cheater
Reputation: 0
Joined: 22 Jun 2019 Posts: 13
|
Posted: Sat Jun 22, 2019 10:26 pm Post subject: Constructing multilevel pointers in AA |
|
|
I regularly need to construct multilevel pointers in AA scripts, so I wrote a custom AA command for that.
My code is very naive and does not contain any error handling. The idea is so obvious there must exist implementations with much more robust code.
I wanted to include try..except block into code generated by AA command, but don't think it's possible right now. Or am I wrong?
An example of my "multilevel pointer mov" command:
| Code: |
mlmov(rax, [[[Game.exe+456789]+80]+1F90]+18)
test byte ptr [rax+D8], 1
|
Command's code:
| Code: |
-- "Multilevel mov"
-- Allows to concisely construct multilevel pointers in AA scripts.
-- Arguments:
-- register to build a pointer in
-- multilevel pointer in format [[[base]+offset]+offset]+offset
-- (optional) a place to jump to in case of failed zero check
-- If you need more thorough error handling, consider wrapping code it try..except block instead.
-- Examples:
-- mlmov(rax, [[[Game.exe+456789]+80]+1F90]+18)
-- assembles into
-- mov rax, [Game.exe+456789]
-- mov rax, [rax+80]
-- mov rax, [rax+1F90]
-- mov rax, [rax+18]
--
-- mlmov(rax, [Game.exe+456789]+80, no_player)
-- assembles into
-- mov rax, [Game.exe+456789]
-- test rax, rax
-- jz short no_player
-- mov rax, [rax+80]
-- test rax, rax
-- jz short no_player
local function mlmov(parameters, syntaxcheckonly)
if syntaxcheckonly then return end
local reg, path, on_error = string.match(parameters, '(%w+)%s*,%s*%[+([%w%.%]%+]+)%s*,%s*(.+)')
if not reg then
reg, path = string.match(parameters, '(%w+)%s*,%s*%[+(.+)')
end
local offsets = {}
string.gsub(path, "[^%]]+", function(c) offsets[#offsets+1] = c end)
local asm = ''
for i,offset in ipairs(offsets) do
asm = asm..string.format("mov %s, [%s%s]\r\n", reg, i==1 and '' or reg, offset)
if on_error then
asm = asm..string.format("test %s, %s\r\njz short %s\r\n", reg, reg, on_error)
end
end
return asm
end
registerAutoAssemblerCommand("mlmov", mlmov)
|
|
|
| Back to top |
|
 |
nexnex Newbie cheater
Reputation: 0
Joined: 22 Jun 2019 Posts: 13
|
Posted: Sun Jun 23, 2019 4:05 pm Post subject: |
|
|
I realize my question may be unclear, I'll try to ask it again.
Is it possible to output try..except directives from a custom AA command?
In other words can AA command's output be this:
| Code: |
{$try}
xor eax, eax
jmp success
{$except}
jmp error
|
|
|
| Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 960
|
Posted: Sun Jun 23, 2019 4:32 pm Post subject: |
|
|
I doubt it can be, as {$try/except} tag should happen before lua processing, as {$lua} should be recognized 1st, if assume all {$...} tag are interpreted in same round.
So since autoAssembler-command run after lua ({$lua}) process, both this or Lua return a string should not work.
You may try registerAutoAssemblerPrologue , this can be set (postAOB=false) as so that your own processing happened first of all.
For instance, (not tested)
| Code: |
mlmovID = registerAutoAssemblerPrologue(function(script,syntaxcheck)
local code = script.Text -- script is a stringlist
code = code:gsub("mlmov(%b()) ",function( mlmov_params )
-- your processing here on selected text mlmov_params, insert valid aa command etc.
end)
script.Text = code -- update script, nothing changed if not set.
end )
|
Note tho registerAutoAssemblerPrologue more suitable for more generic string/template processing, may not best for individual command.
_________________
- Retarded.
Last edited by panraven on Sun Jun 23, 2019 6:43 pm; edited 1 time in total |
|
| Back to top |
|
 |
nexnex Newbie cheater
Reputation: 0
Joined: 22 Jun 2019 Posts: 13
|
Posted: Sun Jun 23, 2019 5:25 pm Post subject: |
|
|
Thank you, it looks like what I'm searching for, will try it.
A bit strange part is that I can use try..except from {$lua} section, but not from AA command.
For example, this works as expected:
| Code: |
...
{$lua}
return [[
{$try}
mov eax,[ecx+10]
jmp short noerror
{$except}
xor eax,eax
noerror:
ret
]]
{$asm}
...
|
|
|
| Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 960
|
Posted: Sun Jun 23, 2019 7:23 pm Post subject: |
|
|
oh, so I'm wrong {$...} do in same round.
Anyway, may mov the {$try} out of the custom command, it is more flexible and allow custom AA to use.
My try:
| Code: |
autoAssemble"globalalloc(__,$1000)" -- storage for test
unregisterAutoAssemblerCommand"mlMov"
registerAutoAssemblerCommand("mlMov", function(params, sc)
-- format mlMov(register, base, ofs1, ofs2, ...)
local rs, codes = {},{}
for p in params:gmatch"[^,]+"do
p = p:match"^%s*(.-)%s*$"
if not p then error"missing entry"end
rs[1+#rs] = p
end
if #rs<2 then error"not enough params"end
local reg, base, fms = rs[1], rs[2], string.format
codes[1] = fms("mov %s,%s", reg, base)
for i=3,#rs do
codes[i-1] = fms([[
test %s,%s
cmovne %s,[%s+%s]
]], reg, reg, reg, reg, rs[i] )
end
codes[1+#codes]= fms("test %s,%s",reg, reg)
codes = table.concat(codes,'\n')
return codes
end)
-- test // NOTE: in my ce 6.6 {$try}/{$exceot} are just ignored, may be as {} comment
autoAssemble[[
__:
xor eax,eax
{$try}
mlMov(rbx, __+10, 108,2c,38)
je @f
inc eax
@@:
{$except}
ret
]]
|
_________________
- Retarded. |
|
| Back to top |
|
 |
nexnex Newbie cheater
Reputation: 0
Joined: 22 Jun 2019 Posts: 13
|
Posted: Sun Jun 23, 2019 9:49 pm Post subject: |
|
|
I need to read your code more carefully, it seems to have interesting ideas, thanks!
However, I'm not sure why you chose to use cmovne.
If one of the levels points to zero, test sets zero flag and cmovne won't do the moving part, yes, but it still will try to access memory from the second argument.
And it will result in an exception.
Which will be caught by try..except block.
Which makes both test and cmovne unnecessary.
Or, I'm grossly mistaken
Try to run this code, it should fail:
| Code: |
xor rax,rax // zeroes rax and sets zero flag
cmovne rax,[rax+80] // will try to read [0+80] memory address anyway
|
And with syntax [[[Game.exe+456789]+80]+1F90]+18 for a multilevel pointer I aimed to reuse the same format that CE already uses.
Familiar and could be just copy/pasted from/to lua code or some other place.
|
|
| Back to top |
|
 |
panraven Grandmaster Cheater
Reputation: 62
Joined: 01 Oct 2008 Posts: 960
|
Posted: Mon Jun 24, 2019 1:42 am Post subject: |
|
|
| Quote: | | ...but it still will try to access memory from the second argument |
I've not check/run the actual code, but it seem the memory is not access if condition not met, https://www.felixcloutier.com/x86/cmovcc , it should not be access [eax+78] if eax is null... or may be I'm wrong again?
As why use cmovcc, it is because no jump no label need.
Some AA processing order again.
custom AA command happened before actual ce's assembler. If your output assembler code string contain some label, the assembler will see the label. What the problem? It may only affect how @f @b interpret. eg
| Code: |
...
mov eax, base
jmp @f --<1>
customAACommandWithLabel(...)-> expand to as [[
..
@someInternalLabel --<2>
..
]]
@@: --<3>
...
The jump from <1> will land on <2> instead of <3>.
|
but unnamed label (@f @b @@) is helpful to generate repeated code, or your custom AA command will have duplicated label prevent it to compiled if invoked more than 2 times.
When internal label is need , it is better use registerAssembler(...) which is a whole custom assembler convert instruction string to bytes sequence, so no internal label visible from outside.
I've made a miniMacro extension which is use as an alternative assembler, here you may check https://forum.cheatengine.org/viewtopic.php?t=588194
The source is in the table files of the CT, save to disk to view.
The source is unfortunate minimized however, may be some day I'll remake it.
Anyway, hope the explain is not confusing you more
ADDED:
1. as of the pointer format, it is up to your implementation. I just go for easier one as an example.
2.TESTED your code, yes, surprise to me . cmovcc do access memory anyway.
3.Try an AA custom with jmp and label version, but not work, always not compiled on label usage, even @f or named. I think I've not make ce cheat too long
_________________
- Retarded. |
|
| Back to top |
|
 |
nexnex Newbie cheater
Reputation: 0
Joined: 22 Jun 2019 Posts: 13
|
Posted: Mon Jun 24, 2019 3:57 am Post subject: |
|
|
wow, registerAssembler(...) is very interesting thing!
I looked at your miniMacro, I'm not sure I can understand it right away, will look more closely.
I didn't even know about @f and @b labels, thanks.
Your code example seems logical to me, at least it wouldn't surprise me that jump from <1> will land on <2>.
Sorry, but I don't understand this
| Quote: | | 3.Try an AA custom with jmp and label version, but not work |
You mean when generated asm code contains label declaration? Can you give a code example of what doesn't compile?
|
|
| 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
|
|