终于下载好安卓模拟器了,就来解决这道题吧(因为工具用的还不熟悉,所以是在互联网帮助下解决的……)
首先下载好文件解压,然后用安卓模拟器打开:
输入数字 会出现 Not Right! 输入字母 会出现Not a Valid Integer number 。
直接JEB开搞吧:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(2130968600);
this.findViewById(2131492946).setOnClickListener(new View$OnClickListener() {
public void onClick(View v) {
int inputInteger;
String inputIntegerString = this.val$ed.getText().toString();
try {
inputInteger = Integer.parseInt(inputIntegerString);
}
catch(NumberFormatException v0) {
this.val$tv1.setText("Not a Valid Integer number");
return;
}
if(MainActivity.this.check(inputInteger, 99) == 1835996258) { //关键点1
this.val$tv1.setText("The flag is:");
this.val$tv2.setText("alictf{" + MainActivity.this.stringFromJNI2(inputInteger) +
"}");//关键点2
}
else {
this.val$tv1.setText("Not Right!");
}
}
});
}
发现关键点1,2
将输入传入check函数,判断结果由stringFromJNI2函数输出flag。
这两个函数都是Native函数 :
public native int chec(int arg1, int arg2) {
}
public int check(int input, int s) {
return this.chec(input, s);
}
public String messageMe(String text) {
return "LoopOk" + text;
}
还是要逆一下so了
看了一下stringFromJNI2函数,只能继续逆chec函数。
chec伪代码里看出大致思路:调用Java层的三个check函数对输入数字进行处理,要得到真正的逻辑我们还需要看汇编。
可以看出IDA转换为伪代码的时候,* _JNIEnv::CallIntMethod*少传了一个参数
因此调用的应该是:
result = _JNIEnv::CallIntMethod(Evn, obj, *(&check1_id + 2 * _99 % 3), _99 - 1);
Java层的三个check代码为:
public int check1(int input, int s) {
int v1 = input;
int v0;
for(v0 = 1; v0 < 100; ++v0) {
v1 += v0;
}
return this.chec(v1, s);
}
public int check2(int input, int s) {
int v2;
int v3 = 1000;
int v1 = input;
if(s % 2 == 0) {
int v0;
for(v0 = 1; v0 < v3; ++v0) {
v1 += v0;
}
v2 = this.chec(v1, s);
}
else {
for(v0 = 1; v0 < v3; ++v0) {
v1 -= v0;
}
v2 = this.chec(v1, s);
}
return v2;
}
public int check3(int input, int s) {
int v1 = input;
int v0;
for(v0 = 1; v0 < 10000; ++v0) {
v1 += v0;
}
return this.chec(v1, s);
}
很明显,我自己写不出来这个逆向代码,就联网了一下:
def getNumber():
output = 1835996258
for i in range(2,100):
num = 2 * i % 3
if num == 0:
output = check1(output, i - 1)
elif num == 1:
output = check2(output, i - 1)
else:
output = check3(output, i - 1)
print output
def check1(input, loopNum):
t = input
for i in range(1,100):
t -= i
return t
def check2(input, loopNum):
t = input
if loopNum % 2 == 0:
for i in range(1,1000):
t -= i
return t
for i in range(1,1000):
t += i
return t
def check3(input, loopNum):
t = input
for i in range(1,10000):
t -= i
return t
if __name__ == '__main__':
getNumber()
运行得到密码236492408
再次在模拟器上运行此APK输入得flag:alictf{Jan6N100p3r}
感触颇深啊
通过这道题,明显感到了自己还差的很多,比如逆向代码的编写,代码分析等等,总之来说自己的编程能力还明显不足,以后得好好补补了,不能再急躁了