 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Dr.Disrespect Grandmaster Cheater
Reputation: 3
Joined: 17 Feb 2016 Posts: 526
|
Posted: Fri Mar 25, 2016 7:34 pm Post subject: How to declare a variable in Auto Assmble? |
|
|
I have read some tutorials, and they say the way of defining a byte variable in assembly language is:
But I have been told in cheat engine, the way to declare a variable is like this:
Code: |
alloc(value1,1)
resigtersymbol(value1)
panding1:
db (int) 0
|
So, who should I listen to? I am confused. Thanks in advance.
|
|
Back to top |
|
 |
STN I post too much
Reputation: 43
Joined: 09 Nov 2005 Posts: 2676
|
Posted: Fri Mar 25, 2016 8:01 pm Post subject: |
|
|
Both but you should listen close and understand it more clearly. I don't know why you would assume an assembly programming language will have similar syntax to a tool made for gamehacking. I guess you need more reading up on what an assembler, compiler, linker etc are for you to understand this.
Anyhow, you can define a variable/symbol in CE several ways
var:
db/dd/dq 0
or
label()
registersymbol()
or
label() // local scope i.e limited to the script in wich defined
or
allocating memory like you did.
CE does NOT actually define a variable by itself like a programming lang does but you have to tell CE YOURSELF where the variable or more appropriately where the symbol is pointing to. The way you do that is you define an address and below that define your var/symbol like this
92ace:
var:
db 0
or
newmem:
var:
db 0
As a matter of fact you dont need the db 0 part, this is just initializing.
_________________
|
|
Back to top |
|
 |
Dr.Disrespect Grandmaster Cheater
Reputation: 3
Joined: 17 Feb 2016 Posts: 526
|
Posted: Fri Mar 25, 2016 8:07 pm Post subject: |
|
|
STN wrote: | Both but you should listen close and understand it more clearly. I don't know why you would assume an assembly programming language will have similar syntax to a tool made for gamehacking. I guess you need more reading up on what an assembler, compiler, linker etc are for you to understand this.
Anyhow, you can define a variable/symbol in CE several ways
var:
db/dd/dq 0
or
label()
registersymbol()
or
label() // local scope i.e limited to the script in wich defined
or
allocating memory like you did.
CE does NOT actually define a variable by itself like a programming lang does but you have to tell CE YOURSELF where the variable or more appropriately where the symbol is pointing to. The way you do that is you define an address and below that define your var/symbol like this
92ace:
var:
db 0
or
newmem:
var:
db 0
As a matter of fact you don't need the db 0 part, this is just initializing. |
Thanks for the reply. Yes, I do need more readings about what you said, I am still new to programming.
Can you explain more about this: "As a matter of fact you dont need the db 0 part, this is just initializing. "?
Moreover, if I understand correctly, using "label(var)" assigns a memory address to "var" in the brackets, right? Then I can give "var" a value, which means that value is stored in the memory address of "var"? Am I right?
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4702
|
Posted: Fri Mar 25, 2016 8:55 pm Post subject: |
|
|
No. A label is only a representation of an address in memory. That address has to exist in order for it to be valid. You are responsible for assigning the memory address of the label yourself.
All memory CE allocates is always filled with the byte 00. Therefore, you don't always need to write some memory to an address if all you're going to be writing is 0 anyways. However, you still may need to. Take this for instance:
Code: | alloc(newmem,1024)
label(num1)
label(num2)
newmem:
num1:
db 0
num2:
db 3 |
CE allocates some memory to some address. It then assigns the label "newmem" to hold that address. Note that the scope of all labels is restricted to the script (unless you register it as a symbol). CE also sees that you say you have two labels in the script: num1 and num2. If you don't have these in your script when you say that you do, CE will return an error when you try to execute it.
Now it gets down to where you're declaring stuff. Because num1 is right under newmem and newmem is already defined, it's going to assign num1 the same address as newmem. Writing db 0 lets CE know that it should write the byte 00 to that address. Moving on to num2, it's address will be one byte after num1 since you wrote one byte of memory between num2 and num1. Then, it just writes the byte 03 into that address and it's done.
If you don't write db 0 under num1, then CE doesn't know that there's suppose to be one byte there, and it would assign num2 the same address as num1. This poses a problem since now you now only have one variable.
Also, you may have noticed this already, but since different data types take up different amounts of memory, you'll need to use different keywords when writing a value into memory. Namely:
Code: | db - declare bytes. Used for single bytes, AoBs, and strings.
dw - declare word. Used for 2 byte integers.
dd - declare doubleword. Used for 4 byte integers or floats. Make sure to cast floats by prepending the number with (float).
dq - declare quadword. Used for 8 byte integers or doubles. Make sure to cast doubles by prepending the number with (double). |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Fri Mar 25, 2016 8:59 pm Post subject: |
|
|
If you only want to declare a single 4-byte variable, you can:
Code: | alloc(myvar,4) // creates 4 bytes of memory with a label of "myvar"
registersymbol(myvar) // registers the label "myvar" |
Now lets say you want to declare several variables of various types in a single memory location:
Code: | alloc(newmem,16) // creates 16 bytes of memory with a label of "newmem"
label(myvar1) // creates a label named "myvar1"
label(myvar2)
label(myvar3)
label(myvar4)
label(myvar5)
newmem: // defines the start of the "newmem" memory location
myvar1: // defines the start of the "myvar1" label inside "newmem"
dd 0 // populates myvar1 with a 4-byte value of 0
myvar2:
dw 0 // populates myvar2 with a 2-byte value of 0
myvar3:
db 0 // populates myvar3 with a 1-byte value of 0
myvar4:
myvar5: // since "myvar4" didn't reserve any bytes, "myvar5" will have the same address
dd (float)1.0 // populates "myvar5" (and "myvar4") with a float taking up 4 bytes
registersymbol(myvar1) // registers the label "myvar1"
registersymbol(myvar2)
registersymbol(myvar3)
registersymbol(myvar4)
registersymbol(myvar5) |
|
|
Back to top |
|
 |
Dr.Disrespect Grandmaster Cheater
Reputation: 3
Joined: 17 Feb 2016 Posts: 526
|
Posted: Fri Mar 25, 2016 10:06 pm Post subject: |
|
|
@ParkourPenguin
@Zaner
OMG, you guys are so awesome. I really appreciate your help like I always do. Both of your explanations really help me figure out what is going on with the "alloc", "label" and the interaction between memory location and labels etc. Those are among the best guides I have ever read. Thank you both so much.
PS: where can I find this kind of information or how do you know this? I really want to learn.
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4702
|
Posted: Fri Mar 25, 2016 10:18 pm Post subject: |
|
|
I learned all of this primarily through trial and error. I got the basics down from some random tutorials online, but those don't truly teach you that much. What really helped me learn was finding something I wanted to do in some game and using Google to figure out how to do it. Looking at already existing asm in processes themselves is a (usually) good source of example code. Google anything you don't know, and if you don't understand the explanation, google that too.
The templates CE makes for you are helpful and mostly self-explanatory if you understand the relevant concepts of computer science going on (e.g. what is memory, what are bytes, what is asm), so that was never that much of a problem for me. CE's help file (under the help menu) has information on all the functions you can use in an AA script (e.g. assert, readmem, etc.). Downloading and looking at other people's AA scripts is (usually) a good source of examples.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Dr.Disrespect Grandmaster Cheater
Reputation: 3
Joined: 17 Feb 2016 Posts: 526
|
Posted: Fri Mar 25, 2016 10:21 pm Post subject: |
|
|
ParkourPenguin wrote: | I learned all of this primarily through trial and error. I got the basics down from some random tutorials online, but those don't truly teach you that much. What really helped me learn was finding something I wanted to do in some game and using Google to figure out how to do it. Looking at already existing asm in processes themselves is a (usually) good source of example code. Google anything you don't know, and if you don't understand the explanation, google that too.
The templates CE makes for you are helpful and mostly self-explanatory if you understand the relevant concepts of computer science going on (e.g. what is memory, what are bytes, what is asm), so that was never that much of a problem for me. CE's help file (under the help menu) has information on all the functions you can use in an AA script (e.g. assert, readmem, etc.). Downloading and looking at other people's AA scripts is (usually) a good source of examples. |
I really appreciate your advice and patience for explaining so much to a newbie like me. God bless you!
|
|
Back to top |
|
 |
blueboy90780 Newbie cheater
Reputation: 0
Joined: 18 Dec 2016 Posts: 14 Location: Vietnam
|
Posted: Mon Feb 06, 2017 2:24 am Post subject: |
|
|
ParkourPenguin wrote: | No. A label is only a representation of an address in memory. That address has to exist in order for it to be valid. You are responsible for assigning the memory address of the label yourself.
All memory CE allocates is always filled with the byte 00. Therefore, you don't always need to write some memory to an address if all you're going to be writing is 0 anyways. However, you still may need to. Take this for instance:
Code: | alloc(newmem,1024)
label(num1)
label(num2)
newmem:
num1:
db 0
num2:
db 3 |
CE allocates some memory to some address. It then assigns the label "newmem" to hold that address. Note that the scope of all labels is restricted to the script (unless you register it as a symbol). CE also sees that you say you have two labels in the script: num1 and num2. If you don't have these in your script when you say that you do, CE will return an error when you try to execute it.
Now it gets down to where you're declaring stuff. Because num1 is right under newmem and newmem is already defined, it's going to assign num1 the same address as newmem. Writing db 0 lets CE know that it should write the byte 00 to that address. Moving on to num2, it's address will be one byte after num1 since you wrote one byte of memory between num2 and num1. Then, it just writes the byte 03 into that address and it's done.
If you don't write db 0 under num1, then CE doesn't know that there's suppose to be one byte there, and it would assign num2 the same address as num1. This poses a problem since now you now only have one variable.
Also, you may have noticed this already, but since different data types take up different amounts of memory, you'll need to use different keywords when writing a value into memory. Namely:
Code: | db - declare bytes. Used for single bytes, AoBs, and strings.
dw - declare word. Used for 2 byte integers.
dd - declare doubleword. Used for 4 byte integers or floats. Make sure to cast floats by prepending the number with (float).
dq - declare quadword. Used for 8 byte integers or doubles. Make sure to cast doubles by prepending the number with (double). |
|
I have a question - would it be the same thing if we just allocate memory the label in the first place?
for example, on "num1" you declared 3 bytes. If I were to type this code down:
wouldn't that be the same thing?
|
|
Back to top |
|
 |
Corroder Grandmaster Cheater Supreme
Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Mon Feb 06, 2017 3:29 am Post subject: |
|
|
I am also newbie with AA and starting to learn (while continue learning lua).
after read all explanations on this post, then if I am not wrong :
Code: | alloc (num1, 3) // allocate 3 bytes inside open process and store address in num1
label(myNum) // This part should defined later, set value when assembler hits it
registersymbol(num1 ) // make num1 available everywhere
registersymbol(myNum) // make myNum available everywhere
num1: // start assembling in allocated memory
// .. doing something
// .. doing something else
ret
myNum: // value will be set to address after ret
CreateThread(num1) // create new thread in open process |
is this right ?
Thanks
|
|
Back to top |
|
 |
SunBeam I post too much
Reputation: 65
Joined: 25 Feb 2005 Posts: 4023 Location: Romania
|
Posted: Mon Feb 06, 2017 4:03 am Post subject: |
|
|
Hi Corroder. A few things you should know:
1. alloc( x, 1..1024 ) or alloc( x, 0x1..0x1000 ) will allocate 0x1000 (that is 1024) bytes in memory. If, for example, you give it 1025 or 0x1001, it will allocate 2048 (0x2000). If you want to allocate the exact amount, I think you can use globalalloc. See more here: http://wiki.cheatengine.org/index.php?title=Cheat_Engine:Auto_Assembler.
2. Cheat Engine 6.6 doesn't necessarily require label( x ) to exist for you to use a label It's best practice to still declare it, to keep track, but you can very well omit it.
For the rest of it, you are correct.
Also, remember to unregistersymbol and dealloc (in FILO style: first-in last-out) in the [DISABLE] part of the script:
Code: | [ENABLE]
alloc( x )
registersymbol( x )
..
[DISABLE]
unregistersymbol( x )
dealloc( x ) |
That way you avoid keeping registered symbols/allocated memory after disabling a script.
BR,
Sun
|
|
Back to top |
|
 |
Corroder Grandmaster Cheater Supreme
Reputation: 75
Joined: 10 Apr 2015 Posts: 1668
|
Posted: Mon Feb 06, 2017 4:23 am Post subject: |
|
|
Hi SunBeam,
Thank so much for quick replay and also some important information's.
Before this i didn't know if allocate > 1025 or 0x1001 it will allocate as 2048 or 0x2000 (2 MB), then i guess if > 2049 or 0x2001 will allocate as 3072 or 0x3000 and so on...
And also for, CE 6.6 doesn't necessarily require label( x ) to exist for us to use label.
Of course I need learn by read some tutorials, references, get and understand some samples and the important thing is, run some trials and errors. Soon will practice how to implementation, AA script to a simple real game, something like windows pinball, etc. Just to get how it work and clearly understand about using AA.
Thanks and BR...
|
|
Back to top |
|
 |
SunBeam I post too much
Reputation: 65
Joined: 25 Feb 2005 Posts: 4023 Location: Romania
|
Posted: Mon Feb 06, 2017 4:40 am Post subject: |
|
|
Correct with the allocations
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4702
|
Posted: Mon Feb 06, 2017 11:31 am Post subject: |
|
|
blueboy90780 wrote: | would it be the same thing if we just allocate memory the label in the first place? |
I'm not sure if the following parlance is officially correct, but it's at least reasonably coherent.
The identifier representing an address in memory is called a symbol.
Code: | alloc(newmem,1024) // newmem is a symbol
label(return) // return is a symbol
game.exe+123DEF: // game.exe is a symbol
... |
A symbol declared explicitly using the keyword label (or implicitly by just defining it) can represent any address in memory. It is defined relative to the previous address used to declare a memory region in the script.
Code: | label(mylabel) // declaration of the label mylabel
0045C000: // every instruction after this is written sequentially starting here
db 00 01 02 03
mylabel: // definition of mylabel; address is 0045C004
db 04 |
A symbol defined using alloc represents the start of a memory block with a specified size. Memory is allocated in page-size chunks (usually 4KB) on an OS-defined granularity (usually 64KB). Multiple uses of alloc in the same script will allocate memory sequentially based on the order of the alloc statements.
Code: | alloc(newmem,512)
alloc(number,4)
alloc(pi,8)
newmem: // address is 0C480000
...
number: // address is 0C480200
dd 0
pi: // address is 0C480204
dq (double)3.141592653589793 |
It is important to allocate enough memory to store the required value. For example, 4-byte integers, floats, and 32-bit addresses require 4 bytes, while doubles and 64-bit addresses require 8 bytes.
A value's alignment in memory could also be an issue for some instructions (e.g. movapd, movaps, movdqa).
SunBeam:
0x1000 = 4096 bytes.
As far as I can tell, globalalloc allocates at least 64KB (or however much contiguous memory is required) and uses that memory region for storing all globalalloc symbols.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
SunBeam I post too much
Reputation: 65
Joined: 25 Feb 2005 Posts: 4023 Location: Romania
|
Posted: Mon Feb 06, 2017 11:35 am Post subject: |
|
|
ParkourPenguin wrote: | SunBeam:
0x1000 = 4096 bytes.
As far as I can tell, globalalloc allocates at least 64KB (or however much contiguous memory is required) and uses that memory region for storing all globalalloc symbols. |
Yup, my bad. Just noticed
Allocating 1, 2, .. 1024, 2048, 3072, 4096 - allocates in fact 0x1000 (4096) bytes. If more than 0x1000, moves to next 0x1000 section (0x2000, which is 8192)
Also correct about globalalloc.
BR,
Sun
|
|
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
|
|