assembly - 汇编指令修改被调用函数内的返回地址
问题描述
我对汇编程序很陌生,但我仍然不知道大部分指令。
我正在尝试向 C 程序添加一些 asm 行(只是为了好玩,玩弄它)来修改函数的返回地址。
C代码看起来像
int my_function()
{
int my_number = 1;
__asm__ ("nop");
__asm__ ("nop");
return my_number;
}
int main(int argc, char *argv[])
{
//declarations
...lots of stuff
int my_number = my_function();
do_something;
...lots of stuff
do_other_thing;
... lots of stuff (46 bits in assembler)
return 0;
}
所以,我尝试做的是修改堆栈中的返回地址,my_function
所以,当返回时,它会去do_other_thing
而不是去do_something
为了使它更好,动态地,我不喜欢硬编码返回地址,所以我想添加那些 46 位。我也知道退货地址在EBP + 4
. 我已经在 内手动测试了它x32dgb
,它可以工作。
我想我将不得不:
- 获取 EBP + 4 指向的内容(可能在 EAX 中)
- 总和 46 到 EAX
- 将此值写回 EBP + 4
到目前为止我已经理解了,但不知道如何将它编码成 ASM 语句......
你能帮帮我吗?
解决方案
我正在尝试向 C 程序添加一些 asm 行(只是为了好玩,玩弄它)来修改函数的返回地址。
不。
对于用 C 编写的代码;编译器拥有堆栈,编译器生成适合自身及其优化的函数启动代码,编译器生成退出代码以适合自己的启动代码。任何对堆栈布局做出任何假设的内联汇编都是“脆弱的”——任何地方的微小变化(甚至只是更改一个无辜的局部变量、更改编译器命令行参数或将编译器更新到下一个版本)都可能并最终导致堆栈布局的差异将破坏内联汇编。在实践中它实际上比这更糟糕 - 编译器可以并且将生成同一“C函数”的多个不同版本(并将某些版本内联到其他函数中以避免函数调用的成本等),这样您最终会得到相同的内联程序集,它正在尝试(并保证会失败)处理多个完全不同的堆栈布局;即使您确实成功地返回了其他地方,您也无法可靠地避免在函数返回后搞砸一切。
另一个问题是,几乎从来没有一个理智的理由想要首先这样做。即使您正在编写可以完全控制堆栈布局的汇编语言(而不是使用无法控制堆栈布局的内联汇编语言编写 C)。
本质上; 对于试图学习汇编以花时间学习的人来说,有很多事情更重要(这些事情不是“脆弱的”,也不是没用的)。这就像学习如何用手站立驾驶汽车(用你的脸在加速器/制动踏板上并且看不到你周围的任何东西) - 它没有用。
推荐阅读
- javascript - JavaScript 对象属性包括空格字符
- python - 带有 HEVC 编解码器的 cv2.VideoWriter() 文件格式 .mp4
- sql - 从表中返回一列中的值大于下一列但相邻列中的相应值较小的行
- javascript - 清除旧的间隔 id 计数器后继续增长
- c - 读取时出现分段错误
- python-3.x - 带有 ORM 的 SQLAlchemy 异步引擎无法执行基本查询
- reactjs - ContextProvider => Context APi : 儿童动态渲染
- intershop - 应用程序之间意外的购物篮共享
- android - 颤振)图标的状态不能立即改变(编辑)
- c# - 需要在 Windows 启动时从 WPF UI 设置控制台应用程序