别被外壳骗了,那只是柔软的伪装 - 某小说App Token算法分析
好的,我现在需要帮用户总结一篇文章的内容,控制在100字以内。首先,我得仔细阅读文章,理解其主要信息。 文章主要讲的是逆向工程中的脱壳和token算法分析。作者详细介绍了如何使用工具和方法来脱壳APK,然后通过查找字符串和分析代码来找到token的生成逻辑。最后,通过hook函数验证了结果,并总结了逆向过程中的关键点。 接下来,我需要将这些内容浓缩到100字以内。要注意用词简洁,涵盖主要步骤和结论。同时,不需要使用特定的开头语,直接描述内容即可。 可能会遇到的问题是如何在有限的字数内准确传达所有关键点。比如脱壳、字符串分析、函数hook等步骤都需要提及。此外,还要提到逆向过程中的运气因素和壳的重要性。 最终,我应该确保总结清晰明了,涵盖文章的主要内容和结论。 </think> 文章介绍了一个加壳APK的逆向过程,通过脱壳、字符串分析和代码解析找到token生成逻辑,并使用Frida Hook验证了h函数的运算结果。最终总结出逆向工程的关键在于突破壳的限制,并强调了运气和技术的重要性。 2025-10-13 05:18:21 Author: 91fans.com.cn(查看原文) 阅读量:1 收藏

一、目标

一、目标

token
1:token

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

二、步骤

脱壳

先把apk拉进jadx

qihoo
1:ke

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

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

字符串查找

tokenshow
1:token

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

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

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

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

tokensrc1
1:tokensrc1

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

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验证

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对应的函数,给壳一点加载的时间。

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

[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转成其他的语言。

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

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

ffshow
1:ffshow

坚硬只是表现

100

关注微信公众号,最新技术干货实时推送

100

文章作者 奋飞

上次更新 2025-10-13

许可协议 奋飞安全原创,转载请注明出处。


文章来源: http://91fans.com.cn/post/txtread/
如有侵权请联系:admin#unsafe.sh