IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 利用Unidbg辅助还原哔哩哔哩Sign算法. -> 正文阅读

[移动开发]利用Unidbg辅助还原哔哩哔哩Sign算法.

bilibili - unidbg

http://www.zhuoyue360.com/crack/87.html

老色批想抓哔哩哔哩的全站数据,通过人工智能自动找出美女 (:色

image-20220408100207636

咱们想抓它一个个人信息.

抓包分析

1. android 7.0+ 证书配置

参考这篇文章.

http://www.zhuoyue360.com/crack/60.html

2.抓包.

证书设置好, postern配置好。胸弟们就可以愉快的进行抓包啦~

image-20220408100641810

是它,是它,就是它! 我们的小哪吒,小ki! 轻轻松松的就抓包成功,没有任何的对抗。就很巴适!

3. Sign分析

jadx反编译

经过自己不断的搜搜搜下(网上文章的思路下),至于找到了关键的位置. s

image-20220408100904496

想上找可以找到载入的so文件

static {
    c.c("bili");
}

4. IDA分析.

查看导出函数,那可是干干净净的~,那么我们就要看动态注册的函数了.

image-20220408101209869

使用yang神的hook_RegisterNatives.js .即可拿到地址.

s的偏移是0x741d,过去看看~

image-20220408101417710

简单的跟了一下,发现有轻微的混淆。 先不理。 祭神器,unidbg

image-20220408101537590

image-20220408101602317

Unidbg

从Part2已知, 我们的s大宝贝入口是0x741d.

Unidbg基础代码写好,运行一下,报错了。

image-20220408101901653

@Override
public boolean callBooleanMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
    switch (signature){
        case "java/util/Map->isEmpty()Z":
            TreeMap<String, String> treeMap = (TreeMap<String, String>)dvmObject.getValue();
            return treeMap.isEmpty();
    }
    return super.callBooleanMethod(vm, dvmObject, signature, varArg);
}

image-20220408101933964

@Override
public DvmObject<?> callObjectMethod(BaseVM vm, DvmObject<?> dvmObject, String signature, VarArg varArg) {
    switch (signature){
        case "java/util/Map->get(Ljava/lang/Object;)Ljava/lang/Object;":
            StringObject keyObject = varArg.getObjectArg(0);
            String key = keyObject.getValue();

            TreeMap<String, String> treeMap = (TreeMap<String, String>)dvmObject.getValue();
            String value = treeMap.get(key);
            return new StringObject(vm,value);
    }
    return super.callObjectMethod(vm, dvmObject, signature, varArg);
}

image-20220408102023188

这里把SignedQuery这个类都拿过来.稍稍修改一番~

package com.danmaku;



import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/* compiled from: BL */
/* loaded from: classes2.dex */
public final class SignedQuery {
    public static final String KEY_VALUE_DELIMITER = "=";
    public static final String FIELD_DELIMITER = "&";

    private static final char[] a = "0123456789ABCDEF".toCharArray();
    public final String rawParams;
    public final String sign;

    public SignedQuery(String str, String str2) {
        this.rawParams = str;
        this.sign = str2;
    }

    private static boolean a(char c2, String str) {
        return (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z') || !((c2 < '0' || c2 > '9') && "-_.~".indexOf(c2) == -1 && (str == null || str.indexOf(c2) == -1));
    }

    static String b(String str) {
        return c(str, null);
    }

    static String c(String str, String str2) {
        StringBuilder sb = null;
        if (str == null) {
            return null;
        }
        int length = str.length();
        int i = 0;
        while (i < length) {
            int i2 = i;
            while (i2 < length && a(str.charAt(i2), str2)) {
                i2++;
            }
            if (i2 != length) {
                if (sb == null) {
                    sb = new StringBuilder();
                }
                if (i2 > i) {
                    sb.append((CharSequence) str, i, i2);
                }
                i = i2 + 1;
                while (i < length && !a(str.charAt(i), str2)) {
                    i++;
                }
                try {
                    byte[] bytes = str.substring(i2, i).getBytes("UTF-8");
                    int length2 = bytes.length;
                    for (int i3 = 0; i3 < length2; i3++) {
                        sb.append('%');
                        char[] cArr = a;
                        sb.append(cArr[(bytes[i3] & 240) >> 4]);
                        sb.append(cArr[bytes[i3] & 15]);
                    }
                } catch (UnsupportedEncodingException e2) {
                    throw new AssertionError(e2);
                }
            } else if (i == 0) {
                return str;
            } else {
                sb.append((CharSequence) str, i, length);
                return sb.toString();
            }
        }
        return sb == null ? str : sb.toString();
    }

    static String r(Map<String, String> map) {
        if (!(map instanceof SortedMap)) {
            map = new TreeMap(map);
        }
        StringBuilder sb = new StringBuilder(256);
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            if (!key.isEmpty()) {
                sb.append(b(key));
                sb.append(KEY_VALUE_DELIMITER);
                String value = entry.getValue();
                sb.append(value == null ? "" : b(value));
                sb.append(FIELD_DELIMITER);
            }
        }
        int length = sb.length();
        if (length > 0) {
            sb.deleteCharAt(length - 1);
        }
        if (length == 0) {
            return null;
        }
        return sb.toString();
    }

    public String toString() {
        String str = this.rawParams;
        if (str == null) {
            return "";
        }
        if (this.sign == null) {
            return str;
        }
        return this.rawParams + "&sign=" + this.sign;
    }
}

然后再补环境

@Override
public DvmObject<?> callStaticObjectMethod(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
    switch (signature){
        case "com/bilibili/nativelibrary/SignedQuery->r(Ljava/util/Map;)Ljava/lang/String;":
            DvmObject<?> mapObject = varArg.getObjectArg(0);
            TreeMap<String, String> mymap = (TreeMap<String, String>) mapObject.getValue();
            String value = SignedQuery.r(mymap);
            return new StringObject(vm, value);

    }
    return super.callStaticObjectMethod(vm, dvmClass, signature, varArg);
}

image-20220408102149927

@Override
public DvmObject<?> newObject(BaseVM vm, DvmClass dvmClass, String signature, VarArg varArg) {
    switch (signature){
        case "com/bilibili/nativelibrary/SignedQuery-><init>(Ljava/lang/String;Ljava/lang/String;)V":
            String arg0 = (String) varArg.getObjectArg(0).getValue();
            String arg1 = (String) varArg.getObjectArg(1).getValue();

            return vm.resolveClass("com/bilibili/nativelibrary/SignedQuery").newObject(new SignedQuery(arg0, arg1));
    }
    return super.newObject(vm, dvmClass, signature, varArg);
}

突然,unidbg不报错了,跑出来了hhhhh.

image-20220408102234228

这就是我们要的东西.

image-20220408102321782

诶,真香~

算法还原[待更新]

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-15 00:12:54  更:2022-04-15 00:14:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 20:59:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码