Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Using Lua to find what address is accessed by an instruction

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
wowcarol
How do I cheat?
Reputation: 0

Joined: 06 Oct 2016
Posts: 3

PostPosted: Thu Oct 06, 2016 8:22 pm    Post subject: Using Lua to find what address is accessed by an instruction Reply with quote

Hi,

I have found an instruction that access all the 'nodes' x cords on a map and I want to store some of these cords. The code is something like this where +130 is x cord, +134 is y cord and +138 is z cord.
Code:
movaps  xmm0, xmmword ptr [edi+130h]


I noticed that [edi+2C] is different between different types of nodes. So for example, if [edi+2C]=4, then the node is an NPC while [edi+2C]=3, the node is a gatherable resource. I want only the gatherable resource nodes in this case, thus I want to filter all the addresses the above instruction accessed base on the +2C offset.

I can use CE and right click the code and use the 'find what address this instruction accesses' to get all the x cords. But I want to also be able to store these x cords in a lua table so I can use them in my trainer.

Similar question has been asked in the forum(can't post url yet. google search cheat engine Using Lua to find what address is accessed by an instruction fitst hit). I tried using the lua debug method at the end of this thread but somehow it does not work...
Code:

node_addresses = {}
debug_setBreakpoint("xxx.exe+E5CD1F", 1, bptExecute, function()
        x_value=readFloat(tonumber(EDI,16)+tonumber('130',16))   
        y_value=readFloat(tonumber(EDI,16)+tonumber('134',16))       
        z_value=readFloat(tonumber(EDI,16)+tonumber('138',16)) 
        type_value = readInteger(tonumber(EDI,16)+tonumber('2C',16))
       //prob filter the address here base on type_value
      node_addresses[EDI]={type=type_value ,x=x_value,y=y_value,z=z_value}
      debug_continueFromBreakpoint(co_run)
      return 1
end)


And I could not understand the ASM code provided in the above link...Can someone explain a bit more how to do this in ASM, or help me with the lua script for this task? I am also wondering if the lua method causes any lag compare to the ASM method, since the op code is constantly being called to refresh nodes cords as I move my character(even when I stand still).

Thanks!
Back to top
View user's profile Send private message
wowcarol
How do I cheat?
Reputation: 0

Joined: 06 Oct 2016
Posts: 3

PostPosted: Fri Oct 07, 2016 7:17 am    Post subject: Reply with quote

I manage to make the lua debug approach work but it is causing a big lag in the game.

I am trying the ASM approach but the game crashed when I enable the aob injection script. Basically what I want to do is, to store all the addresses that my target instruction access(EDI is enough since I know the +130/134/138/2C are the offsets that I am interesting in) in an ASM array and then access the array within lua. Can anyone help me with the script?

Code:

[ENABLE]
aobscanmodule(INJECT,xxx.exe,0F 28 87 30 01 00 00 0F 29)
registersymbol(arr)
alloc(newmem,$1000)
alloc(arr_size,4)
alloc(arr,$1000)
alloc(parseArray,$1000)

label(code)
label(return)

parseArray:
pushad
mov ebx,[arr_size]
xor ecx,ecx //loop counter
@@:
cmp [arr+ecx*4],edi
je @f
add ecx,1
cmp ecx,ebx
jb @b
@@:
popad
ret

newmem:

code:
  movaps xmm0,[edi+00000130]
  call parseArray
  je return
  push ebx
  mov ebx,[arr_size]
  add ebx,1
  mov [arr_size],ebx
  mov [arr+ebx*4],edi
  pop ebx

INJECT:
  jmp code
  nop
  nop
return:
registersymbol(INJECT)


[DISABLE]
INJECT:
  db 0F 28 87 30 01 00 00

unregistersymbol(INJECT)
unregistersymbol(arr)
dealloc(newmem)


Thanks!!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4299

PostPosted: Fri Oct 07, 2016 7:32 am    Post subject: Reply with quote

http://forum.cheatengine.org/viewtopic.php?p=5679490#5679490

It isn't the exact same scenario, but it should offer some insight.

Also, calling CE Lua code from the target should be faster with 6.6, so consider that an option.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
wowcarol
How do I cheat?
Reputation: 0

Joined: 06 Oct 2016
Posts: 3

PostPosted: Fri Oct 07, 2016 8:46 am    Post subject: Reply with quote

Thank you ParkourPenguin for the suggestion. This looks insightful and I will start working on it and see if I can apply this on my task.

----------------------------------update--------------------------------------------

I manage to make the following AOB script works and using a lua script to reset the result when it is full. However, I dont know how to access the result memory region from lua? I am still new to lua and AA so forgive me if its silly...

Also I notice that some of the highly accessed addresses were stored multiple times. It is worth checking(causing any delay?) if the address already exist in the results region before saving?

AA script:
Code:

[ENABLE]
aobscanmodule(INJECT,xxx.exe,0F 28 87 30 01 00 00 0F 29) // should be unique
alloc(newmem,$1000)
alloc(results,$14000)  // allocate more memory if needed
label(exit)
registersymbol(results)
label(return)

newmem:
 push edx
  mov edx,[results]
  cmp edx,#10000
  jae short @f
    lea edx,[edx*4+results+4]
    mov [edx],edi
    inc [results]
    jmp short exit
  @@:
    mov [results],FFFFFFFF //signal to Lua for max reached

exit:
  pop edx
  movaps xmm0,[edi+00000130]
  jmp return


INJECT:
  jmp newmem
  nop
  nop

return:
registersymbol(INJECT)

[DISABLE]
INJECT:
  db 0F 28 87 30 01 00 00

dealloc(newmem)
dealloc(results)
unregistersymbol(INJECT)
unregistersymbol(results)


lua code:
Code:

if readInteger("results")==0xFFFFFFFF then
 --access all the addresses store in the "result" memory region
 --not sure how to do this...
 writeInteger("results", 0)  --reset
end


Thanks!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 140

Joined: 06 Jul 2014
Posts: 4299

PostPosted: Fri Oct 07, 2016 3:01 pm    Post subject: Reply with quote

Minor note: you only need 10 pages of memory (i.e. alloc(results,$A000)) to store 10000 4-byte entries plus the number of valid records at the start.

That script was originally designed to log data in which each record was important, even if there were repeats. If you don't want there to be repeats, loop through the valid part of the buffer, compare each value with edi, and jump out if you find it. When/if you get to the end, append the entry if there's room left in the buffer.

In this short example, I changed the buffer from being length-prefixed to null-terminated. EDI == 0 will never be a valid case since the process would crash anyways upon execution of the original code.
Code:
label(nextLoop)
label(enterLoop)
label(exit)
label(save)

newmem:
  push ecx
  push edx
  xor ecx,ecx
  jmp short enterLoop
nextLoop:
  test edx,edx
  je short save
  inc ecx
  cmp ecx,#10000
  je short exit
enterLoop:
  mov edx,[results+ecx*4]
  cmp edx,edi
  jne short nextLoop
exit:
  pop edx
  pop ecx
  movaps xmm0,[edi+00000130]
  jmp return
save:
  mov [results+ecx*4],edi
  jmp short exit


I don't know what you want to do with those addresses in Lua. If you're talking about syntax instead of semantics, you can use a loop like so:
Code:
local i = 0
local results = getAddress("results")

-- not safe, but it'll probably be fine (call pause() before this if you have problems)
while i < 10000 do
  local current = readInteger(results + i*4)
  if current == 0 then break end

  -- do whatever you want with the current record/address

  -- if you want to remove records from the buffer:
--writeInteger(results + i*4, 0)
  i = i + 1
end

This is assuming the buffer is null-terminated. If you're using a length-prefixed buffer, processing it would obviously be different, but you should be able to figure it out.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites