スタックに置く必要がある文字列は次のとおりです。
//bin/sh + '\0'(null terminator) + alignment(3 additional null characters) - gives 3 DWORDs (12 bytes)
そのためには、一連の命令を適切な順序で実行する必要があります。
xor eax, eax ;zero out full 32 bits of eax register
push eax ;0x00000000
push 0x68732f6e ;hs/n
push 0x69622f2f ;ib//
なぜそのような順序で?
スタックの性質のため。要素は、後で適切に読み取られるように、逆の順序で挿入する必要があります。スタックは、先入れ後出し(FILO) 順序 (ヒープとは逆)を持つデータ構造です。これは、スタックに最初に入れられたアイテムが最後にスタックから出てくることを意味します。スタックのサイズが変化するにつれて、スタックはメモリ アドレスの下位に向かって上向きに成長します。
memory
.---------------.-- 00 <-- top / low addresses
| . | x+1
| /|\ | x+2
| | | .
| stack | .
|grows up toward| .
|lower addresses| x+n
'---------------'-- FF <-- bottom / high addresses
0x68732f6e (hs/n)
では、次の 2 つのダブル ワードについてはどう0x69622f2f (ib//)
でしょうか。それらはどのように関連してい//bin/sh
ますか?
見ると0x68732f6e
、実際にメモリに格納されているバイトごとに表示されたバイト反転効果、4 バイト: を見ることができます0x6e 0x2f 0x73 0x68 (n/sh)
。これはIA-32アーキテクチャー固有のエンディアンに関連しており、手動でバイトをスタックに入れる際に考慮する必要があります。x86 プロセッサでは、値はリトル エンディアン(SPARC プロセッサのビッグ エンディアンとは逆) のバイト順で格納されます。つまり、最下位バイトが最初に格納されます (リトル エンドが最初に格納されます)。
byte3 byte2 byte1 byte0
次のようにメモリに配置されます。
base address+0 byte0
base address+1 byte1
base address+2 byte2
base address+3 byte3
最後に、メモリ空間がどのように満たされるかを視覚化するために、以下を見てください。
.--------- push eax ;0x00000000
| .----- push 0x68732f6e ;hs/n bytes reversed
| | .- push 0x69622f2f ;ib// bytes reversed
| | |
| | | register
| | '> |69|62|2f|2f| (ib//) memory
| | | | | | ..
| | | | | '-------> x: 2f '/'
| | | | '----------> x+1: 2f '/'
| | | '-------------> x+2: 62 'b'
| | '----------------> x+3: 69 'i'
| | little endian
| |
| '----> |68|73|2f|6e| (hs/n)
| | | | |
| | | | '-------> x+4: 6e 'n'
| | | '----------> x+5: 2f '/'
| | '-------------> x+6: 73 's'
| '----------------> x+7: 68 'h'
|
'--------> |00|00|00|00| (\0\0\0\0)
| | | |
| | | '-------> x+8: 00 '\0'
| | '----------> x+9: 00 '\0'
| '-------------> x+10: 00 '\0'
'----------------> x+11: 00 '\0'
..
gdbを使用して調べることができます:
(gdb) x/12b $sp
0xbfb530b0: 0x2f 0x2f 0x62 0x69 0x6e 0x2f 0x73 0x68
0xbfb530b8: 0x00 0x00 0x00 0x00
(gdb) x/12c $sp
0xbfb530b0: 47 '/' 47 '/' 98 'b' 105 'i' 110 'n' 47 '/' 115 's' 104 'h'
0xbfb530b8: 0 '\0' 0 '\0' 0 '\0' 0 '\0'
(gdb) x/3w $sp
0xbfb530b0: 0x69622f2f 0x68732f6e 0x00000000