一、目标
今天我们的目标是某问答社区App的 x-zse-96

1:main
版本: v8.21.1
二、步骤
搜x-zse-96
常规做法是jadx打开apk,然后搜索x-zse-96。
神奇的是,居然没有结果,这就有点意思了,App给我们加戏了,把一些明显的字符串做了加密隐藏。
观察共性
观察一下,签名有两个共性
1、 都是 1.0_ 开头
2、 后面接着的很像Base64
那就先从hook开头开始吧。继续用大海捞针法来捞开头。
1// 靠字符串去定位 2var strCls = Java.use("java.lang.StringBuilder"); 3strCls.toString.implementation = function(){ 4 var result = this.toString(); 5 6 // console.log(result.toString()); 7 8 if(result.toString().indexOf("1.0_") >= 0 ) 9 { 10 console.log(result.toString()); 11 12 var stack = threadinstance.currentThread().getStackTrace(); 13 console.log("Rc Full call stack:" + Where(stack)); 14 15 } 16 return result; 17}
来跑一下。

幸运的是,我们这次猜对了开头,也猜对了结果。
下面的目标就是这个 com.zxxxu.android.net.d.i.e 了

点这个encryp函数进去
1 public interface b { 2 byte[] encrypt(byte[] bArr); 3 }
发现b变量是个接口类型,所以我们还得知道它实际被赋值的变量是什么类型才可以。
打印类成员变量
这个我们会 http://91fans.com.cn/post/idlesignone/ 以前介绍过打印类的成员变量。
1var requestCls = Java.use("com.zxxxu.android.net.d.i"); 2requestCls.e.implementation = function(a){ 3 console.log(" ========== "); 4 5 var fields = Java.cast(this.getClass(),Java.use('java.lang.Class')).getDeclaredFields(); 6 //console.log(fields); 7 for (var i = 0; i < fields.length; i++) { 8 var field = fields[i]; 9 field.setAccessible(true); 10 var name = field.getName(); 11 var value =field.get(this) 12 console.log("name:"+name+"\tvalue:"+value); 13 } 14 15 console.log(" ========== "); 16 var result = this.e(a); 17 return result; 18}
结果出来了

1:rc1
这个类名出来了 -$$Lambda$AshC3KZBWneDDB5y10Ccx5ghIWw 看上去还是比较复杂的

1:rc2
这个 a.a 函数继续往下找,最后就找到这里了

1:rc3
可以写代码去hook了, 从名称上看大概率是 aes算法。而且除了明文还有两个参数,那么大概率是key和iv了。
三、总结
App开始狡猾了,明显的字符串做了加密,我们找起来就没那么方便了。
关键点还是共性,只要有共性,就有线索了。
com.secneo.apkwrapper.H.d 这个函数大家可以分析下,它应该就是加密那个明显字符串的。从它可以暴露出x-zse-96。

无人与问,但浊酒相呼,疏帘自卷,微月照清饮。
Tip:
: 本文的目的只有一个就是学习更多的逆向技巧和思路,如果有人利用本文技术去进行非法商业获取利益带来的法律责任都是操作者自己承担,和本文以及作者没关系,本文涉及到的代码项目可以去 奋飞的朋友们 知识星球自取,欢迎加入知识星球一起学习探讨技术。有问题可以加我wx: fenfei331 讨论下。
关注微信公众号:奋飞安全,最新技术干货实时推送
