1

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.

c00l
  • 60
  • 1
  • 6
  • What is buffer? – Devolus Feb 09 '21 at 09:50
  • What is the type of `buffer`? – Ori David Feb 09 '21 at 09:50
  • This requires too much guessing. Please provide more context, maybe in the shape of a [mre]. – Yunnosch Feb 09 '21 at 09:51
  • That code assumes `sizeof(unsigned int)` is `4`. C doesn't guarantee that, and it's not always the case. (It's not the case in Windows.) – ikegami Feb 09 '21 at 09:55
  • That code assumes the address of buffer is suitably aligned for an `unsigned int`. I wonder if that's really the case. It will still work on x86 and x64 even if it isn't, although slower. It will outright fail on other machines. – ikegami Feb 09 '21 at 09:57
  • In short, you're asking us to explain bad code to you. Explainining how it works would be litered with caveats. It's a waste of energy. – ikegami Feb 09 '21 at 09:59
  • Why you have closed the question? Doesn't require so much guess, it use the variable `buffer` incremented by its type related step and use the result as a pointer to `unsigned int` to retrieve data from memory. All other clarification are not due. This is perfectly legal code, the user surely got it from existing, we can't say that this is good or bad, we have just to explain what it can do when used, and **eventually** ask more details to give more details on how it's working. – Frankie_C Feb 09 '21 at 10:00
  • Actually I didn't close the question stack overflow did. I already edited the question. Please help me. – c00l Feb 09 '21 at 10:03
  • The sample code casts the address obtained from the expression `buffer+1` to a pointer to `unsigned int` and then dereference the address and assign the `unsigned int` obtained to the variable `ret`. Perfectly legal if `buffer` is a pointer of any type, or an array name. – Frankie_C Feb 09 '21 at 10:08
  • What the programmer want to do and why she/he needed to read memory as `unsigned int` isn't important, and we don't even should require, the question is about what the code due, not what was the programming job, as we don't have to write the code. – Frankie_C Feb 09 '21 at 10:12
  • `buffer` is a char*, `i` is an int, thus `buffer+i` is a char*. This result then cast to `unsigned int *`, thus the final type of `buffer+i` is `unsigned int *` before the `*(...)` is applied. Then the `*(...) = ret` of that means assign the *unsigned int* at this *buffer+i* address to `ret`. That address being `buffer + i*sizeof(char)`, since buffer is a `char *`. – Déjà vu Feb 09 '21 at 10:12
  • *What does this syntax `*((unsigned int *)(buffer+i))` mean in C* It means ["strict aliasing violation"](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and undefined behavior. – Andrew Henle Feb 09 '21 at 10:19

2 Answers2

3

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.

Frankie_C
  • 4,764
  • 1
  • 13
  • 30
1

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.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115