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 


[C++] Multi level pointers?

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

Joined: 26 Jun 2017
Posts: 27

PostPosted: Mon Jun 26, 2017 6:29 am    Post subject: [C++] Multi level pointers? Reply with quote

Sorry if this is asked a lot, but I can't seem to find anything clear through Google. It's annoying the hell out of me. I've spent a few hours mindlessly testing different combinations and recompiling, injecting, and restarting the program, as well as using ofstream to debug (as a side question, any tips on debugging using visual studio if I'm compiling a DLL and injecting? That's the only way I've thought of debugging). My code is just such a mess too.

Say I have a five-level pointer (example attached as image since I can't post links).

Say I want to do ReadProcessMemory on the floating point value that the whole thing points to. How on earth do I write this out using DWORD and dereferencing each address?



sadsad.png
 Description:
 Filesize:  19.82 KB
 Viewed:  14993 Time(s)

sadsad.png


Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Mon Jun 26, 2017 2:18 pm    Post subject: Reply with quote

If you are injected, you don't need to use ReadProcessMemory. You have direct access to the processes memory. You can cast pointers.

For example, to read the first pointer in your picture:
Code:
auto pointer1 = *(uintptr_t*)((uint32_t)::GetModuleHandle("chrome.exe") + 0x123456);


Afterward you would add each pointer onto this such as:
Code:

auto pointer2 = *(uintptr_t*)(pointer1 + 0xAAA);
auto pointer3 = *(uintptr_t*)(pointer2 + 0xBBB);


Be sure to check that the read info is valid before trying to read the next pointer otherwise you can crash the process trying to read invalid memory.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Mon Jun 26, 2017 5:09 pm    Post subject: Reply with quote

Wow, that's something I did not realize, that kind if makes it a lot easier.

Just a quick question, what would you suggest to do for testing and debugging? Recompiling, restarting, and reinjecting is kind of annoying.

Maybe I shouldn't DLL inject and just use a console and use ReadProcessMemory?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Mon Jun 26, 2017 5:46 pm    Post subject: Reply with quote

DLL injection is fine. Use an injector that offers the ability to eject as well or add code in your DLL to allow you to eject it on request or via a keypress, for example in a thread looping look for a specific key press to cause the DLL to unload itself.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Mon Jun 26, 2017 6:16 pm    Post subject: Reply with quote

Do you know of any injectors that would allow ejecting? I've never heard of such a thing, but it sounds super useful. I've just been using some random simple injector that was used for Halo, so I definitely don't think it can eject itself.
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Mon Jun 26, 2017 8:09 pm    Post subject: Reply with quote

Xenos Injector is a fairly popular one that includes the ability to eject modules.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Mon Jun 26, 2017 9:32 pm    Post subject: Reply with quote

Thanks, this does seem to have an "Eject modules" function. However, it just seems to crash after trying to eject it.


This is the thing that it shows when I try to eject the dll. Usually this is an error I've seen when just having an error in my code and injecting it. My code might be bad and I'm not checking for null pointers and stuff, but I'm not sure why that might affect trying to eject the code. Nothing is wrong when the code is injected, nor is anything wrong when I try to do what I'm trying to do (even though it's not working).

EDIT: I actually just tested this with pretty much everything being blank.
It still crashes when trying to eject.



0uZNDaM.png
 Description:
 Filesize:  26.29 KB
 Viewed:  14897 Time(s)

0uZNDaM.png


Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8516
Location: 127.0.0.1

PostPosted: Mon Jun 26, 2017 11:26 pm    Post subject: Reply with quote

If you are injecting a DLL and modifying the game's code to jump to your DLLs own functions and stuff, you need to undo your patches and stuff before you eject it. Otherwise, the game will just crash due to trying to jump to invalid memory spaces.

If it's failing on injection then it's probably your code being incorrect. Access violations can also happen if the address space is protected.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Tue Jun 27, 2017 3:33 am    Post subject: Reply with quote

So I'm still struggling with what I'm trying to do. Clearly there is some basic concept I'm not accounting for. I've attached the exact pointers I'm trying to write.

I'm trying to pull a floating point value. The address for it should be m_xAddr. This is what I wrote based on what you told me.



Code:
auto pointer1 = *(uintptr_t*)((uint32_t)::GetModuleHandleW(0) + 0x108D600);
auto pointer2 = *(uintptr_t*)(pointer1 + 0x100);
auto pointer3 = *(uintptr_t*)(pointer2 + 0x20);
auto m_xAddr = *(uintptr_t*)(pointer3 + 0x63C);


And this is what I already had.

Code:
DWORD Base = (DWORD)GetModuleHandleW(0);
DWORD thefirst = (DWORD)(*(DWORD*)(Base + 0x108D600));
DWORD thesecond = (DWORD)(*(DWORD*)(thefirst + 0x100));
DWORD thethird = (DWORD)(*(DWORD*)(thesecond + 0x20));
DWORD m_xAddr = (DWORD)(*(DWORD*)(thethird + 0x63C));


Neither works. All I'm trying to do is output the addresses into a file using ofstream when I press a button.



sad.png
 Description:
 Filesize:  17.7 KB
 Viewed:  14871 Time(s)

sad.png


Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

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

PostPosted: Tue Jun 27, 2017 6:18 am    Post subject: Reply with quote

the last one is just +63c , no need to dereference
_________________
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
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Tue Jun 27, 2017 4:23 pm    Post subject: Reply with quote

I actually had those lines but I commented them out because I think they didn't work for some reason. Here they are:

Code:
DWORD m_xAddr = thethird + 0x63C;
DWORD m_yAddr = thethird + 0x640;


and (one or the other)

Code:
auto m_xAddr = pointer3 + 0x63C;
auto m_yAddr = pointer3 + 0x640;


But they don't work for some reason. I'm just trying to output the last to a file and it crashes instantly. I know that the pointers exist because I check in cheat engine and they're working.

EDIT: So it appears that even the first address "thefirst" is not correct, and I think I have the problem. I've checked the outputs of the addresses. "Base" is correct. It matches what I put in cheat engine (I put it in the offset box and it shows me the value and it matches). However, there's one thing that I'm not understanding.

Code:
"starbound.exe"+0108D600


This is the very first one, at the bottom box when entering the pointer values. "starbound.exe" is equal to 3F190000. However, if I put 3F190000+0108D600 it gives me something different. It actually gives me exactly what I output into the txt file. Here's what's shown in the text file:

Code:
1058603008 (the base address in decimal)
1075984528 (the first address in decimal)


In hex, it becomes 3F190000 and 40223890. The first one is right, the second one is not. The second one is supposed to be 034C6000 So I can see where it's going wrong, I just don't know why. Am I supposed to dereference the base first?
Back to top
View user's profile Send private message
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Wed Jun 28, 2017 5:47 pm    Post subject: Reply with quote

Sorry for the doublepost, but this is actually the weirdest thing. I fixed it, but I have literally no clue why this works the way it does. Maybe it has something to do with memory or RAM or just simply Cheat Engine that I don't understand.

So my problem was that "starbound.exe"+0108D600 was not pointing to the same address in cheat engine as it was showing. In the boxes, the values were "starbound.exe"+0108D600, then 100, then 20, then 63C. So ideally I would just put these exact values in my code, but apparently that's wrong.

"starbound.exe"+0108D600 in Cheat Engine was different from what it actually should be. When in Cheat Engine, it shows that "starbound.exe"+0108D600 -> 34C60000 (or something like that), but in my code it would point to something WAY different (and more than 8 long). So I just searched for the address 34C60000 to see what the actual value was that was pointing to it, and it turns out it's 9 long. It was 140C5D600. That's funny, because what
"starbound.exe"+0108D600 should equal is 40C5D600. Which means all I did to my code to fix it was just add 100000000.

Code:
DWORD m_xAddr = *(DWORD*)(*(DWORD*)(*(DWORD*)((DWORD)GetModuleHandleW(0) + 0x108D600 + 0x100000000) + 0x100) + 0x20) + 0x63C;
DWORD m_yAddr = *(DWORD*)(*(DWORD*)(*(DWORD*)((DWORD)GetModuleHandleW(0) + 0x108D600 + 0x100000000) + 0x100) + 0x20) + 0x640;
DWORD xAddr = *(DWORD*)(*(DWORD*)(*(DWORD*)(*(DWORD*)((DWORD)GetModuleHandleW(0) + 0x1090EB0 + 0x100000000) + 0x20) + 0x5F8) + 0x658) + 0x318;
DWORD yAddr = *(DWORD*)(*(DWORD*)(*(DWORD*)(*(DWORD*)((DWORD)GetModuleHandleW(0) + 0x1090EB0 + 0x100000000) + 0x20) + 0x5F8) + 0x658) + 0x3B8;


So why does this work? Why didn't it work before? My previous hacks worked just fine without doing this. Maybe I'm using enough RAM to expand to another region of memory that I haven't used before, and Cheat Engine accounts for that without me knowing?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Wed Jun 28, 2017 8:07 pm    Post subject: Reply with quote

The 8-byte value 140C5D600 is being truncated to the 4-byte value 40C5D600. Instead of storing 64-bit addresses in a DWORD (4-byte value type), store it in a type that can actually fit an 8-byte value. Use Google for examples.
_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
horsedeg
Cheater
Reputation: 0

Joined: 26 Jun 2017
Posts: 27

PostPosted: Wed Jun 28, 2017 10:30 pm    Post subject: Reply with quote

Well, that makes sense. That's kind of stupid of me. I fixed it. I used the suggestion atom0s gave me except instead of uint32_t I used uint64_t. Thanks a lot.
Back to top
View user's profile Send private message
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