- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
没搜到网上有相应的帖子,自己研究了下
源码是这样滴:
crtbegin_dynamic/static.c
- typedef struct
- {
- void (**preinit_array)(void);
- void (**init_array)(void);
- void (**fini_array)(void);
- void (**ctor_list)(void);
- } structors_array_t;
- extern int main(int argc, char **argv, char **env);
- extern void __libc_init(
- unsigned int *elfdata,
- void (*onexit)(void),
- int (*slingshot)(int, char**, char**),
- structors_array_t const * const structors
- );
- __attribute__ ((section (".preinit_array")))
- void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;
- __attribute__ ((section (".init_array")))
- void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;
- __attribute__ ((section (".fini_array")))
- void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;
- __attribute__ ((section (".ctors")))
- void (*__CTOR_LIST__)(void) = (void (*)(void)) -1;
- __attribute__((visibility("hidden")))
- void _start() {
- structors_array_t array;
- void *elfdata;
- array.preinit_array = &__PREINIT_ARRAY__;
- array.init_array = &__INIT_ARRAY__;
- array.fini_array = &__FINI_ARRAY__;
- array.ctor_list = &__CTOR_LIST__;
- elfdata = __builtin_frame_address(0) + sizeof(void *);
- __libc_init(elfdata, (void *) 0, &main, &array);
- }
复制代码
拿init_array来说:执行main之前,先进行init_array初始化,而数组第一个元素被编译器置为-1,本来是个函数指针数组,再看__libc_init实现,
发现对init_array处理是判断是否为0
libc_init_static/dynamic.cpp
- static void call_array(void(**list)()) {
- // First element is -1, list is null-terminated
- while (*++list) {
- (*list)();
- }
- }
- __noreturn void __libc_init(void* raw_args,
- void (*onexit)(void) __unused,
- int (*slingshot)(int, char**, char**),
- structors_array_t const * const structors) {
- KernelArgumentBlock args(raw_args);
- __libc_init_tls(args);
- __libc_init_AT_SECURE(args);
- __libc_init_common(args);
- apply_gnu_relro();
- call_array(structors->preinit_array);
- call_array(structors->init_array);
- if (structors->fini_array != NULL) {
- __cxa_atexit(__libc_fini,structors->fini_array,NULL);
- }
- exit(slingshot(args.argc, args.argv, args.envp));
- }
复制代码
可见,判断init_array是否执行的依据是该项是否为0,因此只要想办法吧函数指针加到init_array段已经有的-1的后面就好了!
下面提供这种方法,无需改源码:
- #include <stdio.h>
- volatile int testnum=0;
- void func1(void){testnum=1;};
- void func2(void){testnum=2;};
- void func3(void){testnum=3;};
- void func4(void){testnum=4;};
- //__attribute__ ((section (".preinit_array")))
- //__attribute__ ((section (".fini_array")))
- //__attribute__ ((section (".ctors")))
- __attribute__ ((section (".init_array"))) void(*initfunc[])(void)={&func1,&func2,&func3,&func4};//放入多个函数
- __attribute__ ((section (".init_array"))) void(*initfunc1)(void)=&func1;//放入单个函数
- int main(int argc, char *argv[])
- {
- printf("testnum=%d\n",testnum);
- }
复制代码 |
|