【发布时间】:2019-07-17 03:27:36
【问题描述】:
我是汇编程序的新手,我仍然不知道大部分指令。
我正在尝试在 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 语句......
你能帮帮我吗?
【问题讨论】:
-
在
my_function()中,您可以使用 x=46 位执行add dword [EBP+4], x。但是 46 位很可能是错误的......也许是 46 字节或其他东西 - 无论调用后和do_other_thing之间的区别是什么。 -
并确保编译器选项-fomit-frame-pointer 未激活。
-
GCC 有
__builtin_return_address(0)来读取当前函数的返回地址 (How can I determine the return address on stack?)。我想我记得有一个内置函数来获取返回地址的 address of,所以你可以用 C 来修改它,但我做不到这样的事情。那是有道理的,您可能应该在纯 asm 中编写上下文切换函数。在没有 asm 的情况下,你几乎无法用这样的东西做有用的事情,而在 asm 中编写一个完整的函数意味着你不必保存/恢复调用破坏的寄存器。 -
@zx485 这将是一个很好的解决方案,但在我的情况下它不起作用,语法上的东西??
-
错误:表达式后出现垃圾 `[ebp+4]'