- 用JEB或者APK改之理载入后查看java源码。
- MainActivity函数如上。
- 程序调用了一个 native 的 chec函数
- 调出apk文件里面的liblhm.so
- 用IDA打开 .so文件
- 在函数栏里面搜索 chec,双击进入 然后F5进行反编译
a1,a2 为JNI接口指针和对对象和Java类的引用,是默认的,后两个参数即为Java层参数。
以及GetMethodID与CallIntMethod为JNI层调用Java层方法的函数。
分析算法得到:
当 java层传入的第二个参数 - 1<=0 返回java层的第一个参数
else 根据java层第二个参数*2 %3的结果 来判断选择哪个GetMethodID方法。
分析 check1 方法 :每次将第一个参数 加上4950
对于check2 方法 : APK改之理得到的java码与JEB得到的java码不同。并且 APK改之理得到的码略有错误 。
以JEB得到的java源码为例
如果第二个参数%2 == 0则 第一个参数 +499500 否则 第一个参数 - 499500
对于check3方法 第一个参数+49995000
对于 验证算法。
if (MainActivity.this.check(i, 99) == 1835996258) { localTextView.setText("The flag is:"); paramBundle.setText("alictf{" + MainActivity.this.stringFromJNI2(i) + "}"); return; }
第一个参数 i 为 我们输入的 数字 第二个参数 固定为 99
每个 check系列的函数 最后都会再次返回 chec函数, 再次判断执行哪个check函数,直到第二个参数-1<=0才结束并最终返回第一个参数。
鉴于 check 1 、2 、 3三个函数 都对第二个参数没有影响 故可得解密算法如下:
得到运行结果 236492408
此值即为输入以后能够得到flag 的 数。
方法一: 在模拟器上安装该程序 然后输入 236492408
方法二: 分析 JNI2方法 。
以方法二为例:
IDA载入.so文件 然后 在函数栏搜索JNI2
双击进入 F5反编译。
- 能力不够 告辞。