逆向爬虫39 Frida环境搭建和Hook初体验
手机环境:红米Note11Pro + Android11
PC环境:Python3.9
一. Frida环境搭建
-
PC端
pip install frida==14.2.18 pip install frida-tools==9.2.5
-
手机端(必须root)
-
确定手机芯片架构,我的手机是arm 64位处理器
>>> adb shell getprop ro.product.cpu.abi arm64-v8a
-
根据处理器类型去github上下载对应版本的rida-server,frida-server-14.2.18-android-arm64.xz
-
解压并把里面的可执行文件(不是文件夹),放进手机
/data/local/tmp
目录下,这一步必须手机有root权限 -
通过adb进入到手机命令行,使用
su
命令获取root权限,进到/data/local/tmp
目录,使用chmod 777 frida-server-14.2.18-android-arm64
给frida-server文件执行权限 -
./frida-server-14.2.18-android-arm64
,无报错且阻塞则说明手机端frida安装完成。
备注:如果出现下面这样的报错
{"type":"error","description":"Error: invalid address","stack":"Error: invalid address\n at Object.value [as patchCode] (frida/runtime/core.js:170:1)\n at zt (frida/node_modules/frida-java-bridge/lib/android.js:945:1)\n at Ut.activate (frida/node_modules/frida-java-bridge/lib/android.js:998:1)\n at Gt.replace (frida/node_modules/frida-java-bridge/lib/android.js:1045:1)\n at Function.set [as implementation] (frida/node_modules/frida-java-bridge/lib/class-factory.js:1010:1)\n at Function.set [as implementation] (frida/node_modules/frida-java-bridge/lib/class-factory.js:925:1)\n at installLaunchTimeoutRemovalInstrumentation (/internal-agent.js:435:37)\n at init(/internal-agent.js:51:3)\n at c.perform (frida/node_modules/frida-java-bridge/lib/vm.js:11:1)\n at g._performPendingVmOps (frida/node_modules/frida-java-bridge/index.js:238:1)","fileName":"frida/runtime/core.js","lineNumber":170,"columnNumber":1}
执行下这个命令
setenforce 0
,方法源自 (55条消息) frida: Error: invalid address_curiousChen的博客-CSDN博客 -
二. Hook初体验
-
PC端
终端执行两条端口转发命令
>>>adb forward tcp:27042 tcp:27042 >>>adb forward tcp:27043 tcp:27043
-
手机端
进入到
/data/local/tmp
目录,将frida-server运行起来 -
python脚本
编写2个程序,第一个用来获取手机上运行的进程,第二个用来Hook函数
# 获取当前运行App进程 import frida # 获取设备信息 rdev = frida.get_remote_device() # 枚举所有的进程 # processes = rdev.enumerate_processes() # for process in processes: # print(process) # 获取在前台运行的APP front_app = rdev.get_frontmost_application() print(front_app) # Application(identifier="com.che168.autotradercloud", name="XXX+", pid=30246)
输出结果如下:
Application(identifier="com.che168.autotradercloud", name="XXX+", pid=30246)
将上面输出结果中的
com.che168.autotradercloud
写进第二个Hook脚本rdev.attach()
中,然后src里用js写hook脚本,以后要hook其他App的函数时,只需要替换这两个地方的内容即可。import frida import sys # 连接手机设备 rdev = frida.get_remote_device() # Hook手机上的那个APP(app的包名字) # 注意事项:在运行这个代码之前,一定要先在手机上启动app session = rdev.attach("com.che168.autotradercloud") # "XXX+" scr = """ Java.perform(function () { // 包.类 var UserModel = Java.use("com.che168.autotradercloud.user.model.UserModel"); var SecurityUtil = Java.use("com.autohome.ahkit.utils.SecurityUtil"); // Hook,替换 UserModel.loginByPassword.implementation = function(str,str2,str3,callback){ console.log(str,str2,str3); // 执行原来的方法 this.loginByPassword(str,str2,str3,callback); } // Hook,替换 SecurityUtil.encodeMD5.implementation = function(str){ console.log(str); // 执行原来的方法 var res = this.encodeMD5(str); console.log(res); return res; } }); """ script = session.create_script(scr) def on_message(message, data): print(message, data) script.on("message", on_message) script.load() sys.stdin.read()
上面脚本hook了两个函数,第一个函数只在hook中输出了传入的参数,第二个函数还输出了函数返回值。
输出结果如下:
com.che168.autotradercloud.user.LoginActivity@e5b8700 15222222222 123456 123456 e10adc3949ba59abbe56e057f20f883e
第一行是传给第一个函数的三个字符串,第二行是密码加密的明文,第三行是密码加密后的密文