android 进程注入动态库 inject

#include <stdio.h>  
#include <stdlib.h>  
#include <asm/user.h>  
#include <asm/ptrace.h>  
#include <sys/ptrace.h>  
#include <sys/wait.h>  
#include <sys/mman.h>  
#include <dlfcn.h>  
#include <dirent.h>  
#include <unistd.h>  
#include <string.h>  
#include <elf.h>  
#include <android/log.h>  




#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>


#include <cutils/compiler.h>
#include <cutils/properties.h>


#include <utils/Log.h>


//#include "AudioResamplerSinc.h"








  
#if defined(__i386__)  
xxxxxxxxxxxxx
#define pt_regs         user_regs_struct  
#endif  
  
#define ENABLE_DEBUG 1  
  
#if ENABLE_DEBUG  
#define  LOG_TAG "INJECT"  
//#define  LOGD(fmt, args...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, fmt, ##args)  




#define  LOGD(fmt, args...) printf(ANDROID_LOG_DEBUG,LOG_TAG, fmt, ##args)  


//dddd
#define DEBUG_PRINT(format,args...) \  
    LOGD(format, ##args)  
#else  
#define DEBUG_PRINT(format,args...)  
#endif  
  
#define CPSR_T_MASK     ( 1u << 5 )  
  
const char *libc_path = "/system/lib/libc.so";  
const char *linker_path = "/system/bin/linker";  
  
int ptrace_readdata(pid_t pid,  uint8_t *src, uint8_t *buf, size_t size)  
{  
    uint32_t i, j, remain;  
    uint8_t *laddr;  
  
    union u {  
        long val;  
        char chars[sizeof(long)];  
    } d;  
  
    j = size / 4;  
    remain = size % 4;  
  
    laddr = buf;  
  
    for (i = 0; i < j; i ++) {  
        d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);  
        memcpy(laddr, d.chars, 4);  
        src += 4;  
        laddr += 4;  
    }  
  
    if (remain > 0) {  
        d.val = ptrace(PTRACE_PEEKTEXT, pid, src, 0);  
        memcpy(laddr, d.chars, remain);  
    }  
  
    return 0;  
}  
  
int ptrace_writedata(pid_t pid, uint8_t *dest, uint8_t *data, size_t size)  
{  
    uint32_t i, j, remain;  
    uint8_t *laddr;  
  
    union u {  
        long val;  
        char chars[sizeof(long)];  
    } d;  
  
    j = size / 4;  
    remain = size % 4;  
    laddr = data;  
    //printf( "j = %x\n", j);
    //printf( "remain = %x\n", remain );
    //printf( "laddr = %x\n", laddr );
  
    for (i = 0; i < j; i ++) {  
        memcpy(d.chars, laddr, 4);  
        ptrace(PTRACE_POKETEXT, pid, dest, d.val);  
  
        dest  += 4;  
        laddr += 4;  
    }  
  
    if (remain > 0) {  
        d.val = ptrace(PTRACE_PEEKTEXT, pid, dest, 0);
        //printf( "d.val = %x\n", d.val );
        for (i = 0; i < remain; i ++) {  
            d.chars[i] = *laddr ++;  
        }  
  //printf( "d.val = %x\n", d.val );
  
        ptrace(PTRACE_POKETEXT, pid, dest, d.val);  
    }  
  
    return 0;  
}  
  
#if defined(__arm__)  
int ptrace_call(pid_t pid, uint32_t addr, long *params, uint32_t num_params, struct pt_regs* regs)  
{  
    uint32_t i;  
    for (i = 0; i < num_params && i < 4; i ++) {  
        regs->uregs[i] = params[i];  
    }  
  
    //  
    // push remained params onto stack  
    //  
    if (i < num_params) {  
        regs->ARM_sp -= (num_params - i) * sizeof(long) ;  
        ptrace_writedata(pid, (void *)regs->ARM_sp, (uint8_t *)&params[i], (num_params - i) * sizeof(long));  
    }  
  
    regs->ARM_pc = addr;  
    if (regs->ARM_pc & 1) {  
        /* thumb */  
        regs->ARM_pc &= (~1u);  
        regs->ARM_cpsr |= CPSR_T_MASK;  
    } else {  
        /* arm */  
        regs->ARM_cpsr &= ~CPSR_T_MASK;  
    }  
  
    regs->ARM_lr = 0;      
  
    if (ptrace_setregs(pid, regs) == -1   
            || ptrace_continue(pid) == -1) {  
        printf("error\n");  
        return -1;  
    }




    int stat = 0;


    waitpid(pid, &stat, WUNTRACED);
while (stat != 0xb7f) {
            if (ptrace_continue(pid) == -1){
                printf("error\n");
                return -1;
}
            waitpid(pid, &stat, WUNTRACED);
    }
  
    return 0;  
}  
  
#elif defined(__i386__)  
long ptrace_call(pid_t pid, uint32_t addr, long *params, uint32_t num_params, struct user_regs_struct * regs)  
{  
    regs->esp -= (num_params) * sizeof(long) ;  
    ptrace_writedata(pid, (void *)regs->esp, (uint8_t *)params, (num_params) * sizeof(long));  
  
    long tmp_addr = 0x00;  
    regs->esp -= sizeof(long);  
    ptrace_writedata(pid, regs->esp, (char *)&tmp_addr, sizeof(tmp_addr));   
  
    regs->eip = addr;  
  
    if (ptrace_setregs(pid, regs) == -1   
            || ptrace_continue( pid) == -1) {  
        printf("error\n");  
        return -1;  
    }  
  
聽聽聽 int stat = 0;
聽聽聽 waitpid(pid, &stat, WUNTRACED);
聽聽聽 while (stat != 0xb7f) {
聽聽聽聽聽聽聽 if (ptrace_continue(pid) == -1) {
聽聽聽聽聽聽聽聽聽聽聽 printf("error\n");
聽聽聽聽聽聽聽聽聽聽聽 return -1;
聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽 waitpid(pid, &stat, WUNTRACED);
聽聽聽 }
  
    return 0;  
}  
#else   
#error "Not supported"  
#endif  
  
int ptrace_getregs(pid_t pid, struct pt_regs * regs)  
{  
    if (ptrace(PTRACE_GETREGS, pid, NULL, regs) < 0) {  
        perror("ptrace_getregs: Can not get register values");  
        return -1;  
    }  
  
    return 0;  
}  
  
int ptrace_setregs(pid_t pid, struct pt_regs * regs)  
{  
    if (ptrace(PTRACE_SETREGS, pid, NULL, regs) < 0) {  
        perror("ptrace_setregs: Can not set register values");  
        return -1;  
    }  
  
    return 0;  
}  
  
int ptrace_continue(pid_t pid)  
{  
    if (ptrace(PTRACE_CONT, pid, NULL, 0) < 0) {  
        perror("ptrace_cont");  
        return -1;
    }  
  
    return 0;
}  
  
int ptrace_attach(pid_t pid)  
{  
    if (ptrace(PTRACE_ATTACH, pid, NULL, 0) < 0) {  
        perror("ptrace_attach");  
        return -1;  
    }  
  
    int status = 0;  
    waitpid(pid, &status , WUNTRACED);  
  
    return 0;  
}  
  
int ptrace_detach(pid_t pid)  
{  
    if (ptrace(PTRACE_DETACH, pid, NULL, 0) < 0) {  
        perror("ptrace_detach");  
        return -1;  
    }  
  
    return 0;  
}  
  
void* get_module_base(pid_t pid, const char* module_name)  
{  
    FILE *fp;  
    long addr = 0;  
    char *pch;  
    char filename[32];  
    char line[1024];  
  
    if (pid < 0) {  
        /* self process */  
        snprintf(filename, sizeof(filename), "/proc/self/maps", pid);  
    } else {  
        snprintf(filename, sizeof(filename), "/proc/%d/maps", pid);  
    }  
  
    fp = fopen(filename, "r");  
    //printf("filename = %s\n", filename);
    if (fp != NULL) {  
        while (fgets(line, sizeof(line), fp)) { 
 
            if (strstr(line, module_name)) {  
 //printf("line = %s\n", line);
                pch = strtok( line, "-" );  
                addr = strtoul( pch, NULL, 16 );  
  
                if (addr == 0x8000)  
                    addr = 0;  
  
                break;  
            }  
        }  
  
        fclose(fp) ;  
    }  
  
    return (void *)addr;  
}  
  
void* get_remote_addr(pid_t target_pid, const char* module_name, void* local_addr)  
{  
    void* local_handle, *remote_handle;  
  
    local_handle = get_module_base(-1, module_name);  
    remote_handle = get_module_base(target_pid, module_name);  
  
    //printf("[+] get_remote_addr: local[%x], remote[%x]\n", local_handle, remote_handle);  
    //printf("[+] get_remote_addr: local_addr[%x], local_addr[%x]\n", local_addr, local_addr); 
    void * ret_addr = (void *)((uint32_t)local_addr + (uint32_t)remote_handle - (uint32_t)local_handle);  
  
#if defined(__i386__)  
    if (!strcmp(module_name, libc_path)) {  
        ret_addr += 2;  
    }  
#endif  
    return ret_addr;  
}  
  
int find_pid_of(const char *process_name)  
{  
    int id;  
    pid_t pid = -1;  
    DIR* dir;  
    FILE *fp;  
    char filename[32];  
    char cmdline[256];  
  
    struct dirent * entry;  
  
    if (process_name == NULL)  
        return -1;  
  
    dir = opendir("/proc");  
    if (dir == NULL)  
        return -1;  
  
    while((entry = readdir(dir)) != NULL) {  
        id = atoi(entry->d_name); 
//printf("entry->d_name = %s.\n", entry->d_name);
        //printf("id = %d.\n", id);
        if (id != 0) {  
            sprintf(filename, "/proc/%d/cmdline", id);  
            fp = fopen(filename, "r");  
            if (fp) {  
                fgets(cmdline, sizeof(cmdline), fp);  
                fclose(fp);  
  
                if (strcmp(process_name, cmdline) == 0) {  
                    /* process found */  
                    pid = id;  
                    break;  
                }  
            }  
        }  
    }  
  
    closedir(dir);  
    return pid;  
}  
  
long ptrace_retval(struct pt_regs * regs)  
{  
#if defined(__arm__)  


    return regs->ARM_r0;  

#elif defined(__i386__)
xxxxxx  
    return regs->eax;  
#else  
vvxxxxxx
#error "Not supported"  
#endif  
}  
  
long ptrace_ip(struct pt_regs * regs)  
{  
#if defined(__arm__)  
    return regs->ARM_pc;  
#elif defined(__i386__)  
    return regs->eip;  
#else  
#error "Not supported"  
#endif  
}  
  
int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, long * parameters, int param_num, struct pt_regs * regs)   
{  
    printf("[+] Calling %s in target process.\n", func_name);  
    if (ptrace_call(target_pid, (uint32_t)func_addr, parameters, param_num, regs) == -1)  
        return -1;  
  
    if (ptrace_getregs(target_pid, regs) == -1)  
        return -1;  
    printf("[+] Target process returned from %s, return value=%x, pc=%x \n",   
            func_name, ptrace_retval(regs), ptrace_ip(regs));  
    return 0;  
}  
  
int inject_remote_process(pid_t target_pid, const char *library_path, const char *function_name, const char *param, size_t param_size)  
{  
    int ret = -1;  
    void *mmap_addr, *dlopen_addr, *dlsym_addr, *dlclose_addr, *dlerror_addr;  
    void *local_handle, *remote_handle, *dlhandle;  
    uint8_t *map_base = 0;  
    uint8_t *dlopen_param1_ptr, *dlsym_param2_ptr, *saved_r0_pc_ptr, *inject_param_ptr, *remote_code_ptr, *local_code_ptr;  
  
    struct pt_regs regs, original_regs;  
    extern uint32_t _dlopen_addr_s, _dlopen_param1_s, _dlopen_param2_s, _dlsym_addr_s, \  
        _dlsym_param2_s, _dlclose_addr_s, _inject_start_s, _inject_end_s, _inject_function_param_s, \  
        _saved_cpsr_s, _saved_r0_pc_s;  
  
    uint32_t code_length;  
    long parameters[10];  
  
    printf("[+] Injecting process: %d\n", target_pid);  
  
    if (ptrace_attach(target_pid) == -1){  
  //结婚
        goto exit;  
    }
  
    if (ptrace_getregs(target_pid, &regs) == -1){ 
        //婚前财产公证 
        goto exit;  
    }
  
    //save original registers  
    memcpy(&original_regs, &regs, sizeof(regs)); 
    //为离婚做准备
  
    mmap_addr = get_remote_addr(target_pid, libc_path, (void *)mmap);  
    printf("[+] Remote mmap address: %x\n", mmap_addr);  
    //获取mmap函数的执行虚地址  





    //call mmap  
    parameters[0] = 0;  
    //addr  
    parameters[1] = 0x4000; 
    //size  
    parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC;  
    //prot  
    parameters[3] =  MAP_ANONYMOUS | MAP_PRIVATE; 
    //flags  
    parameters[4] = 0; 
    //fd  
    parameters[5] = 0; 
    //offset
    if( ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, &regs) == -1 ){  
        goto exit;  
    }  
    map_base = ptrace_retval(&regs);  
    printf( "map_base: %x\n", map_base );






    dlopen_addr = get_remote_addr( target_pid, linker_path, (void *)dlopen );  
    dlsym_addr = get_remote_addr( target_pid, linker_path, (void *)dlsym );  
    dlclose_addr = get_remote_addr( target_pid, linker_path, (void *)dlclose );  
    dlerror_addr = get_remote_addr( target_pid, linker_path, (void *)dlerror );  
 
    printf("[+] Get imports: dlopen: %x, dlsym: %x, dlclose: %x, dlerror: %x\n",  
            dlopen_addr, dlsym_addr, dlclose_addr, dlerror_addr);  
  
    printf("library path = %s\n", library_path);  
    ptrace_writedata(target_pid, map_base, library_path, strlen(library_path) + 1);  
  
    parameters[0] = map_base;     
    parameters[1] = RTLD_NOW| RTLD_GLOBAL;   
  
    if( ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, &regs) == -1 ){ 
        //打开动态链接库
        goto exit;  
    }
    void * sohandle = ptrace_retval(&regs);
    //返回动态链接库的控制句柄
  
    #define FUNCTION_NAME_ADDR_OFFSET       0x100  
    ptrace_writedata(target_pid, map_base + FUNCTION_NAME_ADDR_OFFSET, function_name, strlen(function_name) + 1);  
    //将钩子函数的函数名写入内存
    parameters[0] = sohandle;     
    parameters[1] = map_base + FUNCTION_NAME_ADDR_OFFSET;   
    if( ptrace_call_wrapper(target_pid, "dlsym", dlsym_addr, parameters, 2, &regs) == -1 ){
        //调用系统函数dlsym,参数为包含钩子函数动态库的首地址,钩子函数的名称
        goto exit;  
    } 
    void * hook_entry_addr = ptrace_retval(&regs);
    //其结果就是返回钩子函数的句柄,即函数的执行地址
    printf("hook_entry_addr = %p\n", hook_entry_addr);  
  
    #define FUNCTION_PARAM_ADDR_OFFSET      0x200  
    ptrace_writedata(target_pid, map_base + FUNCTION_PARAM_ADDR_OFFSET, param, strlen(param) + 1);  
    //将欲调用的钩子函数的参数写入内存
    parameters[0] = map_base + FUNCTION_PARAM_ADDR_OFFSET;     
    if( ptrace_call_wrapper(target_pid, "hook_entry", hook_entry_addr, parameters, 1, &regs) == -1 ){
        //调用钩子函数
        goto exit;  
    }
  
    printf("Press enter to dlclose and detach\n");  
    getchar();  
    //从控制台获取一个字符
    parameters[0] = sohandle;     
    if( ptrace_call_wrapper(target_pid, "dlclose", dlclose, parameters, 1, &regs) == -1 ){  
        //关闭钩子函数动态链接库
        goto exit;  
    }
  
    //restore  
    ptrace_setregs(target_pid, &original_regs);  
    //归还结婚戒指,恢复程序现场
    ptrace_detach(target_pid);  
    //离婚
    ret = 0;  
  
exit:  
    return ret;  
}






//dd
  
int main(int argc, char** argv) {
    pid_t target_pid;
printf("inject.c main.\n");
    target_pid = find_pid_of("/system/bin/htfsk");
    if (-1 == target_pid) {
        printf("Can't find the process\n");
        return -1;
    }
printf("target_pid = %d.\n", target_pid);
    //target_pid = find_pid_of("/data/test");
    //inject_remote_process(target_pid, "/data/libhello.so", "hook_entry", "I'm parameter!", strlen("I'm parameter!"));

//inject_remote_process(target_pid, "/system/lib/libtest_hello.so", "hook_entry", "I'm parameter!", strlen("I'm parameter!"));
inject_remote_process(target_pid, "/system/lib/libtest_hello.so", "hook_entry", "I'm parameter!", strlen("I'm parameter!"));
    return 0;

}









#include <stdio.h>  
#include <stdlib.h>  
#include <asm/user.h>  
#include <asm/ptrace.h>  
#include <sys/ptrace.h>  
#include <sys/wait.h>  
#include <sys/mman.h>  
#include <dlfcn.h>  
#include <dirent.h>  
#include <unistd.h>  
#include <string.h>  
#include <elf.h>  
#include <android/log.h>  




#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <dlfcn.h>


#include <cutils/compiler.h>
#include <cutils/properties.h>


#include <utils/Log.h>


//#include "AudioResamplerSinc.h"








  
#if defined(__i386__)  
xxxxxxxxxxxxx
#define pt_regs         user_regs_struct  
#endif  
  
#define ENABLE_DEBUG 1  
  
#if ENABLE_DEBUG  
#define  LOG_TAG "INJECT"  
//#define  LOGD(fmt, args...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, fmt, ##args)  




#define  LOGD(fmt, args...) printf(ANDROID_LOG_DEBUG,LOG_TAG, fmt, ##args)  


//dddd
#define DEBUG_PRINT(format,args...) \  
    LOGD(format, ##args)  
#else  
#define DEBUG_PRINT(format,args...)  
#endif  
  
#define CPSR_T_MASK     ( 1u << 5 )  
  




  


  














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




#define TAG  "htfsk"


#define LOGE(x...) do { KLOG_ERROR("events", x); } while (0)
#define LOGI(x...) do { KLOG_INFO("events", x); } while (0)
#define LOGV(x...) do { KLOG_DEBUG("events", x); } while (0)
#if 0
int debug_msg(const char *format, ...)
{
    char tmpbuf[4096];
    unsigned int send_len;
    va_list vArgs;
    va_start(vArgs, format);  
    vsnprintf( (char *)&tmpbuf[0], sizeof(tmpbuf), (char const *)format, vArgs );   
    va_end(vArgs);
    send_len = strlen(&tmpbuf[0]);
__android_log_write( ANDROID_LOG_DEBUG, TAG, tmpbuf );  
    return 0;
}
#endif
   


int hook_entry(char * a){
    //debug_msg("Hook success, pid = %d\n", getpid());
    //debug_msg("Hello %s\n", a);


//__android_log_write( ANDROID_LOG_DEBUG, TAG, "hook_entry 123" ); 

system("echo mabi 123 >/dev/ttyS0");
    return 19;
}

















include $(CLEAR_VARS)
LOCAL_SRC_FILES := bionic/inject.c
LOCAL_MODULE := test_dlclose_destruction1
LOCAL_LDFLAGS := -ldl
#LOCAL_SHARED_LIBRARIES := libdlclosetest1 libdlclosetest2
LOCAL_MODULE_TAGS := tests
include $(BUILD_EXECUTABLE)










include $(CLEAR_VARS)
LOCAL_SRC_FILES := bionic/lib_hello.c
LOCAL_MODULE    := libtest_hello
LOCAL_MODULE_TAGS := tests
#LOCAL_SHARED_LIBRARIES := libdlclosetest1 libdlclosetest2 liblog


include $(BUILD_SHARED_LIBRARY)














结果:

shell@astar-dvk3:/proc/self # 
shell@astar-dvk3:/proc/self # 
shell@astar-dvk3:/proc/self # 
shell@astar-dvk3:/proc/self # test_dlclose_destruction1                        
inject.c main.
target_pid = 757.
[+] Injecting process: 757
[+] Remote mmap address: 401bbcf9
[+] Calling mmap in target process.
[+] Target process returned from mmap, return value=417cf000, pc=0 
map_base: 417cf000
[+] Get imports: dlopen: 400c7f4d, dlsym: 400c7e9d, dlclose: 400c7e19, dlerror: 400c7dc9
library path = /system/lib/libtest_hello.so
[+] Calling dlopen in target process.
[+] Target process returned from dlopen, return value=415fbc90, pc=0 
[+] Calling dlsym in target process.
[+] Target process returned from dlsym, return value=417ac359, pc=0 
hook_entry_addr = 0x417ac359
[+] Calling hook_entry in target process.
mabi 123
[+] Target process returned from hook_entry, return value=13, pc=0 
Press enter to dlclose and detach


[+] Calling dlclose in target process.
[+] Target process returned from dlclose, return value=415fbc90, pc=4008be18 
shell@astar-dvk3:/proc/self # 
shell@astar-dvk3:/proc/self # 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值