Android逆向之so修改

前言

本文将详细介绍在二进制层面修改android的so库,以实现so逻辑的修改。
  为了用最短的文字把问题说的最透彻,我们尽可能的简化,这里采用可执行程序来作为例子,需要修改的可执行程序main很简单,代码如下:

void say(char* name)
{
    printf("Hello %s , let`s hurt each other!\n" , name);
}

int main(int argc, char** argv)
{
    if (argc < 2)
    {
        printf("you must tell me your name!\n");
        return -1;
    }   
    say(argv[1]);
    return 0;
}

假设我们现在有个需求,就是我们要把argv[1]这个命令行参数作为某个可执行程序test的路径,让main调用execve去执行这个程序test。

修改

我们先用IDA打开可执行程序main,并且打开IDA View的二进制显示


Android逆向之so修改_第1张图片
打开IDA View视图的二进制显示

  
找到say函数,如下图所示:


Android逆向之so修改_第2张图片
say函数

函数say的参数name是通过寄存器R0传入的,我们通过系统调用号的方式直接调用execve,其中execve的系统调用号为0xB,如下图:  


execve的系统调用号

结合say函数的特点我们选择在地址为00008192处开始修改汇编代码(注意维持栈平衡),插入的汇编代码shellcode如下:

@execve的函数声明:int execve(const char* filename,char *const argv[],char *const envp[]);
MOVS     R0, R0  @filename,say函数的参数name传给它
MOVS    R1, #0  @argv,我们设为NULL
MOVS    R2, R1  @envp,我们设为NULL
MOV     R7, #0xB   @execve的系统调用号0xB通过寄存器R7传入
SVC     0    @State change Supervisor Call
POP     {R3 ,PC}    @维持栈平衡

接下来需要把它转换成二进制,我们在可以在http://armconverter.com/上转换,也可以用一个很不错的开源项目miasm来转换.

Android逆向之so修改_第3张图片
Online ARM To Hex Converter

生成的二进制shellcode共占12字节,而say函数留给我们的空间是地址00008192到000081A3,足够放入我们的二进制shellcode了。
接下来找到地址00008192相应的文件偏移,并且用生成的二进制覆盖


修改相应文件偏移的二进制

保存main后重新用IDA打开,查看修改之后的say函数:


Android逆向之so修改_第4张图片
修改之后的say函数

测试

测试程序test的代码如下:

#include 

int main(int argc, char** argv)
{
    int i = 0;
    while(i < 100)
    {
        printf("test is running!---->pid:%d, ppid:%d, uid:%d, gid:%d\n", 
                   getpid(), getppid(), getuid(), getgid()); 
        sleep(1);
        i++;
    }
}

把修改后的main和测试程序test上传到手机,并运行:

Android逆向之so修改_第5张图片
成功调用test

修改后的main成功运行测试程序test!

总结

读者可以进一步发散,譬如如何访问全局变量,如果可供修改的空间不足以放下我们的shellcode又怎么办等等。
另外,这里顺便推荐几款比较方便的IDA插件给大家:ida-patcher keypatch
https://jinyu00.github.io/2017/11/07/patch_file_methods.html

你可能感兴趣的:(Android逆向之so修改)