BUUCTF Reverse/findit

下载得到一个apk文件,直接用JEB打开,找到MainActive按下TAB查看伪代码

package com.example.findit;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View$OnClickListener;
import android.view.View;
public class MainActivity extends ActionBarActivity {
public MainActivity() {
super();
}
protected void onCreate(Bundle arg8) {
super.onCreate(arg8);
this.setContentView(0x7F030018);
this.findViewById(0x7F05003D).setOnClickListener(new View$OnClickListener(new char[]{'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'}, this.findViewById(0x7F05003E), new char[]{'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'}, this.findViewById(0x7F05003F)) {
public void onClick(View arg13) {
int v11 = 17;
int v10 = 0x7A;
int v9 = 90;
int v8 = 65;
int v7 = 97;
char[] v3 = new char[v11];
char[] v4 = new char[38];
int v0;
for(v0 = 0; v0 < v11; ++v0) {
if(this.val$a[v0] >= 73 || this.val$a[v0] < v8) {
if(this.val$a[v0] < 105 && this.val$a[v0] >= v7) {
label_39:
v3[v0] = ((char)(this.val$a[v0] + 18));
goto label_44;
}
if(this.val$a[v0] >= v8 && this.val$a[v0] <= v9 || this.val$a[v0] >= v7 && this.val$a[v0] <= v10) {
v3[v0] = ((char)(this.val$a[v0] - 8));
goto label_44;
}
v3[v0] = this.val$a[v0];
}
else {
goto label_39;
}
label_44:
}
if(String.valueOf(v3).equals(this.val$edit.getText().toString())) {
v0 = 0;
goto label_18;
}
else {
this.val$text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~");
return;
label_18:
while(v0 < 38) {
if(this.val$b[v0] < v8 || this.val$b[v0] > v9) {
if(this.val$b[v0] >= v7 && this.val$b[v0] <= v10) {
label_80:
v4[v0] = ((char)(this.val$b[v0] + 16));
if((v4[v0] <= v9 || v4[v0] >= v7) && v4[v0] < v10) {
goto label_95;
}
v4[v0] = ((char)(v4[v0] - 26));
goto label_95;
}
v4[v0] = this.val$b[v0];
}
else {
goto label_80;
}
label_95:
++v0;
}
this.val$text.setText(String.valueOf(v4));
}
}
});
}
public boolean onOptionsItemSelected(MenuItem arg3) {
boolean v1 = arg3.getItemId() == 0x7F050040 ? true : super.onOptionsItemSelected(arg3);
return v1;
}
}
分析代码得知flag的长度为38位,存储在v4中,而只有label_18一下的代码涉及到v4的值,直接照着写出脚本
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char Str2[] = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3',
'3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'};
int v11 = 17;
int v10 = 0x7A;
int v9 = 90;
int v8 = 65;
int v7 = 97;
char v4[38] = {0} ; //创建一个长度为38的数组
int v0 = 0;
while(v0 < 38)
{
if(Str2[v0] < v8 || Str2[v0] > v9)
{
if(Str2[v0] >= v7 && Str2[v0] <= v10)
{
label_80:
v4[v0] = Str2[v0] + 16;
if( (v4[v0] <= v9 || v4[v0] >= v7)&&(v4[v0] < v10) )
{
goto label_95;
}
v4[v0] -= 26;
goto label_95;
}
v4[v0] = Str2[v0];
}
else
{
goto label_80;
}
label_95:
++v0;
}
for(int i = 0 ; i < 38 ; i++)
{
printf("%c",v4[i],v4[i]);
}
return 0;
}
发现运行出来是乱码

改一下输出查找原因

出现了负数,找了下原因发现是数值溢出了

我一开始定义的v4是char类型的数组,而char的取值范围为 -128到+127,中间有一个 +16的操作,加完后就溢出了

那么简单的把v4的类型改为int就可以了


然后是改过后的脚本
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char Str2[] = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3',
'3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'};
int v11 = 17;
int v10 = 0x7A;
int v9 = 90;
int v8 = 65;
int v7 = 97;
int v4[38] = {0} ; //创建一个长度为38的数组
int v0 = 0;
while(v0 < 38)
{
if(Str2[v0] < v8 || Str2[v0] > v9)
{
if(Str2[v0] >= v7 && Str2[v0] <= v10)
{
label_80:
v4[v0] = Str2[v0] + 16;
if( (v4[v0] <= v9 || v4[v0] >= v7)&&(v4[v0] < v10) )
{
goto label_95;
}
v4[v0] -= 26;
goto label_95;
}
v4[v0] = Str2[v0];
}
else
{
goto label_80;
}
label_95:
++v0;
}
for(int i = 0 ; i < 38 ; i++)
{
printf("%c",v4[i],v4[i]);
}
return 0;
}
运行得到flag

通过对BUUCTF Reverse挑战中的APK文件进行逆向工程,解析出MainActivity伪代码并分析得出Flag。通过将关键字符串转换及处理,最终获得正确的Flag。

5500

被折叠的 条评论
为什么被折叠?



