郑州网站建设咨询/百度怎么优化关键词排名
初探
附件是一个apk,现在模拟器跑一下:
我么随便输入一个字符,点击CHECK:
打印提示信息“You are wrong! Bye~”,然后程序自动退出。
没有过多信息,反编译一下:
使用jd-gui查看得到的jar包。
静态分析
先来到MainActivity,在OnCreate函数中找到注册按钮响应函数的位置:
findViewById(2131427446).setOnClickListener(new View.OnClickListener(this, (Context)this)
{public void onClick(View param1View){if (MainActivity.b(((EditText)((MainActivity)this.a).findViewById(2131427445)).getText().toString()).booleanValue()) {Toast.makeText(this.a, "You are right!", 1).show();return;} Toast.makeText(this.a, "You are wrong! Bye~", 1).show();TimerTask timerTask = new TimerTask(this) {public void run() {System.exit(1);}};(new Timer()).schedule(timerTask, 2000L);}
});
这里的onClick就是点击按钮后调用的函数。
这个函数逻辑也十分清晰,就是一个if判断,两个分支分别打印“right”和“wrong”。如果打印“wrong”,则延时2秒后退出程序。
所以重点在if判断的条件,该条件为一个函数调用的返回值:
MainActivity.b(((EditText)((MainActivity)this.a).findViewById(2131427445)).getText().toString())
总结就是以我们输入的字符串为参数,调用b函数,然后以返回值作为if判断的条件。
b函数
b函数的反编译代码为:
private static Boolean b(String paramString) {int i = 0;//字符串以flag{开头if (!paramString.startsWith("flag{"))return Boolean.valueOf(false); //字符串以}结尾if (!paramString.endsWith("}"))return Boolean.valueOf(false); //去除开头、结尾,得到中间的子串paramString = paramString.substring(5, paramString.length() - 1);//插件类a和b,并调用其一个整形参数的构造函数b b = new b(Integer.valueOf(2));a a = new a(Integer.valueOf(3));//创建用于保存结构的字符串对象StringBuilder stringBuilder = new StringBuilder();//遍历输入的字符串,一次取一个字符,调用函数afor (int j = 0; i < paramString.length(); j = k) {stringBuilder.append(a(paramString.charAt(i) + "", b, a));Integer integer = Integer.valueOf(b.b().intValue() / 25);int k = j;if (integer.intValue() > j) {k = j;if (integer.intValue() >= 1)k = j + 1; } i++;} //比较变形后的字符串是否等于“wigwrkaugala”return Boolean.valueOf(stringBuilder.toString().equals("wigwrkaugala"));}
b函数先检查输入字符串开头是否为flag{,结尾是否为}。
然后截取开头和结尾,获得{}中间部分的子串。
之后在一个循环中遍历子串,每次取一个字符作为参数调用MainActivity的a函数,a函数返回一个char。
将a函数返回的所有char拼接起来,如果等于“wigwrkaugala”,表示验证成功。
总体来看,这是一个算法题,关键是让输入的字符串经过a函数计算后,变成“wigwrkaugala”。
下面看a函数。
上面调用a函数进行变形时,还需要类a和类b的对象作为参数,这两个对象的创建位置是:
b b = new b(Integer.valueOf(2));
a a = new a(Integer.valueOf(3));
也就是,创建这两个对象都调用了对应类的构造函数,并且调用的都是有一个整形参数的构造函数。
a函数
a函数代码为:
private static char a(String paramString, b paramb, a parama) {return parama.a(paramb.a(paramString));
}
a函数就是将传入的字符先交给类b的a函数处理,然后经过类a的a函数处理,最后将类a的a函数处理结果返回。
下面我们分别看看类a和类b。
既然是算法题,多说也无益了,只能去看算法了。下面我就不粘贴那么多伪代码了,大家可以自己在jd-gui里看,我直接上两个类的描述了。
类a
两个重要数据成员:
b = "abcdefghijklmnopqrstuvwxyz";
c = {7, 14, 16, 21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8}
三个函数成员:
构造函数:
public a(Integer paramInteger)
根据参数,将整形数组c内的成员循环左移n。
更新函数:
public static void a()
将整形数组c内的成员循环左移1。
这里有个混淆,这个函数是类a的a函数,虽然函数名和类名相同,但这不是构造函数,因为返回值为void。我开始就搞错了,因为做C++开发多,这里容易被混淆。
变形函数:
public char a(Integer paramInteger)
去参数在整形数组c中的位置index
调用更新函数,更新整形数组c的内容
返回b字符串中位置index处的字符
类b
和类a类似
两个重要数据成员:
b = "abcdefghijklmnopqrstuvwxyz";
c = {8, 25, 17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13}
三个重要函数成员:
构造函数:
public b(Integer paramInteger)
根据参数,将整形数组c内的成员循环左移n。
更新函数:
public static void a()
将整形数组c内的成员循环左移1。
变形函数:
public Integer a(String paramString)
在字符串b中找参数字符的位置index1
在整形数组c中找index1的位置index2
调用更新函数,更新整形数组内容
返回index2
解答
搞清楚算后,我们可以穷举输入字符串,使用原算法,得到正确的输入字符串。
也可以设计逆算法,根据输出字符串,计算出正确的输入字符串。
这道题算法不难,我们设计逆算法解题,python代码如下:
# b构造方法
tb = [8, 25, 17, 23, 7, 22, 1, 16, 6, 9, 21, 0, 15, 5, 10, 18, 2, 24, 4, 11, 3, 14, 19, 12, 20, 13]
lb = []
v0 = 2
while v0 < len(tb):lb.append(tb[v0])v0 = v0+1
v0 = 0
while v0 < 2:lb.append(tb[v0])v0 = v0+1print(lb)# a构造方法
ta = [7, 14, 16, 21, 4, 24, 25, 20, 5, 15, 9, 17, 6, 13, 3, 18, 12, 10, 19, 0, 22, 2, 11, 23, 1, 8]
la = []
v0 = 3
while v0 < len(ta):la.append(ta[v0])v0 = v0+1
v0 = 0
while v0 < 3:la.append(ta[v0])v0 = v0+1
print(la)al = list('abcdefghijklmnopqrstuvwxyz')
sec = 'wigwrkaugala'def dec(s):global lbglobal laglobal alv1 = ord(s) - ord('a')v0 = v1arg5 = la[v0]bv1 = arg5bv0 = bv1bv2 = lb[bv0]barg5 = al[bv2]print(barg5,end='')al.append(al[0])al = al[1:27]lb.append(lb[0])lb = lb[1:27]# print(al)# print(lb)for s in sec:dec(s)
最终得到结果:flag{venividivkcr}
欢迎关注我的微博:大雄_RE。专注软件逆向,分享最新的好文章、好工具,追踪行业大佬的研究成果。