安卓逆向-抓包

本文不构成任何技术操作指导或建议,仅供技术交流与学习参考。如发现本文内容存在可能违反法律规定的情况,请立即联系本人删除相关内容。(已对图片中出现的包名和应用名进行处理)

Charles使用

官网网址:https://www.charlesproxy.com
网上已经有很多相关的教程了,我这里写一遍有点浪费时间。这里给几个链接:

  • 激活工具:https://down.52pojie.cn/?query=chales
  • 教程:https://blog.csdn.net/weixin_43612602/article/details/135287720
    这个教程缺少手机端的操作:
    下载安装好证书之后,电脑和手机连接到同一个网络,手机WIFI设置中,长按连接的网络,选择修改网络,其中代理选择手动,代理主机名是电脑的IP地址(IP并不是每次都不变的,路由器的ARP表会更新的,所以一段时间之后重新进行代理,一定要记得重新设置一下‘代理服务器主机名’这一项)
    Pastedimage20250524172222.png

端口往往是8888:
可以在电脑端Charles中的Help->SSL Proxying->install charles RootCertificate on a Mobile……..
Pastedimage20250524172648.png
然后,当开始抓包时,
Pastedimage20250524173255.png
点击Allow即可。

应用抓包

这次的目标是一款心理治愈类APP,它有个挖胶囊的功能,但是每个账号每天只能抓5个胶囊。
开始之前,可以先把本地抓包关闭了,只抓手机上的数据包:
[Pastedimage20250524175146.png]
关闭Windows Proxy。
然后挖个胶囊看看怎么个事:
[Pastedimage20250524194201.png]
先发送一个POST请求,获取Yaoyiyao服务,服务器随机返回一个用户的info,然后APP根据info再次发送info中相关资源的GET请求,获取诸如头像,图片,音乐之类的资源,最后再获取与该info相关的评论。
再看看POST请求的param怎么设计的,有哪些参数:
[Pastedimage20250524194829.png]
我们照着这个请求自己实现一下POST:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests  

URL="https://服务器/services/v2/xxxx/yaoYiYao"
myparams = {
"userId":100000,
"longitude":100,
"latitude":50,
"blindBox":0
}
myheader={
"Content-Length": "0",
"Host": "服务器",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/4.10.0"
}
response=requests.post(url=URL,params=myparams,headers=myheader)
print(response.text)

[Pastedimage20250524200553.png]
这样就能获得服务了,id可以随意伪造,longitude和latitude也是可以随意伪造的。这个功能有个机制就是每个账号每天只能挖五个胶囊,我们可以设计一下,每请求5次,更改一下账号和经纬度,就能继续获取。
我据此实现了一个漂流瓶功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
import requests  
import random
import time
import json

class Myhttp:
def __init__(self):
# 基础URL和默认参数
self.base_url = "https://服务器/services/v2/xxxx/yaoYiYao"
self.userId = 100000
self.longitude = 109
self.latitude = 35
self.blindBox = 0

# 通用请求头
self.headers = {
"Content-Length": "0",
"Host": "服务器",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/4.10.0"
}

def update_params(self):
"""更新请求参数(随机化)"""
random.seed(time.time())
temp = random.random()

# 更新参数(使用更合理的随机化逻辑)
self.userId += int(temp * 1000000) # 随机增加用户ID
self.longitude += (temp - 0.5) * 20 # 经度随机浮动
self.latitude += (temp - 0.5) * 20 # 纬度随机浮动

# 打印当前参数(调试用)
print(f"当前参数: UserID={self.userId}, 经纬度=({self.longitude}, {self.latitude})")

def post(self):
"""发送POST请求(无需参数)"""
try:
# 构建请求参数
params = {
"userId": self.userId,
"longitude": self.longitude,
"latitude": self.latitude,
"blindBox": self.blindBox
}

# 发送请求
response = requests.post(self.base_url, params=params, headers=self.headers)
response.raise_for_status() # 若状态码不是2xx,抛出异常
response_text=json.loads(response.text)
#print(response.text)

return response_text # 返回JSON格式的响应数据

except requests.RequestException as e:
print(f"请求出错: {e}")
exit()


def Myprint(msg):
"""安全地打印消息内容,处理可能的空数据情况"""
if msg is None or msg.get("datas") is None:
print("没有找到有效的漂流瓶数据,跳过打印")
return

xxxx_dto = msg["datas"].get("xxxxDTO")
if not xxxx_dto:
print("没有找到有效的漂流瓶信息,跳过打印")
return

# 安全获取各个字段的值
xxxx_info = xxxx_dto.get("xxxxInfo", "")
user = xxxx_dto.get("user", {})
nickname = user.get("nickName", "无名人")
city_name = xxxx_dto.get("cityName", "未知地")
create_date_short = xxxx_dto.get("createDateShort", "")
media_url_list = xxxx_dto.get("mediaUrlList", "")

# 打印获取到的信息
print(nickname, 'from', city_name, '\n', xxxx_info, '\n', create_date_short, '\n', media_url_list)
# 使用示例
if __name__ == "__main__":
http_client = Myhttp()

while True:
http_client.update_params()
for i in range(5):
msg=http_client.post() # 发送请求
Myprint(msg)
time.sleep(2) # 等待2秒
print("\n\n\n\n\n\n下一个漂流瓶来咯~~~~~~\n\n")
# 每5次请求后等待更长时间
print("===== 休息5秒 =====")
time.sleep(3)

再加上一点页面:
[Pastedimage20250524201438.png]