Get address that is pointed to from another address - c++

For practice I am trying to get the address that a certain memory address is pointing at. I have a tool which shows what result I have to get. In my case it is:
"clientApp.exe"+0x11F9B08 -> 0E4C5F90
So I am assuming this basically means: ("The base address of the .exe" + 0x11F9B08) and that points to the address 0x0E4C5F90.
I already have the base address of the clientApp.exe. I used EnumProcessModules and GetModuleFileNameEx for that.
Small snippet
if ( GetModuleFileNameEx( hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
{
if(gameName.compare(szModName))
{
dwClientBase = (DWORD)hMods[i]; //base address
break;
}
}
Then later on i'm trying to get the address that is pointed to. But the following give me a whole other result:
DWORD result = (DWORD)(dwClientBase + 0x11F9B08);
This gives me: 23042824. And i'm looking for: 0x0E4C5F90. I guess i'm close, but not sure what I could try next.
Anyone any idea what I should do in order to get the same result as the tool is giving me?

What type is dwClientBase? If it is a DWORD then you should cast to a BYTE * and then do your arithmetic, making sure to dereference the pointer to return the value pointed to by that address:
DWORD result = *(DWORD *)( (BYTE *)dwClientBase + 0x11F9B08);
When adding a number to a pointer the compiler will add a number of bytes equal to the number multiplied by the size of the pointer type. This is why we convert to a BYTE * first, so what we add on exactly 0x11F9B08 bytes.

You do not dereference the pointer. Try either
DWORD result = *(DWORD*)(dwClientBase + 0x11F9B08);
or
DWORD result = *(DWORD*)(0x11F9B08);
The cast to DWORD* says the compiler to treat the number as a pointer, then dereferencing * it causes read the actual number.

Related

Need help understanding ida pseudocode

I am new to reversing. I have stumbled upon a line of code which I am unable to understand.
return (*(_int64(**)(void))(**(_QWORD **)(v1 + 0x3C8) + 0x68LL ))();
The code is for arm64 lib. So , what I understood is that it's returning a pointer out as unsigned int64 data type. But , when I try to use it as ,
return (unsigned long) ((unsigned long)(v1 + 0x3C8) + 0x68) ;
, the result is so out of the unsigned long range , for example one result is 19985131375820901. Also , _int64 and _QWORD both have the size of 8 bytes and so does unsigned long. So I am a little confused here how is this happening. Can anybody help with the correct interpretation of this pls ?
v1 + 0x3C8
Yes. This adds 0x3C8 to v1. But you seemed to have overlooked something else that happens before 0x68 gets added to it.
(_QWORD **)
The result of this addition gets casted to a pointer to a pointer to a _QWORD. That's what this means in C++.
**
And dereferenced. Twice. That produces a _QWORD, from somewhere. Wherever those pointers lead to.
+0x68LL
And only then does 0x68 gets added to whatever you have now.
But you're not done yet. There's still more C++ code left that you need to unravel.
(_int64(**)(void))
This gets now casted to a pointer to a pointer to a function that takes no parameters and returns an _int64.
*
And the pointer dereferenced.
()
And the function call is finally made, which returns an _int64 value.

Add offset to pointer without casting to UINT

If have written the following code to learn a bit about pointers and pointer arithmetic, meaning going from offset to offset to read something from a struct.
I have the following code
DWORD * x = (DWORD*)((UINT)ptr1 + sizeof(int) + sizeof(float));
float f = *(float*)x;
This Code works as it should. However I struggled a lot to get it working as at the beginning I was not casting ptr1 to UINT and therefore was getting a different address as I wanted to have.
Now it works. However can someone explain to me why I cannot add the offset (sizeof...) to the ptr1 directly which is of type DWORD * ?
DWORD * x = (DWORD*)(ptr1 + sizeof(int) + sizeof(float));
float f = *(float*)x;
Adding a number n to a T * pointer will move the pointer sizeof(T)*n bytes (not n bytes).
For your example, if we suppose that both sizeof(int) and sizeof(DWORD) are 4, adding sizeof(int) to ptr1 will move ptr1 16 bytes (instead of 4, which you likely intended).
going from offset to offset to read something from a struct.
You can't do that. That's not how pointers work. You shall not treat them as just numbers, addresses; that way madness lies. C++ is an abstraction and you can only have a pointer to an object or an array of objects. Once you start playing around with it to navigate between objects, you've lost. Prepare for UB weirdness relating to padding, alignment, aliasing, optimisations...

memset pointer + offset

For example, I have:
DWORD pointer = 0x123456;
DWORD offset = 0xABC;
I want to add offset to pointer and set the value at the address pointed by that pointer to 1.0f. How do I give memset() a pointer and an offset as first argument?
DWORDs are the same as uint32_t's. Just add them together as you would with any other integer.
Also, while setting a float (I am assuming you're setting a float due to the 'f' after the '1.0'), I wouldn't use memset. Just cast the pointer to a float, and de-reference it like so:
DWORD pointer = 0x123456;
DWORD offset = 0xABC;
pointer += offset;
float* float_pointer = reinterpret_cast<float*>(pointer);
*float_pointer = 1.0f;
This can be straightforward pointer arithmetic, but we've got a few preliminary issues to take care of first.
Why is your pointer variable declared as a DWORD? We'll need a proper pointer type eventually.
Why are you asking about memset, if you're trying to set a floating-point value? memset sets plain bit patterns; it's not much good for floating-point.
I assume your offset is supposed to be measured in bytes, not sizeof(float).
Anyway, computing the pointer you want could go something like this:
float *fp = (float *)(pointer + offset);
[Notice that I perform the addition inside the parens, before the cast, so as to get a byte offset. If I instead wrote (float *)pointer + offset, it'd offset by `sizeof(float).]
Once we've got that float pointer, we can set the location it points to to 1.0 in the usual way:
*fp = 1.0f;
Or we could set it to 0 using memset:
memset(fp, 0, sizeof(float));

Dereferencing pointer in Code Composer Studio

I have a value I receive in an unsigned byte array that I would like to dereference as a float. Take ptr as a uint8_t* pointing at a byte array of four values 0,0,0xCD,0x42 (this is a little endian system).
float val = *(float*)ptr;
is return -1.34e8
When I type:
*(float*)ptr;
In the expressions window after hitting a break point in that section of code, it gives me 102.5 as expected. Further, when I type:
*(float*)(ptr - 1);
I get the incorrect -1.34e8, as if the compiler used ptr - 1 instead of what I typed.
I'm confused - am I missing something here?
Basically the deref is correct.
If you printf("%p", ptr); do you get an address that is maybe not 4-byte aligned (or at least 2-byte aligned)? This may be necessary on some platforms.
For test, just pass the value of a real float in the uint8_t*, e.g.
float f= 102.5;
yourfunct((uint8_t*)&f);
and see if that works.
*(float*)(ptr - 1);
is the same as this
ptr--; //move the pointer to point to charackter in front of the previous one
*(float*)ptr;
Is this your intention ?
Or do you just want to subtract 1 from the value that is being pointed to be ptr.

Where is pointer metadata stored?

Could be that I am overlooking something obvious, but where is pointer metadata stored? For instance if I have a 32-bit int pointer ptr and I execute ptr++ it knows to advance 4 bytes in memory. However, if I have a 64-bit int pointer it knows to advance 8 bytes. So who keeps track of what type of pointer ptr is and where is it stored? For simplicity you can limit this to C++.
It isn't stored anywhere, per-se. The compiler looks at the type of the ptr and turns the ++ operation into an increment of the correct number of bytes.
In the symbol table while the compiler runs. Nowhere while your program runs, or rather it is implicit in the lower level code produced by the compiler.
It's not stored anywhere, it's determined at compile time. In fact, take this code as an example:
int *abc = NULL;
cout << abc + 1; /* Prints sizeof(int) */
cout << (void *)((char *)abc + 1); /* Prints 1. Casting it back to void * is necessary,
otherwise it will try to dereference it and print as a string. */