0
    jmp    0x2a                     # 3 bytes
    popl   %esi                     # 1 byte
    movl   %esi,0x8(%esi)           # 3 bytes
    movb   $0x0,0x7(%esi)           # 4 bytes
    movl   $0x0,0xc(%esi)           # 7 bytes
    movl   $0xb,%eax                # 5 bytes
    movl   %esi,%ebx                # 2 bytes
    leal   0x8(%esi),%ecx           # 3 bytes
    leal   0xc(%esi),%edx           # 3 bytes
    int    $0x80                    # 2 bytes
    movl   $0x1, %eax               # 5 bytes
    movl   $0x0, %ebx               # 5 bytes
    int    $0x80                    # 2 bytes
    call   -0x2f                    # 5 bytes
    .string \"/bin/sh\"             # 8 bytes

したがって、ジャンプして呼び出し、「文字列アドレスはリターンアドレスとしてスタックにプッシュされます」。このアドレスがesiに保存されているのはなぜpopesiですか?

4

2 に答える 2

1

これは、位置に依存しないコード(どのアドレスにあるかに関係なく正常に実行できるコード)を記述する一般的な方法です。

call命令は2つのことを行います:

  1. リターンアドレス(呼び出し直後の命令のアドレス)をスタックにプッシュします
  2. 指定したアドレスにジャンプします。

したがって、呼び出し後、文字列 "/ bin/sh"のアドレスがスタックにあります。次の命令、pop esiは、そのアドレスをスタックから取り出してesiレジスタに入れ、使用できるようにします。

于 2012-08-06T23:07:24.860 に答える
0

さて、callが実行されると、リターンアドレス(呼び出しオペコードの後のアドレス)がスタックにプッシュされるため、ret(通常の操作で)検出されると、実行は中断したところから続行されます。これは、標準のx86呼び出し規約です。

コードでは、プッシュされるリターンアドレスは「/ bin/sh」の場所です。その値をesiレジスタに入れます。このレジスタはポインタとして使用され、Linuxシステム上にあるsyscallにpop %esi渡され、文字列で指定されたコマンドが実行されます。0xbexecve

x86の呼び出し規約には多くの優れたリソースがありますが、その中でlinuxx86が特に興味深いと思います。

于 2012-08-06T23:10:31.830 に答える