【发布时间】:2017-03-14 08:11:10
【问题描述】:
我正在编写一个包含一些 asm 指令的简单 C++ 程序。
void call(){
__asm__("mov -0x10(%rbp),%eax;"
"add $0x10,%eax;"
"mov %eax,%edx;"
"shr $0x1f,%edx;"
"add %edx,%eax;"
"sar %eax;"
"add %eax,-0x4(%rbp);"
"mov $0x4c,%eax;"
"mov -0x8(%rbp),%eax;"
"add %eax,%eax;"
"sub -0x4(%rbp),%eax;"
"add %eax,-0xc(%rbp);");
}
但是,从执行行为中我意识到,这个 asm 体操作的寄存器实际上是被函数中的其他变量使用的。
是否可以调用编译器来隔离 asm 标签中使用的寄存器并确保它们不受影响?
操作系统:Linux 编译器:G++
也欢迎使用非编译器方法
【问题讨论】:
-
这很糟糕,非常糟糕。此代码假定堆栈上的变量位于特定位置。您应该使用GCC extended assembly template 并将变量作为约束传递给模板,以免依赖硬编码的位置。同样,由于您没有使用任何约束,因此您正在破坏可用于其他目的的 EAX 和 EDX。 GCC 不对您的内联汇编器做任何假设(与 MASM 不同)。
-
我会问一个问题。尽管在代码函数
callOne中没有局部变量,但您拥有的汇编程序假定堆栈上有局部变量(即来自RBP 的负位移)。这是该函数的完整代码 sn-p 还是还有更多?这是什么操作系统(Windows/Linux/BSD?)。为什么不能为此创建 C++ 代码?你在做漏洞利用吗? -
@MichaelPetch 我更新了这个问题。 Linux,这是我不再使用代码的完整功能。
-
如果这是完整的代码,请问您使用的汇编代码来自哪里?似乎它可能是从其他代码中提取的(反汇编?)并插入。我这样说是因为无论该代码来自何处,它最初都是具有许多局部变量的函数的一部分(似乎其中有 4 个来自目测如果涉及数组,则代码或可能更少)
-
" 我不关心结果,而关心代码是否运行" = 但这是一回事。访问无效内存会使它崩溃,所以让它“不运行”,但如果地址意外有效,它会以垃圾结果运行。我看不出这对你有什么不同。无论哪种情况,您发布的这段代码都需要先进行大量重写才能在 64b C++ 项目中有意义。你基本上可以直接删除它(因为它对代码的 C++ 部分没有做任何重要的事情),并且代码将比现在运行得更好,而无需一些流氓 asm 指令修改一些随机内存。
标签: c++ assembly x86 g++ x86-64