日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )

發(fā)布時(shí)間:2025/6/17 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 ) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一、準(zhǔn)備 mmap 函數(shù)的參數(shù)
  • 二、mmap 函數(shù)遠(yuǎn)程調(diào)用





一、準(zhǔn)備 mmap 函數(shù)的參數(shù)



上一篇博客 【Android 逆向】Android 進(jìn)程注入工具開(kāi)發(fā) ( 注入代碼分析 | 遠(yuǎn)程調(diào)用 目標(biāo)進(jìn)程中 libc.so 動(dòng)態(tài)庫(kù)中的 mmap 函數(shù) 一 | mmap 函數(shù)簡(jiǎn)介 ) 中介紹了 mmap 函數(shù) ;

mmap 函數(shù)的函數(shù)原型如下 :

<sys/mman.h> void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset); int munmap(void* start,size_t length);

mmap 函數(shù)參數(shù)含義 :

  • void* start : 如果為 0 就是讓系統(tǒng)自動(dòng)分配 , 如果不為 0 , 則由用戶(hù)指定分配的地址 ;
  • size_t length : 申請(qǐng)分配內(nèi)存的大小 ;
  • int prot : 內(nèi)存保護(hù)標(biāo)志 , 如 PROT_READ | PROT_WRITE | PROT_EXEC , 表示 可讀 | 可寫(xiě) | 可執(zhí)行 ;
  • int flags : 映射對(duì)象類(lèi)型標(biāo)志位標(biāo)志位 , 如 MAP_ANONYMOUS | MAP_PRIVATE , 表示 匿名 | 私有 ;
  • int fd : 文件描述符 ; 沒(méi)有設(shè)置為 0 ;
  • off_t offset : 被映射對(duì)象的起點(diǎn)偏移量 , 一般設(shè)置 0 ;

將 mmap 的參數(shù)放到 parameters 數(shù)組中 , 之后要將該地址傳遞給遠(yuǎn)程進(jìn)程的 ESP 寄存器 , 用于指定

long parameters[10];/* 下面是遠(yuǎn)程調(diào)用 mmap 函數(shù)分配棧內(nèi)存信息 *//* call mmap 調(diào)用 mmap 函數(shù)傳入的參數(shù) */parameters[0] = 0; // addr 地址讓系統(tǒng)分配 , 也可以指定內(nèi)存地址parameters[1] = 0x4000; // size 分配的內(nèi)存大小 0x4000 字節(jié) , 也就是 16KB , mmap 函數(shù)的參數(shù)胡parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot 可讀 | 可寫(xiě) | 可執(zhí)行 parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags 匿名 | 私有 parameters[4] = 0; //fd 文件描述符 parameters[5] = 0; //offset 偏移量



二、mmap 函數(shù)遠(yuǎn)程調(diào)用



由于遠(yuǎn)程調(diào)用涉及到寄存器的操作 , 因此 arm 架構(gòu) 與 x86 架構(gòu)的 遠(yuǎn)程調(diào)用是不同的 , 本次開(kāi)發(fā)的是 x86 架構(gòu)下的遠(yuǎn)程調(diào)用 ;


首先 , 將 mmap 函數(shù)執(zhí)行的參數(shù) , 寫(xiě)出到遠(yuǎn)程進(jìn)程的內(nèi)存中 , 調(diào)用 ptrace_writedata 方法 , 寫(xiě)出內(nèi)存數(shù)據(jù) ;

/* 設(shè)置 ESP 棧指針寄存器 */regs->esp -= (num_params) * sizeof(long);/* 將 long* params 參數(shù)寫(xiě)出到 pid 對(duì)應(yīng)的遠(yuǎn)程進(jìn)程中 , 然后將寫(xiě)出后數(shù)據(jù)的首地址 , 設(shè)置到 pid_t pid 進(jìn)程號(hào)對(duì)應(yīng)的遠(yuǎn)程進(jìn)程的 ESP 寄存器中 , 設(shè)置的數(shù)據(jù)長(zhǎng)度 4 字節(jié) */ptrace_writedata(pid, (uint8_t*)(void*)regs->esp, (uint8_t*)params, (num_params) * sizeof(long));

此外還要在棧中設(shè)置一個(gè) 0 地址 , 為了保證遠(yuǎn)程進(jìn)程執(zhí)行完畢后 , 自動(dòng)訪(fǎng)問(wèn) 0 地址 , 導(dǎo)致崩潰 , 這樣調(diào)試程序就可以收回控制權(quán) ; 參考 【Android 逆向】Android 進(jìn)程注入工具開(kāi)發(fā) ( EIP 寄存器指向 dlopen 函數(shù) | ESP 寄存器指向棧內(nèi)存 | 調(diào)試程序收回目標(biāo)進(jìn)程控制權(quán) ) 博客 ;

/* 設(shè)置一個(gè) 0 地址 */long tmp_addr = 0x00;/* 設(shè)置 0 地址的作用是 保證 遠(yuǎn)程進(jìn)程 訪(fǎng)問(wèn)該 0 地址 導(dǎo)致崩潰 , 調(diào)試工具收回進(jìn)程控制權(quán) */regs->esp -= sizeof(long);ptrace_writedata(pid, (uint8_t*)(regs->esp), (uint8_t*)&tmp_addr, sizeof(tmp_addr));

然后 , 設(shè)置 遠(yuǎn)程進(jìn)程 的 EIP 寄存器 , 指定執(zhí)行哪個(gè)函數(shù) , 這個(gè) 函數(shù)地址 是在 【Android 逆向】Android 進(jìn)程注入工具開(kāi)發(fā) ( 注入代碼分析 | 獲取 遠(yuǎn)程 目標(biāo)進(jìn)程 中的 /system/lib/libc.so 動(dòng)態(tài)庫(kù)中的 mmap 函數(shù)地址 ) 博客中獲取的 mmap 函數(shù)地址 ;

/* 設(shè)置 EIP 寄存器值 , 存儲(chǔ) CPU 下一條將要執(zhí)行的指令 */regs->eip = addr;/* 設(shè)置 pid 遠(yuǎn)程進(jìn)程的寄存器值 */if (ptrace_setregs(pid, regs) == -1|| ptrace_continue(pid) == -1) {printf("error\n");return -1;}

最后 , 調(diào)用 ptrace_continue 方法 , 執(zhí)行該 mmap 函數(shù) ;

ptrace_continue(pid)

mmap 函數(shù)遠(yuǎn)程調(diào)用 完整代碼 :

#elif defined(__i386__) long ptrace_call(pid_t pid, uint32_t addr, long* params, uint32_t num_params, struct user_regs_struct* regs) {/* 參數(shù)說(shuō)明 : */if (num_params > 0 && (params != NULL)) {/* 設(shè)置 ESP 棧指針寄存器 */regs->esp -= (num_params) * sizeof(long);/* 將 long* params 參數(shù)寫(xiě)出到 pid 對(duì)應(yīng)的遠(yuǎn)程進(jìn)程中 , 然后將寫(xiě)出后數(shù)據(jù)的首地址 , 設(shè)置到 pid_t pid 進(jìn)程號(hào)對(duì)應(yīng)的遠(yuǎn)程進(jìn)程的 ESP 寄存器中 , 設(shè)置的數(shù)據(jù)長(zhǎng)度 4 字節(jié) */ptrace_writedata(pid, (uint8_t*)(void*)regs->esp, (uint8_t*)params, (num_params) * sizeof(long));}/* 設(shè)置一個(gè) 0 地址 */long tmp_addr = 0x00;/* 設(shè)置 0 地址的作用是 保證 遠(yuǎn)程進(jìn)程 訪(fǎng)問(wèn)該 0 地址 導(dǎo)致崩潰 , 調(diào)試工具收回進(jìn)程控制權(quán) */regs->esp -= sizeof(long);ptrace_writedata(pid, (uint8_t*)(regs->esp), (uint8_t*)&tmp_addr, sizeof(tmp_addr));/* 設(shè)置 EIP 寄存器值 , 存儲(chǔ) CPU 下一條將要執(zhí)行的指令 */regs->eip = addr;/* 設(shè)置 pid 遠(yuǎn)程進(jìn)程的寄存器值 */if (ptrace_setregs(pid, regs) == -1|| ptrace_continue(pid) == -1) {printf("error\n");return -1;}/* 等待遠(yuǎn)程調(diào)用執(zhí)行完畢 */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; }

總結(jié)

以上是生活随笔為你收集整理的【Android 逆向】Android 进程注入工具开发 ( 注入代码分析 | 远程调用 目标进程中 libc.so 动态库中的 mmap 函数 二 | 准备参数 | 远程调用 mmap 函数 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。