This article is based on Android WeChat 8.0.3.
Recently, I started doing some reverse engineering learning for software and decided to document it.
This article is the first in the WeChat series and analyzes the dice rolling and rock-paper-scissors functions.
Both dice rolling and rock-paper-scissors produce random results, so it is speculated that they are implemented using random numbers, which was later confirmed.
1. Finding the hook point#
The Java class corresponding to the Java Random class is java.util.Random. I used objection to watch it:
When sending the dice emoji, the following methods of Random are called:
I watched java.util.Random.nextInt and rolled the dice again to dump the call stack, parameters, and return value:
nextInt(n): Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and n (exclusive) from this method call.
The parameter of nextInt is 6, and the return value is 1, which means the result of rolling the dice is 2.
Actually, this can also be a hook point, but it is not detailed enough. The only points that need to be hooked are dice rolling and rock-paper-scissors. It would be too rough to directly hook the random number methods of the Java utility class.
Tracing back the call stack, getIntRandom is a method in the Tencent SDK, which is obviously a method for generating random numbers.
Continuing upwards, we have e.f.o in com.tencent.mm.plugin.emoji.e.f. I watched these two methods to see if I can get any additional information.
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
Rolling the dice again, this time the result is 5.
The parameters of e.f.o are:
The return value is:
From the parameters and return value of this method, it can be inferred that dice.png is the image for rolling the dice, and dice_5.png is the image for 5 points on the dice.
In this call process: From the image, it can be seen that the random number obtained by getIntRandom is "0-5", corresponding to the points "1-6" on the dice.
Next, I looked at the logic of rock-paper-scissors, which is the same as dice rolling.
- The field_name is 'jsb.png', which is the acronym for rock-paper-scissors in Chinese:
- The parameter of getIntRandom is 2, which gets a random int between 0 and 2:
- The field_name in the return value is jsb_b.png, which corresponds to the result "布" (rock-paper-scissors).
Based on this analysis, during the utilization process, we can determine whether to obtain a random number for rock-paper-scissors or dice rolling based on the parameters of e.f.o, and then hook and modify the return value of getIntRandom to get the desired result.
To summarize, the points that can be hooked are:
com.tencent.mm.plugin.emoji.e.f.o(com.tencent.mm.storage.emotion.EmojiInfo)
com.tencent.mm.sdk.platformtools.Util.getIntRandom(int,int)
2. Writing the Frida script#
Setting: Only scissors are chosen for rock-paper-scissors, and only 6 points are chosen for dice rolling.
Write the Frida script:
function main() {
Java.perform(function () {
Java.openClassFile("/data/local/tmp/r0gson.dex").load();
const gson = Java.use('com.r0ysue.gson.Gson')
var jsb = 0 // Only scissors
var dice = 5 // Only 6 points
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('Rolling the dice')
hookIntRandom(dice)
} else if (xstr.search('jsb.png') != -1) {
console.log("Playing rock-paper-scissors")
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)
Note: The script uses Gson by r0ysue to print objects, which works well.
3. References#
Reference
Printing [object] in Frida to solve the problem of Gson package name conflict - https://bbs.pediy.com/thread-259186.htm