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