别被外壳骗了,那只是柔软的伪装 - 某小说App Token算法分析

一、目标

今天的目标是这个 token 参数的算法,这个样本比较适合初学者,难度1星。

二、步骤

脱壳

先把apk拉进jadx

很明显不对劲,这种只有2-3个类的,就是加壳之后的明显特征,至于加了什么壳, qihoo 已经很明白告诉我们了,就是数字壳。

之前的教程我们介绍过 FRIDA-DEXDump脱壳或者刷个脱壳rom, 当然最方便的还是找个脱壳云服务。(私信给我,我把云服务的地址发你)

字符串查找

这种 com.bytexxx / com.baidx / com.ss 之类的看上去就很妖艳的都是大厂的sdk,都是来迷惑你的道心的。

只有像这种带着app包名中类似单词的才是你的小清新。

token长得很想base64,所以我们点 com.novel.basic.token.Base64 进去看看,看上去是一个自己实现的base64类。

没看出有啥特别的,先不管,我们从左边展开类名,看看 com.novel.basic.token 包下面还有哪些类?

神奇的是,我们没有找到 com.novel.basic.token 包,也许是dump的时候丢了。更神奇的是,我们找到了一个 com.novel.basic.token.xz 包,里面有个看上去浓眉大眼的 TokenUtil类

java 复制代码
public class TokenUtil {
    ...

public static String g(Map<String, String> map) {
        ArrayList<String> arrayList = new ArrayList(map.keySet());
        Collections.sort(arrayList);
        StringBuffer stringBuffer = new StringBuffer();
        for (String str : arrayList) {
            String str2 = map.get(str);
            stringBuffer.append("&");
            stringBuffer.append(str + "=" + str2);
        }
        return stringBuffer.toString().substring(1, stringBuffer.length());
    }

    public static String h(String str, String str2) {
        String str3;
        try {
            str3 = e(f(str, str2) + "_" + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
            str3 = "";
        }
        return d(str3);
    }

    public static void i(String[] strArr) throws Exception {
        HashMap hashMap = new HashMap();
        hashMap.put(PackageDocumentBase.OPFTags.packageTag, "com.mianfeinovel");
        hashMap.put("os", "android");
        hashMap.put("v", "1.0.1");
        hashMap.put("channel", "blf1298_12243_001");
        hashMap.put("udid", "aaaaaaaaaaaa");
        String g = g(hashMap);
        System.out.println("/v1/recommend/female?" + g + "&token=" + h("/v1/recommend/female", g));
    }

...
}

从 i 函数上分析, token的运算很有可能是 h函数干的, 那就啥也不说了,hook先

Hook验证

java 复制代码
function main() {   
    Java.perform(function () {
        var threadef = Java.use('java.lang.Thread');
        var threadinstance = threadef.$new();

        let TokenUtil = Java.use("com.novel.basic.token.xz.TokenUtil");
        TokenUtil["h"].implementation = function (str, str2) {
            console.log(`TokenUtil.h is called: str=${str}, str2=${str2}`);
            let result = this["h"](str, str2);
            console.log(`TokenUtil.h result=${result}`);
            return result;
        };
	
    });	
}

setTimeout(main, 5000);
// setImmediate(main);

由于是加壳应用,所以需要延迟个几秒再去hook对应的函数,给壳一点加载的时间。

跑一下,运气不错,就是我们要的结果

bash 复制代码
[M2010J19SC::cn.ttkmfxs.novel ]-> TokenUtil.h is called: str=/v1/ipcn, str2=channel=zxf2019_19206_001&ip=&os=Android&package=cn.ttkmfxs.novel&udid=01bb90d6de80f3cb01bb90d6de80f3cb&v=3.3.24.R
TokenUtil.h result=B993s65X5IwPTsXrgV%2F2rNvCYKcIjT4lyXrthojQ0LY%3D

三、总结

这个样本的算法比较清晰,可以直接扣出java代码,或者让ai转成其他的语言。

很多加壳应用最大的难点就是壳,敲开壳之后就是一马平川了。

做逆向运气很重要,真的。

坚硬只是表现

相关推荐
千里马学框架6 分钟前
如何改进车载三分屏SplitScreen启动交互方式?
android·智能手机·分屏·aaos·安卓framework开发·车载开发·3分屏
REDcker2 小时前
Android WebView 版本升级方案详解
android·音视频·实时音视频·webview·js·编解码
麦兜*2 小时前
【springboot】图文详解Spring Boot自动配置原理:为什么@SpringBootApplication是核心?
android·java·spring boot·spring·spring cloud·tomcat
le1616162 小时前
Android 依赖种类及区别:远程仓库依赖、打包依赖、模块依赖、本地仓库依赖
android
lxysbly2 小时前
psp模拟器安卓版带金手指
android
云上凯歌3 小时前
02 Spring Boot企业级配置详解
android·spring boot·后端
hqiangtai3 小时前
Android 高级专家技术能力图谱
android·职场和发展
aqi003 小时前
FFmpeg开发笔记(九十七)国产的开源视频剪辑工具AndroidVideoEditor
android·ffmpeg·音视频·直播·流媒体
stevenzqzq3 小时前
Android Koin 注入入门教程
android·kotlin
炼金术4 小时前
SkyPlayer v1.1.0 - 在线视频播放功能更新
android·ffmpeg