我有一个堆栈损坏的核心转储。 我试着拆开它,发现下面的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指令可以导致核心转储吗?
答案 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