shopee app算法分析第一篇

shopee app算法分析第一篇

分析完整算法大概要好几篇,耐心等待下

抓包

image-20241126220341011

抓的搜索接口,get请求,核心的有3个4字节键和x-sap-ri,如果是post,就是4个4字节键和值,多出来的一个和post的表单有关

image-20241126220612188

后续内容都是post的,post会了,get肯定也会了,4个4字节3个短的,一个长的.这5个参数来着同一个so,libshpssdk.so,后面说怎么定位到的.

4字节的key和value也是一直变化的,最好摸清楚生成机制,随机可能引起风控.(有9套算法)

定位加密位置

1

2

3

4

5

6

7

8

9

10

11

Java.perform(function (){

    //     HashMap.put

    var hashMap = Java.use("java.util.HashMap");

    hashMap.put.implementation = function (a, b) {

        if(a!=null && a.equals("x-sap-ri")){

            console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()))

            console.log("hashMap.put: ", a, b);

        }

        return this.put(a, b);

    }

})

太长了,放前面的结果

1

2

3

4

5

6

7

8

9

10

11

java.lang.Throwable

    at java.util.HashMap.put(Native Method)

    at org.json.JSONObject.put(JSONObject.java:276)

    at org.json.JSONTokener.readObject(JSONTokener.java:394)

    at org.json.JSONTokener.nextValue(JSONTokener.java:104)

    at org.json.JSONObject.<init>(JSONObject.java:168)

    at org.json.JSONObject.<init>(JSONObject.java:185)

    at com.shopee.shpssdk.SHPSSDK.uvwvvwvvw(Unknown Source:81)

    at com.shopee.shpssdk.SHPSSDK.requestDefense(Unknown Source:59)

hashMap.put:  x-sap-ri 443e41678c54f44f62b70d1901d115bc703ebab92a5b4251176d

在com.shopee.shpssdk.SHPSSDK.uvwvvwvvw方法里,这个app有很多站点的,初步看了只是包名不一样,函数,so偏移都是一样的,包名是com.shopee.xx xx是域名后面的,我使用的样本是ph,3.37.31

1

2

3

4

5

6

7

8

马来西亚:https://shopee.my

新加坡:https://shopee.sg

泰国:https://shopee.th

印度尼西亚:https://shopee.id

越南:https://shopee.vn

菲律宾:https://shopee.ph

台湾:https://shopee.tw

大陆:https://shopee.cn

image-20241126221616280

这个位置值已经生成了,往上找调用,就一个,结果来自wvvvuwwu.vuwuuwvw(str.getBytes(), bArr),hook发现,第一个参数url,第二个表单(get就是null)

image-20241126221714102

点过去来到native注册的地方

image-20241126221845356

hook下libart

1

2

3

4

5

[RegisterNatives] method_count: 0x4

name: com.shopee.shpssdk.wvvvuwwu vuwuuwvv sig: (I)V module_name: libshpssdk.so offset: 0x1bef84

name: com.shopee.shpssdk.wvvvuwwu vuwuuwvu sig: (Lcom/shopee/shpssdk/wvvvuvvv;)I module_name: libshpssdk.so offset: 0x1bf478

name: com.shopee.shpssdk.wvvvuwwu vuwuuwvw sig: ([B[B)Ljava/lang/String; module_name: libshpssdk.so offset: 0x995dc

name: com.shopee.shpssdk.wvvvuwwu vuwuuwvvw sig: ([B)V module_name: libshpssdk.so offset: 0x9932c

so名字libshpssdk,偏移0x995dc,到lib目录下找发现一个so都没有,hook下dlopen

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

var dlopen = Module.findExportByName(null"dlopen");//6.0

var android_dlopen_ext = Module.findExportByName(null"android_dlopen_ext");//高版本8.1以上

Interceptor.attach(dlopen, {

    onEnter: function (args) {

        var path_ptr = args[0];

        var path = ptr(path_ptr).readCString();

        console.log("[dlopen:]", path);

    },

    onLeave: function (retval) {

        // Thread.sleep(3);

    }

});

Interceptor.attach(android_dlopen_ext, {

    onEnter: function (args) {

        var path_ptr = args[0];

        var path = ptr(path_ptr).readCString();

        console.log("[dlopen_ext:]", path);

    },

    onLeave: function (retval) {

            // Thread.sleep(3);

    }

});

1

/data/app/~~KVEKJlJur2r6197VML5LRw==/com.shopee.sg-ZyVbLWincySSEAiqQSuPLQ==/split_config.arm64_v8a.apk!/lib/arm64-v8a/libshpssdk.so

可以看到so是压缩了下,拖出来即可.

hook和主动调用

hook 固定一组入参

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

Java.perform(function (){

    console.log('======================')

    let wvvvuwwu = Java.use("com.shopee.shpssdk.wvvvuwwu");

    wvvvuwwu["vuwuuwvw"].implementation = function (bArr, bArr2) {

        var ByteString = Java.use("com.android.okhttp.okio.ByteString");

        if(bArr!==null){

            try{

                console.log('111111111')

                console.log(`wvvvuwwu.vuwuuwvw is called: bArr=${ByteString.of(bArr).utf8()}, bArr2=${bArr2}`);

            }catch (e) {

            }

        }

        // console.log(`wvvvuwwu.vuwuuwvw is called: bArr=${bArr}, bArr2=${bArr2}`);

        let result = this["vuwuuwvw"](bArr, bArr2);

        console.log(`wvvvuwwu.vuwuuwvw result=${result}`);

        return result;

    };

})

注意脚本写法(排除空,异常字段),很多时候排除掉手机,app,frida版本这些的问题, 为什么明明确定是这个位置hook脚本就是没输出,考虑下是不是脚本有问题,有时候有问题是不会输出东西的,也不报错,然后你以为没走这,就是因为你对参数进行了错误操作,比如类型没判断正确,空没有排除掉导致脚本什么都不打印.好几个人问我,这里统一回复下.

call

都是基本写法,不熟悉多google,自己琢磨才能记得住.

1

2

3

4

5

6

7

8

9

10

11

12

function call(){

    Java.perform(function (){

        let wvvvuwwu = Java.use("com.shopee.shpssdk.wvvvuwwu");

        var str = 'https://mall.shopee.ph/api/v4/pages/bottom_tab_bar'

        var StringClass = Java.use('java.lang.String');

        var byteArray = StringClass.$new(str).getBytes();

        var str2 = '{"img_size":"3.0x","latitude":"","location":"[]","longitude":"","new_arrival_reddot_last_dismissed_ts":0,"feed_reddots":[{"timestamp":0,"noti_code":28}],"client_feature_meta":{"is_live_and_video_merged_tab_supported":false},"video_reddot_last_dismissed_ts":0,"view_count":[{"count":1,"source":0,"tab_name":"Live"}]}'

        var byteArray2 = StringClass.$new(str2).getBytes();

        var res = wvvvuwwu["vuwuuwvw"](byteArray,byteArray2)

        console.log('res==>',res)

    })

}

连续调用会有一个4字节key不变,1A9EC9B9,这个只和url有关,后续写还原,这个键对应的值解密出来是16字节随机+9套算法中的哪3套,第二篇写算法还原

1

2

3

4

5

6

7

8

9

url = '/api/v4/pages/bottom_tab_bar'

def getKey1(url):

    tmp = 0

    for in bytearray(url.encode()):

        tmp = tmp*0x334b 0xffffffff

        tmp=(tmp+i) & 0xffffffff

    key = tmp&0x7fffffff

    return f"{key:04X}"

print('getKey1',getKey1(url)) # 1A9EC9B9 还原这个只需要url

native call

native call的作用是方便确定哪些是so的初始化函数(不管有没有),可以节省后续很多时间.

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

function stringToHexArray(str) {

    var hexArray = [];

    for (var i = 0; i < str.len

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值