Clan x86

Technical (Development, Security, etc.) => General Programming => Topic started by: mynameistmp on November 12, 2005, 05:13:58 pm

Title: Help with C pointers
Post by: mynameistmp on November 12, 2005, 05:13:58 pm
I found this brief piece of code that I don't really understand. Obviously there is some major concept that I am missing. I was hoping someone here could explain it a little bit. This guy stores shellcode in a char array then executes the shellcode. If you run the program it works, but I don't understand why. Here is the code:

Code: [Select]
char shellcode[] = "blahblah";

int main()
{
      int *ret;
      ret = (int *)&ret + 2;
      (*ret) = (int)shellcode;
}

I don't really understand how that results in the shellcode being executed. Thanks in advance.


   

Title: Re: Help with C pointers
Post by: iago on November 12, 2005, 05:21:20 pm
Heya, no problem!  The trick is that he's writing to a memory address on the stack (the return address), obviously.  I'll explain how he manages to do that:

Code: [Select]
char shellcode[] = "blahblah";

int main()
{
      /* Declare a variable on the stack. */
      int *ret;

      /* &ret is the address of the variable ret, which is a stack location.  It's incremented by 2*sizeof(int) (pointers
       * always increment by sizeof(datatype)).  &ret+1 would be the saved frame pointer, and +2 would be the
       * saved return address.  Don't forget that the stack grows downward, so you increment to move back on
       * it.  Assign the location of the saved return address to ret. */
      ret = (int *)&ret + 2;

      /* Set the memory pointed to by ret (which happens to be the return address) to the shellcode. */
      (*ret) = (int)shellcode;

      /* When the function returns, it pops off the saved ebp, which wasn't modified.  Then it pops off the return
       * address, writing it to EIP.  Since the return address now points to the shellcode string, the shellcode is
       * executed. */
      return;
}

Title: Re: Help with C pointers
Post by: mynameistmp on November 12, 2005, 06:00:39 pm
Ah. He's using the integer variable ret as a reference to find ret on the stack, then using the integer variable again as a vector for overwriting it. Thanks.
Title: Re: Help with C pointers
Post by: iago on November 12, 2005, 06:58:53 pm
Correct.  I was going to point out that he's using it for different things, but I figured you'd catch on :)
Title: Re: Help with C pointers
Post by: MyndFyre on November 13, 2005, 02:58:25 am
There might be one other thing that is confusing that I wanted to point out.  It deals with these two lines:
Code: [Select]
char shellcode[] = "blahblah";

      (*ret) = (int)shellcode;
I just wanted to remind everyone the type of shellcode is actually char*, and so when you cast it to an int, you're not losing any data.  If the value of shellcode is a pointer to the memory location 0x50348520, then cast as an int it will be 0x50348520.  Since we're assigning to a dereferenced int*, the value needs to be cast as a value and not just a pointer.  If you forgot to dereference it, you'd probably end up with "blah" in the return address, which would likely crash you.  :)  Otherwise you'd get a compile-time error.
Title: Re: Help with C pointers
Post by: mynameistmp on November 17, 2005, 03:21:58 am
Quote
Since we're assigning to a dereferenced int*, the value needs to be cast as a value and not just a pointer.  If you forgot to dereference it, you'd probably end up with "blah" in the return address, which would likely crash you. 

Hmmm... you don't need to cast at all if you don't want.

Code: [Select]
      (*ret) = shellcode;

That works just fine. And if you didn't dereference it you'd just wind up having ret point to shellcode[0].