LoopAndLoop(阿里CTF)-Bugku
一道简单的安卓逆向
载入 GDA,查看 MainActivity
可以看到题目将我们输入的内容经过 check 的一系列变化,将变换后的结果与 1835996258 进行比较,如果一致就输出 flag,反之输出 "Not Right!"
所以接下来查看 check 方法
可以看到 check 方法为 native 层的原生函数,还包含有 check1,check2,check3 方法
接下来分析一下 so 文件,反编译 apk,IDA 打开 lib\armeabi\liblhm.so,定位到主函数部分
-
_JNIEnv::GetMethodID: GetFieldID 是得到 java 类里的参数 ID,GetMethodID 得到 java 类里方法的 ID,它们只能调用类里声明为 public 的参数或方法
-
_JNIEnv::CallIntMethod: 得到 java 类里 Int 类型的方法
经过分析可以发现 chec 方法是根据其第二个参数 * 2 % 3 的结果调用 Java 层的三个 check 函数对第一个参数进行处理
所以可以依据这个思路写出逆向脚本,exp 如下:
#include <bits/stdc++.h>
using namespace std;
long long num = 1835996258;
inline int check1(int input, int s) {
int t = input;
for (int i = 1; i < 100; i++) t -= i;
return t;
}
inline int check2(int input, int s) {
int t = input;
if (!(s % 2)) {
for (int i = 1; i < 1000; i++) t -= i;
return t;
} else {
for (int i = 1; i < 1000; i++) t += i;
return t;
}
}
inline int check3(int input, int s) {
int t = input;
for (int i = 1; i < 10000; i++) t -= i;
return t;
}
int main() {
for (int i = 2; i < 100; i++) {
if (2 * i % 3 == 0) num = check1(num, i - 1);
else if (2 * i % 3 == 1) num = check2(num, i - 1);
else num = check3(num, i - 1);
}
cout << num << endl;
return 0;
}
得到 236492408,输入得到 flag
alictf{Jan6N100p3r}