参加了ali2015 ,但是时间的关系,仅仅弄了50pt的题。
结束了发现,队友真是给力。挺到49名了,差一点到前30就决赛了。 哈哈。
不过逆向之后的成就感还是很强的。
话不多说。上思路:
思路: 没有.so的apk是最好破解的。不择手段的使用工具,综合分析出算法。
jd-gui、smali2java、drEvent、androidKiller等。
1、反编译后,使用jd-gui查看,发现反编译的不充分。使用smali2java,发现根本没有反编译出来。
jd的效果:
smali2java的效果
2、那么,就目前我的能力而言,只能结合jd,还有自己的cfg工具,进行manual分析了。
3、分析的过程比较繁琐,直接上整理后的代码。
public void check(String paramString)
{
int i = 0;
if (paramString.length() != 16) {
throw new RuntimeException();
}
try
{
String str2 = getKey();
str1 = str2;
}
catch (Exception localException1)
{
String str1 = getKey();
System.arraycopy(str1, 0, paramString, 5, 5);
}
arrayOfInt = new int[16];
arrayOfInt[0] = 0;
arrayOfInt[12] = 14;
arrayOfInt[10] = 7;
arrayOfInt[14] = 15;
arrayOfInt[15] = 42;
try
{
arrayOfInt[1] = 3;
arrayOfInt[5] = 5;
System.out.println();
}
catch
{
arrayOfInt[5] = 37;
arrayOfInt[1] = 85;
}
arrayOfInt[6] = 15;
arrayOfInt[2] = 13;
arrayOfInt[3] = 19;
arrayOfInt[11] = 68;
arrayOfInt[4] = 85;
arrayOfInt[13] = 5;
arrayOfInt[9] = 7;
arrayOfInt[7] = 78;
arrayOfInt[8] = 22;
for(i=0 ; i < paramString.length() ;i++)
{
if ( (0xFF & arrayOfInt[i]) != (0xFF & (paramString.charAt(i) ^ str1.charAt(i % str1.length()) ) ))
throw new RuntimeException();
}
}
public String getKey()
{
return "bobbydylan";
}
4、关键程序就是check,那么以上代码就能大概分析出意图了。有个地方需要注意,就是使用的getkey不是当前的getkey,是另外一个文件的getkey。
我开始也在这里卡了一下,后来发现了字符有点不一样,还以为是看错了,原来真的就是不一样了。
5、那么,整个加密算法的过程就是。
[
1.获取getkey加密字符串str1[];
2.指定位置赋值的arrayint[];
3.关键的判断(0xFF & arrayOfInt[i]) != (0xFF & (paramString.charAt(i) ^ str1.charAt(i % str1.length()) ),这个要假才行。
那么逆向过来,就是param[i] = ar ^ intStr[ i%len(str1)] ) & 0xff.
]
6、接着写脚本逆向。
param = []
#'bloq,av"wie +lgvN'
#str1 = 'bobbydylan'
str1 = 'bobdylan'
#intStr = [98, 111, 98, 98, 121, 100, 121, 108, 97, 110]
intStr = [98, 111, 98, 100, 121, 108, 97, 110]
arrayint = [0, 3, 13, 19, 85, 5, 15, 78, 22, 7, 7, 68, 14, 5, 15, 42]
i=0
for ar in arrayint:
param.append( ( ar ^ intStr[ i%len(str1)] ) & 0xff )
i +=1
print ''.join(map(chr,param))
7、最终得到答案: blow,in the winD
总结下来,还是很简单的。
关键是:1、有耐心分析真正的加密过程;2、细心观察函数。
就是小cake。