声明:本文只做技术交流,如有侵权,请告知删除,谢谢。
frida入门教程请参考Loco大神的文章,传送门:
https://mp.weixin.qq.com/s/bfurT1h32A1bLiBHa73oJA
今天使用frida框架做一个简单的破解,假定你的手机已经root,电脑已经安装java环境和jadx工具,样例是52破解里面的crakeme,链接如下:
https://www.52pojie.cn/thread-365394-1-1.html
下载附件并安装到手机或者模拟器都行,进行特征识别:
将apk文件拖入到 jadx工具中,进行字符搜索。
点击 工具栏中的 魔法棒,进行搜索(如用户名):
发现并没有相关的代码段,那我们再搜索 "username" 试试(中文搜不到,就试试英文咯):
看到第三行,有个checkSN函数,点击进去看看:
再看看在哪里调用,鼠标放在函数名上面,点击右键,选择 查找用例:
只有一处调用,在 onClick函数这里(为什么我不一开始就查找 onClick 函数呢,真是笨),
这就是我们点击注册时的处理逻辑了。
这段代码告诉我们,一个条件判断的语句执行不同的代码,关键就是这个 checkSN 函数了。
我们回到定义的地方,他只是一个私有的普通方法,非构造函数也非重载函数,那这样就好办了,我们开始请出我们的神器 frida吧!
PS:算法可以直接分析出来,不过主要介绍 frida 的用法,就不在这里分析了。
一,手机连接电脑,并开启 frida-server服务:
这样,我们就开启了 frida-server服务。
二,按照官方给的例子来改写代码,对 checkSN进行Hook,
官方的官方的例子:
https://www.frida.re/docs/examples/android/
需要更改的位置如下:
process = frida.get_usb_device().attach('com.example.seccon2015.rock_paper_scissors')
将这里的包名改成crakeme的包名,那包名是啥呢?
在 jadx工具,点击 AndroidManifest.xml,右边的 package 就是包名,如图:
将包名替换即可:
process = frida.get_usb_device().attach('com.droider.crackme0201')
现在就来更改核心的地方了:jscode代码段,
jscode = """
Java.perform(function () {
var check = Java.use('com.droider.crackme0201.MainActivity');
check.checkSN.implementation = function (a,b) {
console.log('用户名:',a);
console.log("注册码:",b)
return true;
}
});
"""
这段代码改写也非常简单,定义一个变量check,指向当前的某个类,这里指向的是这个:
com.droider.crackme0201.MainActivity
这样,你对类里的成员方法可以随意Hook,当然有需要注意的地方,比如构造函数的写法,还有重载函数的写法,都是与普通的方法不一样的,这里就是个普通的方法,所以可以直接写下来。
我们在控制台中打印出当前的参数值,并将结果强制变为true,这样就达到了爆破的效果:
手机端结果:
显示注册成功,怎么样,是不是非常的简单方便,既不用修改smail代码,而已不用重新编译安装,简直不要太省事。
这只是爆破,我们来追它的算法吧:
private boolean checkSN(String userName, String sn) {
if (userName == null) {
return false;
}
try {
if (userName.length() == 0 || sn == null || sn.length() != 16) {
return false;
}
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(userName.getBytes());
String hexstr = toHexString(digest.digest(), "");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexstr.length(); i += 2) {
sb.append(hexstr.charAt(i));
}
if (sb.toString().equalsIgnoreCase(sn)) {
return true;
}
return false;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return false;
}
}
这段代码很容易理解,对username进行MD5加密,并换转为字符串,取出偶数位的字符,再与注册码进行比较,如果相等返回true,否则返回false。
这样,我们就很容易写出类似注册机效果的Hook脚本,如图:
今天就说到这里吧,只是对 frida 框架进行一个简单的使用。
回复"太简单了",获取本文中的crakeme样本及frida脚本。