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 


Can I create hotkeys without the normal GUI?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
muGaen
Newbie cheater
Reputation: 0

Joined: 10 Jan 2018
Posts: 17

PostPosted: Wed Jan 17, 2018 1:44 am    Post subject: Can I create hotkeys without the normal GUI? Reply with quote

Hello everybody,

I've found myself at the problem, that I have to find out a certain value which is written at an address, and use this value at another assembler script.

I'm not sure if there's a better approach to do this, but I'm writing the found value to a static unused address, so I can read from that address using the second script.

Now the problem I'm facing is.. how do I create hotkeys automatically, since I get to know the needed value at runtime only?

Greetings,

muGaen
Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Wed Jan 17, 2018 1:28 pm    Post subject: Reply with quote

Hm... to answer the question lua has a generic createHotkey function (give it a lua function to run and a table of Virtual KeyCodes that trigger it, eg.
Code:
hotkey = createHotkey(function(hk_sender) print(hk_sender, 'said hi') end, VK_F2, string.byte('W',1))
will create a hotkey that prints eg "083B01F0 said hi" when F2 and w are pressed.

Now you should be able to read memory from within an AA script if you can get the addresses without a hotkey though... generally done with code mov or the instruction readmem. You just need the address either because it's static or a pointer or via an aobscan etc.

Though I'm not sure why you'd need to create the hotkeys automatically, GUI hotkeys should be able to exist regardless of whether the value is there or not, or even if you're attached to a process, so you should be able to set them up ahead of time and just save them in the table. If you're creating a memory record from lua and that's why you can't have a hotkey (because the mr doesn't exist until runtime) then the simple solution there is to just change the address of an existing mr instead of creating a new mr. That way it can have a hotkey set and stay, though if you do end up creating new mrs (perhaps there's an array that can get large but is usually fairly small so new ones might get created) then you could call createHotkey on the mr passing a table of VK codes, the "action" and an optional value (optional based on the chosen action, actions listed with the MemoryRecordHotkey class in celua.txt).
Back to top
View user's profile Send private message
muGaen
Newbie cheater
Reputation: 0

Joined: 10 Jan 2018
Posts: 17

PostPosted: Thu Jan 18, 2018 1:27 am    Post subject: Reply with quote

Thanks a lot, FreeEr.

I think the single problem I'm having with this, is that if that address get's an unexpected value, it crashes everytime. that's why I need to find out, what value it uses after a fresh game reboot.
example
1st run: finding the values 12, 51
after rebooting the game, same address uses the values 17,10.

it looks like the value is being calculated every reboot anew
So the problem is not about the value not being there, just that if it gets a different value to what it calculated before, the game crashes.

But yes, i plan to have the hotkey from the beginning, just runnung the script should alter the values being changed on trigger, in order to get the right values for the game not to crash.

Since the address always will stay the same, I don't plan to create every hotkey automatically.

Could you possibly show me a good example of readmem()? Whenever I tried using it, my script wouldn't run (can't set it active).
it might be some datatype problem again..
is this code correct?

Code:
alloc(rdmm,1)

rdmm:
  readmem(somePointer,1)


which would read the byte value of where that pointer will point at.
and that value will be stored within rdmm.

Did I misunderstand something?


I'd like to have it that way (altough I don't know how to do that right now):

I want to have an address within my allocated memory, which is storing an array of bytes (starting from that address + 16 bytes), and not being overwritten by other routines.
how do I do that the right way?

I was trying something like that, but I haven't succeeded yet:

Code:
assert(address,bytes)
alloc(newmemMouse,$1000)

label(code)
label(return)
label(myStorage)
globalalloc(mousePointer,4)
alloc(store,32)
registersymbol(myStorage)

newmemMouse:



code:
  fstp dword ptr [eax]
  mov  [myStorage],128  //newmemMouse+128(?)
  mov [mousePointer],eax
  lea eax,[ebp-01]
  mov [myStorage+2],store //store 16 bytes at newmemMouse+130(?is that still right?)
  jmp return

store:
        readmem(mousePointer,16)

myStorage:
         

address:
  jmp code
return:


I think I'm still getting confused by the assembler syntax, which makes some of my codes weird (like having different approaches in one script, and such)

Greetings, mu
Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Thu Jan 18, 2018 10:14 am    Post subject: Reply with quote

Code:
alloc(rdmm,1)
rdmm:
  readmem(somePointer,1)
should work as long as somePointer was a valid memory address (number, define, label, and symbol should all work)

running something like
Code:
400290:
  dd 12345678
400294:
  readmem(400290,1)
400298:
  readmem(400290,2)
40029C:
  readmem(400290,4)

(note 400290 is a read only code cave in the x86 tutorial, so if you want to write to it with actual assembly code not just instructions like readmem use fullAccess(400290, number of bytes to get access to) lol)

will result in these values (in hex of course)
00000078
00005678
12345678

the 78 is copied first because values are stored backwards by byte in memory ("little endian") so that you can read a 4 byte value as a 1 byte value without doing anything special when you go to read the value. Some emulators won't do this, I feel like Mac also doesn't ("big endian")...

you can also do something like this
Code:
400294:
  readmem([4002A0],4)


which causes it to treat 4002A0 as a pointer, so it reads the address there and then reads the value at that address.



as for the script mov [myStorage],128 and mov [storage], newmemMouse+128 are significantly different, the first just moves the value 0x128 into the address myStorage, while the second moves the address of newmemMouse plus hex 128 into the address myStorage

mov [myStorage+2],store would not write 16 bytes at newmemMouse+130, it'd write the address store referred to into memory at myStorage+2.

To copy 16 bytes from store to myStorage+130 you could use

Code:
// save any registers as necessary via push
lea esi, [store] // Load Effective Address - LEA, Extended Source "Index"- ESI
// ^ same as mov esi, store
lea edi, [myStorage+130] // Extended Destination "Index" - EDI
// ^ same as mov edi, myStorage, followed by add edi, 130
mov ecx, #16 // intended as a "Counter" register
rep movsb // repeat following instruction until ecx is 0, move byte (not sure why s is there lol)
// restore any registers as necessary via pop


Though I read that rep movsb is slow for small blocks, less than 256 bytes or so. As such you might just use standard movs to load 4 bytes from esi into eax and write eax to edi, adding 4 to edi and esi afterwards to adjust the addresses (or hardcode [store], [store+4], [store+8], etc).

oh and readmem(mousePointer,16) is trying to read 16 bytes but you only asked for 4 when allocating it Smile
Back to top
View user's profile Send private message
muGaen
Newbie cheater
Reputation: 0

Joined: 10 Jan 2018
Posts: 17

PostPosted: Fri Jan 19, 2018 12:42 am    Post subject: Reply with quote

Thank you very much. That's just what I needed to understand this the right way.

My readmem() attempt didn't work because I forgot that deleted all the user defined symbols the night before, so that [myPointer] didn't exist anymore. thanks for the hint.

I think I've learnt a lot about the missing links within my understanding of the basics about assembler.

I'm going to play around with it now. Arrow Arrow
(thank you again.)
Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Fri Jan 19, 2018 7:08 am    Post subject: Reply with quote

Have fun! Very Happy
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking 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