|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
coffeeAchiever Newbie cheater Reputation: 0
Joined: 27 Dec 2014 Posts: 22
|
Posted: Fri Jan 02, 2015 2:15 pm Post subject: Black vs Green Addresses |
|
|
If you read CE tutorials, you'll read that black addresses are dynamic and green are static, but what does that really mean?
I know more about Linux than Windows, but if I had to take a guess at what static and dynamic means if CE were a Linux application, I would say that CE reads the following segments of a process's virtual address space:
1. data segment: pre-initialized statics/globals
2. BSS segment: kernel-initialized statics/globals
3. stack: automatic variables
4. heap: dynamically allocated variables
I also see offsets into other process's address spaces, so CE probably follows dynamically linked references to other processes. Libraries, for instance. I never learned the details of how shared code is stored in memory, but I assume it has its own address space which somehow gets "tacked on" to the virtual space of other processes. Somehow.
I know this isn't quite correct for Win32, but I'm sure there must be parallels. If I had to take a guess, I'd say:
1. black addresses are heap addresses and green addresses are everything else.
or
2. black addresses are heap and stack variables, and green variables are everything else.
I looked up virtual memory layouts on Windows. It looks more complicated, but the ideas are the same. Anyway, I'm sure that's completely out of scope for these forums (unless anyone here gets off on stuff like this -- I would love to learn more.)
My main questions:
1. If I asked a computer science professor what the difference is between black and green addresses in CE, what would he tell me?
2. There's a ton of tutorials about CE in the context of cheating at games. Some of them are quite good, but is there a more theoretically minded CE tutorial that anyone has written?
Thanks!
|
|
Back to top |
|
|
Krampus Cheater Reputation: 0
Joined: 22 Nov 2014 Posts: 41
|
Posted: Fri Jan 02, 2015 2:27 pm Post subject: |
|
|
1. Black addresses are dynamic. They change every time the game is reset, sometimes even while playing the game. Green addresses are static. Usually they point to dynamic addresses. In coding, a green address would be a pointer to dynamically allocated memory.
In C++ (A lot of games are written in C++), I could declare a pointer to memory on the heap like this:
int * pPointer = new int;
This is an integer pointer, and it points to a piece of allocated memory. That allocated memory could kind of be seen as a black address. The pointer can be seen as a green address.
At the end, or during the runtime, we free the allocate memory:
delete pPointer;
pPointer = NULL;
When this happens, the address of the dynamic memory changes. If we found the pointer, we wouldn't have to deal with that issue.
I probably WAY over explained that, as well as made a few errors in the process, but it should get the idea over nicely .
2. Not that I know of.
_________________
There is no spoon. |
|
Back to top |
|
|
zm0d Master Cheater Reputation: 7
Joined: 06 Nov 2013 Posts: 423
|
Posted: Fri Jan 02, 2015 3:24 pm Post subject: |
|
|
GingerBreadMan wrote: |
int * pPointer = new int; [...] The pointer can be seen as a green address.
|
That's actually wrong. Green addresses are global variables (in C, addresses that you don't put in the main()-function nor any other function) and static variables (those are declared with the keyword static in C)
The thing GingerBreadMan said wouldn't make sense. You have so many black addresses in memory that contain other addresses (pointers)... and they are not green.
Those variables are green because they are stored in the DATA section from the PE file. Since the PE file in-memory looks mostly the same like the actual file on hard-disk, you know that those green addresses are "hard-coded" in the PE-file and, infact they keep always the same address. This is why those addresses are great for base-pointers.
Also green addresses are relative to the modules base address. It means they are an offset to the base address of e.g. the .exe file.
Black addresses are everything else except static or global variables.
|
|
Back to top |
|
|
coffeeAchiever Newbie cheater Reputation: 0
Joined: 27 Dec 2014 Posts: 22
|
Posted: Fri Jan 02, 2015 5:32 pm Post subject: |
|
|
Thanks -- I had to look up what PE (it's the Win32 version of the ELF or COFF format), but makes perfect sense.
Black variables are both stack and heap, and that makes perfect sense. Heap is a no-brainer. Stack makes sense because any program that has control flow will not allocate stack items in the same order and therefore not have the same address. The only thing you can be 100% sure of are the addresses that are pre-allocated at compile time, which are globals and statics, both initialized explicitly by the programmer or implicitly by the compiler. Thanks for explaining that.
As a followup question, one difference between MS Win and Linux is that the Linux stack/heap is pretty high in the address space. On Win32, it's extremely low. Below everything except except for some system reserved stuff.
But then I see scans like this where black addresses are much higher than green addresses, like the scan I'm attaching.
What precisely is happening here? Shouldn't the black addresses be generally lower than green addresses?
Description: |
|
Filesize: |
56.38 KB |
Viewed: |
34668 Time(s) |
|
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Fri Jan 02, 2015 5:54 pm Post subject: |
|
|
stack is actually a "semi" static address. the symbol threadstack0 will point to a certain constant position in the main thread's stack. At initialization there is a high chance the first local variables and passed parameters are always in the same order and can contain interesting references.
e. g: CGame *g=new CGame(); g->run();
the local varable g would recide in the stack and contain the pointer to the game object (which is quite handy to have)
It's not shown in the addresslist, but some features can use it (pointerscan for one)
the location of stack and heap is actually randomized since windows vista(every run they get allocated at a new position)
and when the current heap region is used up windows will just allocate a new block at another location
also, besides heap there are other memory management options.
e.g: it's common to use an api like virtualalloc to allocate a block of memory and manage it yourself (similar to using mmap in linux)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Krampus Cheater Reputation: 0
Joined: 22 Nov 2014 Posts: 41
|
Posted: Fri Jan 02, 2015 6:30 pm Post subject: |
|
|
zm0d wrote: | GingerBreadMan wrote: |
int * pPointer = new int; [...] The pointer can be seen as a green address.
|
That's actually wrong. Green addresses are global variables (in C, addresses that you don't put in the main()-function nor any other function) and static variables (those are declared with the keyword static in C)
The thing GingerBreadMan said wouldn't make sense. You have so many black addresses in memory that contain other addresses (pointers)... and they are not green.
Those variables are green because they are stored in the DATA section from the PE file. Since the PE file in-memory looks mostly the same like the actual file on hard-disk, you know that those green addresses are "hard-coded" in the PE-file and, infact they keep always the same address. This is why those addresses are great for base-pointers.
Also green addresses are relative to the modules base address. It means they are an offset to the base address of e.g. the .exe file.
Black addresses are everything else except static or global variables. |
Thank you for correcting me! So when a pointer is declared, it wouldn't be considered a static address? I feel rather silly having gone on an explanation, and gotten it wrong! I always assumed that the green addresses were pointers to dynamically allocated memory.
So essentially, globals, and static declared variables are green, and everything else is black?
I'm going to write a program with a few different variables, and open it up with CE to look at the results.
Sorry @OP, didn't realize I was that off!
_________________
There is no spoon. |
|
Back to top |
|
|
zm0d Master Cheater Reputation: 7
Joined: 06 Nov 2013 Posts: 423
|
Posted: Fri Jan 02, 2015 6:53 pm Post subject: |
|
|
GingerBreadMan wrote: | So when a pointer is declared, it wouldn't be considered a static address? |
A pointer is nothing else, than a variable that stores a 4 byte (on 32-bit) value (more specific, an address). Regardless if the type of this pointer-variable is bool, int, double long, ... etc. it's always 4 byte, since addresses are 4 bytes long on a 32 bit system. The type of a pointer is important for the pointer-arithmetic.
Of course, pointers can be static and/or global variables, which would lead to green addresses in cheat engine.
|
|
Back to top |
|
|
coffeeAchiever Newbie cheater Reputation: 0
Joined: 27 Dec 2014 Posts: 22
|
Posted: Sat Jan 03, 2015 4:47 am Post subject: |
|
|
GingerBreadMan wrote: |
So essentially, globals, and static declared variables are green, and everything else is black?
I'm going to write a program with a few different variables, and open it up with CE to look at the results.
Sorry @OP, didn't realize I was that off! |
This reminds me of a joke someone once told: Nobody knows what new features will become a part of the next C standard, but you can bet that they'll all be called "static" (I think it's funnier after having a conversation about the static keyword in C). Anyway, static is a pretty overloaded term in C.
You can have static functions and even static array type declarations as formal parameters to a function, but if we limit ourselves to variables only, then:
1. Local static variables keep their values between function calls. They do this by keeping their storage outside the stack so when a function call pops off the callstack, the variable doesn't go out of scope.
2. Global static variables have module scope (they are only accessible in the file they're defined in).
It's kind of weird because these are two unrelated things, except for the fact that they are kept in the same memory segment.
In your example, the declaration of "int * pPointer" isn't static because you don't declare it static. I think everyone assumed your intention was that the declaration/definition was inside a function. HOWEVER (and please correct me if I'm wrong) if your code was outside of any function, then indeed your variable would be a green variable. Inside of a function it would be a black variable.
If you look at something like this:
Code: |
char *igcp = "hello";
char *ugcp;
int main( void )
{
char c = 'c';
static char static_c = 'c';
static char ustatic_c;
char *dynamic = (char *) malloc(100);
printf("Address of char: %p.\n", &c);
printf("Address of static char: %p.\n", &static_c);
printf("Address of ustatic char: %p.\n", &ustatic_c);
printf("Address of igcp: %p.\n", &igcp);
printf("Address of ugcp: %p.\n", &ugcp);
printf("Address of heap ptr: %p\n", &dynamic);
return 0;
} |
The output on my Linux box is:
Quote: | Address of char: 0xbfc31efb.
Address of static char: 0x804a028.
Address of ustatic char: 0x804a02d.
Address of igcp: 0x804a024.
Address of ugcp: 0x804a030.
Address of heap ptr: 0xbfc31efc |
and you can compare the addresses using something like nm (I'm sure Windows has some equivalent thing) Note I removed some of the libc stuff to make it more readable:
Quote: |
Symbols from a.out:
Name Value Class Type Size Line Section
__bss_start |0804a029| B | NOTYPE| | |.bss
completed.6590 |0804a02c| b | OBJECT|00000001| |.bss
__data_start |0804a01c| D | NOTYPE| | |.data
data_start |0804a01c| W | NOTYPE| | |.data
deregister_tm_clones|08048390| t | FUNC| | |.text
__do_global_dtors_aux|08048400| t | FUNC| | |.text
__do_global_dtors_aux_fini_array_entry|08049f0c| t | OBJECT| | |.fini_array
__dso_handle |0804a020| D | OBJECT| | |.data
_DYNAMIC |08049f14| d | OBJECT| | |.dynamic
_edata |0804a029| D | NOTYPE| | |.data
_end |0804a034| B | NOTYPE| | |.bss
_fini |08048564| T | FUNC| | |.fini
_fp_hw |08048578| R | OBJECT|00000004| |.rodata
frame_dummy |08048420| t | FUNC| | |.text
__frame_dummy_init_array_entry|08049f08| t | OBJECT| | |.init_array
__FRAME_END__ |08048700| r | OBJECT| | |.eh_frame
_GLOBAL_OFFSET_TABLE_|0804a000| d | OBJECT| | |.got.plt
__gmon_start__ | | w | NOTYPE| | |*UND*
igcp |0804a024| D | OBJECT|00000004| |.data
_init |080482d4| T | FUNC| | |.init
__init_array_end |08049f0c| t | NOTYPE| | |.init_array
__init_array_start |08049f08| t | NOTYPE| | |.init_array
_IO_stdin_used |0804857c| R | OBJECT|00000004| |.rodata
_ITM_deregisterTMCloneTable| | w | NOTYPE| | |*UND*
_ITM_registerTMCloneTable| | w | NOTYPE| | |*UND*
__JCR_END__ |08049f10| d | OBJECT| | |.jcr
__JCR_LIST__ |08049f10| d | OBJECT| | |.jcr
_Jv_RegisterClasses | | w | NOTYPE| | |*UND*
main |0804844d| T | FUNC|0000009d| |.text
malloc@@GLIBC_2.0 | | U | FUNC| | |*UND*
printf@@GLIBC_2.0 | | U | FUNC| | |*UND*
register_tm_clones |080483c0| t | FUNC| | |.text
_start |08048350| T | FUNC| | |.text
static_c.1903 |0804a028| d | OBJECT|00000001| |.data
__TMC_END__ |0804a02c| D | OBJECT| | |.data
ugcp |0804a030| B | OBJECT|00000004| |.bss
ustatic_c.1904 |0804a02d| b | OBJECT|00000001| |.bss
__x86.get_pc_thunk.bx|08048380| T | FUNC|00000004| |.text
|
It's not important to know what everything here is. Suffice to say that this is a "map" of a.out, and it gets reproduced pretty faithfully in memory as a process. But notice what's here and what's not.
The local non-static variables, like "c" and even "dynamic" (which would be the equivalent of your example in C) are missing. That's because they haven't been created yet! These would be your black variables.
The global and static variables, like "static_c", "ustatic_c", "igcp", and "ugcp" are all here. They've been pre-allocated by the compiler. These would be your green variables.
Now hopefully *I* didn't make any mistakes, because I feel pretty comfortable with this now!
I think Dark Byte made it clear why we want green variables. They literally have to be where they are, and contain what was specified by the programmer at compile time.
I'm always fascinated by this stuff. You get to see some really wild things like C's "hidden functions" like _init or the inner workings of the C library: notice how external linkages to malloc() and printf() get expressed. Pretty wild stuff! One of my interests in Cheat Engine is that it makes all this theory come alive. It's pretty cool to be able to learn theory and then see such a cool application of it in something I really enjoy doing.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sat Jan 03, 2015 5:31 am Post subject: |
|
|
yes, that's basically it. The assembler code generated actually references those addresses directly (e. g: mov eax, [804a024]) so they have to be there else things go wrong
(in windows and possibly linux there is also a relocation table that can change that code when loaded, but it is all relative to eachother. always the same distance. And look up "position independant code" )
and change
Code: |
printf("Address of heap ptr: %p\n", &dynamic);
|
to
Code: |
printf("Address of heap ptr: %p\n", dynamic);
|
to see the real heap address (else you'll get the address of dynamic, which is in the stack instead)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
giomismo How do I cheat? Reputation: 0
Joined: 30 Dec 2017 Posts: 1
|
Posted: Tue Jan 23, 2018 5:16 pm Post subject: |
|
|
zm0d wrote: | GingerBreadMan wrote: |
int * pPointer = new int; [...] The pointer can be seen as a green address.
|
That's actually wrong. Green addresses are global variables (in C, addresses that you don't put in the main()-function nor any other function) and static variables (those are declared with the keyword static in C)
The thing GingerBreadMan said wouldn't make sense. You have so many black addresses in memory that contain other addresses (pointers)... and they are not green.
Those variables are green because they are stored in the DATA section from the PE file. Since the PE file in-memory looks mostly the same like the actual file on hard-disk, you know that those green addresses are "hard-coded" in the PE-file and, infact they keep always the same address. This is why those addresses are great for base-pointers.
Also green addresses are relative to the modules base address. It means they are an offset to the base address of e.g. the .exe file.
Black addresses are everything else except static or global variables. |
Thank you very much for the explanation, it is just what I was looking for!
|
|
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
|
|