pusha汇编语言教学

时间:2010-02-17 10:30:53

标签: c compiler-construction assembly gdb core

我有一个堆栈损坏的核心转储。 我试着拆开它,发现下面的PLZ帮我分析它..

(gdb) bt
#0  0x55a63c98 in ?? ()
#1  0x00000000 in ?? ()

(gdb) disassemble 0x55a63c90 0x55a63ca8

Dump of assembler code from 0x55a63c90 to 0x55a63ca8:

0x55a63c90:     add    %cl,%dh

0x55a63c92:     cmpsb  %es:(%edi),%ds:(%esi)

0x55a63c93:     push   %ebp

0x55a63c94:     add    %al,(%eax)

0x55a63c96:     add    %al,(%eax)

**0x55a63c98:     pusha**

0x55a63c99:     lret   $0x9

0x55a63c9c:     subb   $0x56,0xd005598(%ebp)

0x55a63ca3:     push   %ebp

0x55a63ca4:     jo     0x55a63cc5

0x55a63ca6:     sahf

0x55a63ca7:     push   %ebp

End of assembler dump.
(gdb) q

这个pusha指令可以导致核心转储吗?

4 个答案:

答案 0 :(得分:6)

没有 * ,所有pusha都将所有通用寄存器推送到堆栈,包括堆栈指针!造成核心转储的原因是pusha之后的指令,lret,这是一个带有堆栈弹出的长期返回。返回地址是推送到堆栈的最新值,在这种情况下将是esi:edi中的任何值(因为它们是由pusha指令推送的最后一个值),并且这可能指向某个随机位置。

*除非你的堆栈空间不足。

答案 1 :(得分:4)

绝对。 PUSHA后跟RET永远不正确,返回地址将是垃圾。看到ADD AL,你的反汇编中的[EAX]是另一个死的,这就是0的反汇编。

换句话说:你是在拆解数据,而不是代码。你的程序遭到轰炸,因为它正在执行数据。发生的经典方法是使用缓冲区溢出来破坏堆栈帧。当函数返回时,它会从损坏的堆栈中弹出一个无效的返回地址,然后跳转到永不落地。没有得到段错误是非常不吉利的。

难以调试,堆栈跟踪被废弃。您需要在最后一个已知的良好代码地址处设置断点并开始单步执行。你在炸弹爆炸之前遇到的最后一个好功能通常是麻烦制造者。

答案 2 :(得分:0)

如果此时发生堆栈溢出,

pusha只能导致核心转储。该指令将所有寄存器值压入堆栈,这可能导致溢出。然而,问题的根源可能在其他地方 - 很可能调用堆栈在那一点太深,而pusha恰好会导致这样的后果,因为它是在这样的条件下执行的。

答案 3 :(得分:0)

检查是否看到对齐的反汇编代码:

x/i $eip

还显示寄存器值:

i r