├── .idea
├── .gitignore
├── misc.xml
├── vcs.xml
├── inspectionProfiles
│ ├── profiles_settings.xml
│ └── Project_Default.xml
├── modules.xml
└── 安卓逆向案例.iml
├── Frida常用以及框架脚本
├── 查看当前运行.py
├── frida-rpc框架.py
└── frida-hook框架.py
├── adb使用笔记.md
├── 得物
├── 测试主页推荐.py
├── hook.js
└── newSign.py
├── 豆瓣
├── hook_sig.py
└── 发送请求.py
├── README.md
└── frida使用笔记.md
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # 默认忽略的文件
2 | /shelf/
3 | /workspace.xml
4 | # 基于编辑器的 HTTP 客户端请求
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Frida常用以及框架脚本/查看当前运行.py:
--------------------------------------------------------------------------------
1 | import frida
2 |
3 | rdev = frida.get_remote_device()
4 | print(rdev)
5 |
6 | processes = rdev.enumerate_processes()
7 | for process in processes:
8 | print(process)
9 |
10 | front_app = rdev.get_frontmost_application()
11 | print(front_app)
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/安卓逆向案例.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Frida常用以及框架脚本/frida-rpc框架.py:
--------------------------------------------------------------------------------
1 | import frida
2 |
3 | rdev = frida.get_remote_device()
4 | session = rdev.attach("名称")
5 |
6 |
7 | # 整体思路和hook差不多,但是需要在rpc里面进行导出
8 | src = """
9 | rpc.exports = {
10 | CustomizationFunctionName: function(参数列表) {
11 | var res;
12 | Java.perform(function(){
13 | var CustomizationObjectName = Java.use("包名.类名");
14 | res = CustomizationObjectName.函数名(参数列表);
15 | });
16 | return res;
17 | }
18 | }
19 |
20 | """
21 |
22 | script = session.create_script(src)
23 | script.load()
24 |
25 | wanna_args = script.exports_sync.CustomizationFunctionName("参数列表")
26 | print(wanna_args)
27 |
28 |
--------------------------------------------------------------------------------
/adb使用笔记.md:
--------------------------------------------------------------------------------
1 | # 此文件记录adb的使用
2 | ## 安装
3 | 此过程略,可以在网上轻易获取到
4 | ## 使用
5 | 首先我们介绍一下adb命令的基本构成
6 | ```bash
7 | adb -s 设备 命令
8 | ```
9 | 十分简洁,我们只需要知道我们需要执行什么命令即可。
10 |
11 | 同时,如果你的设备只有一个,那么命令可以简化为
12 | ```bash
13 | adb 命令
14 | ```
15 |
16 | ### 常用命令
17 |
18 | 我们首先需要知道启动以及结束和连接设备
19 |
20 | ``` bash
21 | adb start-server # 启动服务
22 | adb kill-server # 中止服务
23 | adb -s 设备 connect ip:host # 连接设备
24 | ```
25 |
26 | 我们使用下述命令进行查看设备
27 |
28 | ```bash
29 | adb devices
30 | ```
31 |
32 | 这个命令可以把连接到的设备展示出来
33 |
34 | 另外例如推送文件,下载apk相关我们可以直接输入adb获取它的使用文档
35 |
36 | 下面介绍查看手机或虚拟机的cup型号的命令,会在我们使用frida时有用
37 |
38 | ```bash
39 | adb shell getprop ro.product.cpu.abi # 查看型号
40 | ```
41 |
42 | 同时,我们可以通过下述命令进入手机的Linux终端(记得开启root哦)
43 |
44 | ```bash
45 | adb shell
46 | ```
47 |
48 |
--------------------------------------------------------------------------------
/Frida常用以及框架脚本/frida-hook框架.py:
--------------------------------------------------------------------------------
1 | import frida
2 | import sys
3 |
4 | rdev = frida.get_remote_device()
5 | # app名称或者app包名称
6 | session = rdev.attach("com.shizhuang.duapp")
7 |
8 | # 目标:指定替换是那个包中的方法名
9 | # - 包名称:com.shizhuang.duapp.common.utils
10 | # - 类名称:RequestUtils
11 | # - 方法名:c m30623c-jadx工具给你创造的。
12 | # - 类名称.方法名.implementation = function(方法的参数列表){var res = this.方法(参数);return res}
13 | # - 如果是由重载的函数,那么需要携带参数类型,详情可以看frida的报错信息
14 | # - 这里给一个具体的例子RequestUtils.a.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation
15 | scr = """
16 | Java.perform(function () {
17 | // 导入类
18 | var RequestUtils = Java.use("包名.类名");
19 |
20 | // 找到类中的方法进行hook
21 | RequestUtils.c.implementation = function(map,j){
22 | console.log("666");
23 | var res = this.c(map,j);
24 | console.log("999");
25 | return res;
26 | }
27 |
28 | });
29 | """
30 | script = session.create_script(scr)
31 |
32 |
33 | def on_message(message, data):
34 | print(message, data)
35 |
36 |
37 | script.on("message", on_message)
38 |
39 | script.load()
40 | sys.stdin.read()
41 |
--------------------------------------------------------------------------------
/得物/测试主页推荐.py:
--------------------------------------------------------------------------------
1 | import requests
2 | from newSign import get_newSign
3 |
4 |
5 | headers = {
6 | "User-Agent": "duapp/5.28.0(android;9)",
7 | "Connection": "Keep-Alive",
8 | "Accept-Encoding": "gzip",
9 | "cookieToken": "",
10 | "webua": "Mozilla/5.0 (Linux; Android 9; SM-G977N Build/LMY48Z; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile Safari/537.36/duapp/5.28.0(android;9)",
11 | "duplatform": "android",
12 | "duv": "5.28.0",
13 | "duloginToken": "",
14 | "shumeiid": "",
15 | "X-Auth-Token": "",
16 | }
17 | cookies = {
18 | "HWWAFSESTIME": ""
19 | }
20 | url = "https://app.dewu.com/sns-rec/v1/recommend/all/feed"
21 | params = {
22 | "lastId": "",
23 | "limit": "20",
24 | "deliveryProjectId": "0",
25 | "negativeFeedbackUids": "",
26 | "negativeFeedbackCids": "",
27 | "pushChannel": "",
28 | "pushContentId": "",
29 | "lastExposureCids": "",
30 | "abV518Autoplay": "0",
31 | "ab528feedsCardNewCommodity": "1",
32 | "deviceNetwork": "WIFI",
33 | "abVIcon": "2",
34 | "abCoverReverse": "0",
35 | }
36 | sign_time = get_newSign(params)
37 | params['newSign'] = sign_time[0]
38 | headers['timestamp'] = sign_time[1]
39 | response = requests.get(url, headers=headers, cookies=cookies, params=params)
40 |
41 | print(response.json())
42 |
43 |
--------------------------------------------------------------------------------
/豆瓣/hook_sig.py:
--------------------------------------------------------------------------------
1 | import frida
2 | import sys
3 |
4 | rdev = frida.get_remote_device()
5 | session = rdev.attach("豆瓣")
6 |
7 |
8 | scr = """
9 | Java.perform(function () {
10 | // 导入类
11 | var RequestUtils = Java.use("com.douban.frodo.network.ApiSignatureHelper");
12 | var encrypted = Java.use("com.douban.frodo.utils.crypto.HMACHash1");
13 | var apiKey = Java.use("com.douban.ad.utils.ApiUtils")
14 |
15 | // 找到类中的方法进行hook
16 | RequestUtils.a.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation =
17 | function(str, str1, str2){
18 | console.log(str, str1, str2);
19 | var res = this.a(str, str1, str2);
20 | console.log(res);
21 | return res;
22 | }
23 | encrypted.a.implementation = function(str, str1){
24 | console.log(str, str1)
25 | var res = this.a(str, str1)
26 | console.log(res);
27 | return res;
28 | }
29 | apiKey.getApiKey.implementation = function(context){
30 | console.log(context)
31 | var res = this.getApiKey(context)
32 | console.log(res);
33 | return res;
34 | }
35 |
36 | });
37 | """
38 | script = session.create_script(scr)
39 |
40 |
41 | def on_message(message, data):
42 | print(message, data)
43 |
44 |
45 | script.on("message", on_message)
46 |
47 | script.load()
48 | sys.stdin.read()
49 |
--------------------------------------------------------------------------------
/得物/hook.js:
--------------------------------------------------------------------------------
1 | // hook 添加params试图定位添加newsign的地方
2 | Java.perform(function () {
3 | // 导入类
4 | var RequestUtils = Java.use("com.shizhuang.duapp.common.helper.net.ParamsBuilder");
5 |
6 | // 找到类中的方法进行hook
7 | RequestUtils.addParams.overload('java.lang.String', 'java.lang.Object').implementation = function(str, str1){
8 | console.log(str, str1);
9 | showStacks()
10 | var res = this.addParams(str, str1);
11 | return res;
12 | }
13 | })
14 | // 定位加密点
15 | Java.perform(function () {
16 | // 导入类
17 | var RequestUtils = Java.use("com.duapp.aesjni.AESEncrypt");
18 |
19 | // 找到类中的方法进行hook
20 | RequestUtils.encode.implementation = function (obj, str) {
21 | console.log('=================================================')
22 | console.log('obj', obj);
23 | console.log('str', str);
24 | console.log('=================================================')
25 | var res = this.encode(obj, str);
26 | console.log(res)
27 | console.log('=================================================')
28 | showStacks()
29 | console.log('=================================================')
30 | return res;
31 | }
32 | })
33 | // 显示调用栈
34 | function showStacks() {
35 | Java.perform(function () {
36 | console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
37 | });
38 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 安卓逆向合集
2 | > 此项目为安卓逆向实战合集以及部分笔记
3 | >
4 | > 仅作学习分析以及学习记录,__禁止商用__,如遇__侵权__请联系删除
5 | >
6 | > 本项目将持续更新
7 | ### 我的个人博客
8 | [回锅炒辣椒的个人博客](https://www.xsblog.site/)
9 | ## 环境篇
10 | 众所周知,安卓逆向首先需要一个安卓环境,有两种方案,第一是模拟器,第二是真机
11 |
12 | ### 模拟器
13 | 市面上有很多模拟器可以用,up选择的是夜神模拟器,在官网下载好模拟器后,我们需要改一些配置
14 |
15 | 第一,抓包配置 --> 配置WIFI的IP以及按照你的抓包工具进行配置。
16 |
17 | 第二,开root,很简单
18 |
19 | > 但是会出现抓包抓不到的情况,这种是由于在java层配置了不走系统代理,所以我们需要别的工具:
20 | >
21 | > 1. drony(不推荐),有时会导致无法上网,不稳定
22 | > 2. SocksDroid(推荐),开启工具时记得删除系统代理
23 |
24 | > 注: 夜神模拟器默认的端口是62025, 所以我们需要连接这个端口(不一定,我的电脑是这个端口)
25 |
26 | ### 反编译工具
27 |
28 | 1. jadx(java层)
29 | 2. jeb(java层)
30 | 3. ida(so层,c语言层)
31 |
32 | ### 查壳脱壳工具
33 |
34 | 按照自己的喜好即可,网上有很多
35 |
36 | ### 获取apk途径
37 |
38 | 百度搜索即可
39 |
40 | ## 实战篇
41 |
42 | > 更多的笔记见其他文件。
43 |
44 | | 项目 | 难度 |
45 | | ---- | ---- |
46 | | 豆瓣 | 简单 |
47 | | 某物 | 中等 |
48 |
49 | ### 豆瓣
50 |
51 | 想必大家爬虫梦的开始就是豆瓣250吧,那么我们安卓逆向的开始也从豆瓣开始吧~
52 |
53 | 分析过程:
54 |
55 | 1. 首先抓包分析,确认接口,确认加密参数名: _sig
56 | 2. 全局搜索,确认加密位置
57 | 3. hook加密函数,分析加密流程
58 | 4. 用python改写,实现发包
59 |
60 | 总结算法: 豆瓣的_sig是由请求方式以及url的path和时间戳以&相连,进行一次hmacsha1,然后将结果转化为base64的格式
61 |
62 | ### 某物
63 |
64 | 第二个案例首先更新第一部分,newSign的获取。得物前几个版本比较简单,但是新版本有些内容不太一样
65 |
66 | 第一,newSign放到so层添加,并且是VMP的so文件,在这里我们不分析这个so文件,在全局搜索其他部分,找到加密位置
67 |
68 | 分析过程:
69 | 1. 首先抓包分析,需要分析参数: newSign
70 | 2. 全局搜索其他关键字
71 | 3. hook函数,然后去so层分析
72 | 4. 用python改写
73 |
74 | 总结: 这个算法是将params添加四个额外的内容,排序,然后用aes加密之后在加密md5得到newSign
75 |
76 | 之后更新搜索接口的加密以及解密...
77 |
--------------------------------------------------------------------------------
/得物/newSign.py:
--------------------------------------------------------------------------------
1 | import base64
2 | import time
3 |
4 | from Crypto.Cipher import AES
5 | from Crypto.Util.Padding import pad
6 | import hashlib
7 |
8 |
9 | def get_newSign(search_dict: dict) -> tuple[str, str]:
10 | new_dict = {
11 | 'uuid': '',
12 | 'timestamp': str(int(time.time() * 1000)),
13 | 'loginToken': '',
14 | 'platform': 'android'
15 | }
16 | new_dict.update(search_dict)
17 | str_to_encode = ''.join(
18 | [f'{k}{v}' for k, v in sorted(new_dict.items(), key=lambda item: item[0])]
19 | )
20 | newSign = encrypt(str_to_encode)
21 | md5_hash = hashlib.md5()
22 | md5_hash.update(newSign.encode())
23 | return md5_hash.hexdigest(), new_dict['timestamp']
24 |
25 |
26 | def encrypt(plaintext):
27 | cipher = AES.new("d245a0ba8d678a61".encode('utf-8'), AES.MODE_ECB)
28 | padded_plaintext = pad(plaintext.encode('utf-8'), AES.block_size)
29 | ciphertext = cipher.encrypt(padded_plaintext)
30 | ciphertext = str(base64.encodebytes(ciphertext), 'utf-8').replace('\n', '')
31 | return ciphertext
32 |
33 |
34 | if __name__ == '__main__':
35 | params = {
36 | "lastId": "",
37 | "limit": "20",
38 | "deliveryProjectId": "0",
39 | "negativeFeedbackUids": "",
40 | "negativeFeedbackCids": "",
41 | "pushChannel": "",
42 | "pushContentId": "",
43 | "lastExposureCids": "",
44 | "abV518Autoplay": "0",
45 | "ab528feedsCardNewCommodity": "1",
46 | "deviceNetwork": "WIFI",
47 | "abVIcon": "2",
48 | "abCoverReverse": "0",
49 | }
50 | print(get_newSign(params))
51 |
52 |
53 |
--------------------------------------------------------------------------------
/豆瓣/发送请求.py:
--------------------------------------------------------------------------------
1 | import base64
2 | import hashlib
3 | import hmac
4 | import time
5 | from urllib.parse import urlparse, quote
6 |
7 | import requests
8 |
9 |
10 | def sha1_base64(url, method):
11 | path = urlparse(url).path
12 | encoded_path = quote(path, safe='')
13 | timestamp = str(int(time.time()))
14 | key = b'bf7dddc7c9cfe6f7'
15 | message = '&'.join([method, encoded_path, timestamp])
16 | hmac_sha1 = hmac.new(key, message.encode('utf-8'), hashlib.sha1)
17 | hashed_data = hmac_sha1.digest()
18 | return base64.b64encode(hashed_data).decode('utf-8'), timestamp
19 |
20 |
21 | headers = {
22 | "User-Agent": "Rexxar-Core/0.1.3 api-client/1 com.douban.frodo/7.18.0(230) Android/28 product/beyond1qlteue vendor/samsung model/SM-G977N brand/samsung rom/android network/wifi udid/81c09b13e49151d13ed4d8d3817b99c45cf0d399 platform/mobile nd/1 com.douban.frodo/7.18.0(230) Rexxar/1.2.151 platform/mobile 1.2.151",
23 | "Connection": "Keep-Alive",
24 | "Accept-Encoding": "gzip"
25 | }
26 |
27 | url = "https://frodo.douban.com/api/v2/movie/hot_gaia"
28 | sig_ts = sha1_base64(url, 'GET')
29 | params = {
30 | "area": "全部",
31 | "sort": "time",
32 | "playable": "0",
33 | "loc_id": "0",
34 | "start": "0",
35 | "count": "20",
36 | "udid": "81c09b13e49151d13ed4d8d3817b99c45cf0d399", # 和请求头的一致
37 | "rom": "android",
38 | "apikey": "", # 需填写你的key,暂时没分析出生成逻辑
39 | "s": "rexxar_new",
40 | "channel": "Yingyongbao_Market",
41 | "timezone": "Asia/Shanghai", # 时区
42 | "device_id": "", # 设备id
43 | "os_rom": "android",
44 | "apple": "", # 暂未分析,多次固定不变
45 | "sugar": "46007",
46 | "_sig": sig_ts[0],
47 | "_ts": sig_ts[1]
48 | }
49 | response = requests.get(url, headers=headers, params=params)
50 |
51 | print(response.text)
52 | print(response)
53 |
54 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 |
36 |
37 |
38 |
39 |
61 |
62 |
63 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/frida使用笔记.md:
--------------------------------------------------------------------------------
1 | # 此文件记录frida的使用
2 |
3 | ## 电脑安装frida
4 | ```bash
5 | pip install frida
6 | pip install frida-tools
7 | ```
8 | 十分简单
9 | ## 手机安装frida
10 | 首先我们需要确定手机的cpu类型
11 |
12 | 模拟器通常是: x86_64
13 |
14 | 真机通常是: arm
15 |
16 | 我们根据不同的型号去frida的github下载对应的frida-sever
17 |
18 | 下面附录frida的github链接: https://github.com/frida/frida
19 |
20 | 我们下载好之后需要解压然后推送到手机中
21 | ```bash
22 | adb -s 设备 push xx/xxx/xxx/frida-server /sdcard # 首先推送到一个用户目录然后在安卓的Linux推送到系统中
23 | adb shell # 进入手机
24 | su - # 获得root权限
25 | mv /sdcard/frida-server /data/local/tmp # 移动到系统文件
26 | cd /data/local/tmp # 进入目录
27 | chmod 777 frida-server # 赋予最高权限
28 | ./frida-server # 开启服务
29 | ```
30 | 在安卓开启frida服务之前,我们记得在电脑上开启tcp转发
31 | ```bash
32 | adb forward tcp:27042 tcp:27042
33 | adb forward tcp:27043 tcp:27043
34 | ```
35 |
36 | ## 下面介绍一些固定的格式
37 | ### 获取连接设别的信息,确认包名
38 | ```python
39 | import frida
40 |
41 | rdev = frida.get_remote_device()
42 | print(rdev)
43 |
44 | processes = rdev.enumerate_processes()
45 | for process in processes:
46 | print(process)
47 |
48 | front_app = rdev.get_frontmost_application()
49 | print(front_app)
50 |
51 | ```
52 | ### hook类中的方法
53 | 这个是hook的类的方法没有重载的情况
54 | ```python
55 | import frida
56 | import sys
57 |
58 | rdev = frida.get_remote_device()
59 | # app名称或者app包名称
60 | session = rdev.attach("com.shizhuang.duapp")
61 |
62 | # 目标:指定替换是那个包中的方法名
63 | # - 包名称:com.shizhuang.duapp.common.utils
64 | # - 类名称:RequestUtils
65 | # - 方法名:c m30623c-jadx工具给你创造的。
66 | # - 参数1:map
67 | # - 参数2:long
68 | scr = """
69 | Java.perform(function () {
70 | // 导入类, 看文件最顶部的package
71 | var RequestUtils = Java.use("com.shizhuang.duapp.common.utils.RequestUtils");
72 |
73 | // 找到类中的方法进行hook
74 | RequestUtils.c.implementation = function(map,j){
75 | console.log("666");
76 | var res = this.c(map,j);
77 | console.log("999");
78 | return res;
79 | }
80 |
81 | });
82 | """
83 | script = session.create_script(scr)
84 |
85 |
86 | def on_message(message, data):
87 | print(message, data)
88 |
89 |
90 | script.on("message", on_message)
91 |
92 | script.load()
93 | sys.stdin.read()
94 | ```
95 | 下面是类中的函数具有重载的情况
96 | ```python
97 |
98 | scr = """
99 | Java.perform(function () {
100 | // 导入类
101 | var RequestUtils = Java.use("com.douban.frodo.network.ApiSignatureHelper");
102 |
103 | // 找到类中的方法进行hook,然后加上overload参数类型即可
104 | RequestUtils.a.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation =
105 | function(str, str1, str2){
106 | console.log(str, str1, str2);
107 | var res = this.a(str, str1, str2);
108 | console.log(res);
109 | return res;
110 | }
111 |
112 | });
113 | """
114 | script = session.create_script(scr)
115 | ```
116 | ### 下面是hook so层代码的情况
117 | > so层代码的hook需要在真机下才可以,因为默认只有arm芯片,不支持x86_64
118 | >
119 | ```python
120 | scr = """
121 | Java.perform(function () {
122 | var addr_func = Module.findExportByName("libJNIEncrypt.so", "AES_128_ECB_PKCS5Padding_Encrypt");
123 | Interceptor.attach(addr_func, {
124 | onEnter: function(args){
125 | // 进入并执行函数:AES_128_ECB_PKCS5Padding_Encrypt,args就是参数
126 | console.log("-------------参数 1-------------");
127 | console.log(args[0].readUtf8String())
128 |
129 | console.log("-------------参数 2-------------");
130 | console.log(args[1].readUtf8String());
131 | },
132 | onLeave: function(retValue){
133 | console.log("-------------返回-------------");
134 | console.log(retValue.readUtf8String());
135 | }
136 | })
137 | });
138 | """
139 | script = session.create_script(scr)
140 | ```
141 | > 小总结:
142 | >
143 | > frida hook参数函数的时候,前面的基本都不变,只是hook脚本会发送改变
144 |
145 | ### frida rpc调用so层函数
146 |
147 | ```python
148 | import frida
149 |
150 | rdev = frida.get_remote_device()
151 | session = rdev.attach("名称")
152 |
153 |
154 | # 整体思路和hook差不多,但是需要在rpc里面进行导出
155 | src = """
156 | rpc.exports = {
157 | CustomizationFunctionName: function(参数列表) {
158 | var res;
159 | Java.perform(function(){
160 | var CustomizationObjectName = Java.use("包名.类名");
161 | res = CustomizationObjectName.函数名(参数列表);
162 | });
163 | return res;
164 | }
165 | }
166 |
167 | """
168 |
169 | script = session.create_script(src)
170 | script.load()
171 |
172 | wanna_args = script.exports.CustomizationFunctionName("参数列表")
173 | print(wanna_args)
174 | ```
175 | 其实rpc也很简单,就是稍微导出一下方法就可以了.
176 |
177 | ## frida过检测
178 | ### 常见的frida检测
179 | 1、检测文件名
180 |
181 | 2、检测端口
182 |
183 | 3、双进程保护
184 |
185 | 4、检测D-Bus
186 |
187 | 5、检测/proc/pid/maps映射文件
188 |
189 | 6、检测/proc/pid/task/tip/status
190 |
191 | 7、检测/data/local/tmp目录
192 | ### 利用第三方库以及转化端口达到效果
193 | 我们在注入frida的时候,经常会遇到一注入app就闪退的情况,这种情况说明被检测到了frida
194 |
195 | 这里我们采用绕过的方案
196 | 使用Frida的魔改版本 Hluda来隐藏Frida特征,其介绍:跟随 FRIDA 上游自动修补程序,并为 Android 构建反检测版本的 frida-server。使用方式跟官方Frida没有区别。
197 |
198 | github地址:https://github.com/hzzheyang/strongR-frida-android/
199 |
200 | 官方Frida默认端口是27042,现在我们来修改启动端口
201 | ```bash
202 | ./hlu-server_x8664 -l 0.0.0.0:8080
203 | ```
204 | ```bash
205 | adb forward tcp:8080 tcp:8080
206 | frida -H 127.0.0.1:8080 -f com.shizhuang.duapp -l Hook.js
207 | ```
208 | 使用python脚本连接时
209 | ```python
210 | host = '127.0.0.1:8080'
211 | manager = frida.get_device_manager()
212 | device= manager.add_remote_device(host)
213 | ```
--------------------------------------------------------------------------------