This is a small finding I found while I was experimenting on pointers in C. Usually in C the arithmetic on pointers depend on the size of the data types. If we initialize a int variable, the compiler will allocate 4 bytes in memory since its 32 bits. I assume you are well aware of these basics in C ๐ I wanted to store data inside the empty addresses allocated by int data type. This is a bit challenging in a high level programming language. Of course using inline assembly I could have achieved this. But I wanted to achieve this using native C operators.
To understand this letโs begin from a simple approach.
1 2 3 4 5 6 7 8 9 10 |
#include <stdio.h> int main() { unsigned int var = 100; unsigned int var2 = 200; printf("%u\n",var); printf("%u\n",var2); } |
As you can see from the above image 100 in hex is stored in the stack at 0x28FEA8 and 200 is stored at 0x28FEAC. All these address are multiples of 4 because the last 2 bits are 00.
How can we store values at 0x28FEA9, 0x28FEAA, 0x28FEAB which contains 0s in the stack ?
Basically we are trying to store values inside a int variable which is supposed to be 32 bits.
There can be many possible ways of doing this. One of easiest way I found was using a char pointer. Because the compiler treats the char data type as 1 byte. So arithmetic is by 1 address.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <stdio.h> // https://osandamalith.com int main() { unsigned int var = 100; printf("Value of var : %u\n",var); printf("Address of var: %p\n\n",&var); unsigned char *ptr = (unsigned char *) &var; *(ptr + 1) = '\x41'; *(ptr + 2) = 0x42; *(ptr + 3) = 255; printf("Address: %p Value: %u\n", ptr, *ptr); printf("Address: %p Value: %c\n", (ptr + 1), *(ptr + 1)); printf("Address: %p Value: %c\n", (ptr + 2), *(ptr + 2)); printf("Address: %p Value: %u\n", (ptr + 3), *(ptr + 3)); printf("\nvar contains: %X",var); } |
We first initialize a int value and then assign itโs address to a char pointer by typecasting. Next we assign the values to the memory locations. Note that we are storing 8bit values, the maximum number will be 255 for each byte. In the end when we print the value of var you can clearly see that we have written the data filling 32 bits. We can hide 3 bytes of data in a int value containing a 8-bit value.
Another approach is by using logic gates for setting and unsetting bits. I have written this example using OR and AND gates for setting and unsetting the bits one by one and assigning data. I was able to reproduce the above output using this approach too. I have initialized a dummy variable to 0 to stop crashing the application. I donโt know for some reason my compiler stores the return address from msvcrt.753C9AB1 in EAX and pushes on the stack for the printf function. But still the program would write data inside the address, but will crash at printing. So to overcome that issues I used a dummy variable. All these examples were tested in a GNU GCC compiler under Windows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#include <stdio.h> int main() { // https://osandamalith.com unsigned int var = 100; unsigned int ptr = &var; printf("Value of var : %u\n",var); printf("Address of var: %p\n\n",ptr); ptr |= 1; // var + 1 printf("Address of var+1: %p\n\n", ptr); unsigned int *temp = ptr; // assign the address of var to a temp ptr *temp = '\x41'; printf("Address: %p Value: %c\n",temp,*temp); ptr &=~ 1; ptr |= 2; temp = ptr; *temp = 0x42; printf("Address: %p Value: %c\n",temp,*temp); ptr &=~ 2; ptr |= 3; temp = ptr; *temp = 255; printf("Address: %p Value: %u\n\n",temp,*temp); printf("var contains: %X",var); int i = 0; // To avoid writting RETURN from msvcrt.753C9AB1 to EAX } |
It was fun experimenting on pointers ๐ Even though this is not indented to be performed manipulating addresses at a high level is a fun hack ๐
nice thought !
I want to chop my porn videos into 3 bytes pieces ๐
Your article reminded me of the concept of codecaves. But your article takes this concept to an extreme, so congratulations!
For those who do not know what codecaves are, let me explain.
Codecaves are large areas filled with zeros inside files, mainly executables. Since executables have to align their sections within address boundaries, nearly all sections need padding with zeros. The padding creates codecaves.
Codecaves can be used to include code. Not necessarily to hide code, that’s why I used the word “include”.
For example, a company might own an executable program and this company might need to modify it, but the company might have lost the source code.
So they hire a cracker to put the extra functionality in a codecave and change a part of the program to redirect to the codecave. And after the codecave code finishes, it can redirect back to the program.
This way, the executable contains the old program and the new patch. The new patch is inside one of the codecaves of the executable program.
Thanks a lot for the very informative feedback on codecaves ๐
bro . i just fall on love with your article . keep great working
Its looks like binary level injection, like it ! Keep it up ๐