C++
try
的catch
程序,当使用g++
将其编译为汇编代码时(测试在x86 32位Linux上,g++
4.6.3)称为.gcc_except_table
的生成方式如下: 。 但是,我用以下命令转储了这两个部分的内容,将标签的内存地址与
exe file
中定义的内容进行了比较,但对我来说似乎太模糊了... g++ -S cppexcept.cc
所以我的问题是:
有什么方法可以从
ELF
文件的.gcc_except_table
和.eh_frame
中恢复.gcc_except_table
(如上所示)中定义的信息。桌子?#1 楼
(我认为,如果使用-fverbose-asm
,您可能会得到一些额外的注释。)从这些表中恢复信息绝对是可能的,尽管文档很少,而且通常仅在解析它们的代码中提供。
LSB文档中简要描述了
.eh_frame
布局。伊恩·兰斯·泰勒(Ian Lance Taylor)(黄金链接者)还在.eh_frame
和.gcc_except_table
布局上发表了一些博文。 我制作了一个IDA脚本(
gcc_extab.py
),用于解析.eh_frame
和.gcc_except_table
并对其进行很好的格式化。 我将展示GCC生成的注释结构。
首先,介绍
.eh_table
(为清晰起见,省略了一些部分):void f()
{
throw 1;
}
int main()
{
int j;
try {
f();
} catch (int i) {
j = i;
}
return 0;
}
接下来,用FDE 3引用
.gcc_except_table
中的LSDA(语言特定的数据区域):.Lframe1: # start of CFI 1
.long .LECIE1-.LSCIE1 # length of CIE 1 data
.LSCIE1: # start of CIE 1 data
.long 0 # CIE id
.byte 0x1 # Version
.string "zPL" # augmentation string:
# z: has augmentation data
# P: has personality routine pointer
# L: has LSDA pointer
.uleb128 0x1 # code alignment factor
.sleb128 -4 # data alignment factor
.byte 0x8 # return address register no.
.uleb128 0x6 # augmentation data length (z)
.byte 0 # personality routine pointer encoding (P): DW_EH_PE_ptr|DW_EH_PE_absptr
.long __gxx_personality_v0 # personality routine pointer (P)
.byte 0 # LSDA pointer encoding: DW_EH_PE_ptr|DW_EH_PE_absptr
.byte 0xc # Initial CFI Instructions
[...]
.align 4
.LECIE1: # end of CIE 1
[...]
.LSFDE3: # start of FDE 3
.long .LEFDE3-.LASFDE3 # length of FDE 3
.LASFDE3: # start of FDE 3 data
.long .LASFDE3-.Lframe1 # Distance to parent CIE from here
.long .LFB1 # initial location
.long .LFE1-.LFB1 # range length
.uleb128 0x4 # Augmentation data length (z)
.long .LLSDA1 # LSDA pointer (L)
.byte 0x4 # CFI instructions
.long .LCFI2-.LFB1
[...]
.align 4
.LEFDE3: # end of FDE 3
评论
您好Igor,非常感谢您提供的有用答案!您介意附加如何编译简单程序吗?我在计算机上尝试并使用IDA 6.4处理该脚本,但无法获取您的输出。
– lllllllllllll
2014-09-25 14:18
此输出不是来自脚本,而是来自编译器的带注释的汇编器输出。
–伊戈尔·斯科钦斯基♦
2014-09-25 19:51