• 实现对第三方应用任意SO注入


    实现对第三方应用任意SO注入

    0x01

    应用在Android中运行,从外部对该进程可以进行任意SO文件动态注入,就是应用动态运行我们的SO文件

    0x02

    基本的逻辑是:

    1.    获取目标进程的pid,关联目标进程:通过遍历查找/proc/pid/cmdline文件中是否含有目标进程名process_name,若有则进程名对应的进程号即为pid。接着,直接调用函数ptrace_attach(pid)即可完成关联。

    2.   获取并保存目标进程寄存器值:用ptrace(PTRACE_GETREGS, pid, NULL, &saved_regs)

    3.   获取目标进程的dlopen,dlsym函数的绝对地址:首先通过遍历/proc/pid/maps文件分别得到本进程中dlopen函数所在动态库的基地址local_module_base和目标进程dlopen函数所在动态库的基地址remote_module_base,接着获取本进程dlopen函数的绝对地址local_addr = (void*)dlopen。需要明白的是,不同进程中相同的动态库中的同一个函数的偏移地址一定是一样的,所以目标进程dlopen函数的绝对地址为:local_addr – local_module_base + remote_module_base。dlsym同理

    4.   获取并保存目标进程的堆栈,设置dlopen函数的相关参数,将要注入的SO的绝对路径压栈:当我们的要执行的函数的某些参数需要压入堆栈的时候,就需要提前保存堆栈状态,调用ptrace_readdata(pid, (void *)regs.ARM_sp, (void *)sbuf, sizeof(sbuf)),其中sbuf为char数组,用来存放堆栈。调用ptrace_writedata(pid, (void *)regs.ARM_sp, (void *)so_path, strlen(so_path) + 1),其中so_path为SO的绝对路径。函数传参规则:前四个参数分别由寄存器r0、r1、r2、r3存放,超过四个参数则压入堆栈。

    5.  调用dlopen函数:参数设置好后,设置ARM_pc = dlopen_addr, ARM_lr = 0。调用ptrace_setregs(pid, regs)写入修改后的寄存器值,调用ptrace_continue( pid )使目标进程继续运行。(注:dlopen_addr为0x03获取到的目标进程dlopen函数的绝对地址,ARM_lr = 0的目的在于当目标进程执行完dlopen函数,使目标进程发生异常,从而让本进程重新获得控制权)

    6.  调用dlsym函数,获取SO中要执行的函数地址:实现方式与调用dlopen函数类似,不再详述

    7.   调用要执行的函数:实现方式与调用dlopen函数类似

    8.   恢复目标进程的堆栈,恢复目标进程寄存器值,解除关联,完成SO动态库注:调用ptrace_writedata(pid, (uint8_t *)saved_regs.ARM_sp, (uint8_t *)sbuf, sizeof(sbuf))恢复堆栈,调用ptrace_setregs(pid, &saved_regs)恢复寄存器值,调用ptrace_detach(pid)解除关联,完成SO动态库注入

    0x03

    我知道都不爱看上边原理,下面直接开始吧

    首先我有一个可以root机器(没有别玩了,我是自己买的5儿子)

    Linux下安装NDK 在环境变量里配好(kali /etc/profile),加上解压后的NDK路径

    下面我们需要编译两个文件 xxxx.so(你的SO),nject(用来注入的)

    为了编译我们需要创建两个文件夹在任意目录下

    两个文件夹都是xxx.c+jni(文件夹)  ,jni下放的是Android.mk文件

    1.hello 下的 hello.c

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <android/log.h>
    #include <elf.h>
    #include <fcntl.h>

    #define LOG_TAG “DEBUG”
    #define LOGD(fmt, args…) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##args)

    int hook_entry(char * a){
    LOGD(“Hook success, pid = %d ”, getpid());
    LOGD(“Hello %s ”, a);
    return 0;
    }

    hello/jni/Android.mk

    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog #增加了对android log 库的链接
    LOCAL_MODULE := hello
    LOCAL_SRC_FILES := ../hello.c
    include $(BUILD_SHARED_LIBRARY) #指定编译为动态库

    2.libinject2下的ject.c (太长了加个链接)

    http://blog.csdn.net/jinzhuojun/article/details/9900105

    找不到asm/user.h 请改为sys/user.h

    libinject2/jni/Android.mk

    OCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := inject
    LOCAL_SRC_FILES := ../inject.c
    LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
    include $(BUILD_EXECUTABLE)

    下面就是进行编译这两个文件

    一个是so文件一个可执行文件

    把他俩push到手机的/data/local/tmp文件夹下 chmod 777 即可

    随便PS找到一个进程(我用的com.android.phone)找到进程号,执行./inject

    这里要先把libhello文件移动到上面的路径,运行,监控logcat

    这里的Hook success 和Hello就是SO内容了,到此SO动态注入成功了

    感谢:

    http://blog.csdn.net/jinzhuojun/article/details/9900105

    http://www.cnblogs.com/jiayy/p/4286828.html

  • 相关阅读:
    s
    qq
    qqq
    q
    qq
    http请求报文
    qq
    q
    qqq
    java对象-String的用法
  • 原文地址:https://www.cnblogs.com/nuomin/p/7524908.html
Copyright © 2020-2023  润新知