为什么我的共享库中的__attribute __((构造函数))不起作用?

时间:2018-01-11 17:29:42

标签: c linux clang shared-libraries

我在ctor.c中有这段代码:

#include<stdio.h>

static void __attribute__((constructor)) ctor() {
        printf("HAHA");
}

我用以下代码编译它:

clang -o shared.so -fPIC ctor.c -shared

然后我跑:

LD_PRELOAD=shared.so echo Hallo

打印

Hallo

我期待看到:

HAHAHallo

为什么这不起作用?

有关二进制文件的一些信息:

> objdump -s -j .init_array shared.so

shared.so:     file format elf64-x86-64

Contents of section .init_array:
 200798 b0060000 00000000 e0060000 00000000  ................

> nm shared.so
00000000002007b8 d _DYNAMIC
00000000002009b0 d _GLOBAL_OFFSET_TABLE_
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 w _Jv_RegisterClasses
0000000000000790 r __FRAME_END__
00000000002007b0 d __JCR_END__
00000000002007b0 d __JCR_LIST__
00000000002009e8 d __TMC_END__
00000000002009e8 B __bss_start
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000000670 t __do_global_dtors_aux
00000000002007a8 t __do_global_dtors_aux_fini_array_entry
00000000002009e0 d __dso_handle
0000000000200798 t __frame_dummy_init_array_entry
                 w __gmon_start__
00000000002009e8 D _edata
00000000002009f0 B _end
0000000000000700 T _fini
0000000000000578 T _init
00000000002009e8 b completed.6661
00000000000006e0 t ctor
00000000000005e0 t deregister_tm_clones
00000000000006b0 t frame_dummy
                 U printf@@GLIBC_2.2.5
0000000000000620 t register_tm_clones

这表明:

(a)存在ctor功能。链接器不会删除它,就像有些类似问题的人一样。

(b).init_array对我来说没问题。有两个条目(而不是一个),它们指向frame_dummy和ctor。 (我使用了这个答案:https://reverseengineering.stackexchange.com/a/12793

(c)shared library constructor not working通过一步编译和链接解决了这个问题,我已经在做了

PS:当我用gcc编译时它也不起作用。

2 个答案:

答案 0 :(得分:2)

我遇到了与c ++相似的问题 - 构造函数

struct Foo {
    Foo() {
        printf("foo");
    }
} foo;

这应该在调用main()之前打印“foo”,但它没有。但是我的项目中有非常类似的东西运作良好。

我发现如果源文件中没有其他内容从外部调用,则不会调用构造函数。

尝试从外部调用虚拟函数。

答案 1 :(得分:1)

有两个错误:

(a)LD_PRELOAD需要绝对路径。

(b)“echo”是一个shell-builtin,因此不会启动二进制文件,因此不会预加载任何内容。通过我自己的“hello world”计划,它可以运作。