banner
Silas

REAO

Be a better man
github

微信 | 对掷骰子和猜拳功能的分析

本文基于 Android 微信 8.0.3

最近开始做一些软件的逆向学习,记录一下。

本文为微信系列的第一篇,对掷骰子和猜拳功能的分析。

掷骰子和猜拳都会出现随机的结果,所以猜测,应该是通过随机数实现的,后期发现实际上也是如此。

1、 寻找 hook 点#

Java Random 类对应的类名为 java.util.Random,使用 objection 对其进行 watching:

image

发送骰子的表情,发现 Random 的以下方法被调用:

image

对 java.util.Random.nextInt 进行 watch,再次掷骰子,dump 出调用栈、参数和返回值:

image

nextInt (n) : 在方法调用返回介于 0 (含) 和 n (不含) 伪随机,均匀分布的 int 值。

nextInt 的参数为 6,返回值为 1,掷骰子的结果为 2。

其实此处也可以作为 hook 点,但是不够细致。需要 hook 的点仅仅是掷骰子和猜拳,直接 hook Java 工具类的随机数方法,还是比较粗暴。

上溯调用栈,getIntRandom 是 tencent sdk 中的方法,很明显的一个生成随机数的方法。

继续向上,om.tencent.mm.plugin.emoji.e.f.o ,watch 一波这两个方法,看看能得到什么额外的信息。

android hooking watch class_method  com.tencent.mm.sdk.platformtools.Util.getIntRandom --dump-args --dump-return
android hooking watch class_method com.tencent.mm.plugin.emoji.e.f.o --dump-args --dump-return

再次掷骰子,这次的结果为 5 点。

e.f.o 方法的参数为:

image

返回值为:

image

从这个方法的参数和返回值可以推断出,dice.png 是掷骰子的图片,dice_5.png 是 5 点的骰子。

image

在本次调用过程中:图片可以看出,getIntRandom 得到的随机数 “0-5”, 对应掷骰子结果的点数 “1-6”


接下来,看了一下猜拳的逻辑,和掷骰子一致。

1.field_name 为 ‘jsb.png’,也就是剪刀石头布的拼音首字母:

image

2、getIntRandom 的参数为 2,获取 [0,2] 的 int 随机数:

image

3、返回值中的 field_name 为 jsb_b.png,和猜拳的结果 "布" 一致。

image

image

分析到这里,在利用过程中可以根据 e.f.o 的参数来判断当前要获取随机数的是什么表情(猜拳 OR 掷骰子),然后 hook 并修改 getIntRandom 的返回值,来得到想要的结果。

总结一下,可以用来 hook 的点:

com.tencent.mm.plugin.emoji.e.f.o(com.tencent.mm.storage.emotion.EmojiInfo)

com.tencent.mm.sdk.platformtools.Util.getIntRandom(int,int)

2、编写 Frida script#

设定:猜拳只出剪刀,掷骰子只出 6 点。

编写 frida 脚本:

function main() {

    Java.perform(function () {

        Java.openClassFile("/data/local/tmp/r0gson.dex").load();
        const gson = Java.use('com.r0ysue.gson.Gson')


        var jsb = 0 // 只出剪刀
        var dice = 5 // 只出6点

        var efo = Java.use('com.tencent.mm.plugin.emoji.e.f')


        efo.o.implementation = function (x) {

            var xstr = gson.$new().toJson(x)
            if (xstr.search('dice.png') != -1) {
                console.log('正在掷骰子')
                hookIntRandom(dice)

            } else if (xstr.search('jsb.png') != -1) {
                console.log("正在猜拳")
                hookIntRandom(jsb)
            }
            var res = this.o(x)
            return res
        }

    })
}


function hookIntRandom(a) {
    Java.perform(function () {
        var util = Java.use('com.tencent.mm.sdk.platformtools.Util')
        
        util.getIntRandom.implementation = function (int1, int2) {
            var res = this.getIntRandom(int1, int2)
            return a
        }
    })
}

setImmediate(main)

注:脚本中使用了肉丝的 Gson 来打印对象,不得不说,好使。

image

3、参考资料#

参考资料
Frida 打印 [object] 解决 Gson 包重名的问题 - https://bbs.pediy.com/thread-259186.htm

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。