Loading... # 1、Frida 是什么 > 参考: > > 官网:https://frida.re/ > > github:https://github.com/frida/frida > > Frida 全版本发布件下载:https://github.com/frida/frida/releases - Frida 是一个开源的动态插桩工具,可以在程序运行时动态插入代码到程序的内存空间以监视和修改程序的行为,即 hook 工具 - Frida 支持 Windows、Linux、Android、Mac、iOS 等多种系统平台 - 因为支持动态插桩,所以 Frida 在黑盒测试时十分有用 - Frida 支持 python、javascript 等脚本语言,使用十分方便 - Frida 和平台架构、版本严格绑定,需要正确下载 Frida 文件使用 # 2、Frida 安装及简单使用演示 ## 2.1、在本机安装 Frida > 问题: > > 1、pip install frida 和 pip install frida-tools 有什么不同? **如果只需要监视本机上的程序(即 Frida 和测试的目标程序都在同一台机器上),则只安装 Frida 就可以了。** 使用 python 安装 frida,命令会自动安装最新版(如下为 15.2.2 版本): ```bash PS E:\> pip install frida-tools Collecting frida-tools Downloading frida-tools-11.0.0.tar.gz (174 kB) |████████████████████████████████| 174 kB 409 kB/s Collecting colorama<1.0.0,>=0.2.7 Downloading colorama-0.4.5-py2.py3-none-any.whl (16 kB) Requirement already satisfied: frida<16.0.0,>=15.2.0 in c:\users\abao\appdata\local\programs\python\python38\lib\site-packages (from frida-tools) (15.2.2) Collecting prompt-toolkit<4.0.0,>=2.0.0 Downloading prompt_toolkit-3.0.30-py3-none-any.whl (381 kB) |████████████████████████████████| 381 kB 59 kB/s Collecting pygments<3.0.0,>=2.0.2 Downloading Pygments-2.13.0-py3-none-any.whl (1.1 MB) |████████████████████████████████| 1.1 MB 52 kB/s Requirement already satisfied: setuptools in c:\users\abao\appdata\local\programs\python\python38\lib\site-packages (from frida<16.0.0,>=15.2.0->frida-tools) (56.0.0) Collecting wcwidth Downloading wcwidth-0.2.5-py2.py3-none-any.whl (30 kB) Using legacy 'setup.py install' for frida-tools, since package 'wheel' is not installed. Installing collected packages: wcwidth, pygments, prompt-toolkit, colorama, frida-tools Running setup.py install for frida-tools ... done Successfully installed colorama-0.4.5 frida-tools-11.0.0 prompt-toolkit-3.0.30 pygments-2.13.0 wcwidth-0.2.5 PS E:\> frida --version 15.2.2 ``` 至此,我们安装了 Frida,可以开始监视本机程序了。 ## 2.2、在本机使用 Frida 参考 [Frida Installation](https://frida.re/docs/installation/) 里面的例子,对 Linux 的 cat 进程进行插桩,枚举 cat 进程的每一个模块。创建 cat_enumerate_modules.py 如下: ```python import frida def on_message(message, data): print("[on_message] message:", message, "data:", data) session = frida.attach("cat") script = session.create_script(""" rpc.exports.enumerateModules = function () { return Process.enumerateModules(); }; """) script.on("message", on_message) script.load() print([m["name"] for m in script.exports.enumerate_modules()]) ``` 起一个终端执行 cat,此时 cat 会等待输入: ```bash ┌──(kali㉿kali)-[~/Desktop] └─$ cat ``` 在另一个终端中执行 frida 脚本,成功打印 cat 进程所有模块,Frida hook 成功: ```bash ┌──(kali㉿kali)-[~/Desktop/Frida] └─$ python cat_enumerate_modules.py ['cat', 'linux-vdso.so.1', 'libc-2.33.so', 'ld-2.33.so', 'libpthread-2.33.so', 'frida-agent-64.so', 'libdl-2.33.so', 'librt-2.33.so', 'libm-2.33.so'] ``` 更改例子为 Windows 平台的 notepad.exe 进程,打开记事本,将上述脚本中的 `cat` 更改为 `notepad.exe`,输出: ```bash PS F:\Frida\samples\notepad_enumerate_modules> python .\notepad_enumerate_modules.py ['notepad.exe', 'ntdll.dll', 'KERNEL32.DLL', 'KERNELBASE.dll', 'GDI32.dll', 'win32u.dll', 'gdi32full.dll', 'msvcp_win.dll', 'ucrtbase.dll', 'USER32.dll', 'combase.dll', 'RPCRT4.dll', 'shcore.dll', 'msvcrt.dll', 'COMCTL32.dll', 'IMM32.DLL', 'bcryptPrimitives.dll', 'ADVAPI32.dll', 'sechost.dll', 'kernel.appcore.dll', 'uxtheme.dll', 'clbcatq.dll', 'MrmCoreR.dll', 'SHELL32.dll', 'windows.storage.dll', 'Wldp.dll', 'shlwapi.dll', 'MSCTF.dll', 'OLEAUT32.dll', 'TextShaping.dll', 'efswrt.dll', 'wintypes.dll', 'MPR.dll', 'twinapi.appcore.dll', 'oleacc.dll', 'textinputframework.dll', 'CoreUIComponents.dll', 'CoreMessaging.dll', 'WS2_32.dll', 'ntmarta.dll', 'ole32.dll', 'SogouTSF.ime', 'MSIMG32.dll', 'VERSION.dll', 'SogouPy.ime', 'Resource.dll', 'PicFace64.dll', 'COMDLG32.dll', 'dwmapi.dll', 'profapi.dll', 'PSAPI.DLL', 'frida-agent.dll', 'CRYPT32.dll', 'bcrypt.dll', 'DNSAPI.dll', 'IPHLPAPI.DLL', 'WINMM.dll', 'NSI.dll'] PS F:\Frida\samples\notepad_enumerate_modules> ``` ## 2.3、在其它机器上安装 Frida-Server **如果测试目标不在本机(如在 Windows 安装 Frida,监视 Nexus 5X 手机上的应用),则还需要在目标机器上安装相应版本的 Frida Server。** 首先要确认目标机器的架构,Frida 是严格和平台架构绑定的,不同架构有不同的发布件。进一步地,Frida 是严格和自身版本绑定的,如 Windows 上的 Frida 版本要和 Nexus 5X 上的 Frida Server 版本完全一致。 以监控安卓手机上的应用为例,测试机器为 Nexus 5X,adb shell 进手机后查得机器架构为 arm64-v8a: ```bash bullhead:/ # getprop ro.product.cpu.abi arm64-v8a ``` 则在 [Frida releases 页面](https://github.com/frida/frida/releases)下载 frida server 15.2.2 android arm64 架构版本: ![图片.png](http://47.117.131.13/usr/uploads/2022/08/350330252.png) adb push 到手机上: ```bash PS F:\Frida\frida-server-15.2.2-android-arm64> adb push .\frida-server-15.2.2-android-arm64 /data/local/tmp/ .\frida-server-15.2.2-android-arm64: 1 file pushed, 0 skipped. 17.7 MB/s (47188552 bytes in 2.547s) PS F:\Frida\frida-server-15.2.2-android-arm64> ``` 给 frida server 添加可执行权限: ```bash bullhead:/data/local/tmp # ls -l total 46084 -rw-rw-rw- 1 shell shell 47188552 2022-08-29 23:44 frida-server-15.2.2-android-arm64 bullhead:/data/local/tmp # chmod 777 frida-server-15.2.2-android-arm64 bullhead:/data/local/tmp # ls -l total 46084 -rwxrwxrwx 1 shell shell 47188552 2022-08-29 23:44 frida-server-15.2.2-android-arm64 ``` 至此,目标机器的环境也配置好了。 ## 2.4、在其它机器上使用 Frida 以在 Nexus 5X 手机上 hook Java 层代码为例,编写 apk 主要代码如下: ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int num1 = 10; while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } printSum(num1, 30); num1 += 10; } } void printSum(int num1, int num2) { Log.d("Hello World, sum: ", String.valueOf( num1 + num2 )); } } ``` 该应用每隔 1 秒输出一个递增的和值,关键函数为 printSum,应用包名为 com.example.helloworld。 编写 Frida 脚本 HelloWorld_printSum.js 如下: ```javascript function main() { console.log("Frida script loaded succ") Java.perform(function() { var MainActivity = Java.use('com.example.helloworld.MainActivity') console.log("Java.use succ") MainActivity.printSum.implementation = function(num1, num2) { console.log("num1 => ", num1, " num2 => ", num2) var ret = this.printSum(num1, num2) return ret } }) } setImmediate(main) ``` 然后在手机上执行 Frida-Server。此时可以在电脑上执行 frida-ps -U 以确认 Frida-Server 已运行且可成功连接。frida-ps 是 frida 提供的用以查看 Frida-Server 端进程列表的小工具,在 Frida-Server 没有连接成功时是无法打印进程列表的: ![图片.png](http://47.117.131.13/usr/uploads/2022/08/2610517174.png) 确认 Frida-Server 连接成功后,在电脑上执行 Frida 脚本,成功监视 printSum 方法: ![图片.png](http://47.117.131.13/usr/uploads/2022/08/1461200047.png) # 3、Frida 基本原理 ## 3.1、Frida 框架 如: - Frida - Frida-Server - Frida-ps 等小工具 - 非必要 - Frida 脚本 Frida 由两部分组成:一部分是运行在系统上的交互工具 Frida CLI,另一部分是运行在目标机器上的代码注入工具 Frida-server。 Frida 通过对目标进程做 inline hook 来完成监视工作。执行 Frida 命令后,Frida 和目标机器上的 Frida-Server 通信,Frida-Server 根据包名在目标进程内申请一片可执行内存,写入并执行自己的 agent 执行体,agent 执行体会完成 inline hook、和 host 通信等工作。 // TODO 待补充一张 Frida 运行原理图 ## 3.2、Frida 操作模式 Frida 主要存在两种操作模式: - 其一是通过命令行直接将 javascript 脚本注入到进程中,成为 CLI(命令行)模式 - 其二是执行 python 脚本,在python 中注入 javascript 脚本到目标进程中,这种操作模式成为 RPC 模式 这两种模式本质上是一样的: - 最终完成监视工作的都是 javascript 代码 - 将 javascript 代码注入到目标进程的都是 Frida 框架 只不过增加了 python 代码这一层,我们可以对 javascript 脚本做更强的控制,以处理更复杂的数据及场景。 // TODO 待补充一张两种模式图 回顾上面监控安卓应用的例子,编写 javascript 脚本,然后在命令行中执行 frida 时指定 javascript 脚本文件,这其实就是 CLI 模式: ```bash frida -U -l -f .\HelloWorld_printSum.js HelloWorld ``` 回顾上面监控 cat 及 notepad 的例子,编写 python 脚本,在脚本中 import frida 并添加 javascript 代码,最后直接执行 python 脚本,这其实就是 RPC 模式: ```bash python .\notepad_enumerate_modules.py ``` ## 3.3、Frida 注入方式 Frida 注入 app 的方式有两种: - Spawn 模式 - 由 Frida 启动目标进程,在进程代码执行前完成 Frida 注入工作。如果目标进程在运行中,则会先杀死再重启 - 使用 Spawn 模式需明确指定`-f` 参数 - Attach 模式 - 在目标进程已经启动的情况下,通过 ptrace 注入 javascript 代码到目标进程中 - Frida 默认使用 Attach 模式 上面两个例子都没有明确指明 -f 参数,都是在 cat 进程或安卓应用执行起来后,再执行 Frida 指令,这就是 Attach 模式,在目标进程执行过程中完成注入。 以上面的安卓应用为例演示 Spawn 模式,在 Frida 指令中添加 `-f` 选项,可以看到 Frida 会 Spawning 目标应用,将目标应用拉起后执行入口代码前还会先暂停,等待用户手动确认 resume(输入 %resume 回车): ![图片.png](http://47.117.131.13/usr/uploads/2022/08/3598330667.png) # 4、Frida 脚本 Frida 脚本就是利用 Frida 动态插桩框架,使用 Frida 提供的 API 和方法对目标进程内存空间中的对象和方法进行监视、修改的一段代码。 Frida 的 API 是 javascript 脚本语言编写的,所以我们写的 Frida 脚本也得是 javascript(或者直接由 Frida 框架运行的最接近目标的代码至少得是 javascript 代码,然后可以由 javascript 代码和其它代码如 python 代码协作完成整个监视工作,即上面说的 RPC 操作模式)。 # 5、 最后修改:2022 年 10 月 22 日 04 : 00 PM © 允许规范转载