我已阅读PE and COFF specification,Matt Pietrek的"Peering Inside the PE: A Tour of the Win32 Portable Executable File Format"和"An In-Depth Look into the Win32 Portable Executable File Format"以及其他一些有关该主题的消息来源。
我能够从MinGW GCC 4.7生成的目标文件中读出COFF部分表和COFF符号表(我在调试模式下编译静态库)。
我的最终目标是访问给定目标文件(COFF)中定义的所有函数,并读出构成其机器代码的所有字节。
问题1 : 如何计算COFF文件中单个函数的起始地址?我认为我必须以某种方式使用符号记录的“值”字段作为“SectionNumber”指定的部分的偏移量。
问题2 : 如何找出任何给定函数的长度(我必须读取多少字节)?
问题3 : 根据微软的PE& COFF规范在定义函数的每个符号记录之后应该有一个辅助符号表记录。为什么在我的目标文件(从调试模式下编译的.a文件中提取)中有三个定义的函数只有一个有这样的辅助记录?这也完全被零填充?
答案 0 :(得分:1)
Q1:是的,这似乎是合理的。
第二季度:可能很难。取决于处理器架构。无法保证有任何函数信息可以给出函数的长度 - 特别是,似乎没有任何可用于x86(32位)的函数,并且有时只提供有关长度的信息。其他架构[在例外情况下展开时需要它]。最好的方法可能就是加载符号表,找到NEXT函数的地址顺序,然后假设长度是从函数的开头到下一个函数之前的字节。对于最后一个功能,显然"直到该部分结束"。很多年前,我使用识别返回指令的方法来查找函数的长度,但是现代编译器经常生成具有多个返回指令的代码,在返回后将if / else代码放回到主函数代码中等等,所以它可能不是一个可靠的方法[当然如果有人x = $0xc3;
,0xc3看起来像一个返回指令,但它实际上是数据...;)
问题3:辅助记录完全是可选的:
每个紧随其后的零个或多个辅助符号表记录 标准符号表记录。但是,通常不超过一个 辅助符号表记录遵循标准符号表记录 (具有长文件名的.file记录除外)。
如果存在辅助符号表记录,则它们在符号表记录中的偏移17处指示。
如果您只阅读后面的文字,这可能会令人困惑:
辅助符号表记录始终遵循并适用于某些记录 标准符号表记录。
我认为这应该被视为"如果有辅助符号表记录,它会立即出现在标准表记录之后#34;。