# 微博国际版 app 逆向

  • 登录参数

# 抓包

直接用 charles 抓包,可以看到,登录接口主要是 i,s,p 这三个参数携带了加密信息,

image-20220807163418474

# 静态分析

直接用 jadx 打开,直接在 loginmainactivity 中找,最终可以定位到 WeiboSecurityUtils ,这里的 caculateS 就是计算 S 参数的 native 方法。

image-20220807164251105

接下来直接用 ida 打开

image-20220807165257022

搜 java 找得到,明显是静态注册

image-20220807165939380

大致看一下,除了 sub_1C60 这个函数通过 Content 校验了签名外,貌似也没哈特别的逻辑了

# Unidbg

在捋清楚上述的思路后,接下来就只需要做两件事,patch (过掉) sub_1C60 的逻辑,主动调用生成参数

1C60 的偏移地址可以在 View 界面找到

image-20220807172939604

然后可以采用 hook 的方式,将这里的 FF F7 EB FE 更换为指令 mov ro,1

public void patchVerify(){
        int patchCode = 0x4FF00100; //mov r0,1 对应的操作码
        emulator.getMemory().pointer(module.base + 0x1E86).setInt(0,patchCode);
    }

此外,也可以采用 unidbg 自带的 hook 命令

Pointer pointer = UnidbgPointer.pointer(emulator, module.base + 0x1E86);
        assert pointer != null;
        byte[] code = pointer.getByteArray(0, 4);
        if (!Arrays.equals(code, new byte[]{ (byte)0xFF, (byte) 0xF7, (byte) 0xEB, (byte) 0xFE })) { // BL sub_1C60
            throw new IllegalStateException(Inspector.inspectString(code, "patch32 code=" + Arrays.toString(code)));
        }
        try (Keystone keystone = new Keystone(KeystoneArchitecture.Arm, KeystoneMode.ArmThumb)) {
            KeystoneEncoded encoded = keystone.assemble("mov r0,1");
            byte[] patch = encoded.getMachineCode();
            if (patch.length != code.length) {
                throw new IllegalStateException(Inspector.inspectString(patch, "patch32 length=" + patch.length));
            }
            pointer.write(0, patch, 0, patch.length);
        }

最后正常调用即可

# 参考

Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

Mr2 WeChat Pay

WeChat Pay