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 


Multi level pointers + ReadProcessMemory()

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
Vanapapi
Newbie cheater
Reputation: 0

Joined: 18 Jul 2012
Posts: 12

PostPosted: Fri Jul 20, 2012 5:11 am    Post subject: Multi level pointers + ReadProcessMemory() Reply with quote

Hi, I'm in a little trouble with multi-level pointers, as beginners tend to be.
Now my purpose is to read the value of the adress which has multiple pointers to it, here is the CE result:
epvpimg . com/n8Vgh
And I'm kinda confused with 2 things:
1)I'm using multiple ReadProccessMemory() functions, and I should start it from the bottom adress to the upper right?
2)Should I start with "Game.exe"+0x01D74230 and if I do, how? Or 0x10E62A30?

Here is my current code:
Code:
#include <iostream>
#include <Windows.h>

int FindPointerAddr(HANDLE pHandle,int baseaddr, int pLevel, int offset0 = 0,int offset1 = 0,int offset2 = 0,int offset3 = 0, int offset4 = 0)
{
   int Address = baseaddr;
   int offset = 0;
   for (int i = 0; i < pLevel; i++)
   {
      if (i == 0)
      {
         offset = offset0;
      }
      else if (i == 1)
      {
         offset = offset1;
      }
      else if (i == 2)
      {
         offset = offset2;
      }
      else if (i == 3)
      {
         offset = offset3;
      }
      else if (i == 4)
      {
         offset = offset4;
      }
      ReadProcessMemory(pHandle, (LPCVOID)Address, &Address , 4, NULL);
      Address+=offset;
   }
   return Address;
}

int main()
{
//FIND THE HANDLE//
   DWORD wid;
   HWND w3wnd = FindWindow(NULL, L"Allods Online"); ;
    GetWindowThreadProcessId(w3wnd, &wid);
    HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);
    if (w3wnd==NULL)
    {
        printf("Game Handle not found...\n");
        std::cin.get();
    }
   if (w3wnd!=NULL)
    {
        printf("Game handle found...\n");
        std::cin.get();
    }
//END//
//FIN THE ADRESS//
HANDLE ProcessHandle;
ProcessHandle=w3hnd;
int offset0 = 0x58;
int offset1 = 0x98;
int offset2 = 0x48;
int offset3 = 0x4;
int offset4 = 0x3c;

int myaddr = FindPointerAddr(ProcessHandle, 0x10E62A30, 5, offset0, offset1, offset2, offset3, offset4);
std::cout<<myaddr;
int value;
ReadProcessMemory(ProcessHandle, (LPCVOID)myaddr, &value, sizeof(value), 0);
//DISPLAY THE ADRESS//
std::cout<<"\n";
std::cout<<value;
std::cin.get();
return(0);
}


Thanks in advance,
Vanapapi
Back to top
View user's profile Send private message
lucidity
Advanced Cheater
Reputation: 0

Joined: 16 Feb 2011
Posts: 91

PostPosted: Fri Jul 20, 2012 11:08 am    Post subject: Reply with quote

I definitely have to recommend moving those pointers into an array so you don't have a ton of redundant code.

Make a general process to read the pointers, so you can read a pointer value regardless of how many levels you must traverse.

With regards to your questions:
1) Yes
Game.exe + 1D74230 = 10E62A30
Result +58
Result +98
...etc...

2) You can dynamically calculate the address (get game.exe base, then add the base offset). You can also use 10E62A30 as you are, but it will only work for a short time because the address is not relative to the base. This means you will need to calculate and reenter this address every time you reload the program. It might be simpler to get it working as-is first and then work on getting the base address dynamically after it is working.

What is the problem with the program? What output do you receive? Have you made any attempts at debugging it? Have you ruled anything out?

_________________
» Antec Twelve Hundred Full Tower » EVGA E760 CLASSIFIED » EVGA GeForce GTX 580 SuperClocked 1536MB » i7-980XE » CORSAIR DOMINATOR 6GB PC3 12800 DDR3 » OS: Intel X25-M SSD » Game Storage: Raid-0 2 x WD VelociRaptor 10000 RPM » CE Cache Drive: 500GB WD Caviar » Power Supply: OCZ Z Series Gold 1000W
Back to top
View user's profile Send private message
Vanapapi
Newbie cheater
Reputation: 0

Joined: 18 Jul 2012
Posts: 12

PostPosted: Fri Jul 20, 2012 4:03 pm    Post subject: Reply with quote

lucidity wrote:
I definitely have to recommend moving those pointers into an array so you don't have a ton of redundant code.

I have to declare int type on each one of them... can't figure another way. But let them be, they don't actually make difference in the functioning right?

lucidity wrote:
What is the problem with the program? What output do you receive? Have you made any attempts at debugging it? Have you ruled anything out?

1)The problem with the program is, it doesn't output a correct value.
2) When I run the code, the result is:
"Game handle found..." - as it should be, so finding handle part is working + if I did it with the final adress, it worked, so it definetly can't be the the handle.

"1241452284" - It's the cout<<myaddr, should it be like that?

But then the ouput gets a little weird(at least to my non-experienced eyes Smile):
"-858993460" - This should be the cout<<value, but it isn't everywhere near the value.
3)By debugging I don't think you mean the Visual Studio debugger... so you mean if I have tried to fix it. Well... all I could think of was changing the base address, but it still didn't work.

lucidity wrote:
Make a general process to read the pointers, so you can read a pointer value regardless of how many levels you must traverse.

General process? Explain me more. I'll have to enumerate DLL's and add the dll value to the other value? "Game.exe"+01D74230? How to do that?

Thank you for helping me,
Vanapapi

EDIT: Here is a shorter, perhaps more understandable version of the code demostrating the problem(the handle part is ok, checked it).
Code:

#include <iostream>
#include <Windows.h>

int main()
{
DWORD wid;
   HWND w3wnd = FindWindow(NULL, L"Allods Online"); ;
    GetWindowThreadProcessId(w3wnd, &wid);
    HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);

HANDLE ProcessHandle=w3hnd;

int address=0x10DB3EC0;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);
address+=0x58;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);
address+=0x98;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);
address+=0x48;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);
address+=0x4;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);
address+=0x3c;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);

int value;
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &value, sizeof(value), 0);
std::cout<<value;

std::cin.get();
return(0);
}

I want it to display HP value of 612 not some -xxxxxxxxx(numbers).
I select the first adress from the same place* as 10E62A30 is displayed on the picture in the first post(epvpimg . com/n8Vgh).

note* same place, not the same adress as it keeps changing and it is ultimately useless to use actually since I can stop messing with the pointers and get the final adress when I refresh it every time.

Would like know more about that general process.
EDIT 2:
The problem seems to be with lines
Code:
ReadProcessMemory(ProcessHandle, (LPCVOID)address, &address , 4, NULL);

on my shorter code, do you know how to fix this?


Last edited by Vanapapi on Fri Jul 20, 2012 5:40 pm; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25288
Location: The netherlands

PostPosted: Fri Jul 20, 2012 5:30 pm    Post subject: This post has 1 review(s) Reply with quote

Just wondering, did you make up those addresses or are they real addresses?

e.g: There is no way that "Game.exe"+0x01D74230 equals 0x10E62A30 (it's not even on a page boundary) , so check that first

_________________
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
View user's profile Send private message MSN Messenger
lucidity
Advanced Cheater
Reputation: 0

Joined: 16 Feb 2011
Posts: 91

PostPosted: Fri Jul 20, 2012 5:57 pm    Post subject: Reply with quote

Nice catch DB, you're awesome.

OP, my C++ is not that great, and I haven't tested this, but a simplified version of your script might look like this... note the number "5" does not exist and offsets.size() is used instead. This means if you have more or less offsets, the FindPointerAddr function will still work:
Code:
#include <iostream>
#include <Windows.h>

int FindPointerAddr(HANDLE pHandle,int baseaddr, int offsets[])
{
   int Address = baseaddr;
   int offset = 0;
   for (int i = 0; i < offsets.size(); i++)
   {
      ReadProcessMemory(pHandle, (LPCVOID)Address, &Address , 4, NULL);
      Address+=offset[i];
   }
   return Address;
}

int main()
{
//FIND THE HANDLE//
   DWORD wid;
   HWND w3wnd = FindWindow(NULL, L"Allods Online"); ;
    GetWindowThreadProcessId(w3wnd, &wid);
    HANDLE w3hnd = OpenProcess(PROCESS_ALL_ACCESS, false, wid);
    if (w3wnd==NULL)
    {
        printf("Game Handle not found...\n");
        std::cin.get();
    }
   if (w3wnd!=NULL)
    {
        printf("Game handle found...\n");
        std::cin.get();
    }
//END//
//FIN THE ADRESS//
HANDLE ProcessHandle;
ProcessHandle=w3hnd;
int offsets[] = {0x58, 0x98, 0x48, 0x4, 0x3c};

int myaddr = FindPointerAddr(ProcessHandle, 0x10E62A30, offsets);
std::cout<<myaddr;
int value;
ReadProcessMemory(ProcessHandle, (LPCVOID)myaddr, &value, sizeof(value), 0);
//DISPLAY THE ADRESS//
std::cout<<"\n";
std::cout<<value;
std::cin.get();
return(0);
}


Look into DB's feedback about the address, that is probably the source of your problem.

_________________
» Antec Twelve Hundred Full Tower » EVGA E760 CLASSIFIED » EVGA GeForce GTX 580 SuperClocked 1536MB » i7-980XE » CORSAIR DOMINATOR 6GB PC3 12800 DDR3 » OS: Intel X25-M SSD » Game Storage: Raid-0 2 x WD VelociRaptor 10000 RPM » CE Cache Drive: 500GB WD Caviar » Power Supply: OCZ Z Series Gold 1000W
Back to top
View user's profile Send private message
Vanapapi
Newbie cheater
Reputation: 0

Joined: 18 Jul 2012
Posts: 12

PostPosted: Fri Jul 20, 2012 7:19 pm    Post subject: Reply with quote

@Dark Byte
If it's "AOgame.exe" does it make any difference? Because I didn't make them up.
Here is another picture with another adresses, but "AOgame.exe"+01D7423C and offsets are the same: http://epvpimg.com/9chhh



@lucidity
Your code doesn't work. Sad
I ran into exact same problems when I tried to make it with arrays. (line 9 and 11)
Back to top
View user's profile Send private message
lucidity
Advanced Cheater
Reputation: 0

Joined: 16 Feb 2011
Posts: 91

PostPosted: Fri Jul 20, 2012 7:47 pm    Post subject: Reply with quote

What DB is saying is that your game.exe value cannot be 0x10E62A30 - 0x01D74230, or F0EE800. Though I don't understand what a page boundary is exactly, my interpretation is that F0EE800 should factor evenly into a number which it does not.

You can see the real game.exe base in CE by attaching to game.exe and adding an address of game.exe (type that instead of an address). CE will interpret game.exe and show the address in the list as the base. That address won't be F0EE800 according to DB (I definitely believe him).

This modified code should work (created a size variable before the for loop):
Code:

int FindPointerAddr(HANDLE pHandle,int baseaddr, int offsets[])
{
   int Address = baseaddr;
   int offset = 0;
   int offsetCount = sizeof(offsets)/sizeof(int);
   for (int i = 0; i < offsetCount; i++) {
   {
      ReadProcessMemory(pHandle, (LPCVOID)Address, &Address , 4, NULL);
      Address+=offset[i];
   }
   return Address;
}

_________________
» Antec Twelve Hundred Full Tower » EVGA E760 CLASSIFIED » EVGA GeForce GTX 580 SuperClocked 1536MB » i7-980XE » CORSAIR DOMINATOR 6GB PC3 12800 DDR3 » OS: Intel X25-M SSD » Game Storage: Raid-0 2 x WD VelociRaptor 10000 RPM » CE Cache Drive: 500GB WD Caviar » Power Supply: OCZ Z Series Gold 1000W


Last edited by lucidity on Fri Jul 20, 2012 7:55 pm; edited 1 time in total
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25288
Location: The netherlands

PostPosted: Fri Jul 20, 2012 7:54 pm    Post subject: Reply with quote

10db3ec0 is a dynamic address that is pointed to by game.exe+1d7423c, so that means you must first read the 4 byte address at game.exe+1d7423c

Most likely, it is 0217423c, but it's recommended to get the base address if it shifts on each run

_________________
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


Last edited by Dark Byte on Fri Jul 20, 2012 8:10 pm; edited 1 time in total
Back to top
View user's profile Send private message MSN Messenger
lucidity
Advanced Cheater
Reputation: 0

Joined: 16 Feb 2011
Posts: 91

PostPosted: Fri Jul 20, 2012 7:59 pm    Post subject: Reply with quote

Dark Byte wrote:
Most likely, it is 0217423c, but it's recommended to get the base address if it shifts on each run


Vanapapi you should focus on this, it will fix your problem and it will eliminate the last thing which will change each run, making your program (re)usable.

_________________
» Antec Twelve Hundred Full Tower » EVGA E760 CLASSIFIED » EVGA GeForce GTX 580 SuperClocked 1536MB » i7-980XE » CORSAIR DOMINATOR 6GB PC3 12800 DDR3 » OS: Intel X25-M SSD » Game Storage: Raid-0 2 x WD VelociRaptor 10000 RPM » CE Cache Drive: 500GB WD Caviar » Power Supply: OCZ Z Series Gold 1000W
Back to top
View user's profile Send private message
Vanapapi
Newbie cheater
Reputation: 0

Joined: 18 Jul 2012
Posts: 12

PostPosted: Sat Jul 21, 2012 5:26 am    Post subject: Reply with quote

@Dark Byte
You were right and now it works. Amazing, how did you know the adress without even knowing the actual game? Any easy way I've missed out? Smile
I got it by scanning for the value that "AOgam+exe"+01D74230 created.

@lucidity
Thank you for the code, the
Code:
 int offsetCount = sizeof(offsets)/sizeof(int);

didn't give the right number, but I'm capable of fixing this.

You've both been very helpful so thank you for that! I'll mess around till I stumble on another problem that I'm incapabable to fix. Smile

What I learned is: To make it work I need the static adress(in green). Right?


Last edited by Vanapapi on Sat Jul 21, 2012 12:20 pm; edited 2 times in total
Back to top
View user's profile Send private message
lucidity
Advanced Cheater
Reputation: 0

Joined: 16 Feb 2011
Posts: 91

PostPosted: Sat Jul 21, 2012 5:28 am    Post subject: Reply with quote

right
_________________
» Antec Twelve Hundred Full Tower » EVGA E760 CLASSIFIED » EVGA GeForce GTX 580 SuperClocked 1536MB » i7-980XE » CORSAIR DOMINATOR 6GB PC3 12800 DDR3 » OS: Intel X25-M SSD » Game Storage: Raid-0 2 x WD VelociRaptor 10000 RPM » CE Cache Drive: 500GB WD Caviar » Power Supply: OCZ Z Series Gold 1000W
Back to top
View user's profile Send private message
shakib187
Expert Cheater
Reputation: 0

Joined: 24 May 2007
Posts: 215

PostPosted: Mon Nov 03, 2014 7:18 am    Post subject: Reply with quote

How would this be different in x64 processes? I tried uint64_t already but it didnt do anything for me

Code:


int FindPointerAddr(HANDLE pHandle,int baseaddr, int pLevel, int offset0 = 0,int offset1 = 0,int offset2 = 0,int offset3 = 0, int offset4 = 0)
{
   int Address = baseaddr;
   int offset = 0;
   for (int i = 0; i < pLevel; i++)
   {
      if (i == 0)
      {
         offset = offset0;
      }
      else if (i == 1)
      {
         offset = offset1;
      }
      else if (i == 2)
      {
         offset = offset2;
      }
      else if (i == 3)
      {
         offset = offset3;
      }
      else if (i == 4)
      {
         offset = offset4;
      }
      ReadProcessMemory(pHandle, (LPCVOID)Address, &Address , 4, NULL);
      Address+=offset;
   }
   return Address;
}


Sorry to necro old thread but I didnt wanna create another one
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25288
Location: The netherlands

PostPosted: Mon Nov 03, 2014 7:30 am    Post subject: Reply with quote

Uint64's are 8 byte
_________________
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
View user's profile Send private message MSN Messenger
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