16

In Demystifying the Execve Shellcode is explained a way to write an execve shellcode:

#include<stdio.h>
#include<string.h>

unsigned char code[] = 
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

main()
{

    printf("Shellcode Length: %d\n", strlen(code));

    int (*ret)() = (int(*)())code;

    ret();
}

What does the line int (*ret)() = (int(*)())code; do?

Nino Filiu
  • 16,660
  • 11
  • 54
  • 84
user720694
  • 2,035
  • 6
  • 35
  • 57
  • 2
    [cdecl](http://cdecl.org/) says: cast code into pointer to function returning int – David Ranieri May 18 '13 at 17:23
  • i don't understand the () after *ret and int(*)() before code. – user720694 May 18 '13 at 17:33
  • 1
    To be able to parse such constructions in the head, go through clockwise/spiral rule: http://c-faq.com/decl/spiral.anderson.html – jwaliszko May 18 '13 at 17:50
  • 1
    Btw: this approach is disabled by default on W^X OSes. Running `nop (0x90)` on an 64-bit OS X on a modern processor, `EXC_BAD_ACCESS` because the kernel won't run any code from .bss, .text or the heap because these areas refert o PAE/long mode page table entries with bit 63 set (NX). It might work on a non-PAE/non-long-mode OS without something like PAX/ExecShield in something ancient, like DOS. Writing to code areas also won't work (self-mutating over a bunch of C inline asm `nop`s). Better to make a program which spits out a minimal executable for the given platform(s) and run that. –  Sep 26 '15 at 00:30

4 Answers4

18
  int (*ret)() = (int(*)())code;
  ~~~~~~~~~~~~   ~~~~~~~~~~~~~~
        1              2

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               3
  1. It defines ret as a pointer to a function which has no parameter () and returns int. So, Those () indicates the definition of parameters of a function.

  2. It's for casting code to a pointer to a function which has no parameter () and returns int.

  3. Casts code as a function and assigns it to ret. After that you can call ret();.

 

unsigned char code[] =  "\x31\xc0\x50\x68\x6e\x2f\...

It is a sequence of machine instructions represented by hex values. It will be injected to the code as a function.

masoud
  • 55,379
  • 16
  • 141
  • 208
  • So, when ret() is called, how does the code actually "run", since i see do not seen C call that "loads" the shellcode and runs it? – user720694 May 18 '13 at 17:45
  • @user85030, yes, "load" is called in `ret()`, google for "pointer to function" – David Ranieri May 18 '13 at 17:47
  • The [link](http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html) you've provided is explaining it in 11 steps. That machine instruction sequence is doing everything as same as a call process needs. – masoud May 18 '13 at 17:49
  • Okay. So i read about function pointers and understood part 1). Can part 2) be written as (int* ())code instead of (int(*)())code? To rephrase my question, how is a variable casted into a function? (Since we have a function pointer on the left being assigned to the function on the right. – user720694 May 18 '13 at 18:56
  • You can not use `(int* ())` because it's not the way to declare pointer to function. Think about addresses, in C all objects have addresses, it just casts the address of `code` as the address of a function. – masoud May 18 '13 at 19:09
  • What does (star) in int(*)() signify? I understand that int is the return type and () means a function without any parameters. – user720694 May 18 '13 at 20:14
  • Just out of curiosity, can this function pointer part be avoided to get the same result? i.e. can it be re-written in a different form? – user720694 May 18 '13 at 20:40
  • In C++ there are many different ways, but in C this is common way (maybe the only way) – masoud May 19 '13 at 06:56
  • @MM. Thanks a lot for your help. Can you please have a look at http://stackoverflow.com/questions/16632639/re-writing-a-small-execve-shellcode ? – user720694 May 19 '13 at 08:14
2
    (*(void(*)())shellcode)()

==

    p = (void(*)()) shellcode;
    (*p)();
Jeremy
  • 21
  • 1
1

Can this function pointer part be re-written in a simpler form?

I don't know if you think this is simpler, but maybe:

#include <stdio.h>
#include <string.h>

unsigned char code[] = 
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

typedef int(*shellcode_t)();

int main(int argc, char ** argv) {
    printf("Shellcode Length: %ld\n", strlen(code));

    shellcode_t ret = (shellcode_t)code;

    ret();
}
Robert Larsen
  • 1,018
  • 2
  • 11
  • 18
0

The int line declares the ret() function, by pointing to the code[] array; in other words, the function is mapped to the code[] binary instructions.

The \x construct is a safe way to embed hexadecimal characters in a string. You could for instance replace “\x31” by “1” as the character code of “1” is 49, or hexadecimal 31.

Patrice Levesque
  • 2,079
  • 17
  • 16
  • i don't understand the () after *ret and int(*)() before code. – user720694 May 18 '13 at 17:17
  • `ret` is a function pointer(https://en.wikipedia.org/wiki/Function_pointer) to a function with an undefined number of arguments(`()`) that returns a `int`. `(int(*) () )` It's casting `code` function-address to make according to funtion-pointer address that take undefined number of arguments,that's how `ret` is declared. – Jack May 18 '13 at 17:35
  • Can this function pointer part be re-written in a simpler form? – user720694 May 18 '13 at 19:03