MantisBT - Cheat Engine
View Issue Details
0000419Cheat Engine(No Category)public2015-12-04 05:492015-12-21 10:47
Assigned ToDark Byte 
PlatformOSOS Version
Summary0000419: Pointer size increments by 4 on 64 bit
DescriptionWhen using the "Pointer" address type the size will increase by 4 each time even though pointer size on 64 bit is 8 bytes.
TagsNo tags attached.
Attached Files

2015-12-04 16:39   
Not a bug. 64bit pointer can be at offset 0x0 or at offset 0x4 in the structure.
2015-12-05 01:15   
Well in any function table on x64 the pointers would always be 8 bytes.

By your logic the offset could be at 2 byte or 1 byte assuming that padding was off. Or 6 or even 12 bytes. Maybe we should make the button not do anything.
2015-12-05 11:27   
I don't have time to argue.

Pointers in 64bit targets not always have all offsets dividable by 8.


offset 4 is not dividable by 8
offset 2c is not dividable by 8
2015-12-05 21:09   
Well your example is implementation specific. A compiler with padding enabled would pad each element to 8 bytes no matter what its size.

So I'm standing by we should just make the button not do anything.
2015-12-05 21:12   
And they dont always have offsets dividable by 4, neither by what you're saying nor what the button currently does.
2015-12-06 01:49   
(Last edited: 2015-12-06 01:51)
Those buttons increase/decrease offset by "4".
And, in most cases, it is the better option than "1" or "2" or "8".

If you press CTRL key and click those buttons, it will increase/decrease offset by "1". Useful when you find "specific" structure where pointers start at weird offset, like 2 or 6.

I think DB could merge my modification, maybe SHIFT key, which will increase/decrease offset by pointersize of target process.

I will send pull request on a GitHub.


2015-12-06 09:44   
No. It should by default increase/decrease by the pointer size.
 * Function Tables
 * Properly padded structures
 * Arrays of pointers
 * Multidimensional arrays

^^ All will be located at 8 byte offsets. Guaranteed.

What you have given was an example of an improperly padded struct and said "hey it still works in this odd case". And in doing so you've glazed over any other use. Maybe that's your only use for it, or maybe your understanding of how compilers work is not so great. In either case, what you're proposing is ridiculous. Hidden features that only work if you know the hotkey reminds me of something you'd code in High School, and it doesn't belong in a production product.

And for the record making it increment by 1 is a terrible idea.
2015-12-06 11:10   
(Last edited: 2015-12-06 11:21)
Inc/dec by 1, you say it is a terrible idea? What you're saying is ridiculous.

We are using Inc/Dec buttons in the last node too, you know?

ansi string, unicode string, array of bytes, byte, 2bytes - for those we have inc/dec 1

integer, single - for those, inc/dec 4 (currentHealth and maximumHealth next to it)

long long int, double - just click it two times, wow 4+4 is 8

If you opened 64bit target and you have e.g. arrays of pointers, again, just click it two times. Or maybe you are too lazy? (you started it)

2015-12-06 18:04   
(Last edited: 2015-12-06 18:07)
you clearly have no idea what padding is

Dark Byte   
2015-12-06 22:31   
(Last edited: 2015-12-06 22:36)
64-bit compilers still prefer 32-bit integers and align those on a 32-bit alignment.

But I agree with brainiac, the default stepsize should be the pointersize alignment. The overrides should be 4 and 1
Usually the arrows are used for pointers to quickly see if the pointer you found can be used for other things.
But the the final offset is different though, as that will point to a structure of elements instead of pointers. (Although I guess the final offset could be on a 32-bit stepsize, but that would be inconsistent with the rest)

2015-12-07 01:00   
(Last edited: 2015-12-07 01:08)
@brainiac147, I know what padding is. Stop acting like that. Not cool. Do you know what packing is?

@DarkByte, I thought you left it, as it is, on purpose.

I often use pointerscanner, pointer paths usually looks like this:

pointerbase -> structure1 -> structure2 -> structure3 -> structure4 -> integer/float/double


What if structure3 is packed and it is a mix of elements and pointers. Using arrows with stepsize 8 to see if there are other pointers, we can miss some of them. We can miss much more with stepsize 8 compared to stepsize 4.


#pragma pack( 1 )
struct struct3{
  dword playerID;
  dword Health
  inverntoryItem** list; // offset 0x08
  dword Armor
  integer* ammunition; // offset 0x14
#pragma pack( )

Anyway, no problem for me. I will just remember to override it to 4 by pressing SHIFT when I find such structures in 64bit app.

2015-12-07 01:19   
So you've given again, a specific example, which is a packed struct. Notice you had to put #pragma pack ( 1 ) before that code. And why? Because it's not default behavior.

What if it's not a struct. What if it's say, an array of player pointers? Your whole argument goes out the window if it's anything other than a struct. And it has to be a special kind of struct for you to be right.
2015-12-07 01:26   
(Last edited: 2015-12-07 01:39)
CheatEngine is mainly for games. Games have optimizations. Some structures are packed to save memory, some of them aren't packed.

The default behaviour is to use packing where it is needed.

End of story. Good bye.

2015-12-07 05:12   
Well there's optimizations for memory consumption and then there's optimizations for speed. Nowdays speed is more important.

And you keep on talking about structures after I just told you that's a special case, and only under certain conditions would you be right.
2015-12-07 10:16   
Nowadays ignoring optimizations for memory consumption have impact on speed. Most recent example: Call of Duty: Black Ops 3.

"I just told you that's a special case..." - you still don't get it? This special case is not that rare as you think.

Pointerscanner mostly finds "base > object1 > object2 > ...", rather than "base > array1ofpointers > array2ofpointers > ..."

Anyway, look at latest commit on GitHub:

CE version 6.5 will behave like this:

- target is 32bit:
step is 4 for all nodes.
CTRL overrides step to 1, SHIFT overrides step to 8

- target is 64bit:
step is 8, except the last offset, it is still 4
CTRL overrides step to 1, SHIFT overrides step to 4
2015-12-08 22:44   
(Last edited: 2015-12-08 22:45)
dude you keep going back to structs. I told you 3 times already. There's many other uses where this is absolutely needed and it's not just for structs.

Here's a challenge: Find me a pointer table on x64 that is 32 bit aligned and not 64 bit aligned, and I will take back everything i said. And you're allowed to pack it or do #pragma(whatever) you want.

2015-12-08 23:23   
(Last edited: 2015-12-08 23:46)
@brainiac147, dude, you are irritating. What I'm trying to say, the whole time, is that +-4 is more universal. There is no point in talking to you about this any more.

@Dark Byte, I compiled it, tested and I think it is the best compromise.
I think you could add hints or change captions to "+4" "-4" ("+8" "-8") of those speedbuttons.

Index: formAddressChangeUnit.pas
--- formAddressChangeUnit.pas (revision 2209)
+++ formAddressChangeUnit.pas (working copy)
@@ -358,9 +358,15 @@
         lblPointerAddressToValue.Caption:=sbase+sign+soffset+' = '+inttohex(dword(fBaseAddress+offset),8)
+ sbDecrease.caption:='-4';
+ sbIncrease.caption:='+4';
+ begin
     lblPointerAddressToValue.Caption:='['+sbase+sign+soffset+'] -> '+SPointsTo;
+ sbDecrease.caption:='-'+inttostr( processhandler.pointersize );
+ sbIncrease.caption:='+'+inttostr( processhandler.pointersize );
+ end;
   //update positions
@@ -497,7 +503,7 @@
- sbDecrease.caption:='<';
+ // sbDecrease.caption:='<'; // moved to UpdateLabels
  // sbDecrease.OnClick:=DecreaseClick;
@@ -506,7 +512,7 @@
- sbIncrease.caption:='>';
+ // sbIncrease.caption:='>'; // moved to UpdateLabels
  // sbIncrease.OnClick:=IncreaseClick;


2015-12-09 05:39   
I'm irritating? you're the one who keeps coming back here posting after you said 3 times you were done, and didn't have time or w/e.

Pointer size on 64 bit is 8 bytes! you're traversing from one pointer to the next... should be 8 bytes. Plain and simple! knock this shift/ctrl nonsense.
2015-12-09 11:28   
(Last edited: 2015-12-09 11:39)
"Pointer size on 64 bit is 8 bytes!" - of course it is. I know about it.

If you still don't get it, DarkByte already fixed your issue. Recent SVN version already use step "8" for all nodes except last, when target is 64bit. I will use overrides when I need them. You don't have to.

If you want to try it, install CE6.5 Beta3, and overwrite files from "update"

PS: CTRL override (step "1") exists from CE version 6.2

Issue History
2015-12-04 05:49brainiac147New Issue
2015-12-04 16:39mgr_inz_PlayerNote Added: 0000899
2015-12-05 01:15brainiac147Note Added: 0000900
2015-12-05 11:27mgr_inz_PlayerNote Added: 0000901
2015-12-05 21:09brainiac147Note Added: 0000902
2015-12-05 21:12brainiac147Note Added: 0000903
2015-12-06 01:49mgr_inz_PlayerNote Added: 0000904
2015-12-06 01:50mgr_inz_PlayerNote Edited: 0000904bug_revision_view_page.php?bugnote_id=904#r117
2015-12-06 01:51mgr_inz_PlayerNote Edited: 0000904bug_revision_view_page.php?bugnote_id=904#r118
2015-12-06 09:44brainiac147Note Added: 0000905
2015-12-06 11:10mgr_inz_PlayerNote Added: 0000906
2015-12-06 11:20mgr_inz_PlayerNote Edited: 0000906bug_revision_view_page.php?bugnote_id=906#r120
2015-12-06 11:21mgr_inz_PlayerNote Edited: 0000906bug_revision_view_page.php?bugnote_id=906#r121
2015-12-06 18:04brainiac147Note Added: 0000907
2015-12-06 18:07brainiac147Note Edited: 0000907bug_revision_view_page.php?bugnote_id=907#r123
2015-12-06 22:31Dark ByteNote Added: 0000909
2015-12-06 22:33Dark ByteNote Edited: 0000909bug_revision_view_page.php?bugnote_id=909#r125
2015-12-06 22:34Dark ByteNote Edited: 0000909bug_revision_view_page.php?bugnote_id=909#r126
2015-12-06 22:34Dark ByteNote Edited: 0000909bug_revision_view_page.php?bugnote_id=909#r127
2015-12-06 22:36Dark ByteNote Edited: 0000909bug_revision_view_page.php?bugnote_id=909#r128
2015-12-07 01:00mgr_inz_PlayerNote Added: 0000911
2015-12-07 01:08mgr_inz_PlayerNote Edited: 0000911bug_revision_view_page.php?bugnote_id=911#r130
2015-12-07 01:08mgr_inz_PlayerNote Edited: 0000911bug_revision_view_page.php?bugnote_id=911#r131
2015-12-07 01:19brainiac147Note Added: 0000912
2015-12-07 01:26mgr_inz_PlayerNote Added: 0000913
2015-12-07 01:27mgr_inz_PlayerNote Edited: 0000913bug_revision_view_page.php?bugnote_id=913#r133
2015-12-07 01:39mgr_inz_PlayerNote Edited: 0000913bug_revision_view_page.php?bugnote_id=913#r134
2015-12-07 05:12brainiac147Note Added: 0000914
2015-12-07 10:16mgr_inz_PlayerNote Added: 0000915
2015-12-08 22:44brainiac147Note Added: 0000916
2015-12-08 22:45brainiac147Note Edited: 0000916bug_revision_view_page.php?bugnote_id=916#r136
2015-12-08 23:23mgr_inz_PlayerNote Added: 0000917
2015-12-08 23:46mgr_inz_PlayerNote Edited: 0000917bug_revision_view_page.php?bugnote_id=917#r138
2015-12-09 05:39brainiac147Note Added: 0000918
2015-12-09 11:28mgr_inz_PlayerNote Added: 0000919
2015-12-09 11:39mgr_inz_PlayerNote Edited: 0000919bug_revision_view_page.php?bugnote_id=919#r140
2015-12-21 10:47Dark ByteStatusnew => resolved
2015-12-21 10:47Dark ByteResolutionopen => fixed
2015-12-21 10:47Dark ByteAssigned To => Dark Byte
2016-06-05 15:18JptnucIssue cloned: 0000476