C 汇编语言指令

C 汇编语言指令,c,compiler-construction,assembly,gdb,core,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 %

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

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

pusha只能在该点发生堆栈溢出时导致核心转储。此指令将所有寄存器值推送到堆栈上,这可能导致溢出。但是,问题的根源可能在其他地方-最有可能的是调用堆栈在该点太深,而pusha恰好会导致这样的后果,因为它是在这样的条件下执行的。

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

x/i $eip
还显示寄存器值:

i r

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

x/i $eip
还显示寄存器值:

i r
否*,pusha所做的就是将所有通用寄存器推送到堆栈,包括堆栈指针!导致内核转储的是pusha、lret之后的指令,这是一个带有堆栈pop的长返回。返回地址是推送到堆栈的最新值,在本例中,它将是esi:edi中的任何值,因为它们是pusha指令推送的最后一个值,可能指向随机的某个地方

*除非堆栈空间不足。

否*,否则pusha所做的就是将所有通用寄存器推送到堆栈中,包括堆栈指针!导致内核转储的是pusha、lret之后的指令,这是一个带有堆栈pop的长返回。返回地址是推送到堆栈的最新值,在本例中,它将是esi:edi中的任何值,因为它们是pusha指令推送的最后一个值,可能指向随机的某个地方


*除非堆栈空间耗尽。

绝对如此。PUSHA后跟RET是不正确的,返回地址将是垃圾邮件。在你的反汇编中看到ADD AL,[EAX]是另一个死亡赠品,这是0的反汇编

换句话说:您正在反汇编数据,而不是代码。你的程序爆炸了,因为它正在执行数据。发生这种情况的经典方法是使用缓冲区溢出破坏堆栈帧。当函数返回时,它会从损坏的堆栈中弹出一个无效的返回地址,并跳入never land。没有seg故障是非常不幸运的


很难调试,堆栈跟踪被废弃。您需要在最后一个已知的正确代码地址设置断点,然后开始单步执行。就在它爆炸之前,你进入的最后一个好功能通常是麻烦制造者。

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

换句话说:您正在反汇编数据,而不是代码。你的程序爆炸了,因为它正在执行数据。发生这种情况的经典方法是使用缓冲区溢出破坏堆栈帧。当函数返回时,它会从损坏的堆栈中弹出一个无效的返回地址,并跳入never land。没有seg故障是非常不幸运的


很难调试,堆栈跟踪被废弃。您需要在最后一个已知的正确代码地址设置断点,然后开始单步执行。最后一个在它爆炸之前使用的好功能通常是故障制造者。

如果它从来都不正确,那么为什么会生成此指令集?你没有抓住要点。找到的程序集代码不是代码。这是数据。反汇编数据会生成奇怪的指令。像波帕和萨夫。我解释了你的程序最终是如何执行数据而不是代码的。如果它永远都不正确,那么为什么会生成这个指令集?你没有抓住要点。找到的程序集代码不是代码。这是数据。反汇编数据会生成奇怪的指令。像波帕和萨夫。我解释了你的程序最终是如何执行数据而不是代码的。有什么方法可以验证堆栈溢出吗?@arbit:这取决于,在保护模式下,你会得到SS0 CPU异常。除此之外,您可能会得到一个PFx异常。但这些将被操作系统捕获。nobugz提出了最可能的原因:代码跳转到随机内存位。您可以通过取消对无效指针的引用来实现这一点,通常是通过对尚未初始化的对象调用虚拟方法。是否有任何方法可以验证堆栈溢出?@Arpit:这取决于,在保护模式下,您将获得SS0 CPU异常。除此之外,您可能会得到一个PFx异常。但这些将被操作系统捕获。nobugz提出了最可能的原因:代码中有j 转储到一个随机的内存位。可以通过取消对无效指针的引用来实现这一点,通常是通过对尚未初始化的对象调用虚方法。