技术宅的结界

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

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 722|回复: 1
收起左侧

如何在init_array中植入代码

[复制链接]

271

主题

445

帖子

4762

积分

用户组: 真·技术宅

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

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

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

x
没搜到网上有相应的帖子,自己研究了下
源码是这样滴:
crtbegin_dynamic/static.c
[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

[C] 纯文本查看 复制代码
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的后面就好了!
下面提供这种方法,无需改源码:
[C] 纯文本查看 复制代码
#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);
}

3

主题

40

帖子

145

积分

用户组: 小·技术宅

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

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|技术宅的结界 ( 滇ICP备16008837号|网站地图

GMT+8, 2019-2-19 15:22 , Processed in 0.108892 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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