feat:frida对接多个app

This commit is contained in:
想要成为RapStar吗? 2020-09-24 16:20:21 +08:00
parent 2b27626ca3
commit 1e256785bf
7 changed files with 90 additions and 21 deletions

View File

@ -23,6 +23,14 @@ Do By You Self
`Python`执行`PyexecJs`通过`Js的AST树`结构获取`Frida-Js`脚本中`rpc.exports`的方法以及对应方法的参数个数,根据方法名和参数个数通过`types.FunctionDef`从`Python AST字节码`来动态生成新的`Function对象`,并且结合`pydantic`的`create_model`自动生成的参数模型注册到`FastAPI的路由系统`中,实现`Frida-RPC`的功能。 `Python`执行`PyexecJs`通过`Js的AST树`结构获取`Frida-Js`脚本中`rpc.exports`的方法以及对应方法的参数个数,根据方法名和参数个数通过`types.FunctionDef`从`Python AST字节码`来动态生成新的`Function对象`,并且结合`pydantic`的`create_model`自动生成的参数模型注册到`FastAPI的路由系统`中,实现`Frida-RPC`的功能。
## 核心功能
1. 对接多个`App`的`RPC接口暴露`
2. 自动转化`Js export`方法变成接口
3. 自动生成接口文档
## Install ## Install
```sh ```sh

18
apps/yuxueyuan.js Normal file
View File

@ -0,0 +1,18 @@
var result = null;
function get_sign(body) {
Java.perform(function () {
try {
var ksecurity = Java.use('com.drcuiyutao.lib.api.APIUtils');
result = ksecurity.updateBodyString(body)
console.log("myfunc result: " + result);
} catch (e) {
console.log(e)
}
});
return result;
}
rpc.exports = {
getSign: get_sign,
}

View File

@ -11,3 +11,15 @@
''' '''
from pathlib import Path from pathlib import Path
PRASE_PATH = Path(__file__).absolute().parent / "parse.js" PRASE_PATH = Path(__file__).absolute().parent / "parse.js"
INJECTION_APPS = [
{
"name": "育学园",
"path": "yuxueyuan",
"package_name": "com.drcuiyutao.babyhealth"
},
{
"name": "快读作业",
"path": "kuaiduizuoye",
"package_name": "com.kuaiduizuoye.scan"
}
]

51
main.py
View File

@ -12,6 +12,7 @@
from pathlib import Path from pathlib import Path
from pydantic import BaseModel, Field, create_model from pydantic import BaseModel, Field, create_model
from fastapi import APIRouter from fastapi import APIRouter
from fastapi.openapi.utils import get_openapi
import time import time
import frida import frida
from starlette.applications import Starlette from starlette.applications import Starlette
@ -31,26 +32,37 @@ function_params_hints = {
"encryptData": [0, 0, 0, 0, "", 0, 0, 0, 0, 0, 0] "encryptData": [0, 0, 0, 0, "", 0, 0, 0, 0, 0, 0]
} }
# app相关信息 # app相关信息
_frida_js_path1 = Path(__file__).absolute().parent/"apps/yuxueyuan.js"
_frida_js_path = Path(__file__).absolute().parent/"apps/kuaiduizuoye.js" _frida_js_path = Path(__file__).absolute().parent/"apps/kuaiduizuoye.js"
_package_name = "com.kuaiduizuoye.scan" _package_name = "com.kuaiduizuoye.scan"
_package_name1 = "com.drcuiyutao.babyhealth"
# frida注入 # frida启动前检测
if not detect_frida_state(): if not detect_frida_state():
# 启动frida-server增加延迟防止附加失败 # 启动frida-server增加延迟防止附加失败
start_frida_server() start_frida_server()
time.sleep(3) time.sleep(3)
session = frida.get_usb_device().attach(_package_name)
script = session.create_script( for app_info in INJECTION_APPS:
open(_frida_js_path, encoding="utf-8").read() session = frida.get_usb_device().attach(app_info["package_name"])
) app_info["absolute_path"] = Path(__file__).absolute().parent / \
script.load() f"apps/{app_info['path']}.js"
script = session.create_script(
open(
app_info["absolute_path"],
encoding="utf-8"
).read()
)
script.load()
app_info["script"] = script
def init_app() -> Starlette: def init_app() -> Starlette:
app = FastAPI() app = FastAPI()
# 每个app创建特有路由 # 每个app创建特有路由
for app_info in INJECTION_APPS:
router = APIRouter() router = APIRouter()
for api_name, params in get_app_info(parse_path=PRASE_PATH, frida_js_path=_frida_js_path).items(): for api_name, params in get_app_info(parse_path=PRASE_PATH, frida_js_path=app_info["absolute_path"]).items():
params_dict = dict(zip(params, function_params_hints[api_name])) if ( params_dict = dict(zip(params, function_params_hints[api_name])) if (
api_name in function_params_hints) else dict.fromkeys(params, "bb") api_name in function_params_hints) else dict.fromkeys(params, "bb")
model_name = f"{api_name}Model" model_name = f"{api_name}Model"
@ -58,13 +70,32 @@ def init_app() -> Starlette:
new_api_name = name_transform(api_name) new_api_name = name_transform(api_name)
func = generate_function( func = generate_function(
new_api_name, new_api_name,
script, app_info["script"],
model_name, model_name,
Model Model
) )
router.add_api_route(f"/{new_api_name}", func, methods=["POST"]) router.add_api_route(f"/{new_api_name}", func, methods=["POST"])
# 全局添加各app路由类 app.include_router(
app.include_router(router) router,
prefix=f"/{app_info['path']}",
tags=[app_info["name"]]
)
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title="Arida框架",
version="0.0.1",
description="基于FastAPI实现的Frida-RPC工具 https://github.com/lateautumn4lin/arida",
routes=app.routes,
)
openapi_schema["info"]["x-logo"] = {
"url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
}
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
return app return app

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 40 KiB