實現對第三方應用任意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\n”, getpid());
LOGD(“Hello %s\n”, 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM