More on Accessing Memory [Solved]

Posts 1–15 of 20 · Page 1 of 2
More on Accessing Memory [Solved]
Ok, so thanks to Jason and Hassan I understand how to access pointers and stuff in memory. But the problem is I don't know how far to go in some situations. For example I have found the offset of my player's health in assault cube, it is an integer but i tried to access it by this and it didn't work:

Code:
*(int*)(0x4E4DBC(start of player struct) + 0xF4(player health offset)) = 200;
I didn't affect the health and it didn't do anything to the gameplay. Then i got the base address of ac_client and then added to that the start of the player struct then the offset like this:

Code:
DWORD base = (DWORD) GetModuleHandleA("ac_client.exe");

*(int*) (base + 0x4E4DBC + 0xF4) = 200;
All that did was crash the game.

I don't understand why it's not working so it's hard to fix the problem. Any help is appreciated. Thanks.
Quote Originally Posted by 258456 View Post
Ok, so thanks to Jason and Hassan I understand how to access pointers and stuff in memory. But the problem is I don't know how far to go in some situations. For example I have found the offset of my player's health in assault cube, it is an integer but i tried to access it by this and it didn't work:

Code:
*(int*)(0x4E4DBC(start of player struct) + 0xF4(player health offset)) = 200;
I didn't affect the health and it didn't do anything to the gameplay. Then i got the base address of ac_client and then added to that the start of the player struct then the offset like this:

Code:
DWORD base = (DWORD) GetModuleHandleA("ac_client.exe");

*(int*) (base + 0x4E4DBC + 0xF4) = 200;
All that did was crash the game.

I don't understand why it's not working so it's hard to fix the problem. Any help is appreciated. Thanks.
Have you verified (through CE or something) that whatever (base + 0x4E4DBC + 0xF4) is pointing to is actually your health?

I just tried quickly with it and I got a useless value.

Add Pointer at ( 0x400000 + 0x4E4DBC ) with offset 0xF4 points to nothing. Are you sure your 0x4E4DBC value is correct? I think that 0x4E4DBC was your physical address ( with base added already ). Try this:

Code:
DWORD base = (DWORD)GetModuleHandle("ac_client.exe");
DWORD playerStruct = base +  0xE4DBC;
int *hpPtr = (int*)(playerStruct + 0xF4);
*hpPtr = 200;

EDIT:
Sorry, made a mistake with the offsets.

Code:
#define PLAYER_STRUCT     *(DWORD*)((DWORD)GetModuleHandle("ac_client.exe") + 0xE4DBC)
#define HP_OFFSET         0x000F4
#define NAME_OFFSET       0x00219

DWORD WINAPI main(LPVOID)
{
	char *buffer = new char[10];
	int* hpPtr = (int*)(PLAYER_STRUCT + HP_OFFSET);
	sprintf(buffer, "%d", *hpPtr);
	MessageBoxA(NULL, buffer, "Your HP:", MB_OK);
	char *name = (char*)(PLAYER_STRUCT + NAME_OFFSET);
	MessageBoxA(NULL, name, "Your Name:", MB_OK);
}
Quote Originally Posted by Jason View Post


Have you verified (through CE or something) that whatever (base + 0x4E4DBC + 0xF4) is pointing to is actually your health?

I just tried quickly with it and I got a useless value.

Add Pointer at ( 0x400000 + 0x4E4DBC ) with offset 0xF4 points to nothing. Are you sure your 0x4E4DBC value is correct? I think that 0x4E4DBC was your physical address ( with base added already ). Try this:

Code:
DWORD base = (DWORD)GetModuleHandle("ac_client.exe");
DWORD playerStruct = base +  0xE4DBC;
int *hpPtr = (int*)(playerStruct + 0xF4);
*hpPtr = 200;
EDIT:
Sorry, made a mistake with the offsets.

Code:
#define PLAYER_STRUCT     *(DWORD*)((DWORD)GetModuleHandle("ac_client.exe") + 0xE4DBC)
#define HP_OFFSET         0x000F4
#define NAME_OFFSET       0x00219

DWORD WINAPI main(LPVOID)
{
    char *buffer = new char[10];
    int* hpPtr = (int*)(PLAYER_STRUCT + HP_OFFSET);
    sprintf(buffer, "%d", *hpPtr);
    MessageBoxA(NULL, buffer, "Your HP:", MB_OK);
    char *name = (char*)(PLAYER_STRUCT + NAME_OFFSET);
    MessageBoxA(NULL, name, "Your Name:", MB_OK);
}
This is probably a little off topic but can you help me with this:

Code:
*(float*)((*(DWORD*)((*(DWORD*)(CShell+0xA2A7E8)) +(4*i))) + 0x2424) = 100.0f;
That is for a NoReload hack for crossfire.
Can you explain what all the ((*(DWORD*)((*(DWORD*) stuff is for? And the 4*i (i is a counter).
Quote Originally Posted by _corn_ View Post
This is probably a little off topic but can you help me with this:

Code:
*(float*)((*(DWORD*)((*(DWORD*)(CShell+0xA2A7E8)) +(4*i))) + 0x2424) = 100.0f;
That is for a NoReload hack for crossfire.
Can you explain what all the ((*(DWORD*)((*(DWORD*) stuff is for? And the 4*i (i is a counter).
Can u make another thread please because u r getting my thread offtopic, but I will answer ur question. The float dword pattern u wrote simply means that it is a pointer to a float to a dword pointer pointer to a dword pointer and basically u just dereferenced the address so now that it is like this u can access the actual values in it. As for the 4*i, in asm a pointer is four bytes that is why u r multiplying ur index(i) by four.
Thanks for the quick reply Jason. Thx for the code also but if you don't mind can you explain why for the player struct *(DWORD*) and not *(DWORD**) or something like that? I understand what they mean but my problem that I am having is that how do I know how many levels down a pointer is.
Quote Originally Posted by 258456 View Post
Thanks for the quick reply Jason. Thx for the code also but if you don't mind can you explain why for the player struct *(DWORD*) and not *(DWORD**) or something like that? I understand what they mean but my problem that I am having is that how do I know how many levels down a pointer is.
Okay this a little bit more complicated. Basically the player struct is actually a p2p2p (double level pointer), usually this is the case with classes/structs. Now, an actual pointer occupies 4 bytes (integer) in memory, and tells you where to go. Now, because this is a double level pointer, the first pointer will actually just point to another pointer. sizeof(DWORD) == sizeof(int), so you can use either one to represent a pointer.

So, think of it this way (NOTE: this is just pseudocode so you get an idea of pointer depth)
Code:
PLAYER_STRUCT** pstruct; //player struct is a 2 level pointer.
DWORD* firstPtr = (DWORD*)pstruct; //this has treated the pstruct as a DWORD*, ie C++ is saying treat this address as a pointer to a DWORD.
DWORD val = *firstPtr; //dereferences the DWORD* to find out what the value was
Basically, you have 2 pointers in pstruct
0xDEADBEEF holds the integer value [0x00DEFACED] -> 0x00DEFACED holds the integer value [0xFEEDF00D] -> 0xFEEDF00D holds the PLAYER_STRUCT.

so treating 0xDEADBEEF as a DWORD* rather than a PLAYER_STRUCT** means follow where 0xDEADBEEF points to, then read a DWORD from that address, so dereferencing 0xDEADBEEF gives us 0x00DEFACED, which is 1 level closer to pstruct.

Code:
//moving up pointer levels:
PLAYER_STRUCT** pstruct = somevalue;
PLAYER_STRUCT* uplevel = (PLAYER_STRUCT*)*(DWORD*)pstruct;
It's hard to explain haha, but think of it this way: If you find a class/struct's address (like 0x4E4DBC in AC), think of it as a double level pointer, so you dereference 1 level. I'd recommend the CE tutorials for more pointer explanation, I hate trying to explain pointers lol.
To verify if a pointer is pointing to a valid location in memory before using it you can do:

IsBadReadPtr( Your_pointer ) and IsBadWritePtr() respectively. Also you can wrap your code in an exception handler to test for an invalid pointer.

As for your question, it's very simple, *(DWORD*) = pointer to a DWORD pointer. But is dereferenced in player struct, so all that remains is simply a pointer to your health or name.
To clarify my answer about why it's a double level pointer, as I was a bit hazy in the first post:

The address itself needs to be interpreted as a pointer for C++ to read a specific type from it. I.e say there was a value of 100 starting at 0xDEADBEEF (4 byte value btw)

You can't just go:
DWORD value = (DWORD)0xDEADBEEF
because that will just convert the hex "0xDEADBEEF" to an integer.

But yeah, hopefully you get it now.
Thank you guys so much as usual. It makes a lot more sense to me now then it did yestarday, and that's a huge step for me. Thanks a bunch.

I doubt this is the end of my pointer problems so i will keep you guys updated but i really feel like i get it now. Thanks guys.
And if you're interested:

Code:
#define BASE_ADDRESS      (DWORD)GetModuleHandle("ac_client.exe")
#define PLAYER_STRUCT     *(DWORD*)(BASE_ADDRESS + 0xE4DBC)
#define HP_OFFSET         0x000F4
#define NAME_OFFSET       0x00219
#define UNLIM_AMMO        (BASE_ADDRESS + (DWORD)0x5B75F)
You just need to NOP the UNLIM_AMMO address for 2 bytes (note, singleplayer only)
Quote Originally Posted by Jason View Post
And if you're interested:

Code:
#define BASE_ADDRESS      (DWORD)GetModuleHandle("ac_client.exe")
#define PLAYER_STRUCT     *(DWORD*)(BASE_ADDRESS + 0xE4DBC)
#define HP_OFFSET         0x000F4
#define NAME_OFFSET       0x00219
#define UNLIM_AMMO        (BASE_ADDRESS + (DWORD)0x5B75F)
You just need to NOP the UNLIM_AMMO address for 2 bytes (note, singleplayer only)

Or i can get "unlimited" ammo the cheap and easy way by making my bullet offset in the player class set to 99999999999999. Then being above the map after editing my z coordinate. Then editing another value in the player class that calculates how many cubes per second i can walk and set it to .1 so that i basically have no recoil. HAHAHAHAHa. Thanks for making it possible Jason.
Ok, so i just tried dereferencing the pointer and changing the value of the health but the game crashes. I don't know why. This is my code:

Code:
#include <Windows.h>
#include <iostream>
#include "player.h"
void hack();

DWORD base = (DWORD)GetModuleHandle(TEXT("ac_client.exe"));
DWORD *playerStruct = (DWORD*)(base +  0x4E4DBC);
int *hpPtr = (int*)(playerStruct + 0xF4);

player *me = *(player**)0x4E4DBC;
float zpos;
float xsaved;
float ysaved;
float zsaved;
void hack()
{
	*hpPtr = 200;
	while(true)
	{
	  
		if(GetAsyncKeyState(VK_SPACE)&1)
		{
		
			me->z += 5;
			zpos = me->z;
			while(!GetAsyncKeyState(VK_NUMPAD1)&1)
			{
				if(GetAsyncKeyState(VK_SPACE)&1)
				{
					
					me->z+= 5;
					zpos = me->z;
				}
					me->z = zpos;

				
			}
			
			
		}
		if(GetAsyncKeyState(VK_SHIFT)&1)
		{
			me->z -= 5;
		}
		if(GetAsyncKeyState(VK_LEFT)&1)
		{
			me->x -= 5;
		}
		if(GetAsyncKeyState(VK_RIGHT)&1)
		{
			me->x += 5;
		}
		if(GetAsyncKeyState(VK_UP)&1)
		{
			me->y += 5;
		}
		if(GetAsyncKeyState(VK_DOWN)&1)
		{
			me->y -= 5;
		}
		if(GetAsyncKeyState(VK_NUMPAD8)&1)
		{
			xsaved = me->x;
		    ysaved = me->y;
			zsaved = me->z;
	     }
		if(GetAsyncKeyState(VK_NUMPAD9)&1)
		{
			me->x = xsaved;
			me->y = ysaved;
			me->z = zsaved;
		}

	
		
	}
}
BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:

		CreateThread(NULL, NULL,(LPTHREAD_START_ROUTINE)hack, NULL, NULL, NULL);
		  
       break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
@Jason
@Hassan
You stuffed up the player struct value when declaring the hpPtr (you didn't dereference the playerstruct value), use the defines I gave you earlier:

Code:
#define BASE_ADDRESS      (DWORD)GetModuleHandle("ac_client.exe")
#define PLAYER_STRUCT     *(DWORD*)(BASE_ADDRESS + 0xE4DBC)
#define HP_OFFSET         0x000F4
#define NAME_OFFSET       0x00219
#define UNLIM_AMMO        (BASE_ADDRESS + (DWORD)0x5B75F)

//globals
int* HP_POINTER = (int*)(PLAYER_STRUCT + HP_OFFSET);
player *MY_PLAYER = (player*)(PLAYER_STRUCT);
Oh, I just realized that it was also crashing because i wasn't even accessing the right offset. The struct is located at 0x4E4DBC, but when i add the base + offset of struct it is something else. So I should have written 0xE4DBC since the base address is 0x400000 and 0x400000 + 0xE4DBC = 0x4E4DBC, the address i wanted from the beginning.
your player class fmm. NOPing the ammo calculation is easy though, and if you have godmode on it doesn't matter that the bots have unlimited ammo too
Posts 1–15 of 20 · Page 1 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us