[Help][Pointers]

Posts 16–27 of 27 · Page 2 of 2
ILTClient holds a value itself. In this case it's 0x377ED910, initializing it as a pointer means you can use the reference operator to either change the contents of the address it's holding or simply read it.

Let's assume that the value of the first 4 bytes at 0x377ED910 equal to 1.
Let's also assume that it's possible to read what ever is at the address 0x00000001, let's give it the value 10.

ILTClient = 0x377ED910
*ILTClient = 1
**ILTClient = 10

Why is much better at this... \:
@ Kallisti: Im completely a rookie at programming. I just go off internet tutorials. The fact is they do not show examples like these. So I need to ask for help. But I do agree, I will be revisiting tutorials on pointers.

@why06- I'd like to thank you for helping me with this entire process. I have learned so much it's increadiable. This example really helped.

Overall- I'd like to thank all of you.

@Void- Thank you for the information, and your time for that matter as you've helped me alot as well.

Other then this. I have no more questions other then the Memora ones which were the last two. If someone gets a chance one day it would be great, as the weekend is coming up and I can go over them. Thank you all.
*
**
***
****
*****
****
***
**
*

So many asteriks shet!
Let's turn it into int just to make it more clear for you:

int a;
Normal int, nothing special.

int *b = &a;
b is a pointer, it points to a. so the value of b is the address of a, while *b gives the value of what is pointed to, thus the value of a.

int **c = &b;
c is a pointer to a pointer, so the value of c is the address of b, *c will give you the value of what c points to, which means it gives you the value of b, which is the address of a(does that make sense, if not ill try to rephrase it), so if you want the value of a from c, you'd have to add another star so it looks like **c, which means gimme the value of the object of the pointer i'm pointing to points to(that sounds so messed up >.<)


so:

c -> b -> a
a = 5;
b = &a;
*b = a = 5;
c = &b;
*c = b = &a;
**c = *b = a = 5;
Quote Originally Posted by Aqollo View Post
I'm still stumped ;l

Code:
cILTClient *ILTClient;

ILTClient = *(cILTClient**)0x377ED910
What are the two levels of "indirection" here, this is what I'm not getting clear. Is it that..

You had already mentioned how ILTClient** itself is 0x377ED910 I remember that...

So the two astrieks mean:
initally the address 0x377.. is ILTClient** but the value it holds points to ILTClient* which points to cILTClient?
Okay, ima have a shot too. Do tell us who's explanation you liked best xD

Let's invent a hypothetical LTClient class:

[php]class LTClient
{
bool GetGameStatus();
int RunConsoleCommand(char *szCommand);
}[/php]

Now, in game, let's say I have a function that takes the LTClient as a parameter. I do not want to use a new LTClient, but whatever I do I want to modify the current LTClient. To do this, I use a pointer, which points to the real LTClient, rather than a copy of it.

[php]
void UpdatePlayerPositions(LTClient * client)
{
client->RunConsoleCommand("whatever");

}
[/php]

At this point, we might get the address of the POINTER that tells us (points) where the real LTClient is. Because we've made a hack, we cannot directly access that pointer, and we do not know the address of the original LTClient.

Therefore, we have to create a pointer to that pointer which will then tell us where the real LTClient is.

LTClient** = points to the LTClient* that we know, which points to the LTClient whose address we do not know.

That's why we need 2 levels of indirection. The first level is due to the game, the second is because we need to access something that we don't have direct access to.
Quote Originally Posted by freedompeace View Post
At this point, we might get the address of the POINTER that tells us (points) where the real LTClient is. Because we've made a hack, we cannot directly access that pointer, and we do not know the address of the original LTClient.

Therefore, we have to create a pointer to that pointer which will then tell us where the real LTClient is.

LTClient** = points to the LTClient* that we know, which points to the LTClient whose address we do not know.

That's why we need 2 levels of indirection. The first level is due to the game, the second is because we need to access something that we don't have direct access to.
We can actually ;P remember that the argument passed to the function is a pointer to the original LTClient, and since the value of a pointer is the address pointed to, you could just do something along the lines of "LTClient *pClient = client;"
then pClient will point to the same thing as client does, thus having a direct pointer to the original LTClient instead of a pointer to a pointer.

The only reason you might need a pointer to a pointer is if the pointer to the object itself changes as well, this may happen if the pointer is stored in a class, and that class itself gets a new location thus changing the address of the pointer.
Basically every variable is a pointer
excellent freedom and HD!
And SCHIM, while everything can be pointed to not every variable is a pointer. From an ASM point of view all variables are the same, just memory addresses storing values, It's their function or high level behavior that defines them.
Quote Originally Posted by why06 View Post
excellent freedom and HD!
And SCHIM, while everything can be pointed to not every variable is a pointer. From an ASM point of view all variables are the same, just memory addresses storing values, It's their function or high level behavior that defines them.
That was exactly what I was referring to.
But if you name a variable in asm: schim dd 0
schim is just a symbol used by the programmer to reference to a certain address in memory, and thus a pointer right?
K last but not least you asked me to explain this:
Code:
bool Memoria( void * pDest, char * szPatch, size_t sSize ) //Nopping Method
Memoria is just a fancy way to use memcpy( pDest, szPatch, sSize );
memcpy essentially will copy a string to a destination. And repeat that string to fill to the size specified.


pDest is the address you want write over.
szPatch is a char* or string, but it is important to understand that a c-string is the same thing as a byte array, So what usually is put here are opcodes, which are one byte inside.
sSize is the number of bytes you want to overwrite with your opcodes you provided in szPatch.

Using this function is a piece of cake. Using it effectively is a different story. You can patch anything with this, but it is primarily used for code hence the PAGE_EXECUTE_READWRITE you see being passed to VirtualProtect.
As usual more questions besides the ones I sent 2 u in a pm,


Quote Originally Posted by why06 View Post
Memoria is just a fancy way to use memcpy( pDest, szPatch, sSize );
memcpy essentially will copy a string to a destination. And repeat that string to fill to the size specified.
Just out of curiosity why do we need to fill a size specified by repeating a string?

Also just another question,
I'm seeing
Code:
bool Memoria( void * pDest, char * szPatch, size_t sSize ) //Nopping Method
and
Code:
memcpy( pDest, szPatch, sSize );
taking the same paramaters just about but why is Memoria declaring SzPatch and pDest being declared as pointers to a void type( so pointing to something that takes no value or returns no value), and char type .. Also what is size_t for in Memoria.
Quote Originally Posted by Aqollo View Post
Just out of curiosity why do we need to fill a size specified by repeating a string?
You don't need to, that just the way memcpy works. It will fill as many bytes as you tell it to one way or another.

taking the same paramaters just about but why is Memoria declaring SzPatch and pDest being declared as pointers to a void type( so pointing to something that takes no value or returns no value), and char type .. Also what is size_t for in Memoria.
size_t is an int. YOu can follow its declaration in the Windows header file in VS.
szpatch is just the array of bytes you want to write at the destination.
Finally pDest is the address you want to write to. People use void* to point to memory regions of any type since they don't know what could be there. It eleminates some casting don't worry about what it is, just know that is a memory location that must be passed to Memoria.
Posts 16–27 of 27 · Page 2 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us