文章的案例来自吾爱论坛2021春节安卓题目
链接:案例链接
java用的是unicode编码,c语言用的是ASCII编码
明文限制的长度是30,检测函数在nativel-lib文件里
解压apk并用ida打开so文件
大概分析一下,传进来的参数判断是否为30位,然后进入sub_B90进行处理后,再进入sub_D90处理,结果为v9,最后v9和v19作比较,相等返回1,不等返回0;
用ida动态调试
调试前先把ida目录下的dbgsrv、android-server拷贝到手机上
并修改权限 777
这里需要开启frida去获取so的基址+sub_B90的偏移量=sub_B90的绝对地址
先运行frida,再运行android-server
frida代码
1 | function hook_KeyStore_load() { |
打印结果
so基址: 0x7613313000
0x7613313000+8AC
所以需要在动调调试的时候在位置打上断点
没显示汇编按空格
以go方式打开ida
选择Debugger–》Attach–》Remote ARM Linux/Android debugger
输入手机IP,选择进程
加载好后跳到指定位置,或者快捷键G
打上断点后,点击绿色小箭头继续运行,app点击验证,会断到当前位置
可以转为汇编跟静态ida的作比较,Edit–》Code,或者快捷键C
按F8单步调试
打开寄存器,进入
用Frida
这里直接用fridahook 函数,sub_B90
sub_B90的偏移量为B90
这就是第一轮加密后的
hook 第二个函数
这是明文经两轮加密后的结果
1 | function hook_KeyStore_load() { |
主动调用
1 | # -*- coding: UTF-8 -*- |
异或
大概分析一下sub_b90,是根据传入的第三个参数s把v20进行了一个初始化,然后再把参数a1和v20进行了异或运算,主要看这个异或运算,先设想一下,如果是把a1进行了异或,那么得到的结果和a1之前的数据再异或就可以计算出异或的key,这里我们把它叫做xorkey,那么先看一下我们传入的参数,是30个1,也就是30个0x31 ,然后看结果,第一位是0xe0,0x31^0xe0 = 209,然后把参数改为30个2,即0x32,得出首位的结果是0xe3,0xe3^0x32结果也是209,证明我们的思路是正确的,然后依次求出所有的xorkey,
这里的值是输入,30个1加密后异或来的
明文 ^ 密钥 = 密文
# 拿到密钥
明文 ^ 密文 = 密钥
1 | a = [0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, |
结果:
[209, 90, 6, 144, 68, 230, 199, 229, 222, 40, 247, 242, 102, 145, 200, 133, 66, 223, 249, 224, 130, 1, 43, 59, 56, 99, 55, 189, 46, 77]
异或的key找到了,现在要找异或后的正确值,才能算出答案明文
1.调试
![image.png]
调试到这里,要在寄存器钟拿到v19
这里就是判断的地方,偏移量为B2C
调试
没计算前
计算后
这就是要的密文了
“5Gh2/y6Poq2/WIeLJfmh6yesnK7ndnJeWREFjRx8”
另一种方式hook寄存器
基地址加B30就是结果寄存器的位置,同时我们需要的是x9寄存器的值
1 | function hook_KeyStore_load() { |
异或出答案
密钥:[‘0xd1’, ‘0x5a’, ‘0x6’, ‘0x90’, ‘0x44’, ‘0xe6’, ‘0xc7’, ‘0xe5’, ‘0xde’, ‘0x28’, ‘0xf7’, ‘0xf2’, ‘0x66’, ‘0x91’, ‘0xc8’, ‘0x85’, ‘0x42’, ‘0xdf’, ‘0xf9’, ‘0xe0’, ‘0x82’, ‘0x1’, ‘0x2b’, ‘0x3b’, ‘0x38’, ‘0x63’, ‘0x37’, ‘0xbd’, ‘0x2e’, ‘0x4d’]
结果:“5Gh2/y6Poq2/WIeLJfmh6yesnK7ndnJeWREFjRx8”
结果^密钥=答案
1 | import base64 |
运行结果为:
52pojieHappyChineseNewYear2021