android 怎么调用js项目_APP逆向神器之Frida【Android初级篇】

说到逆向APP,很多人首先想到的都是反编译,但是单看反编译出来的代码很难得知某个函数在被调用时所传入的参数和它返回的值,极大地增加了逆向时的复杂度,有没有什么办法可以方便地知道被传入的参数和返回值呢?

答案是有的,这个方法就是Hook,Hook的原理简单地说就是用一个新的函数替代掉原来的函数,在这个新的函数中你想做什么都可以,为所欲为。

本文中的Frida就是一个很常用的Hook工具,只需要编写一段Javascript代码就能轻松地对指定的函数进行Hook,而且它基本上可以算是全平台的(主流平台全覆盖),除了Android以外,iOS和PC端的APP也可以用它来进行Hook,非常方便。


那么怎么使用呢?首先我们在Frida官方文档中的Installation页可以看到,我们需要有Python环境,并且用pip安装一个叫frida-tools的库,然后才可以开始使用。

f80d9ef5944d2a26c0db6e87e6f2ddb3.png

Python环境相信大家都有了,直接打开命令行,执行一波pip install frida-tools吧。

安装完毕以后,因为这一页文档的下半部分用于测试刚装好的库是否可用的话过于麻烦,我们这里就直接使用frida-ps命令来测试吧。

dbaba3822c5ca7d49e1376eb592dd70e.png

看起来是没问题了,然后我们怎么Hook Android手机上的APP呢?别急,还需要在手机上做一些操作你才能这么做。


我们需要有一台已经Root了的Android手机,因为不同型号的手机Root方法存在差异,本文中就不指导如何对手机进行Root操作了,请自行通过搜索引擎查找方法。实在没有可以Root的Android手机的话可以选择使用模拟器,推荐使用Genymotion之类系统较为原生的模拟器,并将Android版本选择在6.0以上,否则可能会出现一些奇奇怪怪的问题

手机准备好了之后,找到Frida文档中Tutorials栏里的Android页,开始进行Frida的手机端准备工作。

47b7386307abad1019f62cf1c313a8a7.png

文档中能看到,Frida官方最近的大部分测试都是在运行着Android 9的Pixel 3上进行的,所以理论上来讲如果你在使用中遇到任何奇怪的问题,都可能是你手机的系统导致,所以这里再次建议,使用较为原生和偏高版本的系统(建议至少6.0)进行操作

e69c92f8c89507039cd1f9a8686ed4ab.png

接着往下看,我们需要在手机上以Root权限运行一个叫frida-server的东西,这个东西需要在Frida官方的GitHub仓库中下载,文档中有链接可以直接跳转。

7725e9bc1978a1cada40c93ab5d20404.png

打开GitHub之后你会发现,这里有很多个不同的版本,应该下载哪一个呢?

可以看到这一排的文件中,末尾处都有个系统和CPU架构的标识,我们直接看Android的。这里标了Android的一共有四个,然后X86的因为不是手机使用的CPU架构,可以直接pass掉,剩下的就是arm和arm64两种了,那么我们需要怎么判断自己的手机/模拟器属于哪一种CPU架构的呢?

查CPU架构的方法很多,这里介绍一个比较方便快捷的——使用一个名叫Device Info HW的APP。

87a86906e63161f598df130a75f55fbc.png

安装后打开它,在芯片栏中我们可以看到一个叫ABI的东西,右边就是我们手机的CPU架构了,如下:

57306ada9fe985549673addc9ab7d45f.png

所以这里我需要下载的是arm64版本的frida-server,下载后解压出来一个没后缀的文件,然后我们需要将这个文件放入手机中运行起来。先把这个文件的名字改成frida-server,然后在这个文件所在的目录下打开命令行(Windows下为Shift+鼠标右键,选择“在此处打开CMD/PowerShell”),执行以下命令:

1adb root
2adb push frida-server /data/local/tmp/ 
3adb shell "chmod 755 /data/local/tmp/frida-server"
4adb shell "/data/local/tmp/frida-server &"

如果你的手机和我的一样,直接这么运行会提示权限不足的话,可以先进入adb shell,在执行su命令获取Root权限后(手机端可能会弹出Root授权提示),再运行/data/local/tmp/frida-server &启动frida-server。

5c906e89b43c0180efed911aa259cf56.png

启动后,我们先照惯例来测试一下是否能正常使用了,和前面一样,使用frida-ps命令,但在后面加一个-U参数,这个参数的意思是让它对USB连接的设备操作,如果不出意外的话,你应该能看到与不加-U参数时截然不同的显示。

c033c6aedb4ede66acfcab36efdfcce2.png

至此,所有准备工作均已完成。

小提示:在手机重启后需要重新运行一次frida-server,但可以不重新执行adb push操作,因为文件已经放进去了。


终于到了喜闻乐见的实战环节了,就拿Frida官方文档中的提到的CTF APP来开刀吧,找到文档中Examples栏里的Android页,经过几次跳转后下载APP安装、打开,会看到这样的一个界面:

46daae6c05260f7a69c6c2002d0771bf.png

这个APP是一个石头剪子布的游戏,点击下面三个按钮分别选择石头、剪子、布,玩起来的时候是这么一个效果(加号后面的是得分值,正常情况下连胜会每次在原来的基础上+1):

c6ca6210e2776b15ea84adfdbbda978b.png

我们先做个比较简单的操作吧,让我们的每次出招都必胜~先复制一下文档中的代码,建一个.py文件粘贴进去,将this.cnt.value = 999;这一条删除或注释掉,然后运行这个python脚本,在注入完成后,不管你怎么点,你都是必定胜利的,如下图:

f014d8dfd1c0bbacbf5fd783c506e229.png

注:图中左下方显示的是Hook时产生的日志,其中value是得分值。

但是这样子弄,如果我们需要让分值达到很高的话,就需要点很多次了,怎么让它一次就加到999呢?很简单,直接把得分值也给改了就好了,我们把前面去掉的this.cnt.value = 999;再改回来,然后重新运行一遍这个脚本。

e358bbbe658af8bdde61ffdb98908aa7.png

正常情况下这个分值会是一个+999,这里显示成这样是因为这个样例APP太老了,不兼容新版本系统,导致出现这种情况,换旧版本系统可解,所以这里不纠结这个问题。


单看这么一通操作是不是觉得很懵?复制过来的代码是干啥的都不知道,如果换一个APP咋搞?不慌,我把这个代码的意思一行一行地给你解释一遍,你就知道怎么用了。

b2e26f433d3a20d99a79703cd38a5927.png

首先import不用说了吧,大家都懂,直接看on_message这个函数。这个on_message的用途是接收下面Javascript代码中调用send函数传出的日志,通常我们可以不用管它,直接复制出来用就行了,或者可以使用console.log打日志,效果也是差不多的。

然后是jscode这个变量,这个变量其实建议使用一个单独的.js文件代替,因为这样的话可以使用各种编辑器、IDE的JavaScript代码格式化、智能提示等功能,写起来会舒服很多。如果你要替换掉的话,改成读JS代码文件之后read出内容字符串赋值给jscode就行了。

be15de92c21978e13b8056932fea0ba5.png

接着是JS代码中的部分。

先看看Java.perform,在Frida官方文档的javascript-api页中可以看到,它的用途是确保当前线程已连接到VM用的,所以我们直接照着这么用就行了;

然后看看Java.use这个函数,它的用途是获取一个指向某个类的指针,参数中的com.example.seccon2015.rock_paper_scissors.MainActivity就是我们需要Hook的那个类;

接着就是真正执行Hook的部分了,这个代码中使用了一个MainActivity.onClick.implementation,意思就是Hook前面获取到的类中的onClick方法,后面跟着的赋值函数的部分,函数的参数为对应要Hook方法的参数,内部执行的部分就是在对应方法被调用时所执行的代码,这里它是先打了一个onClick日志,然后调用了原始方法(如果不调用的话原始方法不会被执行),接着它将m、n、cnt(变量具体含义请自行反编译APP后查看代码)的值做了修改,最后,它又打了一个携带着cnt变量值的日志。

6b44a44371cbe2c4675247f2f87a82ec.png

最后是一些常规操作,frida.get_usb_device().attach()是获取指定APP(参数为包名)当前运行着的进程,process.create_script(jscode)script.load()是将前面的JS代码注入进去,script.on('message', on_message)是设置消息传出时的回调,最后的sys.stdin.read()是输出日志用的。

总之,除了JS代码部分,其他的其实只是个壳子,核心的Hook操作逻辑全在JS代码中,我们在使用时一般只改JS代码部分和指定包名的部分就可以了。


看了这一篇文章后你应该会对使用Frida对Android手机上Java层的Hook有所了解了吧,如果觉得玩Frida官方文档中的这个石头剪子布APP不够刺激,还可以看看我前面的《当你写爬虫遇到APP的请求有加密参数时该怎么办?【初级篇-秒杀模式】》这篇文章,里面使用的DEMO APP是有SSL Pinning、且对代码进行了混淆的,希望你能够举一反三,自己写出一个干掉这个SSL Pinning的脚本。(如果还不会的话可以看更前面的《当你写爬虫抓不到APP请求包的时候该怎么办?【高级篇-混淆导致通用Hook工具失效】》这篇文章)

发送消息“Frida Android初级篇”到我的公众号【小周码字】即可获得代码和APP的下载地址~

这个时代各种东西变化太快,而网络上的垃圾信息又很多,你需要有一个良好的知识获取渠道,很多时候早就是一种优势,还不赶紧关注我的公众号并置顶/星标一波~ 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/551202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ef mysql modelfirst_MySQL –EF edmx(Model First)– Sql Server table

一、mysql environmentWhen we create an new database,first We need draw er diagram for somebody to show your idea,but our company have no goodauthorised tool to design sqlserver ER diagram,so I use mysql graphical tool to design it, after that,you can use m…

db2 联邦 mysql_DB2联邦数据库及配置方法(及联邦密码修改)

如果您需要使用所有不同的数据库,包括选择、插入、更新和删除,就象所有的表都位于单个数据库中那样,那么将获得非常高的工作效率。数据库联邦就是要做到这一点:使所有表看起来象是在同一个数据库中那么,数据库联邦是怎…

mysql t 保存_检查 (调试) - 离线消息保存到 MySQL - 《EMQ X Enterprise v4.1 中文文档》 - 书栈网 · BookStack...

离线消息保存到 MySQL搭建 MySQL 数据库,并设置用户名密码为 root/public,以 MacOS X 为例:$ brew install mysql$ brew services start mysql$ mysql-u root-h localhost-pALTER USERrootlocalhostIDENTIFIED BYpublic;初始化 MySQL 数据库:$ mysql-u r…

java @valid 密码不一致_一个成熟的Java项目如何优雅地处理异常

(一)概述异常处理是一个系统最重要的环节,当一个项目变得很大的时候,异常处理和日志系统能让你快速定位到问题。对于用户或者接口调用者而言,优雅的异常处理可以让调用者快速知道问题所在。本文将介绍如何优雅地处理异常。(二)使用通用的返回…

spark消费kafka产生数据堆积怎么处理_SparkStreaming读取Kafka的两种方式

本文主要从以下几个方面介绍SparkStreaming读取Kafka的两种方式:一、SparkStreaming简介二、Kafka简介三、Redis简介(可用于保存历史数据或偏移量数据)四、SparkStreaming读取Kafka数据的两种方式 五、演示Demo一、SparkStreaming简介可以参考这篇文章:SparkStreami…

python字符串操作作业_python 第二天作业

#python 中的循环#先介绍for循环#格式#for 临时变量 in 可迭代对象# 循环体#name neusoft#for a in name :# print(a)# if a s# print(嘿嘿)#循环次数哪里去了?# #这个a是什么鬼? a是临时变量 提前声明 python自动为你创建#range (起始位置&#xff0c…

python 白化_Python新疆某气候要素IDW(反距离权重)插值

1、Rbf插值import numpy as npimport cartopy.crs as ccrsimport cartopy.feature as cfeatfrom cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTERfrom cartopy.io.shapereader import Readerimport matplotlib.pyplot as pltimport matplotlib.ticker a…

帆软报表参数传给网络报表_报表开发工具FineReport的使用: 程序网络报表

1定义程序网络报表程序网络报表所在类需要继承com.fr.web.reportlet这个抽象类,并且需要实现createReport(ReportletRequest arg0)这个方法,并返回报表对象。具体代码如下:2//程序网络报表package com.fr.demo; import java.util.Map;impo…

bootstrap 取消_学习写个网站(5)Bootstrap学习2

吃了2天烧烤夜宵&#xff0c;还是得讲点自律。【正文】继续bootstrap&#xff0c;还是菜鸟教程。11. 分页就是还有种就是翻页&#xff0c;12. 标签class"label label-default">默认标签</span>label-primarylabel-success13. 警告就是那种可以取消的消息&am…

jdbc mysql user_tab_comments_MySQL学习(五)——使用JDBC完成用户表CRUD的操作

通过案例我们发现“获得连接”和“释放资源”两次代码将在之后的增删改查所有功能中都存在&#xff0c;开发中遇到此种情况&#xff0c;将采用工具类的方法进行抽取&#xff0c;从而达到代码的重复利用。1、使用properties配置文件开发中获得连接的4个参数(驱动、URL、用户名、…

mysql中try的意思_java中try是什么意思

try是Java中的关键字&#xff0c;主要用于异常处理机制&#xff0c;那么它有什么作用呢&#xff1f;try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内&#xff0c;当try语句块内发生异常时&#xff0c;异常就被抛出。它一般与catch..finally组合使用块…

linux用java连接mysql_Java使用JDBC方式连接数据库

开发一个JDBC应用程序&#xff0c;基本需要以下几个步骤&#xff1a;1.把JDBC驱动类装载入Java虚拟机中。使用java.lang.Class类的静态方法forName(String className)实现。例&#xff1a; Class.forName("JDBC驱动类名称")2.加载驱动&#xff0c;并与数据库建立连接…

java web gradle_gradle学习之旅(四) 使用gradle构建简单的java web项目

本节通过一个简单的javaweb项目来体会gradle的使用需求构建一个javaweb项目&#xff0c;搭建jspservlet开发环境可以将需求分解为两步&#xff1a;使用gradle构建一个java项目为该项目构建web视图层工具gradle4.3ideajdk 1.8实验过程首先在idea中创建一个空的gradle项目创建如下…

java 整数 引用传递_关于Java引用传递的一个困惑?

Java的引用(包括基本类型&#xff0c;对象引用类型)在声明、方法调用等时候都会产生新的引用&#xff0c;复制等号右侧的引用。分为下面3种情况&#xff1a;基本类型代表的值存储在引用里面&#xff0c;引用中专门有个区域存储这个值&#xff0c;所以在复制的时候&#xff0c;值…

java fastjson 泛型_解决fastjson泛型转换报错的解决方法

错误信息Exception in thread "main" java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.xh.demo.UserDO泛性类Datapublic class ResultSetDTO {private Integer totalSize;private Integer count;private List records;}实体类…

通达OA header身份认证绕过漏洞复现

通达OA是中国通达公司的一套协同办公自动化软件&#xff0c;通达OA2013&#xff0c;通达OA2016&#xff0c;通达OA2017 存在身份认证绕过漏洞&#xff0c;攻击者可以利用漏洞生成cookie&#xff0c;实现未授权访问。 1.漏洞级别 高危 2.漏洞搜索 fofa title"office An…

leetcode mysql 排名_Leetcode178.分数排名(中等)

题目编写一个 SQL 查询来实现分数排名。如果两个分数相同&#xff0c;则两个分数排名(Rank)相同。请注意&#xff0c;平分后的下一个名次应该是下一个连续的整数值。换句话说&#xff0c;名次之间不应该有“间隔”。-----------| Id | Score |-----------| 1 | 3.50 || 2 | 3.6…

java post 中文乱码问题_java post中文乱码问题

java post中文乱码问题function addcategory() {if (document.myform.category.value "") {alert("商品分类不能为空");return;}//var categorydocument.getElementById("category").value;var c document.myform.category.value;alert(c);wit…

java struct工作原理_Struts2的工作原理(图解)详解

Struts2的工作原理上图来源于Struts2官方站点&#xff0c;是Struts 2 的整体结构。一个请求在Struts2框架中的处理大概分为以下几个步骤(可查看源码&#xff1a;https://github.com/apache/struts):1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求2 这个请求经过一系列的…

java 旅行家的预算_洛谷 P1016 旅行家的预算 Java解法

洛谷 P1016 旅行家的预算 Java解法洛谷 P1016 旅行家的预算 Java解法package com.two;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);double D1 sc.nextDouble();// 两个城市之间的距离double C …