frida框架
发布日期:2021-05-07 12:09:05 浏览次数:20 分类:原创文章

本文共 12981 字,大约阅读时间需要 43 分钟。

文章目录

简介

Frida是一款基于python + javascript 的hook框架,适用于android/ios/linux/win/osx等平台。Frida的动态代码执行功能,主要是在它的核心引擎Gum中用C语言来实现的。

  1. 注入模式:大部分情况下,我们都是附加到一个已经运行到进程,或者是在程序启动到时候进行劫持,然后再在目标进程中运行我们的代码逻辑。这种方式是Frida最常用的使用方式。注入模式的大致实现思路是这样的,带有GumJS的Frida核心引擎被打包成一个动态连接库,然后把这个动态连接库注入到目标进程中,同时提供了一个双向通信通道,这样控制端就可以和注入的模块进行通信了,在不需要的时候,还可以在目标进程中把这个注入的模块给卸载掉。
  2. 嵌入模式:针对没root过的设备Frida提供了一个动态连接库组件 frida-gadget, 可以把这个动态库集成到程序里面来使用Frida的动态执行功能。一旦集成了gadget,就可以和程序使用Frida进行交互。
  3. 预加载模式:自动加载Js文件。
    在这里插入图片描述

环境搭建

  1. 下载FRIDA
pip install frida
  1. 下载frida-server
    去github上下载frida-server,网址为 ,frida-server 是一个守护进程,通过TCP和Frida核心引擎通信,默认的监听端口是27042
    在这里插入图片描述
adb devices

在这里插入图片描述

  1. 解压后,使用adb将frida-server放到手机目录/data/local/tmp,然后修改属性为可执行
adb push G:\buuctf\frida-server-14.2.2-android-x86\fs  data/local/tmp/frida-server_test						

在这里插入图片描述

sucd data/local/tmpchmod 777 frida-server_test

在这里插入图片描述

  1. 启动手机上的frida服务器,记得要以root权限启动,
./frida-server_test

在这里插入图片描述

  1. 在windows主机上另外开启一个cmd,输入命令 frida-ps -U ,这行命令是列出手机上所有的进程信息,如果出现进程信息则说明环境搭配成功:
frida-ps -U

在这里插入图片描述

疑问点

但是我这里利用脱壳脚本,去连接frida-server,直接连接不上
在这里插入图片描述
求救

脱壳已解决

  1. 第一个问题:未进行端口转发
adb forward tcp:27042 tcp:27042adb forward tcp:27043 tcp:27043

2.第二个问题:sdk中的adb和夜神中的abd版本不合。。adb server version (31) doesn’t match this client (36),以至于每次一使用脚本连接,然后frida-server就会挂掉,然后就出现了上方的报错,只需要把sdk的adb复制一份放在夜神里面就行喽
在这里插入图片描述

  1. 解码
D:\桌面\apktool.jar d D:\桌面\02.apk -o targetappFolder
  1. 将apk重新打包
D:\桌面\apktool.jar  b -o repackaged.apk targetappFolder/
  1. 创建keystore(如果没有的话)
keytool -genkey -v -keystore custom.keystore -alias mykeyaliasname -keyalg RSA -keysize 2048 -validity 10000
  1. 签名
jarsigner -sigalg SHA256withRSA -digestalg SHA1 -keystore custom.keystore -storepass 你的密码 repackaged.apk mykeyaliasname

这个custom.keystore也就是前面所生成的keystore,注意路径问题就行

  1. 验证
jarsigner -verify repackaged.apk	

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

D:\桌面>D:\桌面\apktool.jar d targetapp.apk -o targetappFolderD:\桌面>D:\桌面\apktool.jar d targetapp.apk -o targetappFolderD:\桌面>D:\桌面\apktool.jar d D:\桌面\02.apk -o targetappFolderD:\桌面>apktool b -o repackaged.apk targetappFolder/'apktool' 不是内部或外部命令,也不是可运行的程序或批处理文件。D:\桌面>apktool b -o repackaged.apk targetappFolder/'apktool' 不是内部或外部命令,也不是可运行的程序或批处理文件。D:\桌面>D:\桌面\apktool.jar apktool b -o repackaged.apk targetappFolder/D:\桌面>D:\桌面\apktool.jar  b -o repackaged.apk targetappFolder/D:\桌面>keytool -genkey -v -keystore custom.keystore -alias mykeyaliasname -keyalg RSA -keysize 2048 -validity 10000输入密钥库口令:再次输入新口令:您的名字与姓氏是什么?  [Unknown]:  张瑞彪您的组织单位名称是什么?  [Unknown]:  江科大您的组织名称是什么?  [Unknown]:  江科大您所在的城市或区域名称是什么?  [Unknown]:  江科大您所在的省//自治区名称是什么?  [Unknown]:  江科大该单位的双字母国家/地区代码是什么?  [Unknown]:  江科大CN=张瑞彪, OU=江科大, O=江科大, L=江科大, ST=江科大, C=江科大是否正确?  []:  是正在为以下对象生成 2,048 位RSA密钥对和自签名证书 (SHA256withRSA) (有效期为 10,000):         CN=张瑞彪, OU=江科大, O=江科大, L=江科大, ST=江科大, C=江科大[正在存储custom.keystore]D:\桌面>jarsigner -sigalg SHA256withRSA -digestalg SHA1 -keystore custom.keystore -storepass 你的密码 repackaged.apk mykeyaliasnamejarsigner 错误: java.lang.RuntimeException: 密钥库加载: keystore password was incorrectD:\桌面>jarsigner -sigalg SHA256withRSA -digestalg SHA1 -keystore custom.keystore -storepass 123456 repackaged.apk mykeyaliasnamejarsigner 错误: java.lang.RuntimeException: 密钥库加载: D:\桌面\custom.keystore (系统找不到指定的文件。)D:\桌面>jarsigner -sigalg SHA256withRSA -digestalg SHA1 -keystore D:\桌面\custom.keystore  -storepass 123456 repackaged.apk mykeyaliasnamejar 已签名。警告:签名者证书为自签名证书。为 -digestalg 选项指定的 SHA1 算法被视为存在安全风险。此算法将在未来的更新中被禁用。D:\桌面>zipalign 4 repackaged.apk final.apk'zipalign' 不是内部或外部命令,也不是可运行的程序或批处理文件。D:\桌面>jarsigner -verify repackaged.apkjar 已验证。警告:此 jar 包含其证书链无效的条目。原因: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target此 jar 包含其签名者证书为自签名证书的条目。SHA1 摘要算法被视为存在安全风险。此算法将在未来的更新中被禁用。此 jar 包含的签名没有时间戳。如果没有时间戳, 则在其中任一签名者证书到期 (最早为 2048-08-30) 之后, 用户可能无法验证此 jar。有关详细信息, 请使用 -verbose 和 -certs 选项重新运行。

工具

  1. frida-ps
--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						

在这里插入图片描述
2. frida-trace 动态跟踪

 --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			 --disable-jit         disable 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												

示例:
注意:使用frida-trace时,Android端一定要打开frida-server,否则就会出现这样
启动手机中的Chrome浏览器
在这里插入图片描述
在这里插入图片描述

	frida-trace -i "open" -U com.android.chrome	

在这里插入图片描述
在这里插入图片描述

可以看到终端中出现:open:Loaded handler at :”/用户名/__handlers__/libc.so/open.js”
frida-trace会生成一个javascript文件,然后Frida会将其注入到进程中,并跟踪特定的调用。生成的open.js脚本将钩住libc.so中的open函数并输出参数.
默认的open.js:

/* * Auto-generated by Frida. Please modify to match the signature of open. * This stub is currently auto-generated from manpages when available. * * For full API reference, see: https://frida.re/docs/javascript-api/ */{     /**   * Called synchronously when about to call open.   *   * @this {object} - Object allowing you to store state for use in onLeave.   * @param {function} log - Call this function with a string to be presented to the user.   * @param {array} args - Function arguments represented as an array of NativePointer objects.   * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.   * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.   * @param {object} state - Object allowing you to keep state across function calls.   * Only one JavaScript function will execute at a time, so do not worry about race-conditions.   * However, do not use this to store function arguments across onEnter/onLeave, but instead   * use "this" which is an object for keeping state local to an invocation.   */  onEnter(log, args, state) {       log('open()');  },  /**   * Called synchronously when about to return from open.   *   * See onEnter for details.   *   * @this {object} - Object allowing you to access state stored in onEnter.   * @param {function} log - Call this function with a string to be presented to the user.   * @param {NativePointer} retval - Return value represented as a NativePointer object.   * @param {object} state - Object allowing you to keep state across function calls.   */  onLeave(log, retval, state) {     }}

在这里插入图片描述
在这里插入图片描述
可以修改open.js进行操作,然后进行终端输出:

/*														 * Auto-generated by Frida. Please modify to match the signature of open.		 * This stub is currently auto-generated from manpages when available.		 *														 * For full API reference, see: http://www.frida.re/docs/javascript-api/			 */														{   														  /**														   * Called synchronously when about to call open.						   *														   * @this {object} - Object allowing you to store state for use in onLeave.		   * @param {function} log - Call this function with a string to be presented to 	the user.													   * @param {array} args - Function arguments represented as an array of 		NativePointer objects.											   * For example use Memory.readUtf8String(args[0]) if the first argument is a 	pointer to a C string encoded as UTF-8.								   * It is also possible to modify arguments by assigning a NativePointer 		object to an element of this array.									   * @param {object} state - Object allowing you to keep state across function calls.														   * Only one JavaScript function will execute at a time, so do not worry 		about race-conditions.											   * However, do not use this to store function arguments across onEnter/		onLeave, but instead											   * use "this" which is an object for keeping state local to an invocation.		   */														  onEnter: function (log, args, state) {   								    log("open(" +												      "path=\"" + Memory.readUtf8String(args[0]) + "\"" +					      ", oflag=" + args[1] +										    ")");													  },																												  /**														   * Called synchronously when about to return from open.				   *														   * See onEnter for details.										   *														   * @this {object} - Object allowing you to access state stored in onEnter.		   * @param {function} log - Call this function with a string to be presented to	 the user.													   * @param {NativePointer} retval - Return value represented as a 			NativePointer object.											   * @param {object} state - Object allowing you to keep state across function calls.														   */														  onLeave: function (log, retval, state) {   								  }														}													

在这里插入图片描述

Python绑定

示例:
Python注入chrome.js脚本
注意:从命令行加载脚本然后生成一个命令的进程时,Frida容易崩溃。所以先生成进程,再让Frida注入脚本

#!/usr/bin/python             										import frida												# js														jscode= """													console.log("[*] Starting script");									Java.perform(function() {   										   var Activity = Java.use("android.app.Activity");						    Activity.onResume.implementation = function () {   						        console.log("[*] onResume() got called!");							        this.onResume();											    };														});														"""														# startup frida and attach to com.android.chrome process on a usb device		process = frida.get_remote_device().attach("com.android.chrome")				# create a script for frida of jsccode								script = process.create_script(jscode)								# and load the script											script.load()												

注意点:

  1. 记得端口转发
adb forward tcp:27042 tcp:27042adb forward tcp:27043 tcp:27043

否则如下报错
在这里插入图片描述

  1. 别用frida.get_usb_device().attach(),改用frida.get_remote_device().attach(),否则如下报错:
    在这里插入图片描述

使用

学习Frida的magic,并通过Frida覆盖一个函数。此外,我们还将介绍如何从外部脚本加载代码,而不是将代码键入cli,因为这种方式更方便。首先,将下面的代码保存到一个脚本文件中,例如chrome.js:
1.

  Java.perform(function () {       var Activity = Java.use("android.app.Activity");    Activity.onResume.implementation = function () {           console.log("[*] onResume() got called!");        this.onResume();    };});

上面的代码将会覆盖android.app.Activity类的onResume函数。它会调用Java.use来接收这个类的包装对象,并访问其onResume函数的implementation属性,以提供一个新的实现。在新的函数体中,它将通过this.onResume()调用原始的onResume实现,所以应用程序依然可以继续正常运行。

通过命令行注入:

frida -U -l chrome.js com.android.chrome

一旦触发了onResume——例如切换到另一个应用程序并返回到模拟器中的Chrome——您将收到下列输出:[*] onResume() got called!
在这里插入图片描述

在这里插入图片描述
如上图所示。

个人误区

但是我使用python绑定进行注入,直接没用。。。搞不懂为什么

#!/usr/bin/pythonimport frida# put your javascript-code herejscode= """console.log("[*] Starting script");Java.perform(function() {      var Activity = Java.use("android.app.Activity");    Activity.onResume.implementation = function () {           console.log("[*] onResume() got called!");        this.onResume();    };});"""# startup frida and attach to com.android.chrome process on a usb deviceprocess = frida.get_usb_device().attach("com.android.chrome")# create a script for frida of jsccodescript = process.create_script(jscode)# and load the scriptscript.load()

在这里插入图片描述
在这里插入图片描述
这里呢,是我误会了这行命令行的作用:

frida -U -f com.android.xxxxx —no-pause	

它的作用也就是:—no-pause不会中断应用程序,并将生成的进程的任务留给FRIDA,这会打开一个shell,在里边使用Javascript API向Frida写命令,至于用

frida -U -l chrome.js com.android.chrome

它仅仅只是注入js脚本,然后进行阻塞,回传log

python绑定和它并没有任何关系。python绑定的log回传是在Python脚本里面的。

使用命令的时候,建议使用如下这个:

frida -U -f com.android.chrome --no-pause

如果不加--no-pause的话,那么需要手动启动主线程函数
在这里插入图片描述
输入%resume来进行线程的启动

python绑定解决

这里的话请教了夜影学长,然后他说Python脚本注入的话,显示log是在python里面显示的
在这里插入图片描述
显示的东西是由frida里执行的js发给py的,所以的话,py要自己负责阻塞,需要input阻塞,在最后加上sys.stdin.read(),最后也就变成这样:

#!/usr/bin/pythonimport fridaimport sys# put your javascript-code herejscode= """console.log("[*] Starting script");Java.perform(function() {      var Activity = Java.use("android.app.Activity");    Activity.onResume.implementation = function () {           console.log("[*] onResume() got called!");        this.onResume();    };});"""# startup frida and attach to com.android.chrome process on a usb deviceprocess = frida.get_usb_device().attach("com.android.chrome")# create a script for frida of jsccodescript = process.create_script(jscode)# and load the scriptscript.load()sys.stdin.read()

在这里插入图片描述

上一篇:住院时期
下一篇:angr学习笔记(13)(static_binary)

发表评论

最新留言

很好
[***.229.124.182]2025年04月13日 19时29分57秒