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 


Making scripts, using pointers and Stupid questions.

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

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Aug 23, 2017 4:17 pm    Post subject: Making scripts, using pointers and Stupid questions. Reply with quote

Hey guys,
I'll start off by saying:
I am Sorry If i am posting this in the wrong section! Embarassed



- Background info so you understand where i'm coming from -

I've been playing around with CE for quite a while now but only recently did i start getting into the more fun stuff like making scripts and not having to scan for values every damn time by finding static addresses / pointers and i will admit i am a complete newbie.

However i seem to misunderstand what exactly i can "DO" with a Static address, say you find the address for Health and it looks something like this P->XXXXXXXX and also the value is now in Hex (You can change it by right clicking on it), while that does help me stop searching for the value every time, i still need to edit it or freeze it pretty much every time...

I've only made some AOB Injection scripts so far and it's simple ones like infinite health that just replace the existing value at the point where you take damage etc.



- Cutting to the chase -

Q1: How can i make / assemble a script whose only purpose is to modify the value of the Pointer or freeze it, not one that necessarily injects and replaces code, or would it be better just to set keybinds as much as i don't like that. (Presumably i would do it in Table -> Show CT Lua Script but this is more about the actual code)

Q2: Is it possible to use a pointer in a normal AOB Injection script where you edit what happens after X game function is completed by using "What writes to this address" and "What accesses this address"

Q3: In general, what would be easier or a more convenient way for a newbie to hack, using the disassembler and writing injection codes or finding static addresses?

Q4: Where can i find information on "eax" "ebx" "al" and the commands like "jne" "sub" "add" etc, all i know is E means it's 32 bit and R 64 bit, and very few of the commands like jump if not equal, add, subtract.

Thanks in advance!!!

P.S. - I did look online before posting but searching these specific questions was not the easiest of things, i do apologize if it's been asked before, i hope i wrote the post in an easy to understand way, English is not my native language...
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4703

PostPosted: Wed Aug 23, 2017 5:16 pm    Post subject: Reply with quote

DodgeWolfy wrote:
Q1: How can i make / assemble a script whose only purpose is to modify the value of the Pointer or freeze it...
I don't see why you would want to do this in an AA script when you can already modify the value however you want as a memory record. You still need to click the "Active" box to activate the script, so that doesn't save any time over freezing the memory record and it only saves a few clicks over changing it manually. You could use Lua to automate the process slightly, but assigning hotkeys would be much faster and easier. Right click on a memory record and select "Set hotkeys" to do this.
DodgeWolfy wrote:
Q2: Is it possible to use a pointer in a normal AOB Injection script where you edit what happens after X game function is completed by using "What writes to this address" and "What accesses this address"
The last half of that sentence didn't make sense to me, but you can traverse a pointer path like this:
Code:
/* Pointer Information:
base: "Tutorial-i386.exe"+001FD660
offset 0: C
offset 1: 14
offset 2: 0
offset 3: 18
*/

code:
  mov edx,[Tutorial-i386.exe+001FD660]
  mov edx,[edx+C]
  mov edx,[edx+14]
  mov edx,[edx]
  lea edx,[edx+18]  // edx is now the address of the value being pointed to
  mov [edx],#5000

DodgeWolfy wrote:
Q3: In general, what would be easier or a more convenient way for a newbie to hack, using the disassembler and writing injection codes or finding static addresses?
That depends on what you want to do. Modifying a game's code is obviously more versatile than modifying the values it uses. If you don't plan on using a table more than a few times, don't bother making it reusable in the first place. Otherwise, the pointer scanner requires the least effort and knowledge on the user's part.
DodgeWolfy wrote:
Q4: Where can i find information on "eax" "ebx" "al" and the commands like "jne" "sub" "add" etc, all i know is E means it's 32 bit and R 64 bit, and very few of the commands like jump if not equal, add, subtract.
With regards to the instructions (e.g. mov, add, sub, lea...), any good x86 / x86-64 instruction set reference will do.

If you want to learn about x86 and x86-64 architectures in general, you might be able to find some quick tutorials online, but most of the ones I've seen don't cover much and/or provide false information. You may need to sift through some crap, but they'll give you a basic overview- enough to make simple scripts.

If you want correct, complete, and formal information, look at Intel's software developer manuals. Specifically, V1 gives a good overview of most stuff, and V2 contains information about the instructions themselves. Only consult further volumes if you have a good reason to.

_________________
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
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Wed Aug 23, 2017 5:34 pm    Post subject: Reply with quote

Q1. like this
Code:
[ENABLE]
["Tutorial-i386.exe"+1FD5D0]+480:
  dd #100
  // sizes:
  // dd = 4 byte, dw = 2, db = 1, dq = 8
[DISABLE]
["Tutorial-i386.exe"+1FD5D0]+480:
  dd #200
  // (float) or (double) for floating point values
  // eg. dd (float)100 or dq (double)200
  // # is equivalent to (int) aka decimal values
  // as $ is equivalent to 0x aka hexadecimal
  // values default to hexadecimal if not specified (100 = 256 decimal)
// as OldCheatEngineUser mentioned this works for multiple offsets
// [[[[["module.exe"+offset]+off]+off]+off]+off]+off:
Though you could also use lua eg.
Code:
{$lua}
local addr = "[Tutorial-i386.exe+1FD5D0]+480"
[ENABLE]
-- prevent accidentally running important code when just creating/editing the script
if syntaxcheck then return end
writeInteger(addr,100)
--[[
  size and type are determined by the function you use
  copy/paste from celua.txt in CE install directory
  writeBytes(address, x,x,x,x,...) : Write the given bytes to the given address from a table
  writeBytes(address, table) : Write the given bytes to the given address from a table

  writeSmallInteger(address,value) : Writes a 16-bit integer to the specified address. Returns true on success
  writeInteger(address,value) : Writes a 32-bit integer to the specified address. Returns true on success
  writeQword(address, value): Write a 64-bit integer to the specified address. Returns true on success
  writeFloat(address,value) : Writes a single precision floating point to the specified address. Returns true on success
  writeDouble(address,value) : Writes a double precision floating point to the specified address. Returns true on success
  writeString(address,text, widechar OPTIONAL) : Write a string to the specified address. Returns true on success
]]--
[DISABLE]
-- values are decimal by default, use 0x for hexadecimal
writeInteger(addr,200)

Freezing it without nopping all the code that changes it would require createThread or a timer in lua (or hooking some game function that runs very often)... easier to just have a memory record and freeze it manually.
Q2. sure, the simple way would be to use lua to determine the address when the script is enabled, but of course that only works if the address doesn't change while the script is enabled.
Code:

XGameFunctionHook:
...
{$lua}
local addr = '... pointer path ...'
addr = getAddress(addr) -- get numeric instead of string address
-- return assembly instruction to move 5 into the address
return ('mov [%x], 5'):format(addr)
{$asm}
...
if it does change then you have to read the path manually eg
Code:

// example for base address "Tutorial-i386.exe"+1FD5D0 with offsets 4,C,8 (probably not valid)
XGameFunctionHook:
...
push eax -- save a registers value to the stack or use one you know will be overwritten
mov eax, ["Tutorial-i386.exe"+1FD5D0] // read from base address
// add and dereference each offset, except the last
mov eax, [eax+4]
mov eax, [eax+C]
mov [eax+8], 5 // now set the value at the final address
pop eax -- restore saved value if you saved it to the stack
...
A bit of a pain. Of course, it's much easier if you can hook someplace that already has the address in a register but that case is fairly obvious if you know basic assembly.

Q3. For a newbie, if you can find statics with a few searches, or pointers, then that's great and makes it pretty easy. But most modern games don't use statics anymore and pointers are getting a bit harder to find as well, beyond that you're mostly limited to hotkeys that set or freeze the value if you don't use scripts (either asm or lua) so you'll probably want to learn those at some point, might as well start now and fall back to static/pointers when you just can't get it working.

Q4. http://opensecuritytraining.info/IntroX86.html , http://ref.x86asm.net/index.html , and google (specific instructions along with "assembly" and maybe "x86" or "x64")


Last edited by FreeER on Thu Aug 24, 2017 6:29 am; edited 3 times in total
Back to top
View user's profile Send private message
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Wed Aug 23, 2017 5:48 pm    Post subject: Reply with quote

ParkourPenguin wrote:

Code:

Code:
/* Pointer Information:
base: "Tutorial-i386.exe"+001FD660
offset 0: C
offset 1: 14
offset 2: 0
offset 3: 18
*/

code:
  mov edx,[Tutorial-i386.exe+001FD660]
  mov edx,[edx+C]
  mov edx,[edx+14]
  mov edx,[edx]
  lea edx,[edx+18]  // edx is now the address of the value being pointed to
  mov [edx],#5000



That code will be a really good reference to follow, Thanks!!

ParkourPenguin wrote:

The last half of that sentence didn't make sense to me...


To clarify what i meant - Is it possible to have the code be standalone, without the need of putting it in between functions, so for example instead of doing an AOB injection to have it completely separate from the game and not rely on a function to run.

For example:
Let's say you have a code that sets your infinite money but relies on AOB injection that happens only when you purchase an item. Can you instead have the code run on its' own, completely separate from all game functions / code.
(I think i saw somewhere a video where a guy made a blank script, allocated memory and a thread and did it that way but i'm not completely sure on that one.)
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4703

PostPosted: Wed Aug 23, 2017 6:49 pm    Post subject: Reply with quote

DodgeWolfy wrote:
Is it possible to have the code be standalone, without the need of putting it in between functions, so for example instead of doing an AOB injection to have it completely separate from the game and not rely on a function to run.
...
(I think i saw somewhere a video where a guy made a blank script, allocated memory and a thread and did it that way but i'm not completely sure on that one.)

Sure, that's possible. It's significantly more convoluted than changing it yourself, but if you'd like an example:
Code:
[ENABLE]
alloc(newmem,$1000)
label(shouldExit)
registersymbol(shouldExit)

createthread(newmem)

newmem:
  // your code here
  mov [address],#50  // freezes an address to the 4-byte value 50

  // sleep & check if it should exit
  push #50
  call kernel32.Sleep
  cmp [shouldExit],0
  je newmem
  // free memory, return
  pop eax
  push 8000
  push 0
  push newmem
  push eax
  jmp kernel32.VirtualFree

newmem+800:
shouldExit:
  dd 0

[DISABLE]
unregistersymbol(shouldExit)
shouldExit:
  dd 1

_________________
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
OldCheatEngineUser
Whateven rank
Reputation: 20

Joined: 01 Feb 2016
Posts: 1586

PostPosted: Thu Aug 24, 2017 3:02 am    Post subject: Reply with quote

you can also use this syntax:

Code:
[[[[["module.exe"+offset]+off]+off]+off]+off]+off:

_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote:
i am a sweetheart.
Back to top
View user's profile Send private message Visit poster's website
DodgeWolfy
Newbie cheater
Reputation: 0

Joined: 13 May 2017
Posts: 19

PostPosted: Fri Aug 25, 2017 12:53 am    Post subject: Reply with quote

OldCheatEngineUser wrote:

you can also use this syntax:
Code:

[[[[["module.exe"+offset]+off]+off]+off]+off]+off:


Oh wow, that one's new, may i ask how exactly it differs from the other examples like copying into edx and exactly would i use it to modify something, would it be something along these lines, or how exactly do i implement it.
Code:

push edx
lea edx,[[[["Tutorial-i386.exe"+001FD660]+C]+14]+0]+18:
mov [edx],#5000
pop edx



ParkourPenguin wrote:

Sure, that's possible. It's significantly more convoluted than changing it yourself, but if you'd like an example:

Code:
[ENABLE]
alloc(newmem,$1000)
label(shouldExit)
registersymbol(shouldExit)

createthread(newmem)

newmem:
  // your code here
  mov [address],#50  // freezes an address to the 4-byte value 50

  // sleep & check if it should exit
  push #50
  call kernel32.Sleep
  cmp [shouldExit],0
  je newmem
  // free memory, return
  pop eax
  push 8000
  push 0
  push newmem
  push eax
  jmp kernel32.VirtualFree

newmem+800:
shouldExit:
  dd 0

[DISABLE]
unregistersymbol(shouldExit)
shouldExit:
  dd 1


The idea of doing it that way is not to complicate things for myself but to make it into a trainer, i'm sure there's better ways but still want to try out simple things even if they are less efficient!

I don't seem to understand why use "pop eax" before it's even pushed and also i think cheat engine recognizes "call Sleep" directly, no need for the kernel bit also why there is newmem+800 and what exactly that achieves, i tried making one on my own, but haven't tested it, feel free to tell me how bad it is, anyways, here's the code:
Code:
[ENABLE]
globalalloc(hackingcode,500)
createthread(hackingcode)
label(stopcode)
registersymbol(stopcode)

stopcode:
db 00

hackingcode:
//Code stuffs here
push #1000
call sleep //Calls sleep using number above in Ms from my understanding
cmp [stopcode],01
jne hackingcode
ret

[DISABLE]
stopcode:
db 01

I'm not 100% if the db 00 and db 01 would be needed
Back to top
View user's profile Send private message
OldCheatEngineUser
Whateven rank
Reputation: 20

Joined: 01 Feb 2016
Posts: 1586

PostPosted: Fri Aug 25, 2017 1:17 am    Post subject: Reply with quote

DodgeWolfy wrote:
Oh wow, that one's new, may i ask how exactly it differs from the other examples like copying into edx and exactly would i use it to modify something, would it be something along these lines, or how exactly do i implement it.


you can use it as a label, or load it into a register

_________________
About Me;
I Use CE Since Version 1.X, And Still Learning How To Use It Well!
Jul 26, 2020
STN wrote:
i am a sweetheart.
Back to top
View user's profile Send private message Visit poster's website
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4703

PostPosted: Fri Aug 25, 2017 8:38 am    Post subject: Reply with quote

DodgeWolfy wrote:
Oh wow, that one's new, may i ask how exactly it differs from the other examples like copying into edx and exactly would i use it to modify something, would it be something along these lines, or how exactly do i implement it.
Code:
push edx
lea edx,[[[["Tutorial-i386.exe"+001FD660]+C]+14]+0]+18:
mov [edx],#5000
pop edx
The colon isn't needed and you need square brackets around that pointer path for lea.
The difference is that CE traverses the pointer path once on assembly. If the game changes any node in the pointer path for whatever reason (e.g. level transition), this would probably crash the game.
DodgeWolfy wrote:
I don't seem to understand why use "pop eax" before it's even pushed
The pop eax / push eax instructions are to make VirtualFree return to the return address of whatever called newmem. Since VirtualFree deallocated newmem's memory, trying to return to newmem would crash.
DodgeWolfy wrote:
i think cheat engine recognizes "call Sleep" directly, no need for the kernel bit
True. It's just more descriptive, prevents name collisions, and I prefer it.
DodgeWolfy wrote:
why there is newmem+800 and what exactly that achieves
It makes sure the dword shouldExit is aligned properly. It's not necessary since Intel can address unaligned memory, but again, I prefer it.
DodgeWolfy wrote:
Code:
[ENABLE]
globalalloc(hackingcode,500)
createthread(hackingcode)
label(stopcode)
registersymbol(stopcode)

stopcode:
db 00

hackingcode:
//Code stuffs here
push #1000
call sleep //Calls sleep using number above in Ms from my understanding
cmp [stopcode],01
jne hackingcode
ret

[DISABLE]
stopcode:
db 01
  • Using globalalloc means the memory will only be allocated once and never freed. This also simplifies things because you don't have to worry about freeing the memory, but it's still a one-time memory leak.
  • stopcode is a label. It needs to be defined relative to another address. Either put it after ret, or put something like "hackingcode+100:" before it.
  • You're registering the symbol stopcode in [ENABLE] but not unregistering it in [DISABLE].
  • Since you're using db, put byte ptr behind [stopcode] so CE addresses that memory location as a byte and not as a dword.
  • This is again just my preference, but I'd test [stopcode] against 0 and jump if equal back to the top.
DodgeWolfy wrote:
I'm not 100% if the db 00 and db 01 would be needed
If you want your code to run forever, then replace jne with jmp and remove stopcode, cmp, and ret.
_________________
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 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