2012-01-03 12 views
-1

私はシェルコードを学習しようとしていて、私のUbuntuボックスでセグメンテーションフォールトを取得し続けています。私はそれをexeにすると、私のCコードにセグメンテーションフォールトを続ける

/*shellcodetest.c*/ 
char code[]="\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01"\ 
     "\x59\xb2\x05\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8"\ 
     "\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f\xe8\xd8\xff\xff\xff"\ 
     "\x68\x65\x6c\x6c\x6f\xe8\xce\xff\xff\xff\x68\x65\x6c\x6c"\ 
     "\x6f\xe8\xc4\xff\xff\xff\x68\x65\x6c\x6c\x6f\xe8\xba\xff"\ 
     "\xff\xff\x68\x65\x6c\x6c\x6f"; 
int main(int argc, char **argv) 
{ 
    int (*func)(); 
    func = (int (*)()) code; 
    (int)(*func)(); 
} 

これがなぜ失敗するのかわかりません。私はおそらくヌルポインタを考えていた。 あなたは私がそれに続くことができるという考えがあれば素晴らしいだろう。

+1

どうしますか?つまり、分解などを見せることができますか? –

+1

あなたがむしろ尋ねるべき質問は、なぜ、どのように動作すべきかということです。 – nos

+2

シェルコードは正しいですか? –

答えて

3

OK、あなたのコードを今すぐ調べることができます。

char code[]="\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01"\ 

上の行はcodeと呼ばれるグローバル文字配列を作成し、六角の束で初期化されています。 char[]のメモリはdata-segmentに割り当てられます。

int (*func)(); 

上の行には、引数を取らず、intを返しpointer-to-a-functionを宣言します。このため、メモリは、stackに配置されるが、この変数は、上記線はcodeglobal-character-array)をキャストし、それを指すようにfuncpointer-to-a-function)を作るcode

func = (int (*)()) code; 

を記憶する記憶場所をポイントするように期待されています! code-segmentを指すと考えられる変数stackが今度はdata-segmentを指し示すため、このアクションは未定義の動作です。

割り当てが成功した場合(奇跡のためかもしれません)、次の行でそれらを参照解除することは間違いなく動作するとは思われません!

変数がheapstackcodeセグメントに割り当てられている方法の詳細については、あなたが直接定義することができthis

+0

私は何をしているのか知るためにCコードを学ぶべきですか? –

+1

@DennisHaydenはいサー! –

+0

実際には、シェルコードはデータセグメントではなく、スタックに割り当てられます。ポインタは単にポインタを割り当てるだけなので、割り当ては常に有効です。 –

2

このプログラムでは、定義されていない動作が発生するため、標準では何かが起こります。セグメンテーションフォルトは、このようなプログラムでは完全に受け入れられる結果です。

+0

私は「受け入れ可能な結果」は、それを修正する方法を尋ねているので、間違った言葉だと思います。多分 "期待できる結果" –

1

をご参照ください:

int (*func)() = (int (*)()) "\xeb\x19\x31\xc0..." 

し、それがうまくいきます。

まだ未定義の動作です。

1

答えはありませんが参考になる場合があります。私は64ビットUbuntuで逆アセンブルしています。 32ビットでは、それは異なるでしょう。

(gdb) disassemble /mr func,0x60108A 
Dump of assembler code from 0x601040 to 0x60108a: 
0x0000000000601040 <code+0>:  eb 19 jmp 0x60105b <code+27> 
0x0000000000601042 <code+2>:  31 c0 xor %eax,%eax 
0x0000000000601044 <code+4>:  31 db xor %ebx,%ebx 
0x0000000000601046 <code+6>:  31 d2 xor %edx,%edx 
0x0000000000601048 <code+8>:  31 c9 xor %ecx,%ecx 
0x000000000060104a <code+10>: b0 04 mov $0x4,%al 
0x000000000060104c <code+12>: b3 01 mov $0x1,%bl 
0x000000000060104e <code+14>: 59 pop %rcx 
0x000000000060104f <code+15>: b2 05 mov $0x5,%dl 
0x0000000000601051 <code+17>: cd 80 int $0x80 
0x0000000000601053 <code+19>: 31 c0 xor %eax,%eax 
0x0000000000601055 <code+21>: b0 01 mov $0x1,%al 
0x0000000000601057 <code+23>: 31 db xor %ebx,%ebx 
0x0000000000601059 <code+25>: cd 80 int $0x80 
0x000000000060105b <code+27>: e8 e2 ff ff ff callq 0x601042 <code+2> 
0x0000000000601060 <code+32>: 68 65 6c 6c 6f pushq $0x6f6c6c65 
0x0000000000601065 <code+37>: e8 d8 ff ff ff callq 0x601042 <code+2> 
0x000000000060106a <code+42>: 68 65 6c 6c 6f pushq $0x6f6c6c65 
0x000000000060106f <code+47>: e8 ce ff ff ff callq 0x601042 <code+2> 
0x0000000000601074 <code+52>: 68 65 6c 6c 6f pushq $0x6f6c6c65 
0x0000000000601079 <code+57>: e8 c4 ff ff ff callq 0x601042 <code+2> 
0x000000000060107e <code+62>: 68 65 6c 6c 6f pushq $0x6f6c6c65 
0x0000000000601083 <code+67>: e8 ba ff ff ff callq 0x601042 <code+2> 
0x0000000000601088 <code+72>: 68 65 6c 6c 6f pushq $0x6f6c6c65 

それは非常に最初の行にSIGSEGVで失敗します。

(gdb) display /3i $pc 
1: x/3i $pc 
=> 0x601040 <code>: jmp 0x60105b <code+27> 
0x601042 <code+2>: xor %eax,%eax 
0x601044 <code+4>: xor %ebx,%ebx 

それはデータセグメントにあるため、ジャンプの失敗もいいですか?

関連する問題