如何在init_array中植入代码
没搜到网上有相应的帖子,自己研究了下源码是这样滴:
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 inttestnum=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);
}
居然没人顶超神
页:
[1]