我查看了緩衝區溢出漏洞的基礎知識,並試圖瞭解堆棧如何工作。爲此,我想編寫一個簡單的程序,將返回地址的地址更改爲某個值。任何人都可以幫助我計算出基指針的大小以獲得第一個參數的偏移量嗎?修改堆棧上的返回地址
void foo(void)
{
char ret;
char *ptr;
ptr = &ret; //add some offset value here
*ptr = 0x00;
}
int main(int argc, char **argv)
{
foo();
return 1;
}
生成的彙編程序代碼如下所示:
.file "test.c"
.text
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq -9(%rbp), %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax
movb $0, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
call foo
movl $1, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (GNU) 4.7.1 20120721 (prerelease)"
.section .note.GNU-stack,"",@progbits
foo的幀段的相關部分應該是這樣的:
[炭RET] [基指針] [返回地址]
我有第一個只有1個字節大小的位置。如http://insecure.org/stf/smashstack.html中所提到的,它是否僅比基址指針或單字的大小還要多1個字節?我怎樣才能知道基指針的大小?
+1重新編譯總是可以移動變量。只是在OP的測試中,在這種特殊情況下,返回地址是'&ret + 17',只要該函數中的局部變量沒有改變,該地址不太可能改變。 – ughoavgfhw
抵消了17件作品。你能解釋一下你是如何確定的嗎? – fliX
@fliX在彙編中,指令'leaq -9(%rbp),%rax'正在堆棧中獲取一個地址。由於它是字節對齊的,並且唯一的地址計算必須在'ret'的地方。以9爲前一個64位基址指針加8,就得到了17。 – ughoavgfhw