2013-05-18 7 views
11

リンクhttp://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html は、execveシェルコードを書く方法を強調しています。Cプログラムのシェルコード

#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(); 
} 

int (*ret)() = (int(*)())code;は何をしますか?

+2

[CDECL](http://cdecl.org /)は言っています:intを返す関数へのポインタにコードをキャスト –

+0

コードの前に* afterとint(*)()を理解できません。 – Karan

+1

このような構造を頭の中で解析できるようにするには、時計回り/渦巻き規則を実行してください:http://c-faq.com/decl/spiral.anderson.html – jwaliszko

答えて

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

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
       3 
  1. ではありませんを持つ関数へのポインタとしてretを定義しますパラメータ()を返し、intを返します。したがって、()は、関数のパラメータの定義を示します。

  2. は、パラメータ()を持たない関数へのポインタにキャストし、intを返します。

  3. キャストcodeを機能として割り当て、retに割り当てます。その後、ret();に電話することができます。

 

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

は進値で表されるマシン命令のシーケンスです。それは関数としてコードに注入されます。

+1

+1すてきな説明と良い質問 –

+0

ret()が呼び出されたときに、コードが実際に "実行"されていることがわかりました。私は見たことがないので、シェルコードを "ロード"して実行します。 – Karan

+0

@ user85030、はい、 "load"は 'ret()'、googleは "ポインタを関数"と呼びます –

0

int行は、code []配列を指すことによってret()関数を宣言します。換言すれば、関数はコード[]バイナリ命令にマップされる。

\ x構造体は、文字列に16進文字を埋め込む安全な方法です。あなたは、インスタンスのために置き換えることができ、「\ X31」「1」の文字コードとして「1」によっては、49、または16進数の31

+0

私はコードの前に* retとint(*)()を理解していません。 – Karan

+0

'ret'は未定義の引数('() ')を持つ関数への関数ポインタ(https://en.wikipedia.org/wiki/Function_pointer)で、' int'を返します。'(int(*)())'関数のアドレスを、定義されていない数の引数を取るfuntion-pointerアドレスに従ってキャストしています。つまり、 'ret'が宣言されています。 – Jack

+0

この関数のポインタ部分を簡単な形式で書き直すことはできますか? – Karan

0

この関数のポインタ部分を簡単な形式で書き直すことはできますか?

私はあなたが、これは単純だと思うならば知っているが、そうでないかもしれないん

#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(); 
} 
0
(*(void(*)())shellcode)() 

==

p = (void(*)()) shellcode; 
    (*p)();