首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何执行放置在堆栈上的机器指令

如何执行放置在堆栈上的机器指令
EN

Stack Overflow用户
提问于 2015-10-20 21:19:24
回答 2查看 79关注 0票数 3

我在前一个堆栈帧中有一个返回值,它指向后续堆栈帧中的缓冲区。如何让放在缓冲区中的机器指令执行?

这有可能吗?根据我对堆栈的理解,这是无稽之谈。当然,因为堆栈是后进先出的结构。换句话说,一旦PC到达返回地址,缓冲器就已经被弹出。

有什么想法吗?

<test>函数(如下所示)调用<getbuf>函数(如下所示):

代码语言:javascript
复制
08048c53 <test>:
 8048c53:   55                      push   %ebp
 8048c54:   89 e5                   mov    %esp,%ebp
 8048c56:   83 ec 28                sub    $0x28,%esp
 8048c59:   e8 63 04 00 00          call   80490c1 <uniqueval>
 8048c5e:   89 45 f0                mov    %eax,-0x10(%ebp)
 8048c61:   e8 5f 00 00 00          call   8048cc5 <getbuf>
 8048c66:   89 45 f4                mov    %eax,-0xc(%ebp)
 8048c69:   e8 53 04 00 00          call   80490c1 <uniqueval>
 8048c6e:   8b 55 f0                mov    -0x10(%ebp),%edx
 8048c71:   39 d0                   cmp    %edx,%eax
 8048c73:   74 0e                   je     8048c83 <test+0x30>
 8048c75:   c7 04 24 f0 a3 04 08    movl   $0x804a3f0,(%esp)
 8048c7c:   e8 9f fc ff ff          call   8048920 <puts@plt>
 8048c81:   eb 40                   jmp    8048cc3 <test+0x70>
 8048c83:   8b 55 f4                mov    -0xc(%ebp),%edx
 8048c86:   a1 20 e1 04 08          mov    0x804e120,%eax
 8048c8b:   39 c2                   cmp    %eax,%edx
 8048c8d:   75 21                   jne    8048cb0 <test+0x5d>
 8048c8f:   8b 45 f4                mov    -0xc(%ebp),%eax
 8048c92:   89 44 24 04             mov    %eax,0x4(%esp)
 8048c96:   c7 04 24 19 a4 04 08    movl   $0x804a419,(%esp)
 8048c9d:   e8 ae fb ff ff          call   8048850 <printf@plt>
 8048ca2:   c7 04 24 03 00 00 00    movl   $0x3,(%esp)
 8048ca9:   e8 a0 07 00 00          call   804944e <validate>
 8048cae:   eb 13                   jmp    8048cc3 <test+0x70>
 8048cb0:   8b 45 f4                mov    -0xc(%ebp),%eax
 8048cb3:   89 44 24 04             mov    %eax,0x4(%esp)
 8048cb7:   c7 04 24 36 a4 04 08    movl   $0x804a436,(%esp)
 8048cbe:   e8 8d fb ff ff          call   8048850 <printf@plt>
 8048cc3:   c9                      leave
 8048cc4:   c3                      ret

08048cc5 <getbuf>:
 8048cc5:   55                      push   %ebp
 8048cc6:   89 e5                   mov    %esp,%ebp
 8048cc8:   83 ec 38                sub    $0x38,%esp
 8048ccb:   8d 45 d8                lea    -0x28(%ebp),%eax
 8048cce:   89 04 24                mov    %eax,(%esp)
 8048cd1:   e8 32 01 00 00          call   8048e08 <Gets>
 8048cd6:   b8 01 00 00 00          mov    $0x1,%eax
 8048cdb:   c9                      leave
 8048cdc:   c3                      ret
EN

回答 2

Stack Overflow用户

发布于 2015-10-20 21:24:20

这有可能吗?

如果Data Execution Prevention正在运行,则不会。

缓冲区将已被弹出

POP/RET不会更改堆栈上的任何数据。它只更改堆栈指针SP,而数据保留在被PUSHCALL替换之前的位置。

这就是为什么虫子喜欢

代码语言:javascript
复制
int* foo() {
  int i = 123;
  return &i;
}

在错误显示之前,可能会工作一段时间。在数据在堆栈上的位置被实际覆盖之前,它仍然在那里存在一段不确定的时间。

票数 3
EN

Stack Overflow用户

发布于 2015-10-20 21:39:52

是的,这是可能的预数据执行预防。

一段代码会填充比预期更多的缓冲区,这些缓冲区会漂移到堆栈上。在这一点上,您有两种可用的机制。

1) wikipedia: return into libc

2) wikipedia: stack buffer overflow

返回libc

在这里,您使用一组对函数(通常是程序中预先存在的函数)的调用来覆盖堆栈。这允许你构建更多的代码,并执行你想要的东西。

堆栈缓冲区溢出

此覆盖会修改保存的帧指针或堆栈上的返回地址。这些被更改为函数在堆栈上的预期位置。这在某种程度上是偶然的,所以通常会添加一个缓冲区(nop-slide)来提高可靠性。

wikipedia : address space layout randomization在程序之外增加了这方面的难度,因为您无法预测重要的函数和数据在哪里。

数据执行和地址空间布局随机化有助于缓解这些问题,因为它们通常不是所需的。我强烈建议避免这种形式的动态编程,因为它很容易被一些恶意实体利用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33237786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档