修改栈上的返回地址 [英] Modify return address on stack

查看:34
本文介绍了修改栈上的返回地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我查看了缓冲区溢出漏洞的基础知识,并试图了解堆栈是如何工作的.为此,我想编写一个简单的程序,将返回地址的地址更改为某个值.谁能帮我弄清楚基指针的大小以获取第一个参数的偏移量?

I looked at the basics of buffer overflow vulnerabilities and tried to understand how the stack is working. For that I wanted to write a simple program which changes the address of the return address to some value. Can anybody help me with figuring out the size of the base pointer to get the offset from the first argument?

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 帧段的相关部分应如下所示:

The relevant part of the foo frame segment should look like this:

[char ret] [基指针] [返回地址]

[char ret] [base pointer] [return address]

我有第一个的位置,它的大小只有 1 个字节.是否距离基指针仅 1 个字节或 http://insecure.org/stf/smashstack.html?以及如何知道基指针的大小?

I have the position of the first one which is only 1 byte in size. Is it only 1 byte further to the base pointer or the size of a word as mentioned in http://insecure.org/stf/smashstack.html? And how do I get to know the size of the base pointer?

推荐答案

你的基指针很可能只是一个指针,所以它的大小为 sizeof(int*).但是在变量 ret 和基指针之间还有另一个值.我会假设它的值是一个寄存器(eax?).如果您想要一个无限循环,这将导致类似以下内容:

Your basepointer is most likely just a pointer, so it has the size sizeof(int*). But there is also another value in between your variable ret and the base pointer. I would assume its value of a register (eax?). This would lead to something like the following, if you want an endless loop:

void foo(void)
{
    char ret;
    char *ptr;

    ptr = (char*)(&ret) + (sizeof(ret)  + 2*sizeof(int*)) ;
    *(int*)ptr -= 0x0c;
}

假设它具有指针大小(对于其他指令集可能会有所不同)而被修改的返回目标.通过递减它,返回目标被设置为 foo 的调用点之前的一个点.

The return target which is modified assuming it has the size of a pointer (could differ for other instruction sets). By decrementing it, the return target is set to a point before the calling point of foo.

这篇关于修改栈上的返回地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆