android elf 工具,[分享][原创]修改android app_process elf (实现rrrfff大神 <android全局注入>第一步)...

更新

好久没注意我自己留的坑,所以,看到有人回复想要镜像,于是根据这段时间看android/linker源码的内容,写了一个简单的自动化修改app_process工具,运行过之后返回的so的名字,就是最终你注入的so的名字。

511a1e8a0b35a29b040b245361dcf4d3.png

6755287b222e05b2d5c83004f0e43534.png

tag 为debug的被修改为了我们自己注入的so的名字

原文

我是一名做android安全的新手,最近在论坛里看到@rrrfff大神发的博文一种简单的Android全局注入方案 很受启发,准备结合着xposed学习一下。没想到第一步就遇到了阻碍^_^。不知道论坛里的各位大佬是怎么修改elf的,我的方案是手动寻找到dyn表的位置,然后打印出来tag和value值,再把映射的值放到程序里去写入到app_process中。以下是我个人的思路:

第一步找到dyn在app_process文件中的偏移位置:

readelf -d app_process

看显示内容:

yougar@ubuntu:~/Programs/so_injection/os$ readelf -d app_process

Dynamic section at offset 0x3dc0 contains 32 entries: ## offset

Tag        Type                         Name/Value

0x00000003 (PLTGOT)                     0x4f0c

0x00000002 (PLTRELSZ)                   440 (bytes)

0x00000017 (JMPREL)                     0xe74

0x00000014 (PLTREL)                     REL

0x00000011 (REL)                        0xdb4

0x00000012 (RELSZ)                      192 (bytes)

0x00000013 (RELENT)                     8 (bytes)

0x6ffffffa (RELCOUNT)                   21

0x00000015 (DUBUG)                      0x0

0x00000006 (SYMTAB)                     0x148

0x0000000b (SYMENT)                     16 (bytes)

0x00000005 (STRTAB)                     0x598

0x0000000a (STRSZ)                      1521 (bytes)

0x00000004 (HASH)                       0xb8c

0x00000001 (NEEDED)                     Shared library: [libandroid_runtime.so]

0x00000001 (NEEDED)                     Shared library: [libbinder.so]

0x00000001 (NEEDED)                     Shared library: [libc.so]

0x00000001 (NEEDED)                     Shared library: [libcutils.so]

0x00000001 (NEEDED)                     Shared library: [libdl.so]

0x00000001 (NEEDED)                     Shared library: [liblog.so]

0x00000001 (NEEDED)                     Shared library: [libm.so]

0x00000001 (NEEDED)                     Shared library: [libstdc++.so]

0x00000001 (NEEDED)                     Shared library: [libutils.so]

0x00000020 (PREINIT_ARRAY)              0x4d40

0x00000021 (PREINIT_ARRAYSZ)            0x8

0x00000019 (INIT_ARRAY)                 0x4d48

0x0000001b (INIT_ARRAYSZ)               12 (bytes)

0x0000001a (FINI_ARRAY)                 0x4d54

0x0000001c (FINI_ARRAYSZ)               8 (bytes)

0x0000001e (FLAGS)                      BIND_NOW

0x6ffffffb (FLAGS_1)                    Flags: NOW

0x00000000 (NULL)                       0x0

发现偏移位置为0x3dc0,转换为10进制是15808

第二步结合打印出d_tag为0x00000001,第一个tag类型为needed的d_val,源码如下:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

long parse_long(const char * v) {

long off;

off = atol(v);

if(off == 0) {

if(errno != 0) {

error(201, errno, "parse offset  to unsigned long", v);

return -1;

}

}

return off;

}

int main(int argc, const char **argv) {

if(argc != 3) {

printf("usage:%s  \n", argv[0]);

return -1;

}

off_t offset, current, value;

offset = parse_long(argv[2]);

if(offset == -1) {

return -1;

}

int f_id;

f_id = open(argv[1], O_RDONLY);

if (f_id == -1) {

error(201, errno, "open %s;", argv[1]);

return -1;

}

size_t len = sizeof(Elf32_Dyn); // 单个dyn在文件中所占大小

offset +=  14 * len;  // 由于第一个出现needed类型的tag在tag数组里的偏移是14,所以这里设置偏移长度+14 * len

current = lseek(f_id, offset, SEEK_SET);

if(current == -1) {

error(201, errno, "lseek file with offset %ld", offset);

return -1;

}

if(current != offset) {

printf("file %s current pos  not equal to offset \n", argv[1], current, offset);

return -1;

}

Elf32_Dyn *elf32_dyn = (Elf32_Dyn*)malloc(len);

read(f_id, elf32_dyn, len);

printf("Tag: %u, Val: %u\n", elf32_dyn -> d_tag, elf32_dyn -> d_un.d_val);

}

运行之,打印结果:

Tag: 1, Val: 1413

这里的这个val对应的是字符表的字符偏移,去掉lib占的内存,那么我的程序应该设置的val大小为1416

第三步修改tag和val,代码如下:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

long parse_long(const char * v) {

long off;

off = atol(v);

if(off == 0) {

if(errno != 0) {

error(201, errno, "parse offset  to unsigned long", v);

return -1;

}

}

return off;

}

int main(int argc, const char **argv) {

if(argc != 4) {

printf("usage:%s   \n", argv[0]);

return -1;

}

off_t offset, current, value;

offset = parse_long(argv[2]);

if(offset == -1) {

return -1;

}

value = parse_long(argv[3]);

if(value == -1) {

return -1;

}

int f_id;

f_id = open(argv[1], O_RDWR);

if (f_id == -1) {

error(201, errno, "open %s;", argv[1]);

return -1;

}

size_t len = sizeof(Elf32_Dyn);

offset +=  8 * len; // 要修改的dyn在数组中的偏移位置是8

current = lseek(f_id, offset, SEEK_SET);

if(current == -1) {

error(201, errno, "lseek file with offset %ld", offset);

return -1;

}

if(current != offset) {

printf("file %s current pos  not equal to offset \n", argv[1], current, offset);

return -1;

}

Elf32_Dyn *elf32_dyn = (Elf32_Dyn*)malloc(len);

elf32_dyn -> d_tag = DT_NEEDED;

elf32_dyn -> d_un.d_val = value;

write(f_id, elf32_dyn, len);

}

到这里修改操作全部完成。查看结果:

07437adc5a45b475cfb6ad93de71f6a3.png

有一点我的方案跟rrrfff大神的不太一样,就是我是直接把修改过的app_process push到模拟器里面的,没有改虚拟机文件。在这一步,我还遇到了一点小问题,不过,google之后,还是顺利解决了。这里我还是分享一下吧,作为备忘录。

问题如下:

adb push C:\***\app_process /system/bin之后,报read-only file system错误。这个我早想到过,于是按照有人提出的解决方法mount -o remount,rw /system,发现运行过这个命令之后,竟然报相同的错误。这一解决方案被很多人采纳了,可为啥我的就不行。后来又看到一个相似的提问的回答,然后成功解决了我的问题。回答是:启动模拟器的命令参数要有-writable-system才可以写/system文件夹。

最后于 2018-4-10 16:13

被Yougar编辑

,原因: 提供一个自动化工具

上传的附件:

elf.zip

(3.11kb,129次下载)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值