1, Target
The input parameter of sign is encrypted, but it has two obvious characteristics: one is the end of = = and the other is the beginning of R4iSK.
With these two characteristics, we can start.
2, Steps
Start with Base64
==The approximate rate of the ending data is Base64. Let's Hook it first
// Base64 var Base64Class = Java.use("android.util.Base64"); Base64Class.encodeToString.overload("[B", "int").implementation = function(a,b){ var rc = this.encodeToString(a,b); console.log(">>> Base64 " + rc); return rc; }
Run
The result is yes, but it's not what we want. Keep it first. Maybe we can use it later.
Match beginning of R4iSK
We are very skilled in this routine,
// Locate by string var strCls = Java.use("java.lang.StringBuilder"); strCls.toString.implementation = function(){ var result = this.toString(); if(result.toString().indexOf("R4iSK") == 0 && result.toString().length < 200) { console.log(result.toString()); var stack = threadinstance.currentThread().getStackTrace(); console.log("Rc Full call stack:" + Where(stack)); } return result; }
Run happily
This time I caught it, although the class name of the CrashReport is a little strange
Hook handler
var OperCls = Java.use("com.jxxxxong.sdk.xxcrashreport.a.a.a"); OperCls.a.overload('[B').implementation = function(a){ var result = this.a(a); var StrCls = Java.use('java.lang.String'); var inStr = StrCls.$new(a); console.log(inStr + " >>> " + result); return result; }
The input parameter is a byte [], and the return value looks like Base64, but the probability is not Base64
There are two schemes for printing byte []. One is to print it directly into Hex String, and the other is to bet that it is actually a String and print it directly into String. Let's try to convert it to String first
>>> R4iSKKKKKKKKKBC0CtGnLKMgYWz/LGKKKK==
The printed result is like this. The input parameter is not printed, indicating that the input parameter is not a simple string getBytes().
Backtrack stack up
We continue to trace up the stack to find the init function of a.o,
The byte [] that found this input parameter experienced an xxcrashreport a. The baptism of a.a.b function.
Click in and find that it was a zip compression. Don't say anything. Let's start with the b function Hook
OperCls.b.implementation = function(a){ var StrCls = Java.use('java.lang.String'); var inStr = StrCls.$new(a); console.log(inStr + " >>> "); var result = this.b(a); return result; }
Run again and the result comes out.
{"msg":[{"appId":"fba8ae5a5078417d90ae1355af234d4f","clientVersion":"10.3.2","buildCode":"92141","appArch":"32"}]} >>> >>> R4iSKKKKKKKKKK3Ckm6NCKyP4XpntPMcsmTiVIdoeOlPYBLNS1PK0O4e747X79c5P3zFQbh3LbJlFUCRaaIQTPKmipOYkJUu6OAqZT1xx6MMacwy/v5yxRvbdYAwdhXVCF7zmi+DHbQ16PPDpn/R9PPnPifGbirJeG9yKKKK
It's too cold to finish work. Fresh beer won't be served. Serve Erguotou.
3, Summary
The original String calls once getBytes(), then turns to byte[], then calls b function to do zip compression, and finally calls a function to make a magic change Base64 operation.
The only flaw of the app this time is that the beginning of the ciphertext is unchanged, so we try to ensure that the results are different every time when encrypting, and the ciphertext should be irregular.
A gentleman's business is based on the foundation, and the Tao is born from the foundation