Frida Hook Android framework system_server插桩调试方法
已有环境:
Ubuntu20.04.1
使用工具:
VS code Python3
概述:由于本人的工作调整,所以最近要转战到framework层开发,因此调试framework就成了重中之重,但是在源码中修改代码和添加log,再编译烧录到机器上,这一套流程下去,费时费力,尤其开发人员又受限于后台服务器的安全设定,那就更难受,并且效率十分低下,如果在源码开放的情况下,使用AS断点,也是不错的方法,但是很不幸运,我们的代码不开源,因此只能另外寻求方法。
参考文档:Android Hook工具之Frida安装配置教程
Android Hook工具之Frida 安装配置教程 - 简书
Frida官网地址:Frida • A world-class dynamic instrumentation toolkit | Observe and reprogram running programs on Windows, macOS, GNU/Linux, iOS, watchOS, tvOS, Android, FreeBSD, and QNX
Frida简介:
Frida是一款基于Python + JavaScript的Hook调试框架,可以将自己编写的JavaScript代码注入到Windows,MACOS,Linux, iOS,Android和QNX 的应用中从而进行Hook,其实Frida功能不仅仅是Hook,还包括以下这些功能:
步骤:(Ubuntu环境,已安装Python3.8 直接使用命令行即可)
出现ERROR
ERROR: Could not find a version that satisfies the requirement frida (from versions: none)
ERROR: No matching distribution found for frida
解决:pip3 install frida -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
直接选用pip源并且信任它的来源就可以解决这种问题。
安装完成后,直接在终端中输入frida-ps
命令查看,如果能显示当前系统进程则证明安装成功
下载frida server
Frida-server:
直接去官网下载:https://github.com/frida/frida/releases
对应的版本即可,注意:Frida-server的版本必须跟你宿主机的Frida版本一致。
查看Frida版本
比如我宿主机Frida的版本是14.2.17,Android手机是arm64的,那么应该下载:frida-server-14.2.17-android-arm64.xz 文件。
下载后解压文件
使用adb push命令推送到手机中
推送完成后将frida-sever赋予执行的权限,并运行Frida-server,使用以下命令:
注1: 如果frida-server没有启动,查看一下你是否使用的是Root用户来启动,如果使用Root用户则应该是#
注2: 如果要启动frida-server作为后台进程、可以使用这个命令./frida-server
正常启动后,另开一个终端,使用frida-ps -U命令检查Frida是否正常运行,如果正常运行则会列出Android设备上当前正在运行的进程.
参数-U 代表USB,意思让Frida检查USB设备。
(上述准备工作完成后,开始进行调试步骤)
脚本调试(前期编写比较耗时,之后调试只需微改,比较实用)
以Hook WMS ActivityStarter startActivityUnchecked为例
进程:system_server
Java.use : /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
key point: startActivityUnchecked
编写Python脚本(详细见附件)
创建main.py(注:Python注意空格和换行)
'''
/**
* VS code Ctrl+Alt +- :Go Forward Go Back
* VS code 自动排版: Ctrl+K 紧接着Ctrl+F
*
*/
'''
import frida
import sys
import time
#Hook 进程名称 Frida-ps -U查看 "com.example.testfrida" "system_server"
url_example = "com.example.testfrida"
url_system = "system_server"
#Frida 具体实现JS "./common_function.js" "./recents.js"
JS_common = "./common_function.js"
JS_recents = "./recents.js"
def read_js(file):
with open(file, encoding='UTF-8') as fp:
return fp.read()
def on_message(message, data):
if message["type"] == "send":
print("[+] {}".format(message["payload"]))
else:
print("[-] {}".format(message))
#选择hook方式: 运行时hook False,spawn hook True
def get_session(isSpawn, url):
#开始 hook
remote_device = frida.get_usb_device()
print(remote_device)
#session = remote_device.attach("system_server")
#session = remote_device.attach("com.example.testfrida")
# spawn hook
'''
device = frida.get_usb_device()
print(device)
pid = device.spawn(["com.example.testfrida"])
device.resume(pid)
time.sleep(1) #Without it Java.perform silently fails
session = device.attach(pid)
'''
# spawn hook 调试APP时使用
if isSpawn == True:
pid = remote_device.spawn([url])
remote_device.resume(pid)
time.sleep(1) #Without it Java.perform silently fails
session = remote_device.attach(pid)
else:#运行时hook
session = remote_device.attach(url)
return session
'''
js - Hook 解释文件js,打桩进入目标类&目标方法
isSpawn - Hook选择,是否启动该进程
url - 宿主机器的进程名称
'''
def run(js, isSpawn, url):
src = read_js(js)
script = get_session(isSpawn,url).create_script(src)
script.on("message", on_message)
script.load()
#此处添加需要hook的进程和解释器(js文件),可添加多个
#run("./common_function.js",True,url_example)
run(JS_recents,False,url_system)
sys.stdin.read()
编写JS(主要的Hook工作,全部在JS中完成,详细代码参考附件)
主函数:
/**
* 主函数
*/
Java.perform(function () {
try {
main();
} catch (err) {
console.log(err);
}
});
全局变量赋值:
/**
* 全局变量赋值
*/
var WindowManagerDebigConfig
= Java.use('com.android.server.wm.WindowManagerDebugConfig');
WindowManagerDebigConfig.DEBUG_LAYOUT.value = true;
logi("WindowManagerDebigConfig.DEBUG_LAYOUT: " + WindowManagerDebigConfig.DEBUG_LAYOUT.value);
重写已有函数(注:传参要对应)
/**
* 重写方法
*/
var ActivityStarter = Java.use('com.android.server.wm.ActivityStarter');
var startActivityUnchecked = ActivityStarter.startActivityUnchecked
logi("Hook startActivityUnchecked: " + startActivityUnchecked);
startActivityUnchecked.implementation = function (r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity, restrictedBgActivity) {
logi("startActivityUnchecked: options: " + options + ", r: " + r);
//调用原方法,注:传参多个this变量
var result = startActivityUnchecked.call(this, r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
logi("startActivityUnchecked: result: " + result);
return result;
}
内部类
/**
* 内部类使用$
*/
var Engine = Java.use("android.service.wallpaper.WallpaperService$Engine");
var updateSurface = Engine.updateSurface
logi("Hook updateSurface: " + updateSurface);
updateSurface.implementation = function (forceRelayout, forceReport, redrawNeeded) {
logi("updateSurface: forceRelayout: " + forceRelayout + "; forceReport: " + forceReport + "; redrawNeeded: " + redrawNeeded);
updateSurface.call(this, forceRelayout, forceReport, redrawNeeded);
logi("updateSurface: result: " + result);
}
例子详细见附件:FridaHookAndroidframework-main.zip_fridahook系统system_server-Ubuntu文档类资源-CSDN下载