Reputation: 961
I have this code in ctor.c:
#include<stdio.h>
static void __attribute__((constructor)) ctor() {
printf("HAHA");
}
I compile it with:
clang -o shared.so -fPIC ctor.c -shared
then I run:
LD_PRELOAD=shared.so echo Hallo
it prints
Hallo
I was expecting to see:
HAHAHallo
Why is this not working?
Some info about the binary:
> 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
This indicates:
(a) the ctor function is present. It is not removed by the linker, as for some people with similar problems.
(b) The .init_array looks okay to me. There are two entries (instead of one), and they point to frame_dummy and ctor. (I used this answer: https://reverseengineering.stackexchange.com/a/12793)
(c) shared library constructor not working solved the problem by compiling and linking in one step, which I am already doing
PS: It also does not work when I compile with gcc.
Upvotes: 2
Views: 2795
Reputation: 961
There were two mistakes:
(a) LD_PRELOAD needs an absolute path.
(b) "echo" is a shell-builtin, so no binary will be started and thereby nothing will be preloaded. With my own "hello world" program, it works.
Upvotes: 3
Reputation: 659
I had a similar problem with a c++-constructor
struct Foo {
Foo() {
printf("foo");
}
} foo;
This should print "foo" before the main() is called, but it didn't. But I had very similar stuff in my project that worked well.
I have found out that the constructor isn't called if there is nothing else in the source-file that is called from outside.
Try calling a dummy-function from outside.
Upvotes: 1