参考文章
https://blog.csdn.net/wmh_100200/article/details/73368859
https://bbs.pediy.com/thread-218455.htm
看雪的ctf还是很有水平的,我这菜鸡表示只能看看
用jeb打开,发现做了很恶心的混淆,汗颜。使用n键对变量重命名。
java层的分析我就不写了,这题的考点在于so层算法的分析以及指令的混淆。
ps:我几乎用了一天的时间,去看这个check函数
要么手动的patch要么写个脚本去除,我看还是写个脚本吧,我刚开始手动patch,实在是太累了!!!
#include
static main()
{
auto i,pos,size,JMP_SIZE,FLOWER1_SIZE,FLOWER2_SIZE;
pos=0x286C; //START
size=0x1A000;//SIZE
JMP_SIZE = 0x40;
FLOWER1_SIZE = 0x1e;
FLOWER2_SIZE = 0x8;
for ( i=0; i < size;i++ ) {
//PATCH JMPS
if (
(Byte(pos)==0x13)&&(Byte(pos+1)==0xe0)&&(Byte(pos+2)==0xbd)&&
(Byte(pos+3)==0xe8)&& (Byte(pos+4)==0xf0)&&(Byte(pos+5)==0x47))
{
for(i=0;ipos+i,0x0);//change
}
HideArea(pos,pos+JMP_SIZE,atoa(pos),atoa(pos),atoa(pos+JMP_SIZE),-1);
continue;
}
// PATCH FLOWER1
//.text:00002A80 B1 B5 PUSH {R0,R4,R5,R7,LR}
//.text:00002A82 82 B0 SUB SP, SP, #8
//.text:00002A84 12 46 MOV R2, R2
//.text:00002A86 02 B0 ADD SP, SP, #8
//.text:00002A88 00 F1 01 00 ADD.W R0, R0, #1
//.text:00002A8C A0 F1 01 00 SUB.W R0, R0, #1
//.text:00002A90 1B 46 MOV R3, R3
//.text:00002A92 BD E8 B1 40 POP.W {R0,R4,R5,R7,LR}
//.text:00002A96 01 F1 01 01 ADD.W R1, R1, #1
//.text:00002A9A A1 F1 01 01 SUB.W R1, R1, #1
if (
(Byte(pos)==0xb1)&&(Byte(pos+1)==0xb5)&&(Byte(pos+2)==0x82)&&(Byte(pos+3)==0xb0)&&
(Byte(pos+0x1a)==0xa1)&&(Byte(pos+0x1b)==0xf1)&&(Byte(pos+0x1c)==0x01)&&(Byte(pos+0x1d)==0x01))
{
for(i=0;ipos+i,0x0);
}
HideArea(pos,pos+FLOWER1_SIZE,atoa(pos),atoa(pos),atoa(pos+FLOWER1_SIZE),-1);
continue;
}
//PATCH FLOWER2
// "PUSH.W {R4-R10,LR}"
// "POP.W {R4-R10,LR}"
if (
(Byte(pos)==0x2d)&&(Byte(pos+1)==0xe9)&&(Byte(pos+2)==0xf0)&&(Byte(pos+3)==0x47)&&
(Byte(pos+4)==0xbd)&&(Byte(pos+5)==0xe8)&&(Byte(pos+6)==0xf0)&&(Byte(pos+7)==0x47))
{
for(i=0;ipos +i,0x0);
}
HideArea(pos,pos+FLOWER2_SIZE,atoa(pos),atoa(pos),atoa(pos+FLOWER2_SIZE),-1);
continue;
}
pos++;
}
Message("\n" + "DE-FLOWERS FINISH BY Ericky\n");
}
手动的删除check和jni_load中间的函数,然后重新create_function,之后便可以使用F5反汇编了。虽然仍存在很多混淆指令,但这样已经可以看到check的整个代码了。
可以使用流程图,看整个函数的执行过程
接下来就是需要动态调试去跟了。
由于我们修改了so文件,因此在加载的时候要注意。使ida加载本地的so,而不是手机中的so(只需要默认选择就好)
经过初始化后可以看到该值,这一串字符就是最终我们需要匹配的。也就是最后的密文。
19931012应该就是加密的密匙
最后分析算法(可能也是猜测吧,分析是不可能的,永远也不可能的!),可以知道为rc4算法,找一个在线rc4加解密的网站。最后可以解得密码madebyericky94528
可以说这题折腾了很久,但是最终还是没有整出来,一方面是对指令混淆不熟,说白了也就是对arm指令不熟,另一方面就是对各种算法的反汇编不熟悉,真的很难。而且这两天我心情也不好,很难静下心来仔细的分析。这篇文章匆匆写下,其实那个rc4算法我还是没有看懂,而且密匙为什么是199931012而不是199310124853呢?问题还有很多,我不想折腾了。算法看重的不是加密的过程,而是注意输入和输出,抓住这两点,那么即使这个算法你识别不出来,也是可以看懂的。
这两天心情真的是糟透了,每天都活的很累,好好的假期,每天却如同末日一般。我的心悬在高处,只能用枯燥的指令占据我的逻辑。
程序员是孤独的,因为很少有人能懂他在干什么。不奢求别人能懂,只希望在放松的时候能有人嘘寒问暖 –2018.4.7