YmlsaWJpbGk= app分析

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的分析会补上。

推荐阅读更多精彩内容