一 环境
手机:Pixel 1
系统:Android 8.1
软件:IDA 7.5、JADX、JEB
难度:简单
apk资源(0积分下载)
https://download.csdn.net/download/WuYu_AS/20464210
二.分析过程
1.打开APP,随便输入flag,发现有textview提示,而且很奇怪。将APK放入jadx中,发现搜索字符串没有用,用JEB打开有解析一些字符串,那就先查看onCreate方法,发现了关键的方法。
2.通过简单的跟踪方法发现 this.a(this.e() + this.f() + this.g() + this.h());内有提示成功的提示,关键的是this.e() + this.f() + this.g() + this.h()的值为34。
private void a(int arg8) {
if(arg8 <= 34 && arg8 >= 34) {
try {
//成功的提示
this.n.setText(String.format("%s%s", this.getString(0x7F0B0029), this.l[arg8])); // string:me "\ns \t\tu \t\t\tc \t\t\t\tc \t\t\t\t\te \t\t\t\t\t\ts \t\t\t\t\t\t\ts \t\t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t\t! \n\n\n\n\n\n "
((Button)this.findViewById(0x7F070059)).setEnabled(false); // id:ok
return;
}
catch(Exception unused_ex) {
}
}
//失败的地方
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
}
3.通过引用那么需要(this.e() + this.f() + this.g() + this.h())为34,并且this.j != 0 && this.i != 0 && this.h != 0,那么就需要重点分析this.c();
private void a() {
try {
this.c();
if(this.j != 0 && this.i != 0 && this.h != 0) {
this.d();
this.a(this.e() + this.f() + this.g() + this.h());
return;
}
}
catch(Exception unused_ex) {
}
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
}
4.如果this.j != 0;那么就需要 字符串的前4个字节 转为的整数是num, 0x7BF<num<0x7D7
如果this.i != 0;那么就需要 字符串的4-6个字节 转为的整数是num2, 1<=num<=12
如果 this.h != 0; 那么就需要 字符串的长度大于8 且6-8个字节中 转为的整数是num3, 1<=num<=0x1f
private void c() {
try {
String v0 = ((EditText)this.findViewById(0x7F07002B)).getText().toString(); // id:code
this.j = 0;
this.i = 0;
this.h = 0;
String v2 = v0.length() <= 4 ? v0 : v0.substring(0, 4);
this.j = Integer.parseInt(v2);
if(this.j > 0 && this.j < 0xBD) {
this.j = 0;
}
if(this.j <= 0x7BF || this.j >= 2007) {
this.j = 0;
}
String v2_1 = v0.length() <= 6 ? v0 : v0.substring(4, 6);
this.i = Integer.parseInt(v2_1);
if(this.i < 1 || this.i > 12) {
this.i = 0;
}
if(v0.length() > 8) {
v0 = v0.substring(6, 8);
}
this.h = Integer.parseInt(v0);
if(this.h < 1 || this.h > 0x1F) {
this.h = 0;
return;
}
}
catch(Exception unused_ex) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
return;
}
}
5.对j/i/h的新的限制条件,并且赋值给新的变量 this.g = this.j;this.f = this.i; this.e = this.h;
private void d() {
try {
if(this.j == 0x7C5 || this.j == 2004) {
//这里不能进入 h的最大值为12
this.h = 0x1F;
}
if(this.i == 1 || this.i == 4 || this.i == 5 || this.i == 7 || this.i == 10 || this.i == 11 || this.i == 12) {
this.j = 0x7CF;
}
if(this.j <= 0x7CA && (this.i == 2 || this.i == 6 || this.i == 8)) {
this.i = 3;
}
if(this.j >= 0x7CC && (this.i == 2 || this.i == 6 || this.i == 8)) {
this.i = 9;
}
if(this.j == 0x7CB && (this.h > this.i + 2 || this.i == this.h)) {
this.i = 6;
}
this.g = this.j;
this.f = this.i;
this.e = this.h;
}
catch(Exception unused_ex) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
}
}
6.查看this.e() /this.f() / this.g() /this.h()的实现之后,自己组成可以通过枚举的方法实现算法
private int e() {
try {
return this.d[(this.g - 1900) % 60];
}
catch(Exception unused_ex) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
return 0;
}
}
private int f() {
try {
return this.c[this.f - 1];
}
catch(Exception unused_ex) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
return 0;
}
}
private int g() {
try {
return this.b[this.e - 1];
}
catch(Exception unused_ex) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
return 0;
}
}
private int h() {
int v0_2;
try {
String v0 = ((EditText)this.findViewById(0x7F07002B)).getText().toString(); // id:code
String v0_1 = v0.substring(8, v0.length());
int v3 = this.f;
int v4 = 0;
while(v4 < this.m.length) {
if(v0_1.equals(this.m[v4])) {
if(v3 == 2 && (v0_1.equals(this.m[6]))) {
//0x3F是错误的返回值,单个值就超过了34
return 0x3F;
}
this.k = this.a[v4];
v0_2 = 1;
goto label_36;
}
++v4;
}
v0_2 = 0;
label_36:
if(v0_2 == 0) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
}
return this.k;
}
catch(Exception unused_ex) {
this.n.setText(this.getString(0x7F0B002A)); // string:notMe "f \ta \t\ti \t\t\tl \t\t\t\te \t\t\t\t\td \t\t\t\t\t\t! \t\t\t\t\t\t\t! \t\t\t\t\t\t\t\t!"
return 0;
}
}
7.实现的算法
public static int[] a = new int[]{16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6};
public static int[] b = new int[]{5, 10, 8, 15, 16, 15, 8, 16, 8, 16, 9, 17, 8, 17, 10, 8, 9, 18, 5, 15, 10, 9, 8, 9, 15, 18, 7, 8, 16, 6};
public static int[] c = new int[]{6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5};
public static int[] d = new int[]{7, 7, 9, 12, 8, 7, 13, 5, 14, 5, 9, 17, 5, 7, 12, 8, 8, 6, 19, 6, 8, 16, 10, 6, 12, 9, 6, 7, 12, 5, 9, 8, 7, 8, 15, 9, 16, 8, 8, 19, 12, 6, 8, 7, 5, 15, 6, 16, 15, 7, 9, 12, 10, 7, 15, 6, 5, 14, 14, 9};
public static String[] m = new String[]{"23to01", "01to03", "03to05", "05to07", "07to09", "09to11", "11to13", "13to15", "15to17", "17to19", "19to21", "21to23"};
public static void test(){
for (int j = 0x7BF+1; j < 0x7D7; j++) {
if(j==0x7C5||j==2004)continue;
for (int i = 1; i <=12 ; i++) {
for (int h = 1; h <0x1f ; h++) {
for (int k = 0; k < a.length; k++) {
int local_j=j;
int local_i=i;
if(i==1||i==4||i==5||i==7||i==10||i==11||i==12){
local_j=0x7CF;
}
if(j<=0x7CA&&(i==2||i==6||i==8)){
local_i=3;
}
if(j>=0x7CC&&(i==2||i==6||i==8)){
local_i=9;
}
if(j==0x7CB&&((h>i+2)||(i==h))){
local_i=6;
}
// System.out.println((d[(j-1900)%60]+c[i-1]+b[h-1]+a[k]));
if(i==2&&k==6)continue;
if((d[(local_j-1900)%60]+c[local_i-1]+b[h-1]+a[k])==34){
System.out.println(String.format("d= %d i= %02d b= %02d a= %d",local_j,local_i,h,k));
String result=String.format("%d%02d%02d",j,i,h)+m[k];
}
}
}
}
}
}
三 结果
将获取到的flag=1995020305to07输入,就显示成功的标志,不过以前的题目了无法验证最后的结果