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 

Help with reading a string from memory and the memory

Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
How do I cheat?
Reputation: 0

Joined: 10 Sep 2019
Posts: 1

PostPosted: Tue Sep 10, 2019 12:26 am    Post subject: Help with reading a string from memory and the memory Reply with quote

Hey guys,
Could you help me out a bit please? I'm kinda new to this memory stuff and I'm a bit stuck... here's what I'm trying to do and what goes wrong:
The ultimate goal is to read and then write a static string in a process that changes the address of the string on each execution, but for the sake of learning, I'll focus here on just reading the string correctly from memory and I'll handle the writing later. So...
From what I've understand so far I should find the base address in this case, so that's what (I think) I did. I did a pointer scan, got millions of results, relaunched the process, re-scanned till I got down to only 4 results which had the same base address and I presume that's the base address. And now here comes my troubles.
This is the result in CE:
Base Address: 101A6040; Offsets from 0 - 6: 34 4C 54 74 18 C50 88.
And I have this code:

      GamePID: Cardinal;
      dat: array[1..47] of Char;
      read: SIZE_T;
      Str: String;
      GamePID := 1337;
      GamePID := OpenProcess(PROCESS_ALL_ACCESS, false, GamePID);
      Win32Check(GamePID <> 0);
      if not ReadProcessMemory(GamePID, Pointer($101A6040), @dat, 47, read) then RaiseLastOSError;
      Str := String(dat);

Now here comes my troubles:
1. From what I understand, I'd also have to add the offsets somehow to the code, not only the base address - how to do that?
(PS: the string is 47 characters long so I presume that's how I should declare "dat" array?)
2. The code isn't working, meaning Win32Check returns "Code 5 - Access denied" for this process. I have enabled SeDebugPrivilege for my application and also ran it as admin. How is CE able to access this process, does it do it via a driver or something?
3. From what I understand on this, I should use also VirtualProtectEx, but I don't know how to add that to the code either.
So help with any or both of the questions/points would really really be appreciated. Thanks.
Back to top
View user's profile Send private message
!BEWARE! Deletes post on answer
Reputation: 2

Joined: 19 Dec 2017
Posts: 100

PostPosted: Mon Sep 16, 2019 8:12 am    Post subject: Reply with quote

You could just write a software driver in plain C that scans the entire physical memory address space for the string.
Back to top
View user's profile Send private message
Reputation: 157

Joined: 25 Jan 2006
Posts: 8102

PostPosted: Mon Sep 16, 2019 2:41 pm    Post subject: Reply with quote

1. You need to read the memory of each step in the offset list. Each offset points to a pointer, so you need to read that value then use it in the next step of the reading. There are examples of this all over the forum in various languages, the jist is the same since the API call is the same in all languages.

2. Opening a process handle can be rejected if the process is protected. But, also if the running application does not have permission to use the desired flag. Using PROCESS_ALL_ACCESS requires admin privileges and is generally discouraged from being used anyway in game-hacking related situations. Specify the flags you need properly rather than using the 'all access' flag.

If you still want to use all access, then you need to both make sure your app is running as admin and that you have the proper access (as you mentioned via SeDebugPrivilege).

If you are running the program through the IDE for debugging purposes, the IDE must be started in admin mode as well.

3. VirtualProtectEx should only be needed if you need to adjust the memorys protection. Unless the application has page guards on the pointers, then you shouldn't need to adjust the protection to read the pointers or the value. But, if the memory is protected from writing you may need to adjust it while writing back a string to the end pointer.

You can read more on how VirtualProtectEx works here:

Parameter wise:
- hProcess - Should be the handle returned from OpenProcess.
- lpAddress - Should be the final address where the string is located you want to write to.
- dwSize - The size of data you plan to write. (The system will automatically round up to the proper size of the memory page as needed. Keep in mind this can change protection levels of multiple pages depending on what you give this.)
- flNewProtect - The new protection you wish to set on the memory page. (Generally, you'll want PAGE_EXECUTE_READWRITE for most things.)
- lpflOldProtect - A variable to hold the original protection before you modified it.

Depending on if the process is protected with an anti-cheat or similar, you will need to make sure to restore the page protection that was previously set otherwise it may trigger a detection due to the protection adjustment made.

- Retired.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming 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