Author Topic: Help with C pointers  (Read 5093 times)

0 Members and 2 Guests are viewing this topic.

Offline mynameistmp

  • Full Member
  • ***
  • Posts: 111
  • Hi! I'm new here!
    • View Profile
Help with C pointers
« 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.


   


Offline iago

  • Leader
  • Administrator
  • Hero Member
  • *****
  • Posts: 17914
  • Fnord.
    • View Profile
    • SkullSecurity
Re: Help with C pointers
« Reply #1 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;
}


Offline mynameistmp

  • Full Member
  • ***
  • Posts: 111
  • Hi! I'm new here!
    • View Profile
Re: Help with C pointers
« Reply #2 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.

Offline iago

  • Leader
  • Administrator
  • Hero Member
  • *****
  • Posts: 17914
  • Fnord.
    • View Profile
    • SkullSecurity
Re: Help with C pointers
« Reply #3 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 :)

Offline MyndFyre

  • Boticulator Extraordinaire
  • x86
  • Hero Member
  • *****
  • Posts: 4540
  • The wait is over.
    • View Profile
    • JinxBot :: the evolution in boticulation
Re: Help with C pointers
« Reply #4 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.
I have a programming folder, and I have nothing of value there

Running with Code has a new home!

Our species really annoys me.

Offline mynameistmp

  • Full Member
  • ***
  • Posts: 111
  • Hi! I'm new here!
    • View Profile
Re: Help with C pointers
« Reply #5 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].