0x00 Frida是什麼
這是一個神通廣大的框架,已經編寫好的程序只能運行同一結果太無趣?Frida可以讓你注入/預加載/集成你自己的代碼,於是就能愉快的和已經寫好的程序交互,讓你攔截、記錄、修改程序的運行過程,樂趣多多。支持Windows, macOS, GNU/Linux, iOS, Android, and QNX.
0x01 Frida原理(簡單介紹版)
frida-core - Frida core library intended for static linking into bindings. frida-core對服務端監聽,注入,控制執行等通用操作進行API抽象管理。
frida-gum - Low-level code instrumentation library used by frida-core. frida-gum提供底層代碼執行的支持,如果你在安卓則執行安卓兼容的控制代碼,同樣的,其他Linux平臺IOS平臺都使用會對應frida-gum的底層執行版本。
在注入一個腳本時,腳本將通過frida-core核心控制通過TCP協議推送到frida-server注入到目標進程,之後通過frida-gum解釋執行底層代碼並回傳結果。
0x02 Frida自帶功能組件
除了自己寫功能,frida也提供了一些現成的實用工具。
組件名稱 |
功能描述 |
實例 |
frida-server |
如果你正在對遠程系統,例如USB連接的手機,這個組件將作爲中間件提供統一的API訪問。因此本地運行無需額外開啓frida-server。 |
Github下載對應版本frida-server推送到遠程設備ROOT運行即可。 |
frida-ps |
列舉正在運行的進程名和進程號。
frida-ps --help Usage: frida-ps [options]
Options: --version show program's version number and exit -h, --help show this help message and exit -D ID, --device=ID connect to device with the given ID -U, --usb connect to USB device -R, --remote connect to remote frida-server -H HOST, --host=HOST connect to remote frida-server on HOST -a, --applications list only applications -i, --installed include all installed applications |
>frida-ps
PID Name ----------------------------- 7008 ApplicationFrameHost.exe 6008 Calculator.exe 6744 svchost.exe 5888 taskhostw.exe ... |
frida-CLI |
frida控制檯遊樂園模式開啓入口。 允許你將frida框架對目標程序進行啓動/附加,之後可以進行控制檯交互。
frida --help Usage: frida [options] target
Options: --version show program's version number and exit -h, --help show this help message and exit -D ID, --device=ID connect to device with the given ID -U, --usb connect to USB device -R, --remote connect to remote frida-server -H HOST, --host=HOST connect to remote frida-server on HOST -f FILE, --file=FILE spawn FILE -n NAME, --attach-name=NAME attach to NAME -p PID, --attach-pid=PID attach to PID --debug enable the Node.js compatible script debugger --enable-jit enable JIT -l SCRIPT, --load=SCRIPT load SCRIPT -c CODESHARE_URI, --codeshare=CODESHARE_URI load CODESHARE_URI -e CODE, --eval=CODE evaluate CODE -q quiet mode (no prompt) and quit after -l and -e --no-pause automatically start main thread after startup -o LOGFILE, --output=LOGFILE output to log file |
# 首先,在本機Windows上運行calc,即計算器。
>frida-ps | findstr /I calc 6008 Calculator.exe
>frida -p 6008 ____ / _ | Frida 12.6.8 - A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about 'object' . . . . exit/quit -> Exit . . . . . . . . More info at http://www.frida.re/docs/home/
[Local::PID::6008]-> var a = 123; undefined [Local::PID::6008]-> a; 123
# 由於frida的注入使用GoogleV8引擎來執行,後面的都是JavaScript語法 操作。 |
frida-discover |
frida-discover is a tool for discovering internal functions in a program, which can then be traced by using frida-trace.
在執行期間內對目標進行Profiling,用於發現有追蹤價值的函數。
frida-discover --help Usage: frida-discover [options] target
Options: --version show program's version number and exit -h, --help show this help message and exit -D ID, --device=ID connect to device with the given ID -U, --usb connect to USB device -R, --remote connect to remote frida-server -H HOST, --host=HOST connect to remote frida-server on HOST -f FILE, --file=FILE spawn FILE -n NAME, --attach-name=NAME attach to NAME -p PID, --attach-pid=PID attach to PID --debug enable the Node.js compatible script debugger --enable-jit enable JIT |
>frida-ps | findstr /I calc 35112 Calculator.exe >frida-discover -p 35112
Attaching... Injecting script... Tracing 24 threads. Press ENTER to stop.
Windows.UI.Xaml.dll Calls Function 24121 sub_35d540 1486 sub_121d20 601 sub_121d90 51 sub_17ae60 49 sub_353368 48 sub_168870 1 sub_22b37c 1 sub_1620f0
ntdll.dll Calls Function 1600 RtlEnterCriticalSection 1595 RtlLeaveCriticalSection 435 RtlAcquireSRWLockShared 1 sub_1c690 1 AlpcInitializeMessageAttribute 1 ZwAlpcQueryInformation
KERNELBASE.dll Calls Function 212 GetProcessHeap 157 GetLastError 133 sub_896e0 76 sub_8a78c 76 QuirkIsEnabled 1 CallbackMayRunLong 1 sub_8bfbc 1 FlsGetValue
# 吐槽一下,控制不是很完善,Ctrl+C都停不下來非要關掉目標進程。但總體還是很實用的。 |
frida-trace |
frida-trace is a tool for dynamically tracing function calls.
用於動態追蹤函數調用。
frida-trace --help Usage: frida-trace [options] target
Options: --version show program's version number and exit -h, --help show this help message and exit -D ID, --device=ID connect to device with the given ID -U, --usb connect to USB device -R, --remote connect to remote frida-server -H HOST, --host=HOST connect to remote frida-server on HOST -f FILE, --file=FILE spawn FILE -n NAME, --attach-name=NAME attach to NAME -p PID, --attach-pid=PID attach to PID --debug enable the Node.js compatible script debugger --enable-jit enable JIT -I MODULE, --include-module=MODULE include MODULE -X MODULE, --exclude-module=MODULE exclude MODULE -i FUNCTION, --include=FUNCTION include FUNCTION -x FUNCTION, --exclude=FUNCTION exclude FUNCTION -a MODULE!OFFSET, --add=MODULE!OFFSET add MODULE!OFFSET -T, --include-imports include program's imports -t MODULE, --include-module-imports=MODULE include MODULE imports -m OBJC_METHOD, --include-objc-method=OBJC_METHOD include OBJC_METHOD -M OBJC_METHOD, --exclude-objc-method=OBJC_METHOD exclude OBJC_METHOD -s DEBUG_SYMBOL, --include-debug-symbol=DEBUG_SYMBOL include DEBUG_SYMBOL -q, --quiet do not format output messages -o OUTPUT, --output=OUTPUT dump messages to file |
#上面的frida-discover追蹤到了模塊KERNELBASE.dll裏面有調用函數GetProcessHeap,那麼frida-trace追蹤一下調用吧。
>frida-trace -p 36164 -i GetProcessHeap Instrumenting functions... GetProcessHeap: Auto-generated handler at "Desktop\test\__handlers__\KERNELBASE.dll\GetProcessHeap.js" GetProcessHeap: Auto-generated handler at "Desktop\test\__handlers__\KERNEL32.DLL\GetProcessHeap.js" Started tracing 2 functions. Press Ctrl+C to stop. /* TID 0x97ec */ 860 ms GetProcessHeap() 860 ms GetProcessHeap() 860 ms GetProcessHeap() 860 ms GetProcessHeap() 860 ms GetProcessHeap() ...
# 比較雞肋,傳入參數傳出返回值都沒有log,sub_8bfbc這種匿名函數還不識別。 |
frida-ls-devices |
This is a command-line tool for listing attached devices, which is very useful when interacting with multiple devices.
有多個設備時用於區分ID。 |
>frida-ls-devices Id Type Name -------- ------ ------------------ local local Local System beac33b8 usb Xiaomi MI NOTE LTE tcp remote Local TCP |
frida-kill |
殺死進程
frida-kill --help Usage: frida-kill [options] process
Options: --version show program's version number and exit -h, --help show this help message and exit -D ID, --device=ID connect to device with the given ID -U, --usb connect to USB device -R, --remote connect to remote frida-server -H HOST, --host=HOST connect to remote frida-server on HOST |
0x03 做個小實驗,熟悉一下Frida的運行環境
// test.c
#include <stdio.h>
#include <unistd.h>
void f(int n)
{
printf ("Number: %d\n", n);
}
int main (int argc, char * argv[])
{
int i = 0;
printf ("f() is at %p\n", f);
while (1)
{
f(i++);
sleep (1);
}
}
$ gcc test -o test.c
$ ./test
f() is at 0x400544
Number: 0
Number: 1
Number: 2
…
以上這段C程序將打印出f函數的地址,然後循環每間隔1秒將調用一次f函數。Frida有附加進程並注入代碼運行的能力,那麼來一段hook代碼,在f函數執行時同步觸發執行我們的函數。
import frida
import sys
# 獲取進程會話
session = frida.attach("test")
# 對當前進程會話創建一個腳本
script = session.create_script("""
Interceptor.attach(ptr("%s"), {
onEnter: function(args) {
send(args[0].toInt32());
}
});
""" % int(sys.argv[1], 16))
# 回調函數
def on_message(message, data):
print(message, data)
# 綁定回調事件
script.on('message', on_message)
# 將腳本注入會話進程
script.load()
# 阻塞主線程,防止腳本主動退出
sys.stdin.read()
//-------Shell Code-------//
$ sudo /usr/bin/python3 /home/root2/Desktop/Test2/frida/test.py 0x400544
# 以上命令最後傳了一個地址,正是之前C代碼運行出來的f函數地址
{'type': 'send', 'payload': 310} None
{'type': 'send', 'payload': 311} None
{'type': 'send', 'payload': 312} None
...
# 'payload'就是Js層send函數發出來的值,也就是當時傳入f函數的值
修改注入腳本Interceptor.attach的onEnter事件,就可以實現讀取寫入,阻塞等基本功能。
Frida的用法精髓在於活用內置函數,且數目巨大不便挨個翻譯講解,還需參考官方文檔。
https://www.frida.re/docs/javascript-api/