对于已定义C++ trycatch程序,当使用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