feat:一点已经实现的小思路
This commit is contained in:
parent
f1047e7b6a
commit
690399eb82
92
.gitignore
vendored
Normal file
92
.gitignore
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# Built application files
|
||||||
|
*.apk
|
||||||
|
*.aar
|
||||||
|
*.ap_
|
||||||
|
*.aab
|
||||||
|
|
||||||
|
# Files for the ART/Dalvik VM
|
||||||
|
*.dex
|
||||||
|
|
||||||
|
# Java class files
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
bin/
|
||||||
|
gen/
|
||||||
|
out/
|
||||||
|
# Uncomment the following line in case you need and you don't have the release build type files in your app
|
||||||
|
# release/
|
||||||
|
|
||||||
|
# Gradle files
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Local configuration file (sdk path, etc)
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Proguard folder generated by Eclipse
|
||||||
|
proguard/
|
||||||
|
|
||||||
|
# Log Files
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Android Studio Navigation editor temp files
|
||||||
|
.navigation/
|
||||||
|
|
||||||
|
# Android Studio captures folder
|
||||||
|
captures/
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
*.iml
|
||||||
|
.idea
|
||||||
|
.idea/
|
||||||
|
.idea/*
|
||||||
|
.idea/workspace.xml
|
||||||
|
.idea/tasks.xml
|
||||||
|
.idea/gradle.xml
|
||||||
|
.idea/assetWizardSettings.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
.idea/libraries
|
||||||
|
# Android Studio 3 in .gitignore file.
|
||||||
|
.idea/caches
|
||||||
|
.idea/modules.xml
|
||||||
|
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
|
||||||
|
.idea/navEditor.xml
|
||||||
|
|
||||||
|
# Keystore files
|
||||||
|
# Uncomment the following lines if you do not want to check your keystore files in.
|
||||||
|
#*.jks
|
||||||
|
#*.keystore
|
||||||
|
|
||||||
|
# External native build folder generated in Android Studio 2.2 and later
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx/
|
||||||
|
|
||||||
|
# Google Services (e.g. APIs or Firebase)
|
||||||
|
# google-services.json
|
||||||
|
|
||||||
|
# Freeline
|
||||||
|
freeline.py
|
||||||
|
freeline/
|
||||||
|
freeline_project_description.json
|
||||||
|
|
||||||
|
# fastlane
|
||||||
|
fastlane/report.xml
|
||||||
|
fastlane/Preview.html
|
||||||
|
fastlane/screenshots
|
||||||
|
fastlane/test_output
|
||||||
|
fastlane/readme.md
|
||||||
|
|
||||||
|
# Version control
|
||||||
|
vcs.xml
|
||||||
|
|
||||||
|
# lint
|
||||||
|
lint/intermediates/
|
||||||
|
lint/generated/
|
||||||
|
lint/outputs/
|
||||||
|
lint/tmp/
|
||||||
|
# lint/reports/
|
||||||
|
node_modules/*
|
||||||
|
*.pyc
|
||||||
|
.vscode/*
|
||||||
|
package-lock.json
|
36
apps/kuaiduizuoye.js
Normal file
36
apps/kuaiduizuoye.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
var result = null;
|
||||||
|
function decrypt_data(data) {
|
||||||
|
Java.perform(function () {
|
||||||
|
var rc_class = Java.use("com.baidu.android.common.security.RC4");
|
||||||
|
var func_class = Java.use("com.kuaiduizuoye.scan.utils.a.a");
|
||||||
|
var func_instance = func_class.$new();
|
||||||
|
var stringClass = Java.use("java.lang.String");
|
||||||
|
var stringInstance = stringClass.$new("4edb41c838d8a5c38b772854523658ea6a5f03f2d598caf9f8062e2d5f8d0ed16cc5f1e130de80b44a740cf8e01fdfc931cd22941af1d9898bc5ba70303e73a5");
|
||||||
|
var rc = rc_class.$new(stringInstance);
|
||||||
|
result = func_instance.a(data, rc, false);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
function generate_url(origin_url) {
|
||||||
|
Java.perform(function () {
|
||||||
|
var search_common_api = Java.use("com.kuaiduizuoye.scan.common.net.model.v1.SearchCommonApi$Input");
|
||||||
|
var input_base = search_common_api.$new(origin_url);
|
||||||
|
var func_class = Java.use("com.baidu.homework.common.net.Net");
|
||||||
|
result = func_class.appendSign(input_base);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
function encrypt_data(grade, subject, versionId, term, text, isHitDayup, bookType, isHitPay, dataType, pn, rn) {
|
||||||
|
Java.perform(function () {
|
||||||
|
var func_class = Java.use("com.kuaiduizuoye.scan.base.f");
|
||||||
|
var search_search_api = Java.use("com.kuaiduizuoye.scan.common.net.model.v1.SearchSearch$Input");
|
||||||
|
var input_base = search_search_api.$new(grade, subject, versionId, term, text, isHitDayup, bookType, isHitPay, dataType, pn, rn);
|
||||||
|
result = func_class.a(input_base);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
rpc.exports = {
|
||||||
|
decryptData: decrypt_data,
|
||||||
|
generateUrl: generate_url,
|
||||||
|
encryptData: encrypt_data
|
||||||
|
}
|
18
config.py
Normal file
18
config.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : config.py
|
||||||
|
@Time : 2020/09/22 18:57:19
|
||||||
|
@Author : Lateautumn4lin
|
||||||
|
@Version : 1.0
|
||||||
|
@Contact : Lateautumn4lin
|
||||||
|
@License : (C)Copyright 2020
|
||||||
|
@Desc : None
|
||||||
|
'''
|
||||||
|
|
||||||
|
apps_config = [
|
||||||
|
{
|
||||||
|
"package_name": "com.kuaiduizuoye.scan",
|
||||||
|
"script_name": "kuaiduizuoye.js"
|
||||||
|
}
|
||||||
|
]
|
187
main.py
Normal file
187
main.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
@File : app.py
|
||||||
|
@Time : 2020/09/22 18:52:11
|
||||||
|
@Author : Lateautumn4lin
|
||||||
|
@Version : 1.0
|
||||||
|
@Contact : Lateautumn4lin
|
||||||
|
@License : (C)Copyright 2020
|
||||||
|
@Desc : None
|
||||||
|
'''
|
||||||
|
from pydantic import BaseModel, Field, create_model
|
||||||
|
from typing import NewType
|
||||||
|
from ast import *
|
||||||
|
import types
|
||||||
|
from fastapi import APIRouter
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
import frida
|
||||||
|
from frida import ServerNotRunningError
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from loguru import logger
|
||||||
|
import execjs
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
_parse_path = "parse.js"
|
||||||
|
_package_name = "com.kuaiduizuoye.scan"
|
||||||
|
_frida_js_path = f"apps/kuaiduizuoye.js"
|
||||||
|
|
||||||
|
|
||||||
|
def get_app_info():
|
||||||
|
with open(_parse_path, encoding="utf-8") as f, open(_frida_js_path, encoding="utf-8") as f1:
|
||||||
|
ctx = execjs.compile(f.read())
|
||||||
|
result = ctx.call(
|
||||||
|
'parse', f1.read()
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def on_message(message, data):
|
||||||
|
if message['type'] == 'send':
|
||||||
|
logger.info("[**] {0}".format(message['payload']))
|
||||||
|
else:
|
||||||
|
logger.info(f"log:{message}")
|
||||||
|
|
||||||
|
|
||||||
|
def detect_frida_state():
|
||||||
|
logger.info("Begin Detect Frida State")
|
||||||
|
shell = 'adb shell su -c "ps -ef|grep frida"'
|
||||||
|
p = subprocess.Popen(
|
||||||
|
shell,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT
|
||||||
|
)
|
||||||
|
stdout, stderr = p.communicate()
|
||||||
|
stdout = stdout.decode('utf-8')
|
||||||
|
return ("frida-server" in stdout)
|
||||||
|
|
||||||
|
|
||||||
|
def start_frida_server():
|
||||||
|
logger.info("Begin Start Frida Server")
|
||||||
|
shell = 'adb shell su -c "./data/local/tmp/frida-server &"'
|
||||||
|
subprocess.Popen(
|
||||||
|
shell,
|
||||||
|
shell=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if not detect_frida_state():
|
||||||
|
# 启动frida-server,增加延迟防止附加失败
|
||||||
|
start_frida_server()
|
||||||
|
time.sleep(3)
|
||||||
|
session = frida.get_usb_device().attach(_package_name)
|
||||||
|
script = session.create_script(
|
||||||
|
open(_frida_js_path, encoding="utf-8").read()
|
||||||
|
)
|
||||||
|
script.on('message', on_message)
|
||||||
|
logger.info('[*] Start attach')
|
||||||
|
script.load()
|
||||||
|
Url = create_model("User", **{"origin_url": "asdasd"})
|
||||||
|
function_ast = FunctionDef(
|
||||||
|
lineno=2,
|
||||||
|
col_offset=0,
|
||||||
|
name='generate_url',
|
||||||
|
args=arguments(
|
||||||
|
args=[
|
||||||
|
arg(
|
||||||
|
lineno=2,
|
||||||
|
col_offset=17,
|
||||||
|
arg='item',
|
||||||
|
annotation=Name(lineno=2, col_offset=22,
|
||||||
|
id='Url', ctx=Load()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
posonlyargs=[],
|
||||||
|
vararg=None,
|
||||||
|
kwonlyargs=[],
|
||||||
|
kw_defaults=[],
|
||||||
|
kwarg=None,
|
||||||
|
defaults=[],
|
||||||
|
),
|
||||||
|
body=[
|
||||||
|
Expr(
|
||||||
|
lineno=3,
|
||||||
|
col_offset=4,
|
||||||
|
value=Call(
|
||||||
|
lineno=3,
|
||||||
|
col_offset=4,
|
||||||
|
func=Name(lineno=3, col_offset=4,
|
||||||
|
id='print', ctx=Load()),
|
||||||
|
args=[Name(lineno=3, col_offset=10,
|
||||||
|
id='Url', ctx=Load())],
|
||||||
|
keywords=[],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Assign(
|
||||||
|
lineno=4,
|
||||||
|
col_offset=4,
|
||||||
|
targets=[Name(lineno=4, col_offset=4,
|
||||||
|
id='res', ctx=Store())],
|
||||||
|
value=Call(
|
||||||
|
lineno=4,
|
||||||
|
col_offset=10,
|
||||||
|
func=Attribute(
|
||||||
|
lineno=4,
|
||||||
|
col_offset=10,
|
||||||
|
value=Attribute(
|
||||||
|
lineno=4,
|
||||||
|
col_offset=10,
|
||||||
|
value=Name(lineno=4, col_offset=10,
|
||||||
|
id='script', ctx=Load()),
|
||||||
|
attr='exports',
|
||||||
|
ctx=Load(),
|
||||||
|
),
|
||||||
|
attr='generate_url',
|
||||||
|
ctx=Load(),
|
||||||
|
),
|
||||||
|
args=[
|
||||||
|
Attribute(
|
||||||
|
lineno=4,
|
||||||
|
col_offset=38,
|
||||||
|
value=Name(lineno=4, col_offset=38,
|
||||||
|
id='item', ctx=Load()),
|
||||||
|
attr='origin_url',
|
||||||
|
ctx=Load(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
keywords=[],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Return(
|
||||||
|
lineno=5,
|
||||||
|
col_offset=4,
|
||||||
|
value=Name(lineno=5, col_offset=11, id='res', ctx=Load()),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
decorator_list=[],
|
||||||
|
returns=None,
|
||||||
|
)
|
||||||
|
module_ast = Module(body=[function_ast], type_ignores=[])
|
||||||
|
module_code = compile(module_ast, "<>", "exec")
|
||||||
|
function_code = [
|
||||||
|
c for c in module_code.co_consts if isinstance(c, types.CodeType)][0]
|
||||||
|
test = types.FunctionType(
|
||||||
|
function_code,
|
||||||
|
{
|
||||||
|
"script": script,
|
||||||
|
"Url": Url,
|
||||||
|
"print": print
|
||||||
|
}
|
||||||
|
)
|
||||||
|
test.__annotations__ = {"item": Url}
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
for k, v in get_app_info().items():
|
||||||
|
router.add_api_route("/generate_url", test, methods=["POST"])
|
||||||
|
break
|
||||||
|
app.include_router(router)
|
||||||
|
|
||||||
|
|
||||||
|
# @app.post('/generate_url')
|
||||||
|
# def generate_url(item: c):
|
||||||
|
# res = script.exports.generate_url(item.origin_url)
|
||||||
|
# return res
|
36
parse.js
Normal file
36
parse.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const babel = require('@babel/core')
|
||||||
|
var exports = new Map();
|
||||||
|
var functions = new Map();
|
||||||
|
var result = new Map();
|
||||||
|
function parse(code) {
|
||||||
|
let visitor = {
|
||||||
|
// 处理exports节点,获取导出函数对应表
|
||||||
|
ExpressionStatement(path) {
|
||||||
|
let params = path.node.expression.right;
|
||||||
|
try {
|
||||||
|
params = params.properties
|
||||||
|
for (let i = 0; i < params.length; i++) {
|
||||||
|
exports.set(params[i].value.name, params[i].key.name)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 处理function,获取函数名以及对应参数
|
||||||
|
FunctionDeclaration(path) {
|
||||||
|
let params = path.node;
|
||||||
|
functions.set(params.id.name, params.params.length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
babel.transform(code, {
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
visitor
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
exports.forEach(function (value, key, map) {
|
||||||
|
result.set(value, functions.get(key))
|
||||||
|
})
|
||||||
|
return Object.fromEntries(result);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user