一、課程目標
1.了解Frida-Native-Hook讀寫、主動調用
2.了解常見的frida_trace工具
3.了解控制流混淆對抗新思路
二、工具
1.教程Demo(更新)
2.jadx-gui
3.VS Code
4.jeb
三、課程內容
1.Frida寫數據
復制代碼 隱藏代碼
//一般寫在app的私有目錄里,不然會報錯:failed to open file (Permission denied)(實際上就是權限不足)
var file_path = "/data/user/0/com.zj.wuaipojie/test.txt";
var file_handle = new File(file_path, "wb");
if (file_handle && file_handle != null) {
file_handle.write(data); //寫入數據
file_handle.flush(); //刷新
file_handle.close(); //關閉
}
2.Frida_inlineHook與讀寫匯編
什么是inlinehook?
Inline hook(內聯鉤子)是一種在程序運行時修改函數執行流程的技術。它通過修改函數的原始代碼,將目標函數的執行路徑重定向到自定義的代碼段,從而實現對目標函數的攔截和修改。
簡單來說就是可以對任意地址的指令進行hook讀寫操作
常見inlinehook框架:
Android-Inline-Hook
whale
Dobby
substrate
PS:Frida的inlinehook不是太穩定,崩潰是基操,另外新版的frida兼容性會比較好
復制代碼 隱藏代碼
function inline_hook() {
var soAddr = Module.findBaseAddress("lib52pojie.so");
if (soAddr) {
var func_addr = soAddr.add(0x10428);
Java.perform(function () {
Interceptor.attach(func_addr, {
onEnter: function (args) {
console.log(this.context.x22); //注意此時就沒有args概念了
this.context.x22 = ptr(1); //賦值方法參考上一節課
},
onLeave: function (retval) {
}
}
)
})
}
}
- 將地址的指令解析成匯編
復制代碼 隱藏代碼
var soAddr = Module.findBaseAddress("lib52pojie.so");
var codeAddr = Instruction.parse(soAddr.add(0x10428));
console.log(codeAddr.toString());
- Frida Api
- arm轉hex
復制代碼 隱藏代碼
var soAddr = Module.findBaseAddress("lib52pojie.so");
var codeAddr = soAddr.add(0x10428);
Memory.patchCode(codeAddr, 4, function(code) {
const writer = new Arm64Writer(code, { pc: codeAddr });
writer.putBytes(hexToBytes("20008052"));
writer.flush();
});
function hexToBytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 != 0) {
return null;
}
len /= 2;
var hexA = new Array();
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
hexA.push(v);
pos += 2;
}
return hexA;
}
3.普通函數與jni函數的主動調用
nativefunction
數據類型描述void無返回值pointer指針int整數long長整數char字符float浮點數double雙精度浮點數bool布爾值 復制代碼 隱藏代碼
var funcAddr = Module.findBaseAddress("lib52pojie.so").add(0x1054C);
//聲明函數指針
//NativeFunction的第一個參數是地址,第二個參數是返回值類型,第三個[]里的是傳入的參數類型(有幾個就填幾個)
var aesAddr = new NativeFunction(funcAddr , 'pointer', ['pointer', 'pointer']);
var encry_text = Memory.allocUtf8String("OOmGYpk6s0qPSXEPp4X31g=="); //開辟一個指針存放字符串
var key = Memory.allocUtf8String('wuaipojie0123456');
console.log(aesAddr(encry_text ,key).readCString());
jni的主動調用
參考java的主動調用,簡單快捷
4.Trace
工具名稱描述鏈接jnitrace老牌,經典,信息全,攜帶方便jnitracejnitrace-engine基于jnitrace,可定制化jnitrace-enginejtrace定制方便,信息全面,直接在_agent.js或者_agent_stable.js 里面加自己的邏輯就行jtracehook_art.js可提供jni trace,可以靈活的增加你需要hook的函數hook_art.jsJNI-Frida-Hook函數名已定義,方便定位JNI-Frida-Hookfindhashida插件,可用于檢測加解密函數,也可作為Native Trace庫findhashStalkerfrida官方提供的代碼跟蹤引擎,可以在Native層方法級別,塊級別,指令級別實現代碼修改,代碼跟蹤Stalkersktrace類似 ida 指令 trace 功能sktracefrida-qbdi-tracer速度比frida stalker快,免補環境frida-qbdi-tracer PS:這次介紹的幾款工具都是基礎用法,更深入的還需要大家去看看源碼學習
4.1 frida-trace
官方文檔
frida-trace 可以一次性監控一堆函數地址。還能打印出比較漂亮的樹狀圖,不僅可以顯示調用流程,還能顯示調用層次。并且貼心的把不同線程調用結果用不同的顏色區分開了。
大佬整理的文檔:
frida-trace
復制代碼 隱藏代碼
D:\> frida-trace.exe --help
用法: frida-trace [options] target
位置參數:
args extra arguments and/or target
選項:
-h, --help 顯示幫助
-D ID, --device ID 通過 ID 連接設備
-U, --usb 通過 USB 連接設備
-R, --remote 連接到遠程 frida-server
-H HOST, --host HOST 連接到遠程 host 上的 frida-server
--certificate 證書 設置證書,通過 TSL 與 host 交互
--origin ORIGIN 設置連接到遠程服務的 "Origin" 頭部
--token TOKEN 設置 與host 認證
--keepalive-interval 時間間隔。0表示禁用,-1表示基于傳輸自動選擇
--p2p 建立一個點對點的連接
--stun-server ADDRESS 設置--p2p 的 STUN 服務地址
--relay address,username,password,turn-{udp,tcp,tls} 添加--p2p 延遲
-f TARGET, --file TARGET spawn 模式
-F, --attach-frontmost 附加到最前端的 application
-n NAME, --attach-name NAME 附加到一個名字
-N IDENTIFIER, --attach-identifier IDENTIFIER 附加到標識符
-p PID, --attach-pid PID 附加到 pid
-W PATTERN, --await PATTERN
await spawn matching PATTERN
--stdio {inherit,pipe}
stdio behavior when spawning (defaults to “inherit”)
--aux option set aux option when spawning, such as “uid=(int)42” (supported types are:
string, bool, int)
--realm {native,emulated} 附件的范圍
--runtime {qjs,v8} 使用的腳本運行環境
--debug 啟用 Node.js 兼容的腳本調試器
--squelch-crash 如果啟用,將不會將崩潰報告轉儲到控制臺
-O FILE, --options-file FILE 將信息保存到文件中
--version 顯示版本號
-i/-a: 跟蹤 C 函數或 so 庫中的函數。- PS:-a 包含模塊+偏移跟蹤,一般用于追蹤未導出函數,例子:-a "lib52pojie.so!0x4793c"
包含/排除模塊或函數:
-I: 包含指定模塊。-X: 排除指定模塊。
Java 方法跟蹤:
-j JAVA_METHOD: 包含 Java 方法。-J JAVA_METHOD: 排除 Java 方法。
附加方式:
-f:通過 spwan 方式啟動-F:通過 attach 方式附加當前進程
日志輸出:
-o:日志輸出到文件
復制代碼 隱藏代碼 使用案例: frida-trace -U -F -I "lib52pojie.so" -i "Java_" #附加當前進程并追蹤lib52pojie.so里的所有Java_開頭的jni導出函數

4.2jnitrace
前提
復制代碼 隱藏代碼 pip install jnitrace==3.3.0
使用方法
復制代碼 隱藏代碼 jnitrace -m attach -l lib52pojie.so com.zj.wuaipojie -o trace.json //attach模式附加52pojie.so并輸出日志
-l libnative-lib.so- 用于指定要跟蹤的庫
-m <spawn|attach>- 用于指定要使用的 Frida 附加機制
-i <regex>- 用于指定應跟蹤的方法名稱,例如,-i Get -i RegisterNatives將僅包含名稱中包含 Get 或 RegisterNatives 的 JNI 方法
-e <regex>- 用于指定跟蹤中應忽略的方法名稱,例如,-e ^Find -e GetEnv將從結果中排除所有以 Find 開頭或包含 GetEnv 的 JNI 方法名稱
-I <string>- 用于指定應跟蹤的庫的導出
-E <string>用于指定不應跟蹤的庫的導出
-o path/output.json- 用于指定jnitrace存儲所有跟蹤數據的輸出路徑

4.3sktrace
復制代碼 隱藏代碼 python sktrace.py -m attach -l lib52pojie.so -i 0x103B4 com.zj.wuaipojie

5.控制流混淆對抗新發現
細品sec2023安卓賽題
JEB Decompiler 5.5.0.202311022109 mod by CXV
PS:注意jdk的版本要高于17,不然打不開
下載地址
恐怖如斯的效果對比圖:

RacentYY
RacentYY
RacentYY
Coremail郵件安全
黑白之道
FreeBuf
RacentYY
一顆小胡椒
FreeBuf
尚思卓越
安全圈
一顆小胡椒