利用Unidbg辅助还原哔哩哔哩Sign算法.

2023-11-17

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

诶,真香~

算法还原[待更新]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用Unidbg辅助还原哔哩哔哩Sign算法. 的相关文章

随机推荐

  • Option类型:C++(std::optional)、Rust(Option)、Go(gob.OptionalValue)

    当我们在实现一个函数 fn point 该函数会有返回的point指针有可能是null 那么函数的调用者必须显示的进行判断 避免出现null point引发的程序崩溃 Rust作为强调系统安全的语言 自然是从语言层面上给予了开发者莫大的帮助
  • 2020年集五福攻略:集五福不再难搞

    2020年的春节就要到了 让人期待的支付宝集五福活动也会随之而来 那么 2020支付宝集五福什么时候开始 支付宝的集福卡活动不是第一届了 2017年的支付宝集五福是1月18日开始 2018年的支付宝集五福是2月6日开始 2019年支付宝集五
  • XSS攻击实战

    一 XSS原理与分类 原理 XSS攻击全程跨站脚本攻击 恶意攻击者往Web页面里插入恶意Script代码 当用户浏览该页之时 嵌入其中Web里面的Script代码会被执行 从而达到恶意攻击用户的目的 与SQL注入类似 XSS也是利用提交恶意
  • 每个程序员都该学习的5种开发语言,不可错过!

    每个公司都喜爱精通多种编程语言并且多才多艺的程序员 一个既能很麻利地写脚本 也能编写复杂的Java程序的程序员 确实相当有价值 所以实际上 对于高级开发者来说 学习不止一种编程语言 几乎就是必然的要求 目前而言 面试官越来越看重那些拥有多种
  • 抢小米手机K40脚本

    声明 基于 puppeteer js 仅辅助更快操作浏览器 本脚本仅供米粉购买小米系列产品 请勿充当黄牛 代码地址 https github com shunyue1320 buy xiaomi
  • 应用层 —— 电子邮件

    一 电子邮件的信息格式 二 系统结构 三 SMTP
  • Meta标签中的apple-mobile-web-app-capable属性及含义

    这meta的作用就是删除默认的苹果工具栏和菜单栏 content有两个值 yes 和 no 当我们需要显示工具栏和菜单栏时 这个行meta就不用加了 默认就是显示
  • 内置数据库

    DERBY 完全使用java 开发 可以在任何存在合适的 Java 虚拟机的地方运行 不适用于在其他编程语言内置使用 HSQLDB Java内置的数据库 非常适合在用于快速的测试和演示的Java程序中 无需独立安装数据库 HSQLDB有三种
  • 编译原理LL(1)文法之提取左公因子,消除左递归

    在判断LL 1 文法是否符合的时候 需要判断LL 1 文法是否存在左公因子 和左递归的情况 以下给出相应的判断方法以及通过提取左公因子和消除左递归使非LL 1 文法转换为LL 1 法的方法 第一种情况 存在左公因子 解决方法 提取左公因子
  • 恶魔奶爸沟通课

    01社交本质上是精力问题 1 神奇女侠式 双脚分开 与肩同宽 挺胸抬头 双手叉腰 站立120秒 让自己舒服很多 2 深呼吸 3 适度运动 每周160分钟 4 睡眠 晚上10点半睡觉 早上6点起床 5 不要久坐 坐20分钟起来走走 哪怕30秒
  • uniapp 使用uni-combox组合框实现远程搜索功能

    目录 一 绑定属性 二 js方法 一 绑定属性
  • 串口通信——接收串口数据并处理(C语言)

    本文主要内容包含 1 接收串口数据程序的编程逻辑示意图 2 接收串口数据程序要用到的通用函数模块 可直接引用 无需更改 3 接收串口数据程序的示例 1 接收串口数据程序的编程逻辑示意图 2 与串口有关的函数模块及数组 可直接引用到自己的程序
  • BUAA计算器(表达式计算-表达式树实现)

    问题描述 从标准输入中读入一个整数算术运算表达式 如24 1 2 36 6 2 2 12 2 2 计算表达式结果 并输出 要求 1 表达式运算符只有 表达式末尾的 字符表示表达式输入结束 表达式中可能会出现空格 2 表达式中会出现圆括号 括
  • 实战剖析 Java 秒杀系统的实现

    本场 Chat 将为您介绍 如何从 0 到 1 搭建一个分布式架构的秒杀系统 如何利用 Redis 的特性发挥它在秒杀系统中的大作用 如何利用消息队列实现请求的异步处理 带您思考实现秒杀系统过程中需要注意的点 以及需要掌握的技巧 架构介绍
  • 我与CSDN的这十年——笔耕不辍,青春热血

    1024程序员的节日就要来了 作者也挤时间写了一篇文章 我与CSDN的这十年 分享下程序猿和程序媛的故事 纪念这十年奋斗和感动的日子 十年 说长不长 说短不短 人生进度条的八分之一 都是青春 都是热血 十年 从看博客到写博客 笔耕不辍 从未
  • ubuntu密码正确,却不能登录图形界面

    传统的方法是修改 Xauthority文件权限 不过我试了没有用 后来发现我的问题是因为安装了NVIDIA cuda驱动而导致的 所以先卸载nvidia驱动 再更新 就可以正常进入了 命令 sudo apt get remove purge
  • FreeRTOS临界段

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • [技术发展-28]:信息通信网大全、新的技术形态、信息通信行业高质量发展概览

    目录 前言 第1章 什么是信息与通信 第2章 为啥要编制信息与通信发展规划 第3章 信息与通信如何高质量发展 重点 3 0 发展目标 编辑 3 1 建设新型数字基础设施 3 1 1 移动通信网 无线接入层 1G到5G 3 1 2 固定宽带网
  • android 使用 ImageLoader 显示文章和图片

    android 中使用Textview 显示文章及图片 1 下载 universal image loader 1 9 5 jar 添加到app项目中 2 在android 后台 的 onCreate 方法中初始化 ImageLoader
  • 利用Unidbg辅助还原哔哩哔哩Sign算法.

    bilibili unidbg http www zhuoyue360 com crack 87 html 老色批想抓哔哩哔哩的全站数据 通过人工智能自动找出美女 色 咱们想抓它一个个人信息 抓包分析 1 android 7 0 证书配置