g++
4.6.3和objdump
2.22 这是我正在使用的简单C ++代码: />我可以在下面的hello.s中找到一个
ctors
部分:#include <iostream>
using namespace std;
main()
{
cout << "Hello World!" << endl;
return 0;
}
但是,当我汇编asm代码时,生成一个exe文件并使用
objdump
产生ctors
部分,其内容如下: gcc -S hello.cc
我所能获得的是这样的:我想知道是否有一种方法可以获取与
c++
产生的内容相等的ctors
的内容吗?但是我仍然陷入从ELF二进制文件中查找g++
和class's
信息的问题。一个类的构造函数,而constructor
是它的析构函数。但是,我只是在
destructor
转储的class
或.ctors
部分中找不到相应的信息。我也尝试了_ZN8ComputerC2Ev
和_ZN8ComputerD2Ev
,但是转储的信息非常庞大。我可以不知道这些信息的含义。有人可以给我指导吗?
#1 楼
.ctors
部分是一个以-1(0xFFFFFFFF)结尾的指针的列表,因此反汇编它没有任何意义。如果将字节重新排列为数据,则会得到:__CTOR_LIST__: .long 0xffffffff
__CTOR_END__: .long 0x00000000
因此,无论出于何种原因,生成的exe实际上并不使用
.ctors
节。我怀疑链接器将指针放到了新样式的.init_array
部分中。请注意,它还是一个指针列表,而不是代码。编辑:
.ctors
或.init_array
部分仅包含所谓的构造函数-需要的函数在main()
本身之前在启动时执行。这些通常是编译器生成的函数,这些函数执行全局对象(例如cin
,cout
等)的构造或其他与启动有关的任务。实际上,您可以使用__attribute__((constructor))
将自己的函数添加到该列表。通用的C ++类构造函数没有用,无需在启动时执行它们。当以及如果您构造特定类的对象时,它们将被调用-例如通过声明变量或调用
operator new
。#2 楼
正如Igor所说,.ctors
部分是函数指针的列表,结尾是0xffffffff
的前哨值。要查看其内容,只需执行$ objdump -s -j.ctors bar.so
,但是您的汇编文件仅包含弱符号。这些是其他库中的外部函数,并且在运行时加载它们的库时被调用。
例如,将其放在文件
bar.cpp
中: 用
class Foo {
public:
int i;
Foo(int n) : i(n) {
}
};
Foo global_foo(123);
进行编译.init_array
部分的内容是指针在那里,
0xad060000 00000000
。但是您必须更改其字节序,例如使用Python:$ g++ -shared -fPIC bar.cpp -obar.so
现在列出该地址的所有符号和grep:
$ objdump -s -j.init_array bar.so
bar.so: file format elf64-x86-64
Contents of section .init_array:
200820 ad060000 00000000 ........
反汇编它,
>>> import struct
>>> import binascii
>>> binascii.hexlify(struct.pack("<Q", 0xad06000000000000))
'00000000000006ad'
显示
$ objdump -C --syms bar.so | grep 00000000000006ad
00000000000006ad l F .text 0000000000000015
[... on above line ...] global constructors keyed to bar.cpp
它跳转到
__static_initialization_and_destruction_0(int, int)
:$ objdump -C -d bar.so
将123(
0x7b
)放在堆栈上并调用Foo::Foo(int)
。
评论
时髦!我转储.init_array节的内容,它包含_GLOBAL__sub_I_main函数的地址!
– lllllllllllll
2014-09-23 1:40