 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
rsce How do I cheat?
Reputation: 0
Joined: 13 Mar 2022 Posts: 4
|
Posted: Mon Mar 14, 2022 1:13 am Post subject: Pointer scan for elusive address |
|
|
In Notepad I am attempting to write "Hello world!" to the contents of a live session by use of an external program. So far I have successfully managed to write the individual characters to memory where the file contents buffer is stored.
However I also need to modify the size of the buffer in order for the text to appear. It is possible to fill in gibberish text to artificially increase the buffer size, and then run the script to replace said text with "Hello world!". But I would like to write to the buffer size so that this step is not necessary.
The issue is with obtaining a static address to the buffer size, as it is dynamically allocated for each new live session. Interestingly it was very easy to find the buffer contents via pointer scan. But the buffer size seems to be elusive, and I am not sure why.
Another approach I attempted was to reverse trace the assembly code to find the origin of the base address written for buffer size. Also to no avail, as after having gone back far enough up the stack trace I found a literal disconnect between processes (one DLL call to another) where the information stored in the register was lost in translation. This might be a whole separate topic, and not one I am eager to pursue at this time.
So back to the pointer scan - what might prevent me from locating a static address? There are always zero results on the second (repeat) pointer scan filter when locating the new address for a follow-on session. I am dealing with 64-bit addresses, so I am sure to yield 8-byte results for each search. Not sure what more to try to get a static address. Any recommendations would be greatly appreciated.
See attached the instructions that get run when the buffer size is modified, if that may be helpful. It at least shows there is a final offset of +10. For clarification, when characters are deleted from the contents buffer the top line gets executed, and when characters are added the bottom line is run.
EDIT:
Attached pointer scan search settings.
Description: |
|
Filesize: |
10.36 KB |
Viewed: |
1883 Time(s) |

|
Description: |
|
Filesize: |
5.32 KB |
Viewed: |
1896 Time(s) |

|
Last edited by rsce on Mon Mar 14, 2022 1:45 am; edited 1 time in total |
|
Back to top |
|
 |
Frouk Grandmaster Cheater
Reputation: 5
Joined: 22 Jun 2021 Posts: 510
|
Posted: Mon Mar 14, 2022 1:27 am Post subject: |
|
|
just call the function, is it hard for ya?
|
|
Back to top |
|
 |
rsce How do I cheat?
Reputation: 0
Joined: 13 Mar 2022 Posts: 4
|
Posted: Mon Mar 14, 2022 1:35 am Post subject: Pointer scan for elusive address |
|
|
Frouk wrote: | just call the function, is it hard for ya? |
Which function?
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4695
|
Posted: Mon Mar 14, 2022 11:27 am Post subject: |
|
|
I'm confused by what you're asking. It seems like you already found a buffer that stores the characters drawn to the screen, and you found a pointer path that leads to that address. You say you can't find a pointer path to that buffer's length, but did you even find the address of the buffer's length to begin with?
And do you have any plans to deal with the capacity of the container using that buffer? The program might have initialized the container with a few KiB, but it could resize the buffer later on if needed. You can't just write a larger value to the capacity- that's a buffer overflow. Resizing the buffer correctly isn't an easy thing to do.
You could call one or several functions related to managing the buffer (use ultimap to find it), but that's far easier said than done.
rsce wrote: | what might prevent me from locating a static address? | Maybe the offset and/or max level isn't high enough. There can also be extraordinarily large offsets (MiB / GiB offsets can be common in emulators).
Maybe the last offset isn't correct. It certainly looks to be the case given those two instructions accessing the data, but that can be deceptive if a member of a structure is accessed directly.
If the pointer path passes through some structure with a non-static offset from the base, the pointer scanner won't find it. This can include containers populated under race conditions, implementations using a universal hash function, or any situation where the offset is being managed at runtime (e.g. smallvec / smallstring implementations w/ an inline buffer).
I've also experienced a problem with JIT implementations where the base address of a pointer path is encoded as an immediate in a JIT-compiled instruction. CE doesn't find that.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
rsce How do I cheat?
Reputation: 0
Joined: 13 Mar 2022 Posts: 4
|
Posted: Tue Mar 15, 2022 12:31 am Post subject: |
|
|
Foremost thank you for your reply, it's much appreciated.
ParkourPenguin wrote: | It seems like you already found a buffer that stores the characters drawn to the screen, and you found a pointer path that leads to that address. |
Correct, the pointer scan was readily able to find a static path to the address of the first character in the buffer that gets drawn to the screen. No difficulty there.
ParkourPenguin wrote: | You say you can't find a pointer path to that buffer's length, but did you even find the address of the buffer's length to begin with? |
I cannot find a static pointer path, but I can find the dynamic address by scanning manually for changes in value. But until I get a static pointer I need to repeat this exercise for each new session. It may be incorrect to refer to this as the buffer's length, since it represents the total number of characters currently contained in the contents of the document (rather than max allocated). So it's pretty trivial to scan for; I enter a new character and it increases by 1, remove a character and it decreases by 1. Highlight 2 characters at a time and hit backspace, it decreases by 2, etc.
ParkourPenguin wrote: | And do you have any plans to deal with the capacity of the container using that buffer? The program might have initialized the container with a few KiB, but it could resize the buffer later on if needed. You can't just write a larger value to the capacity- that's a buffer overflow. Resizing the buffer correctly isn't an easy thing to do. |
Again, I may have caused confusion by using a misnomer. It simply represents total number of characters drawn to the screen. And it's easy to manipulate once I find the address to modify it. Say I write "Hello world!" to the screen. The value is 12. If I modify its value to 5, then only "Hello" is displayed. Change it back to 12, and again, "Hello world!" is restored because the contents are still saved in memory (again, the contents that I have established a static pointer path to).
ParkourPenguin wrote: | You could call one or several functions related to managing the buffer (use ultimap to find it), but that's far easier said than done. |
If it's my only option at this point then perhaps I can learn how to do this. But I would really like to understand why the pointer scan yields no results.
The last bit you wrote about offsets being larger than expected could be possible. However to my knowledge vanilla Notepad is not emulated. I have used CE with emulators before, and so I know about those large offsets you are talking about (and dealing with them, oh that was fun). I think that is not likely the case here.
Might it be helpful if I send snippets of the addresses that come up for an arbitrary session?
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4695
|
Posted: Tue Mar 15, 2022 1:01 am Post subject: |
|
|
rsce wrote: | It may be incorrect to refer to this as the buffer's length, since it represents the total number of characters currently contained in the contents of the document (rather than max allocated). | Your usage of "length" is correct.
I'll use the same terminology as is used by C++, Rust, and probably other languages: the length of a string / vector is the currently used bytes, and the capacity of a string / vector is the maximum number of bytes the string / vector can contain until the memory backing the string / vector needs to be expanded.
Normally, the length and capacity of a string / vector would be near the pointer to the backing memory.
Maybe the length value you found is unrelated to the container holding the characters drawn to the screen. Perhaps it's like a C++ string_view or a Rust slice that simply borrows the contents of the actual container.
This is a dumb answer, but the pointer scanner isn't yielding any results because there don't exist any results given the options you set.
I'd guess the max offset and/or max level is too low, and/or the first offset is wrong.
May you click the "Show advanced options" checkbox and show what those options are set to? You may want to try treating the first bit of stack space of the first few threads as static if that option isn't already enabled by default. It's been getting more common to leave stuff on the stack at the start of program execution instead of storing it as a static.
Also, it's recommended to use more than one pointer map when doing a pointer scan. It will save a small amount of time (versus doing multiple pointer scans) and potentially a lot of disk space in the end. See this video on step 8 of the CE tutorial for more information:
https://www.youtube.com/watch?v=3dyIrcx8Z8g
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
rsce How do I cheat?
Reputation: 0
Joined: 13 Mar 2022 Posts: 4
|
Posted: Tue Mar 22, 2022 12:05 am Post subject: |
|
|
Here are my latest settings.
Though I have tried a plethora of other combinations as well, to no avail. For instance, not including the ending offset, using a lower max level with higher offsets, etc.
At this point I would invite anyone else to perhaps try this same exercise to determine if this is even feasible. To scan for this address is simple - its value is equal to the number of characters displayed. And it can be overwritten to modify the character count. But finding a static address? I wish I knew how...
Thank you for your help, @ParkourPenguin. It may be an oversight, or something else, but I have temporarily given up hope.
Description: |
|
Filesize: |
28.2 KB |
Viewed: |
1613 Time(s) |

|
|
|
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
|
|