本题有两种解法
解法一:静态分析法
1.jadx-gui打开MainActivity,可以发现注册了crack_j2c,
且native注册了checkFlag()和 onClick()方法
2-1
2.ida打开so文件分析:
先找到init_array段(没有初始化函数)和jni_onload(初始化了一些全局变量)发现没有什么内容
然后打开 function窗口可以快速找到onclick()和checkflag()方法,
(1)在onclick()方法中对输入字符串为长度为30的判断,并根据checkflag()函数返回布尔值进行Toast消息弹窗输出
2-2
(2)分析checkflag()方法【主要】
在开头有一处关于isDebuggerConnected()方法的反调试检测(但好像没起什么作用)
2-3
接下来这一部分获取字符串,这里在汇编下比较好看一点
(不知道老哥们的F5直接呈现字符串是怎么改的。。)
StringBuilder s1=new StringBuilder("thisiskey");
StringBuilder s2=new StringBuilder("52pojie_2020_happy_chinese_new_year");
StringBuilder s3=new StringBuilder("20200125");
2-4
2-5
2-6
(然后是v11 & 3.这句话看到直接就懵了,看了前辈们的wp后,为是否为4的倍数)
新建了一个 35 位的 Byte 数组,做一个循环,当 i 不为 0 且 i 是 4 的倍数时,下标设置为 (i >> 2) - 1,取 key3 中的值来 append 到数组中;反之,下标设置为 i,取 key2 中的值来 append 到数组中。
如果在循环结尾处下断也可以轻松得到算出来的字符 串:52po2ie_00202hap0y_c0ine1e_n2w_y5ar
2-7
对变形后的字符串“52po2ie_00202hap0y_c0ine1e_n2w_y5ar”进行md5加密,获取16位的byte数组
2-8
将byte数组中的元素和字符串s1取余进行逐位异或:
2-9
将得到的 byte 数组逐位转成 hex 字符串,如果小于 0xF,即只有一位,高位补 0。将结果逐位 append 到一个新的字符串中,得到一个 32 位的字符串
2-10
substring截取字符串1-31,最后与输入sn进行equals比较
2-11
脚本
import hashlib
key1 = "thisiskey"
key2 = "52pojie_2020_happy_chinese_new_year"
key3 = "20200125"
arr = ''
for i in range(35):
if not i or i & 3:
arr += key2[i]
else:
arr += key3[(i >> 2) - 1]
print("1.变形(key2和key3):" + arr)
md5str = hashlib.md5(arr.encode("utf-8")).digest()
print("2.md5加密:" + str(md5str))
xorlist = []
str2 = ""
for i in range(16):
str1 = ord(key1[i % 9]) ^ md5str[i]
xorlist.append(str1)
str2 += hex(str1).replace("0x","")
print("3.异或(md5密文和key1):" + str(xorlist) + " #" + str2)
flag = ''
for i in range(16):
flag += hex(xorlist[i])[2:].zfill(2)
print("4.hexToString:" + flag)
flag = flag[1:31]
print("5.截取1-31:" + flag)
2-12
解法二:hook法(这里采用frida进行hook)
frida的环境安装:https://www.52pojie.cn/forum.php?mod=viewthread&tid=93187
https://www.52pojie.cn/thread-1100931-1-1.html(自己写的~)
1.由解法一我们可以知道,最后在equals()方法里将输入sn和加密后的字符串做了比较,由此可以在这里hook
2.这里直接使用python脚本直接调试:
注意:使用python脚本需要在 ./frida-server 启动后,
还需转发端口 adb forward tcp:27042 tcp:27042
3.脚本:
脚本怎么写,请注意看官方文档:https://frida.re/docs/javascript-api/#java
frida脚本使用:
# 查找USB设备并附加到目标进程
process = frida.get_remote_device().attach('com.wuaipojie.crackme01')
# 在目标进程里创建脚本
script1 = process.create_script(jscode)
# 注册消息回调
# script.on('message', on_message)
# 加载创建好的javascript脚本
script1.load()
# 读取系统输入
sys.stdin.read()
def on_message(message, data):
if message['type'] == 'send':
print(" {0}".format(message['payload']))
else:
print(message)
jscode:
jscode = """
Java.perform(function(){
var String = Java.use('java.lang.String')
String.equals.implementation = function (arg1) {
console.log("string is ==》:" + this.toString()); // 字符串本身
console.log("equals arg1 ==》:" + arg1); // equals 对象
var ret = this.equals(v);
return ret;
}
});
"""
完整脚本:
import frida
import sys
jscode = """
Java.perform(function(){
var String = Java.use('java.lang.String')
String.equals.implementation = function (arg1) {
console.log("string is ==》:" + this.toString());
console.log("equals arg1 ==》:" + arg1);
var ret = this.equals(v);
return ret;
}
});
"""
process = frida.get_remote_device().attach('com.wuaipojie.crackme01')
script1 = process.create_script(jscode)
script1.load()
sys.stdin.read()
hook后图像为
2-13
参考文章:
静态分析法
1.https://www.52pojie.cn/thread-1101220-1-1.html
2.https://www.52pojie.cn/thread-1101176-1-1.html
3.https://www.52pojie.cn/thread-1095089-1-1.html
hook:
1.https://www.52pojie.cn/thread-1101355-1-1.html(frida)
2.https://www.52pojie.cn/thread-1100945-1-1.html(Xposed)
其它:
参考文章
https://www.cnblogs.com/mysticbinary/p/12012935.html
https://frida.re/docs/javascript-api/
https://bbs.pediy.com/thread-226846.htm
https://www.52pojie.cn/forum.php?mod=viewthread&tid=931872
https://bbs.pediy.com/thread-246762.htm