找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3250|回复: 1

如何在init_array中植入代码

[复制链接]

307

主题

228

回帖

7337

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5587 个
贡献
253 次
宅之契约
0 份
在线时间
948 小时
注册时间
2014-1-25
发表于 2016-5-6 00:06:26 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
没搜到网上有相应的帖子,自己研究了下
源码是这样滴:
crtbegin_dynamic/static.c

  1. typedef struct
  2. {
  3.     void (**preinit_array)(void);
  4.     void (**init_array)(void);
  5.     void (**fini_array)(void);
  6.     void (**ctor_list)(void);
  7. } structors_array_t;

  8. extern int main(int argc, char **argv, char **env);

  9. extern void __libc_init(
  10.   unsigned int *elfdata,
  11.   void (*onexit)(void),
  12.   int (*slingshot)(int, char**, char**),
  13.   structors_array_t const * const structors
  14. );

  15. __attribute__ ((section (".preinit_array")))
  16. void (*__PREINIT_ARRAY__)(void) = (void (*)(void)) -1;

  17. __attribute__ ((section (".init_array")))
  18. void (*__INIT_ARRAY__)(void) = (void (*)(void)) -1;

  19. __attribute__ ((section (".fini_array")))
  20. void (*__FINI_ARRAY__)(void) = (void (*)(void)) -1;

  21. __attribute__ ((section (".ctors")))
  22. void (*__CTOR_LIST__)(void) = (void (*)(void)) -1;

  23. __attribute__((visibility("hidden")))
  24. void _start() {
  25.   structors_array_t array;
  26.   void *elfdata;

  27.   array.preinit_array = &__PREINIT_ARRAY__;
  28.   array.init_array =    &__INIT_ARRAY__;
  29.   array.fini_array =    &__FINI_ARRAY__;
  30.   array.ctor_list =    &__CTOR_LIST__;

  31.   elfdata = __builtin_frame_address(0) + sizeof(void *);
  32.   __libc_init(elfdata, (void *) 0, &main, &array);
  33. }
复制代码


拿init_array来说:执行main之前,先进行init_array初始化,而数组第一个元素被编译器置为-1,本来是个函数指针数组,再看__libc_init实现,
发现对init_array处理是判断是否为0

libc_init_static/dynamic.cpp


  1. static void call_array(void(**list)()) {
  2.   // First element is -1, list is null-terminated
  3.   while (*++list) {
  4.     (*list)();
  5.   }
  6. }
  7. __noreturn void __libc_init(void* raw_args,
  8.                             void (*onexit)(void) __unused,
  9.                             int (*slingshot)(int, char**, char**),
  10.                             structors_array_t const * const structors) {
  11.   KernelArgumentBlock args(raw_args);
  12.   __libc_init_tls(args);
  13.   __libc_init_AT_SECURE(args);
  14.   __libc_init_common(args);

  15.   apply_gnu_relro();

  16.   call_array(structors->preinit_array);
  17.   call_array(structors->init_array);

  18.   if (structors->fini_array != NULL) {
  19.     __cxa_atexit(__libc_fini,structors->fini_array,NULL);
  20.   }

  21.   exit(slingshot(args.argc, args.argv, args.envp));
  22. }
复制代码

可见,判断init_array是否执行的依据是该项是否为0,因此只要想办法吧函数指针加到init_array段已经有的-1的后面就好了!
下面提供这种方法,无需改源码:

  1. #include <stdio.h>

  2. volatile int  testnum=0;

  3. void func1(void){testnum=1;};
  4. void func2(void){testnum=2;};
  5. void func3(void){testnum=3;};
  6. void func4(void){testnum=4;};

  7. //__attribute__ ((section (".preinit_array")))
  8. //__attribute__ ((section (".fini_array")))
  9. //__attribute__ ((section (".ctors")))
  10. __attribute__ ((section (".init_array"))) void(*initfunc[])(void)={&func1,&func2,&func3,&func4};//放入多个函数
  11. __attribute__ ((section (".init_array"))) void(*initfunc1)(void)=&func1;//放入单个函数

  12. int main(int argc, char *argv[])
  13. {
  14.         printf("testnum=%d\n",testnum);
  15. }
复制代码
回复

使用道具 举报

3

主题

36

回帖

148

积分

用户组: 小·技术宅

UID
257
精华
0
威望
1 点
宅币
107 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2014-5-6
发表于 2016-5-6 09:36:05 | 显示全部楼层
居然没人顶超神
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-20 16:39 , Processed in 0.035341 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表