一个迷宫题目,查壳发现是upx3.0+的壳,用upx shell脱完之后,再看区段数量感觉有点不对:
打开之后看到代码果然有 没有被反汇编的部分:
由于题目就是Maze,迷宫题目,那么问题就在找到迷宫,起始点,控制方向的相关函数,迷宫好找,就在内存里面:
提取出来,简单排列一下就能得到:
*******+** ******* ** **** ** ** ***** ** **F**** ** **** **********
起始点标记很明显,然后就是对控制算法的提取。
方法1: 因为我ida里面没有插件,我拖入到od里面跑,很快发现关键代码处有一个花指令被过掉:
继续往下动态调试就可以看到控制方向的 "a", "w", "s","d"和对应的移动方法。
方法2: 在ida里面nop掉反调试,选择jnz那一条指令,然后:
nop掉之后就是后面的call语句,我一开始直接nop发现没反应,加上之前od里面的 E8被过掉,所以只有字节修改才能有效, d指令转换成字节:
同上图,选择change byte,修改E8为90,之后就会自动对下面代码反汇编:
然后从main函数之后一直拖到Get falg字符串,P 快捷键成函数,就能F5了:
int __cdecl main(int argc, const char **argv, const char **envp) { signed int i; // [esp+10h] [ebp-14h] char v5[16]; // [esp+14h] [ebp-10h] sub_401140(aGoThroughTheMa); scanf(a14s, v5); for ( i = 0; i <= 13; ++i ) { switch ( v5[i] ) { case 'a': --dword_408078; // 7 break; case 'd': ++dword_408078; break; case 's': --dword_40807C; break; case 'w': ++dword_40807C; break; default: continue; } } if ( dword_408078 != 5 || dword_40807C != -4 ) { sub_401140(aTryAgain); } else { sub_401140(aCongratulation); sub_401140(aHereIsTheFlagF); } return 0; }
思路清晰的很,flag{ ssaaasaassdddw }