题目是upx壳,先用upx脱壳后载入ida。
观察程序的逻辑。有三个关键check,分别进入观察逻辑。
check1(其中sub_401080是相等的比较函数)这段flag的结果就是字符串(注意字符串的顺序)
其实看汇编代码更直接一些。
check2,这是一个aes加密,对字符串进行加密然后和输入的数据进行比较。
可以直接在call这一位置下断,观察rax寄存器的情况。gdb调试下断即可。
查看rax寄存器的内容,得到字符串。
check3同理
拼接起来得到fag c92bb6a5a6c3009124566d882d4bc7ee
一道简单的迷宫题,直接分析算法即可。
逻辑是输入字符串,四种,分别是jkuh四种,进入函数分别代表
向下移动
右移
上移
左移
从23开始走出30。结果jkkjjhjjkjjkkkuukukkuuhhhuukkkk
然后md5
前面是个字符为Dep{}的函数和长度是32的限定。后面有三个限定。
int main()
{
char v59[16] = {51,0,21,9,11,54,6,12,2,58,44,8,49,11,55,12};
char v43[16] = {76,101,96,114,100,73,112,99,108,69,83,97,78,100,72,97};
char v11[32] = {14,5,0,11,13,9,2,3,12,5,15,1,14,4,15,13,1,8,15,15,9,3,15,14,15,4,15,6,2,5,5,13};
char flag[33] = {0};
int i = 0,j = 0,k = 0,v5 = 0;
for(i =31;i > v5;i--)
{
for(j = 33;j<127;j++)//j = byte_404004[v5]
{
for(k = 33;k < 127;k++)//k = byte_404004[i]
{
if((j^k) == v59[v5])
{
if((j&k) == v43[v5])
{
if((j &0xf)==v11[v5] && (k & 0xf) == v11[i])
{
flag[i] = k, flag[v5] = j;
}
}
}
}
}
v5++;
}
puts(flag);
return 0;
}
得到结果
感觉这是一个不唯一的flag。根据提示,字符串用_分割。用上面的代码限定出每个字符所有情况,找到最合适的Nep{mircle_and_maho_is_not_free}
其实在这里只要限定好Dep{}和32位和14位的值正确就可以进行下一步的计算。但最后一步还是需要完整的字符串
挺懵,这个时候需要index = 14的值为正确结果。动态调试进入sub_403000,将代码给dump下来。
ollydbg dump当前状态的方法:动态调试到目标位置ollydump插件。
载入查看结果
根据逻辑
int main()
{
char key[] = "Nep{mircle_and_maho_is_not_free}";
char misc[] = "Sis_puella_magica!";
char x[] = {37,110,49,19,47,40,32,60,53,52,48,109,59,54,7,60,56,127,93,84,40,30,26,47,59,43,85,54,73,109,102,126,0};
char flag[32];
for(int i = 0;i<32;i++)
{
flag[i] = key[i] ^ x[i] ^ misc[i%18];
printf("%c",flag[i]);
}
}