前言
逆向某app時辕漂,想用frida進行hook分析其執(zhí)行流程,遇到了frida的反調(diào)試讼积。這里記錄一下出現(xiàn)問題的情況和反調(diào)試的實現(xiàn).
環(huán)境
Android8
frida12.11.18
windows10
frida 注入
使用frida -U注入app
frida -U com.shark.tracerpidapp
結果如下
____
/ _ | Frida 12.11.18 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://www.frida.re/docs/home/
Failed to spawn: ambiguous name; it matches: com.shark.tracerpidapp (pid: 9802), com.shark.tracerpidapp (pid: 9847)
這里有兩個com.shark.tracerpidapp名稱的進程
我們直接進入adb查看進程
sailfish:/ # ps -A | grep com.shark
u0_a129 9802 671 2251940 73376 SyS_epoll_wait 72493ca5d0 S com.shark.tracerpidapp
u0_a129 9847 9802 2231280 34092 hrtimer_nanosleep 72493cafd8 S com.shark.tracerpidapp
可以看到確實有兩個進程嘹履,frida分不清你要注入哪個進程所以報出如上錯誤。
我們選擇父進程進行注入
(venv) D:\FridaTest>frida -U 9802
____
/ _ | Frida 12.11.18 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://www.frida.re/docs/home/
Failed to attach: unable to access process with pid 9802 due to system restrictions; try `sudo sysctl kernel.yama.ptrace_scope=0`, or run Frida as root
叫我們用root去執(zhí)行羹蚣,這里是沒有用的。我們到adb看看這個父進程的TracerPid信息就知道了
至于為什么看TracerPid請移步文章TracerPid反調(diào)試
sailfish:/ # cat /proc/9802/status | grep TracerPid
TracerPid: 9847
可以看到父進程已經(jīng)被子進程ATTACH,而frida也依賴于ptrace所以這里肯定注入不進去
解決方案
我們不要讓frida注入脸候,而是使用frida啟動app,使用-f選項,我們告訴Frida注入Zygote并開始啟動應用程序
(venv) D:\FridaTest>frida -U -f com.shark.tracerpidapp
____
/ _ | Frida 12.11.18 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://www.frida.re/docs/home/
Spawned `com.shark.tracerpidapp`. Use %resume to let the main thread start executing!
[Pixel::com.shark.tracerpidapp]-> %resume
還有一種打補丁的方式运沦,在下面參考中有泵额。這里就不再贅述。
反調(diào)試實現(xiàn)原理
這個反調(diào)試其實就是用了TracerPid反調(diào)試的原理携添,但是在這里有一些不一樣嫁盲。
1:這里是子進程ATTACH父進程
2:在Android8中ptrace(PTRACE_TRACEME, 0, 0, 0); 雖然返回的不是-1但是無法成功
PTRACE_ATTACH
所以我們這里要使用ptrace(PTRACE_ATTACH, parent, 0, 0)來實現(xiàn)。
PTRACE_ATTACH參數(shù)
ptrace(PTRACE_ATTACH,pid)
跟蹤指定pid 進程薪寓。pid表示被跟蹤進程亡资。被跟蹤進程將成為當前進程的子進程,并進入中止狀態(tài)
PTRACE_CONT參數(shù)
ptrace(PTRACE_CONT, pid, 0, signal)
繼續(xù)執(zhí)行向叉。pid表示被跟蹤的子進程锥腻,signal為0則忽略引起調(diào)試進程中止的信號,若不為0則繼續(xù)處理信號signal
先使用PTRACE_ATTACH進行附加母谎,這時候被附加進程會阻塞瘦黑。再使用PTRACE_CONT繼續(xù)執(zhí)行被附加的進程。為了確保PTRACE_CONT能被執(zhí)行我們在PTRACE_ATTACH完后要馬上wait阻塞當前線程奇唤。當附加成功后wait阻塞解除就能執(zhí)行到PTRACE_CONT了
代碼
void readStatus() {
FILE *fd;
char filename[128];
char line[128];
pid_t pid = syscall(__NR_getpid);
LOGI("PID : %d", pid);
sprintf(filename, "/proc/%d/status", pid);//讀取/proc/pid/status中的TracerPid
pid_t ppid = fork();
if (ppid == 0) {
pid_t parent = getppid();
//parent是被跟蹤的進程 異步操作
int pt = ptrace(PTRACE_ATTACH, parent, 0, 0);
int status = 0;
// ATTACH成功前停下 為了保證下面的PTRACE_CONT操作能夠執(zhí)行到 這樣被ATTACH的進程就不會一直進入中止狀態(tài)
wait(NULL);
//讓被調(diào)試的進程重新恢復運行
if (ptrace(PTRACE_CONT, parent, NULL, 0) < 0) {
perror("ptrace_cont");
return;
}
if (pt == -1)
exit(0);
while (1) {
sleep(CHECK_TIME);
}
} else {
LOGE("fork error");
}
}