Loading

闲鱼猪手配置文件解密

博客已迁移: https://roadtothe.top/

因为太闲,突然想起这个上古大坑了

众所周知,有个很好用的 Xposed 模块叫闲鱼猪手,可惜不知道什么原因,作者已经跑路了,好在原作者是把配置文件放在 Gitee 上的,通过 Commit 记录抢救回了作者的最后一次更新。

作者的加密比较狠,不仅配置文件是加密的,连 APK 本身都经过混淆,加密的配置文件长这样

image.png

因为后缀是 Json,所以猜测 APP 内部获取完在线配置文件后会解密,然后按照 JSON 格式来解析。那么就开始反编译 APK 吧

Jadx 的反混淆是一如既往的弱鸡,啥也看不出来

image.png

但是之前替换配置文件 URL 的时候已经找到了定义 URL 的地方,这也是一个突破口,因为解密部分总在获取 URL 内容之后

image.png

这里继续用一个反混淆比较强的工具: Jeb 来继续反编译。虽然还是有很多鬼画符,但是 Jeb 至少可以反编译出人话了

image.png

鬼画符自然是看不懂的,也不需要看懂,我们只需要知道大致的逻辑就行了

在一个 IF 语句下面发现了 "解密失败" 的提示,那么解密部分肯定在这块 IF 之上咯,上面果然发现了处理解密的部分

image.png

把这块单独拎出来看看

label_235:
    String v1_5 = s9.ۥ۠ۦ(v1_4);  // GET 请求获取配置文件
    if(TextUtils.isEmpty(v1_5)) {
        goto label_369; // 跳获取配置失败
    }

    new String("content");
    char[] v4_1 = v1_5.toCharArray();
    dq.ۥۣ۟(v4_1, "this as java.lang.String).toCharArray()");
    StringBuilder v5 = new StringBuilder();
    // 解密部分
    int v6 = v4_1.length;
    int v7 = 0;
    while(v7 < v6) {
        char v12_1 = v4_1[v7];
        ++v7;
        v5.append(((char)(v12_1 - 12))); // 12
    }

解密部分还是很简单的,就是单纯把每个字符减了 12。用 Python 或者 Java 重写这部分,就是

# Python

encFile = open("C:\\Users\\Ayabe\\Downloads\\debug\\a7.8.50.json", "rb")
decFile = "C:\\Users\\Ayabe\\Downloads\\debug\\a7.8.50_decrypt.json"

data = encFile.read()
encFile.close()
str = data.decode(encoding='utf-8')
charArray = list(str)

v5 = ""
v6 = len(charArray)
v7 = 0
while v7 < v6:
    v12_1 = charArray[v7]
    v7 += 1
    v5 += chr(ord(v12_1) - 12)

with open(decFile, 'w') as f:
    f.write(v5)
// Java

public class main {
    public static void main(String[] args) throws IOException {
        File encFile = new File("C:\\Users\\Ayabe\\Downloads\\debug\\a7.8.50.json");
        FileInputStream fileInputStream = new FileInputStream(encFile);
        byte[] data = new byte[(int) encFile.length()];
        fileInputStream.read(data);
        fileInputStream.close();
        String str = new String(data, StandardCharsets.UTF_8);
        char[] charArray = str.toCharArray();

        StringBuilder v5 = new StringBuilder();
        int v6 = charArray.length;
        int v7 = 0;
        while(v7 < v6) {
            char v12_1 = charArray[v7];
            ++v7;
            v5.append(((char)(v12_1 - 12)));
        }

        System.out.println(v5);
    }
}

这样我们就可以得到解密的 Json 配置文件了

{
	"BottomPanelCls": "com.taobao.idlefish.fun.view.panel.BottomPanel",
	"mBottomPanelClsInitList": "b",
	"mBottomPanelClsClick": "a",
	"BaseCellCls": "com.tmall.wireless.tangram3.structure.BaseCell",
	"vBaseCellClsJsonObj": "n",
	"VideoUGCFeedPlayPluginCls": "com.taobao.homeai.dovecontainer.VideoUGCFeedPlayPlugin",
	"mVideoUGCFeedPlayPluginClsShowVideo": "a",
	"FullVideoViewCls": "com.taobao.homeai.view.video.FullVideoView",
	"ImmersiveComponentViewHolderCls": "com.taobao.homeai.dovecontainer.immersive.ImmersiveComponent$ViewHolder",
	"SaveImageUtilsCls": "com.taobao.fleamarket.user.util.SaveImageUtils",
	"mSaveImageUtilsClsSameBitmap": "a",
	"DxHomeTitleBarCls": "com.taobao.fleamarket.home.dx.home.recommend.ui.HomeTitleBar",
	"PowerHomeTitleBarCls": "com.taobao.idlefish.home.power.home.HomeTitleBar",
	"mHomeTitleBarClsAddBarRight": "addBarRight",
	"SplashAdRequestHelperCls1": "com.alimm.xadsdk.business.splashad.SplashAdRequestHelper$1",
	"mSplashAdRequestHelperCls1OnSuccess": "onSuccess",
	"TBSwipeRefreshLayoutCls": "com.taobao.idlefish.home.power.ui.TBSwipeRefreshLayout",
	"MainActivityCls": "com.taobao.idlefish.maincontainer.activity.MainActivity",
	"TBSoundPlayerCls": "com.taobao.tao.util.TBSoundPlayer",
	"mTBSoundPlayerClsPlayScene": "a",
	"MtopContextCls": "mtopsdk.framework.domain.MtopContext",
	"mMtopContextClsMtopResponse": "c",
	"FishFlutterBoostActivityCls": "com.idlefish.flutterbridge.flutterboost.boost.FishFlutterBoostActivity",
	"vFlutterView": "c",
	"vBottomPanelClsMenuItems": "a",
	"CardSign": false,
	"RP": false
}
posted @ 2023-01-11 22:10  20206675  阅读(3557)  评论(5编辑  收藏  举报