mirror of
https://github.com/xishandong/Android_reverse.git
synced 2024-11-25 16:26:35 +08:00
第一次上传,更新一些笔记以及豆瓣案例
This commit is contained in:
commit
90bc2a329f
8
.idea/.gitignore
vendored
Normal file
8
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
98
.idea/inspectionProfiles/Project_Default.xml
Normal file
98
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,98 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<Languages>
|
||||
<language minSize="491" name="JavaScript" />
|
||||
<language minSize="575" name="Python" />
|
||||
</Languages>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="myValues">
|
||||
<value>
|
||||
<list size="2">
|
||||
<item index="0" class="java.lang.String" itemvalue="font-size" />
|
||||
<item index="1" class="java.lang.String" itemvalue="index" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myCustomValuesEnabled" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="myValues">
|
||||
<value>
|
||||
<list size="7">
|
||||
<item index="0" class="java.lang.String" itemvalue="nobr" />
|
||||
<item index="1" class="java.lang.String" itemvalue="noembed" />
|
||||
<item index="2" class="java.lang.String" itemvalue="comment" />
|
||||
<item index="3" class="java.lang.String" itemvalue="noscript" />
|
||||
<item index="4" class="java.lang.String" itemvalue="embed" />
|
||||
<item index="5" class="java.lang.String" itemvalue="script" />
|
||||
<item index="6" class="java.lang.String" itemvalue="img" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myCustomValuesEnabled" value="true" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="16">
|
||||
<item index="0" class="java.lang.String" itemvalue="clyent" />
|
||||
<item index="1" class="java.lang.String" itemvalue="navigator-updater" />
|
||||
<item index="2" class="java.lang.String" itemvalue="tables" />
|
||||
<item index="3" class="java.lang.String" itemvalue="pycurl" />
|
||||
<item index="4" class="java.lang.String" itemvalue="conda-verify" />
|
||||
<item index="5" class="java.lang.String" itemvalue="h5py" />
|
||||
<item index="6" class="java.lang.String" itemvalue="conda" />
|
||||
<item index="7" class="java.lang.String" itemvalue="conda-build" />
|
||||
<item index="8" class="java.lang.String" itemvalue="menuinst" />
|
||||
<item index="9" class="java.lang.String" itemvalue="anaconda-navigator" />
|
||||
<item index="10" class="java.lang.String" itemvalue="sip" />
|
||||
<item index="11" class="java.lang.String" itemvalue="pytest-cov" />
|
||||
<item index="12" class="java.lang.String" itemvalue="twine" />
|
||||
<item index="13" class="java.lang.String" itemvalue="pre-commit" />
|
||||
<item index="14" class="java.lang.String" itemvalue="tox" />
|
||||
<item index="15" class="java.lang.String" itemvalue="flake8" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="E501" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="N802" />
|
||||
<option value="N801" />
|
||||
<option value="N806" />
|
||||
<option value="N803" />
|
||||
<option value="N813" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyShadowingBuiltinsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredNames">
|
||||
<list>
|
||||
<option value="id" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredIdentifiers">
|
||||
<list>
|
||||
<option value="str.*" />
|
||||
<option value="tuple.*" />
|
||||
<option value="SimpleWeb.blueprints.author.*" />
|
||||
<option value="dict.*" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
4
.idea/misc.xml
Normal file
4
.idea/misc.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="crawl" project-jdk-type="Python SDK" />
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/安卓逆向案例.iml" filepath="$PROJECT_DIR$/.idea/安卓逆向案例.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
8
.idea/安卓逆向案例.iml
Normal file
8
.idea/安卓逆向案例.iml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
58
README.md
Normal file
58
README.md
Normal file
@ -0,0 +1,58 @@
|
||||
# 安卓逆向合集
|
||||
> 此项目为安卓逆向实战合集以及部分笔记
|
||||
>
|
||||
> 仅作学习分析以及学习记录,__禁止商用__,如遇__侵权__请联系删除
|
||||
>
|
||||
> 本项目将持续更新
|
||||
|
||||
## 环境篇
|
||||
众所周知,安卓逆向首先需要一个安卓环境,有两种方案,第一是模拟器,第二是真机
|
||||
|
||||
### 模拟器
|
||||
市面上有很多模拟器可以用,up选择的是夜神模拟器,在官网下载好模拟器后,我们需要改一些配置
|
||||
|
||||
第一,抓包配置 --> 配置WIFI的IP以及按照你的抓包工具进行配置。
|
||||
|
||||
第二,开root,很简单
|
||||
|
||||
> 但是会出现抓包抓不到的情况,这种是由于在java层配置了不走系统代理,所以我们需要别的工具:
|
||||
>
|
||||
> 1. drony(不推荐),有时会导致无法上网,不稳定
|
||||
> 2. SocksDroid(推荐),开启工具时记得删除系统代理
|
||||
|
||||
> 注: 夜神模拟器默认的端口是62025, 所以我们需要连接这个端口(不一定,我的电脑是这个端口)
|
||||
|
||||
### 反编译工具
|
||||
|
||||
1. jadx(java层)
|
||||
2. jeb(java层)
|
||||
3. ida(so层,c语言层)
|
||||
|
||||
### 查壳脱壳工具
|
||||
|
||||
按照自己的喜好即可,网上有很多
|
||||
|
||||
### 获取apk途径
|
||||
|
||||
百度搜索即可
|
||||
|
||||
## 实战篇
|
||||
|
||||
> 更多的笔记见其他文件。
|
||||
|
||||
| 项目 | 难度 |
|
||||
| ---- | ---- |
|
||||
| 豆瓣 | 简单 |
|
||||
|
||||
### 豆瓣
|
||||
|
||||
想必大家爬虫梦的开始就是豆瓣250吧,那么我们安卓逆向的开始也从豆瓣开始吧~
|
||||
|
||||
分析过程:
|
||||
|
||||
1. 首先抓包分析,确认接口,确认加密参数名: _sig
|
||||
2. 全局搜索,确认加密位置
|
||||
3. hook加密函数,分析加密流程
|
||||
4. 用python改写,实现发包
|
||||
|
||||
总结算法: 豆瓣的_sig是由请求方式以及url的path和时间戳以&相连,进行一次hmacsha1,然后将结果转化为base64的格式
|
47
adb使用笔记.md
Normal file
47
adb使用笔记.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 此文件记录adb的使用
|
||||
## 安装
|
||||
此过程略,可以在网上轻易获取到
|
||||
## 使用
|
||||
首先我们介绍一下adb命令的基本构成
|
||||
```bash
|
||||
adb -s 设备 命令
|
||||
```
|
||||
十分简洁,我们只需要知道我们需要执行什么命令即可。
|
||||
|
||||
同时,如果你的设备只有一个,那么命令可以简化为
|
||||
```bash
|
||||
adb 命令
|
||||
```
|
||||
|
||||
### 常用命令
|
||||
|
||||
我们首先需要知道启动以及结束和连接设备
|
||||
|
||||
``` bash
|
||||
adb start-server # 启动服务
|
||||
adb kill-server # 中止服务
|
||||
adb -s 设备 connect ip:host # 连接设备
|
||||
```
|
||||
|
||||
我们使用下述命令进行查看设备
|
||||
|
||||
```bash
|
||||
adb devices
|
||||
```
|
||||
|
||||
这个命令可以把连接到的设备展示出来
|
||||
|
||||
另外例如推送文件,下载apk相关我们可以直接输入adb获取它的使用文档
|
||||
|
||||
下面介绍查看手机或虚拟机的cup型号的命令,会在我们使用frida时有用
|
||||
|
||||
```bash
|
||||
adb shell getprop ro.product.cpu.abi # 查看型号
|
||||
```
|
||||
|
||||
同时,我们可以通过下述命令进入手机的Linux终端(记得开启root哦)
|
||||
|
||||
```bash
|
||||
adb shell
|
||||
```
|
||||
|
143
frida使用笔记.md
Normal file
143
frida使用笔记.md
Normal file
@ -0,0 +1,143 @@
|
||||
# 此文件记录frida的使用
|
||||
|
||||
## 电脑安装frida
|
||||
```bash
|
||||
pip install frida
|
||||
pip install frida-tools
|
||||
```
|
||||
十分简单
|
||||
## 手机安装frida
|
||||
首先我们需要确定手机的cpu类型
|
||||
|
||||
模拟器通常是: x86_64
|
||||
|
||||
真机通常是: arm
|
||||
|
||||
我们根据不同的型号去frida的github下载对应的frida-sever
|
||||
|
||||
下面附录frida的github链接: https://github.com/frida/frida
|
||||
|
||||
我们下载好之后需要解压然后推送到手机中
|
||||
```bash
|
||||
adb -s 设备 push xx/xxx/xxx/frida-server /sdcard # 首先推送到一个用户目录然后在安卓的Linux推送到系统中
|
||||
adb shell # 进入手机
|
||||
su - # 获得root权限
|
||||
mv /sdcard/frida-server /data/local/tmp # 移动到系统文件
|
||||
cd /data/local/tmp # 进入目录
|
||||
chmod 777 frida-server # 赋予最高权限
|
||||
./frida-server # 开启服务
|
||||
```
|
||||
在安卓开启frida服务之前,我们记得在电脑上开启tcp转发
|
||||
```bash
|
||||
adb forward tcp:27042 tcp:27042
|
||||
adb forward tcp:27043 tcp:27043
|
||||
```
|
||||
|
||||
## 下面介绍一些固定的格式
|
||||
### 获取连接设别的信息,确认包名
|
||||
```python
|
||||
import frida
|
||||
|
||||
rdev = frida.get_remote_device()
|
||||
print(rdev)
|
||||
|
||||
processes = rdev.enumerate_processes()
|
||||
for process in processes:
|
||||
print(process)
|
||||
|
||||
front_app = rdev.get_frontmost_application()
|
||||
print(front_app)
|
||||
|
||||
```
|
||||
### hook类中的方法
|
||||
这个是hook的类的方法没有重载的情况
|
||||
```python
|
||||
import frida
|
||||
import sys
|
||||
|
||||
rdev = frida.get_remote_device()
|
||||
# app名称或者app包名称
|
||||
session = rdev.attach("com.shizhuang.duapp")
|
||||
|
||||
# 目标:指定替换是那个包中的方法名
|
||||
# - 包名称:com.shizhuang.duapp.common.utils
|
||||
# - 类名称:RequestUtils
|
||||
# - 方法名:c m30623c-jadx工具给你创造的。
|
||||
# - 参数1:map<string,string>
|
||||
# - 参数2:long
|
||||
scr = """
|
||||
Java.perform(function () {
|
||||
// 导入类, 看文件最顶部的package
|
||||
var RequestUtils = Java.use("com.shizhuang.duapp.common.utils.RequestUtils");
|
||||
|
||||
// 找到类中的方法进行hook
|
||||
RequestUtils.c.implementation = function(map,j){
|
||||
console.log("666");
|
||||
var res = this.c(map,j);
|
||||
console.log("999");
|
||||
return res;
|
||||
}
|
||||
|
||||
});
|
||||
"""
|
||||
script = session.create_script(scr)
|
||||
|
||||
|
||||
def on_message(message, data):
|
||||
print(message, data)
|
||||
|
||||
|
||||
script.on("message", on_message)
|
||||
|
||||
script.load()
|
||||
sys.stdin.read()
|
||||
```
|
||||
下面是类中的函数具有重载的情况
|
||||
```python
|
||||
|
||||
scr = """
|
||||
Java.perform(function () {
|
||||
// 导入类
|
||||
var RequestUtils = Java.use("com.douban.frodo.network.ApiSignatureHelper");
|
||||
|
||||
// 找到类中的方法进行hook,然后加上overload参数类型即可
|
||||
RequestUtils.a.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation =
|
||||
function(str, str1, str2){
|
||||
console.log(str, str1, str2);
|
||||
var res = this.a(str, str1, str2);
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
});
|
||||
"""
|
||||
script = session.create_script(scr)
|
||||
```
|
||||
### 下面是hook so层代码的情况
|
||||
> so层代码的hook需要在真机下才可以,因为默认只有arm芯片,不支持x86_64
|
||||
>
|
||||
```python
|
||||
scr = """
|
||||
Java.perform(function () {
|
||||
var addr_func = Module.findExportByName("libJNIEncrypt.so", "AES_128_ECB_PKCS5Padding_Encrypt");
|
||||
Interceptor.attach(addr_func, {
|
||||
onEnter: function(args){
|
||||
// 进入并执行函数:AES_128_ECB_PKCS5Padding_Encrypt,args就是参数
|
||||
console.log("-------------参数 1-------------");
|
||||
console.log(args[0].readUtf8String())
|
||||
|
||||
console.log("-------------参数 2-------------");
|
||||
console.log(args[1].readUtf8String());
|
||||
},
|
||||
onLeave: function(retValue){
|
||||
console.log("-------------返回-------------");
|
||||
console.log(retValue.readUtf8String());
|
||||
}
|
||||
})
|
||||
});
|
||||
"""
|
||||
script = session.create_script(scr)
|
||||
```
|
||||
> 小总结:
|
||||
>
|
||||
> frida hook参数函数的时候,前面的基本都不变,只是hook脚本会发送改变
|
48
豆瓣/hook_sig.py
Normal file
48
豆瓣/hook_sig.py
Normal file
@ -0,0 +1,48 @@
|
||||
import frida
|
||||
import sys
|
||||
|
||||
rdev = frida.get_remote_device()
|
||||
session = rdev.attach("豆瓣")
|
||||
|
||||
|
||||
scr = """
|
||||
Java.perform(function () {
|
||||
// 导入类
|
||||
var RequestUtils = Java.use("com.douban.frodo.network.ApiSignatureHelper");
|
||||
var encrypted = Java.use("com.douban.frodo.utils.crypto.HMACHash1");
|
||||
var apiKey = Java.use("com.douban.ad.utils.ApiUtils")
|
||||
|
||||
// 找到类中的方法进行hook
|
||||
RequestUtils.a.overload('java.lang.String', 'java.lang.String', 'java.lang.String').implementation =
|
||||
function(str, str1, str2){
|
||||
console.log(str, str1, str2);
|
||||
var res = this.a(str, str1, str2);
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
encrypted.a.implementation = function(str, str1){
|
||||
console.log(str, str1)
|
||||
var res = this.a(str, str1)
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
apiKey.getApiKey.implementation = function(context){
|
||||
console.log(context)
|
||||
var res = this.getApiKey(context)
|
||||
console.log(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
});
|
||||
"""
|
||||
script = session.create_script(scr)
|
||||
|
||||
|
||||
def on_message(message, data):
|
||||
print(message, data)
|
||||
|
||||
|
||||
script.on("message", on_message)
|
||||
|
||||
script.load()
|
||||
sys.stdin.read()
|
53
豆瓣/发送请求.py
Normal file
53
豆瓣/发送请求.py
Normal file
@ -0,0 +1,53 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import time
|
||||
from urllib.parse import urlparse, quote
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def sha1_base64(url, method):
|
||||
path = urlparse(url).path
|
||||
encoded_path = quote(path, safe='')
|
||||
timestamp = str(int(time.time()))
|
||||
key = b'bf7dddc7c9cfe6f7'
|
||||
message = '&'.join([method, encoded_path, timestamp])
|
||||
hmac_sha1 = hmac.new(key, message.encode('utf-8'), hashlib.sha1)
|
||||
hashed_data = hmac_sha1.digest()
|
||||
return base64.b64encode(hashed_data).decode('utf-8'), timestamp
|
||||
|
||||
|
||||
headers = {
|
||||
"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",
|
||||
"Connection": "Keep-Alive",
|
||||
"Accept-Encoding": "gzip"
|
||||
}
|
||||
|
||||
url = "https://frodo.douban.com/api/v2/movie/hot_gaia"
|
||||
sig_ts = sha1_base64(url, 'GET')
|
||||
params = {
|
||||
"area": "全部",
|
||||
"sort": "time",
|
||||
"playable": "0",
|
||||
"loc_id": "0",
|
||||
"start": "0",
|
||||
"count": "20",
|
||||
"udid": "81c09b13e49151d13ed4d8d3817b99c45cf0d399",
|
||||
"rom": "android",
|
||||
"apikey": "0dad551ec0f84ed02907ff5c42e8ec70",
|
||||
"s": "rexxar_new",
|
||||
"channel": "Yingyongbao_Market",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"device_id": "81c09b13e49151d13ed4d8d3817b99c45cf0d399",
|
||||
"os_rom": "android",
|
||||
"apple": "037d50d1066ddb8b0b53dd41e029db0c",
|
||||
"sugar": "46007",
|
||||
"_sig": sig_ts[0],
|
||||
"_ts": sig_ts[1]
|
||||
}
|
||||
response = requests.get(url, headers=headers, params=params)
|
||||
|
||||
print(response.text)
|
||||
print(response)
|
||||
|
Loading…
Reference in New Issue
Block a user