現在、この関数を使用するターゲット プログラムを悪用するシェルコードを作成していputs
ます。プログラムは次のようになります。
#include <stdio.h>
main() {
char buf[123];
puts(gets(buf));
}
私がやりたいことは、このバッファをオーバーフローさせexecve
、いくつかの引数で呼び出すことです。execve
いくつかの引数を指定して呼び出すことができる c/inline アセンブリで記述されたテスト プログラムがありgdb
、このプログラムからシェルコードを取得するために使用します。私の理解では、スタック レイアウトは次のようになります。
|------buffer(+padding)---------|---------sfp--------|-------戻る-------------|
gcc によって生成されたターゲット プログラムのアセンブリ コードの一部を見ると、次のようになります。
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
addq $-128, %rsp
leaq -128(%rbp), %rax
movq %rax, %rdi
call gets
movq %rax, %rdi
call puts
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
バッファとパディングは128バイト、sfp と戻りアドレスはそれぞれ8バイトかかるので、合計で144バイトになると思います。これに基づいて、私の nop sled 、ペイロード、および新しい戻りアドレス (バッファーのアドレスに等しい) を組み合わせた (つまり、私のシェルコード) も144バイトになるはずです。たとえば、ペイロードが 36 バイトの場合、戻りアドレスが 8 バイトを占めるため、nop スレッドは 100 バイトになります。しかし、私がそのようにしたとき、それはうまくいきませんでした。スタック レイアウトの理解の仕方が間違っていたのではないかと思います。違いますか?
私の場合、バッファアドレスがわかっていることに注意してexecstack
くださいsetarch
。したがって、戻りアドレスがバッファーのアドレスによって上書きされた場合、そのバッファーに書き込まれたコードが実行されます。
そして、私はx86 64ビットマシンで作業しています。
スタック レイアウトに関する私の理解が正しければ、シェルコードに関する詳細情報を掲載します。