YmlsaWJpbGk= app分析
版本为6.180,可以到豌豆荚下载。
用到的工具:fiddler,jadx,frida,ida
先看一下搜索的接口
抓不到包,做了ssl证书校验。
用justtrustmeplus过掉
搜索美女第一页
请求头部分
GET https://app.bilibili.com/x/v2/search?appkey=1d8b6e7d45233436&build=6180500&c_locale=zh_CN&channel=shenma069&duration=0&fnval=272&fnver=0&force_host=0&fourk=0&from_source=app_search&highlight=1&is_org_query=0&keyword=%E7%BE%8E%E5%A5%B3&local_time=8&mobi_app=android&platform=android&player_net=1&pn=1&ps=20&qn=32&recommend=1&s_locale=zh_CN&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.18.0%22%2C%22abtest%22%3A%22%22%7D&ts=1640672753&sign=ae612211fa72edbb70e8551f8af18479 HTTP/1.1
Host: app.bilibili.com
Connection: keep-alive
Buvid: XY65DB261AB8366C35C2D38F9F7D16C5C71A0
Device-ID: AmFSM1ZlVGwNaV9oFHYVc0YnRHJDdEVyQDwMNQRnAzFSMHADZgs4Cm0RIRIrTnhIK019RHUWckAjQQ
fp_local: b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88
fp_remote: b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88
session_id: 084cccda
env: prod
APP-KEY: android
User-Agent: Mozilla/5.0 BiliDroid/6.18.0 (bbcallen@gmail.com) os/android model/Nexus 5 mobi_app/android build/6180500 channel/shenma069 innerVer/6180500 osVer/7.1.2 network/2
bili-bridge-engine: cronet
Accept-Encoding: gzip, deflate
搜索美女第二页
GET https://app.bilibili.com/x/v2/search?appkey=1d8b6e7d45233436&build=6180500&c_locale=zh_CN&channel=shenma069&duration=0&fnval=272&fnver=0&force_host=0&fourk=0&from_source=app_search&highlight=1&is_org_query=0&keyword=%E7%BE%8E%E5%A5%B3&local_time=8&mobi_app=android&platform=android&player_net=1&pn=2&ps=20&qn=32&recommend=1&s_locale=zh_CN&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.18.0%22%2C%22abtest%22%3A%22%22%7D&ts=1640672925&sign=475a578aafb1d95949f03c5fa87000ea HTTP/1.1
Host: app.bilibili.com
Connection: keep-alive
Buvid: XY65DB261AB8366C35C2D38F9F7D16C5C71A0
Device-ID: AmFSM1ZlVGwNaV9oFHYVc0YnRHJDdEVyQDwMNQRnAzFSMHADZgs4Cm0RIRIrTnhIK019RHUWckAjQQ
fp_local: b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88
fp_remote: b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88
session_id: 084cccda
env: prod
APP-KEY: android
User-Agent: Mozilla/5.0 BiliDroid/6.18.0 (bbcallen@gmail.com) os/android model/Nexus 5 mobi_app/android build/6180500 channel/shenma069 innerVer/6180500 osVer/7.1.2 network/2
bili-bridge-engine: cronet
Accept-Encoding: gzip, deflate
写了个代码,可以自动构造header头
def str_to_headers():
str2 = '''Host: app.bilibili.com
Connection: keep-alive
Buvid: XY65DB261AB8366C35C2D38F9F7D16C5C71A0
Device-ID: AmFSM1ZlVGwNaV9oFHYVc0YnRHJDdEVyQDwMNQRnAzFSMHADZgs4Cm0RIRIrTnhIK019RHUWckAjQQ
fp_local: b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88
fp_remote: b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88
session_id: 084cccda
env: prod
APP-KEY: android
User-Agent: Mozilla/5.0 BiliDroid/6.18.0 (bbcallen@gmail.com) os/android model/Nexus 5 mobi_app/android build/6180500 channel/shenma069 innerVer/6180500 osVer/7.1.2 network/2
bili-bridge-engine: cronet
Accept-Encoding: gzip, deflate
'''
kav = str2.split('\n')
headers = {}
for kv in kav:
if kv != "":
key = kv.split(":")[0]
value = "".join(kv.split(":")[1:]).strip()
headers[key] = value
headers = json.dumps(headers,indent=4)
print(headers)
return headers
用python的requests模拟重放一下请求
import requests
url = 'https://app.bilibili.com/x/v2/search?appkey=1d8b6e7d45233436&build=6180500&c_locale=zh_CN&channel=shenma069&duration=0&fnval=272&fnver=0&force_host=0&fourk=0&from_source=app_search&highlight=1&is_org_query=0&keyword=%E7%BE%8E%E5%A5%B3&local_time=8&mobi_app=android&platform=android&player_net=1&pn=2&ps=20&qn=32&recommend=1&s_locale=zh_CN&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.18.0%22%2C%22abtest%22%3A%22%22%7D&ts=1640672925&sign=475a578aafb1d95949f03c5fa87000ea'
headers = {
"Host": "app.bilibili.com",
"Connection": "keep-alive",
"Buvid": "XY65DB261AB8366C35C2D38F9F7D16C5C71A0",
"Device-ID": "AmFSM1ZlVGwNaV9oFHYVc0YnRHJDdEVyQDwMNQRnAzFSMHADZgs4Cm0RIRIrTnhIK019RHUWckAjQQ",
"fp_local": "b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88",
"fp_remote": "b7b23526fc7ff041d68887260b02954920211214121130dc28160c5899272a88",
"session_id": "084cccda",
"env": "prod",
"APP-KEY": "android",
"User-Agent": "Mozilla/5.0 BiliDroid/6.18.0 (bbcallen@gmail.com) os/android model/Nexus 5 mobi_app/android build/6180500 channel/shenma069 innerVer/6180500 osVer/7.1.2 network/2",
"bili-bridge-engine": "cronet",
"Accept-Encoding": "gzip, deflate"
}
rq = requests.get(url,headers=headers)
print(rq.status_code)
print(rq.text)
发现是可以正常重发的
对比两次的链接并修改参数重放测试
发现pn表示的是页数,keyword是搜索的关键词,sign参数会有不同
但是发现sign随便写也会返回数据
也就是说没有加密
给哥整不会了
即使是这样,我们还是来看下sign参数是怎么生成的吧,学习学习
jadx打开apk
没有加壳
全局搜索一下sign
直接搜sign太多了,我们可以搜"sign",sign=
这是“sign”搜出来的结果
没啥可疑的
搜sign=
发现这个很可疑
为啥呢
看它的类名,native,signquery
signquery,字面意思sign查询,这理解不过分吧,
native,so层函数,我bb大厂用个so层加密一下不过分吧
行,那我们就用frida hook一下看是不是这里。
hook signQuery的构造函数
function hook_tostring(){
Java.perform(function () {
var signQuery = Java.use("com.bilibili.nativelibrary.SignedQuery");
signQuery.$init.implementation = function (a,b) {
console.log("xiaoixn")
console.log("a==>"+a);
console.log("b==>"+b);
return this.$init(a,b);
}
})
}
setTimeout(function () {
// hookSign()
hook_tostring()
})
输出
a==>appkey=1d8b6e7d45233436&build=6180500&c_locale=zh_CN&channel=shenma069&duration=0&fnval=272&fnver=0&force_host=0&fourk=0&from_source=appsuggest_search&highlight=1&is_org_query=0&keyword=%E7%BE%8E%E5%A5%B3%E6%9D%80%E6%89%8B&local_time=8&mobi_app=android&platform=android&player_net=1&pn=1&ps=20&qn=32&recommend=1&s_locale=zh_CN&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.18.0%22%2C%22abtest%22%3A%22%22%7D&ts=1640677588
b==>89639a4a0dd122fc4d7cc38953acd6b9
说明在这之前就已经生成sign了,我们打下调用栈
function hook_tostring(){
Java.perform(function () {
var signQuery = Java.use("com.bilibili.nativelibrary.SignedQuery");
signQuery.$init.implementation = function (a,b) {
console.log("xiaoixn")
console.log("a==>"+a);
console.log("b==>"+b);
var result = this.$init(a,b)
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
return result;
}
})
}
setTimeout(function () {
// hookSign()
hook_tostring()
})
调用栈如下
`java.la`ng.Throwable`
`at com.bilibili.nativelibrary.SignedQuery.<init>(Native Method)`
`at com.bilibili.nativelibrary.LibBili.s(Native Method)`
`at com.bilibili.nativelibrary.LibBili.g(BL:1)`
`at com.bilibili.okretro.f.a.h(BL:1)`
`at com.bilibili.okretro.f.a.d(BL:7)`
`at com.bilibili.okretro.f.a.a(BL:4)`
`at com.bilibili.okretro.d.a.execute(BL:24)`
`at com.bilibili.okretro.d.a$a.run(BL:2)`
`at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)`
`at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)`
at java.lang.Thread.run(Thread.java:761)`
看下com.bilibili.nativelibrary.LibBili.s(Native Method)
navtive方法,用frida hook下
function hook_s(){
Java.perform(function () {
var lb = Java.use("com.bilibili.nativelibrary.LibBili");
lb.s.implementation = function (m) {
console.log("hook_s开始")
// 打印入参
console.log("\nmap内容:", m.entrySet().toArray());
var result = this.s(m)
console.log("\n返回结果:",result);
console.log("hook_s结束");
return result;
}
})
}
结果
hook_s开始
map内容: appkey=1d8b6e7d45233436,build=6180500,c_locale=zh_CN,channel=shenma069,duration=0,fnval=272,fnver=0,force_host=0,fourk=0,from_source=appsuggest_search,highlight=1,is_org_query=0,keyword=美女杀手,local_time=8,mobi_app=android,platform=android,player_net=1,pn=7,ps=20,qn=32,recommend=1,s_locale=zh_CN,statistics={"appId":1,"platform":3,"version":"6.18.0","abtest":""}
返回结果: appkey=1d8b6e7d45233436&build=6180500&c_locale=zh_CN&channel=shenma069&duration=0&fnval=272&fnver=0&force_host=0&fourk=0&from_source=appsuggest_search&highlight=1&is_org_query=0&keyword=%E7%BE%8E%E5%A5%B3%E6%9D%80%E6%89%8B&local_time=8&mobi_app=android&platform=android&player_net=1&pn=7&ps=20&qn=32&recommend=1&s_locale=zh_CN&statistics=%7B%22appId%22%3A1%2C%22platform%22%3A3%2C%22version%22%3A%226.18.0%22%2C%22abtest%22%3A%22%22%7D&ts=1640680467&sign=c12321062f61ea6dcfe81fe73812047b
hook_s结束
说明就是这个native函数进行加密的
但是不知道是哪个so加载它的
用jnitrace打印一下
jnitrace -l libbili.so tv.danmaku.bili --ignore-vm
刚开始的trace不用管,点击搜索后的输出为
/* TID 27695 */
955371 ms [+] JNIEnv->CallBooleanMethod
955371 ms |- JNIEnv* : 0x634eabd0
955371 ms |- jobject : 0xb2b9e060
955371 ms |- jmethodID : 0x6f6b80c4 { isEmpty()Z }
955371 ms |= jboolean : 0 { false }
955371 ms ------------------------Backtrace------------------------
955371 ms |-> 0x90637697: libbili.so!0x6697 (libbili.so:0x90631000)
/* TID 27695 */
955708 ms [+] JNIEnv->ExceptionCheck
955708 ms |- JNIEnv* : 0x634eabd0
955708 ms |= jboolean : 0 { false }
955708 ms ------------------------Backtrace------------------------
955708 ms |-> 0x9063539b: libbili.so!0x439b (libbili.so:0x90631000)
/* TID 27695 */
956026 ms [+] JNIEnv->NewStringUTF
956026 ms |- JNIEnv* : 0x634eabd0
956026 ms |- char* : 0x906341e4
956026 ms |: appkey
956026 ms |= jstring : 0x200001
956026 ms ------------------------Backtrace------------------------
956026 ms |-> 0x90634019: libbili.so!0x3019 (libbili.so:0x90631000)
/* TID 27695 */
956334 ms [+] JNIEnv->CallObjectMethod
956334 ms |- JNIEnv* : 0x634eabd0
956334 ms |- jobject : 0xb2b9e060
956334 ms |- jmethodID : 0x6f6b8058 { get(Ljava/lang/Object;)Ljava/lang/Object; }
956334 ms |: jobject : 0x200001
956334 ms |= jobject : 0x200005 { java/lang/Object }
956334 ms ------------------------Backtrace------------------------
956334 ms |-> 0x906374dd: libbili.so!0x64dd (libbili.so:0x90631000)
/* TID 27695 */
956588 ms [+] JNIEnv->ExceptionCheck
956588 ms |- JNIEnv* : 0x634eabd0
956588 ms |= jboolean : 0 { false }
956588 ms ------------------------Backtrace------------------------
956588 ms |-> 0x9063539b: libbili.so!0x439b (libbili.so:0x90631000)
/* TID 27695 */
956836 ms [+] JNIEnv->GetStringUTFChars
956836 ms |- JNIEnv* : 0x634eabd0
956836 ms |- jstring : 0x200005
956836 ms |- jboolean* : 0x0
956836 ms |= char* : 0x78ff9910
956836 ms ------------------------Backtrace------------------------
956836 ms |-> 0x9063403d: libbili.so!0x303d (libbili.so:0x90631000)
/* TID 27695 */
957118 ms [+] JNIEnv->NewStringUTF
957118 ms |- JNIEnv* : 0x634eabd0
957118 ms |- char* : 0x906344ac
957118 ms |: ts
957118 ms |= jstring : 0x9
957118 ms ------------------------Backtrace------------------------
957118 ms |-> 0x90634439: libbili.so!0x3439 (libbili.so:0x90631000)
/* TID 27695 */
957373 ms [+] JNIEnv->CallObjectMethod
957373 ms |- JNIEnv* : 0x634eabd0
957373 ms |- jobject : 0xb2b9e060
957373 ms |- jmethodID : 0x6f6b8058 { get(Ljava/lang/Object;)Ljava/lang/Object; }
957373 ms |: jobject : 0x9
957373 ms |= jobject : 0x0 { java/lang/Object }
957373 ms ------------------------Backtrace------------------------
957373 ms |-> 0x906374dd: libbili.so!0x64dd (libbili.so:0x90631000)
/* TID 27695 */
957601 ms [+] JNIEnv->ExceptionCheck
957601 ms |- JNIEnv* : 0x634eabd0
957601 ms |= jboolean : 0 { false }
957601 ms ------------------------Backtrace------------------------
957601 ms |-> 0x9063539b: libbili.so!0x439b (libbili.so:0x90631000)
/* TID 27695 */
957826 ms [+] JNIEnv->NewStringUTF
957826 ms |- JNIEnv* : 0x634eabd0
957826 ms |- char* : 0xb2b9df40
957826 ms |: 1639540783
957826 ms |= jstring : 0xd
957826 ms ------------------------Backtrace------------------------
957826 ms |-> 0x90634471: libbili.so!0x3471 (libbili.so:0x90631000)
/* TID 27695 */
958106 ms [+] JNIEnv->CallObjectMethod
958106 ms |- JNIEnv* : 0x634eabd0
958106 ms |- jobject : 0xb2b9e060
958106 ms |- jmethodID : 0x6f6b8130 { put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; }
958106 ms |: jobject : 0x9
958106 ms |: jobject : 0xd { java/lang/String }
958106 ms |= jobject : 0x0 { java/lang/Object }
958106 ms ------------------------Backtrace------------------------
958106 ms |-> 0x9063759d: libbili.so!0x659d (libbili.so:0x90631000)
/* TID 27695 */
958405 ms [+] JNIEnv->DeleteLocalRef
958405 ms |- JNIEnv* : 0x634eabd0
958405 ms |- jobject : 0x9
958405 ms ------------------------Backtrace------------------------
958405 ms |-> 0x90634485: libbili.so!0x3485 (libbili.so:0x90631000)
/* TID 27695 */
958711 ms [+] JNIEnv->CallStaticObjectMethod
958711 ms |- JNIEnv* : 0x634eabd0
958711 ms |- jclass : 0x20096e { com/bilibili/nativelibrary/SignedQuery }
958711 ms |- jmethodID : 0x8d8d84b8 { r(Ljava/util/Map;)Ljava/lang/String; }
958711 ms |: jobject : 0xb2b9e060
958711 ms |= jobject : 0x100009 { java/lang/Object }
958711 ms ------------------------Backtrace------------------------
958711 ms |-> 0x90634077: libbili.so!0x3077 (libbili.so:0x90631000)
/* TID 27695 */
958926 ms [+] JNIEnv->ExceptionCheck
958926 ms |- JNIEnv* : 0x634eabd0
958926 ms |= jboolean : 0 { false }
958926 ms ------------------------Backtrace------------------------
958926 ms |-> 0x90635379: libbili.so!0x4379 (libbili.so:0x90631000)
/* TID 27695 */
959193 ms [+] JNIEnv->GetStringUTFChars
959193 ms |- JNIEnv* : 0x634eabd0
959193 ms |- jstring : 0x100009
959193 ms |- jboolean* : 0x0
959193 ms |= char* : 0x8e9d6e80
959193 ms ------------------------Backtrace------------------------
959193 ms |-> 0x9063409b: libbili.so!0x309b (libbili.so:0x90631000)
/* TID 27695 */
959424 ms [+] JNIEnv->ReleaseStringUTFChars
959424 ms |- JNIEnv* : 0x634eabd0
959424 ms |- jstring : 0x78ff9910
959424 ms |- char* : 0x78ff9910
959424 ms |: 1d8b6e7d45233436
959424 ms ------------------------Backtrace------------------------
959424 ms |-> 0x906340b7: libbili.so!0x30b7 (libbili.so:0x90631000)
/* TID 27695 */
959710 ms [+] JNIEnv->NewStringUTF
959710 ms |- JNIEnv* : 0x634eabd0
959710 ms |- char* : 0xb2b9df90
959710 ms |: 53c4b4595e506be9b502c307f9e0650b
959710 ms |= jstring : 0x200011
959710 ms ------------------------Backtrace------------------------
959710 ms |-> 0x906341a5: libbili.so!0x31a5 (libbili.so:0x90631000)
/* TID 27695 */
959933 ms [+] JNIEnv->DeleteLocalRef
959933 ms |- JNIEnv* : 0x634eabd0
959933 ms |- jobject : 0x200001
959933 ms ------------------------Backtrace------------------------
959933 ms |-> 0x906341b1: libbili.so!0x31b1 (libbili.so:0x90631000)
/* TID 27695 */
960168 ms [+] JNIEnv->NewObject
960168 ms |- JNIEnv* : 0x634eabd0
960168 ms |- jclass : 0x20096e { com/bilibili/nativelibrary/SignedQuery }
960168 ms |- jmethodID : 0x8d8d8428 { <init>(Ljava/lang/String;Ljava/lang/String;)V }
960168 ms |: jstring : 0x100009
960168 ms |: jstring : 0x200011
960168 ms |= jobject : 0x1
960168 ms ------------------------Backtrace------------------------
960168 ms |-> 0x906341cb: libbili.so!0x31cb (libbili.so:0x90631000)
都是在libbili.so中处理的,并且注意到
/* TID 27695 */
959710 ms [+] JNIEnv->NewStringUTF
959710 ms |- JNIEnv* : 0x634eabd0
959710 ms |- char* : 0xb2b9df90
959710 ms |: 53c4b4595e506be9b502c307f9e0650b
959710 ms |= jstring : 0x200011
959710 ms ------------------------Backtrace------------------------
959710 ms |-> 0x906341a5: libbili.so!0x31a5 (libbili.so:0x90631000)
这个可能就是生成的sign
ida 打开libbili.so,按G键跳转到0x31a5
累了,休息下,so的分析会补上。