前言本题自带call型花指令,考验选手对花指令的理解程度。加密属于基础的异或和左右移位加密。主要考察选手的基础能力,动态调试和写脚本的能力。在这篇文章,详细记录了我的分析过程,相信你会有很大收获。
1、查壳
PE64位,没壳程序
2、IDA分析去花指令使用IDA打开时,发现一片红,很正常的CTF考点:花指令
sub_main
当务之急是如何去除花指令,继续向下分析,发现了一些端倪
花指令的形成是干扰编译器的分析,但又不会影响程序的正常运行。
那么显而易见,会将某个寄存器进行push(保存)然后对其进行复杂操作,最终pop(恢复)该寄存器的值,程序正常执行。
而在本程序中,可以发现该手法:
push ebx.....pop ebx中间的过程均无需再看,直接NOP操作。
nop完记得保存修改。
接下来就可以分析main函数啦
而这两个函数恰好均为关键的函数。
sub_401040
此时,我们可以看到函数开头的位置存在多个push操作,不要急着nop。对照函数结束的部分,避免误杀友军。
可以看到pop和push是相互对应的,开头push,结束就要pop。
此时注意到:push、pop不是要nop的点,我们继续分析
熟悉混淆的朋友一定可以识别出这是一个call型混淆。
call一个地址,然后修改堆栈返回值,retn跳过混淆,相对之前的混淆需要对堆栈有一定的理解。
识别出来,进行nop即可
得到加密函数
int __cdecl sub_401040(char a1, int a2){ return ((a2 ^ a1) << 8) - a2;}sub_401080来分析另一个函数
相同的操作
得到加密算法
int __cdecl sub_401080(char a1, int a2){ return a2 ^ (a1 << 8);}3、分析加密流程
那么现在的任务是获得加密函数的顺序,这里采用动态调试的方法来获得:
得到顺序
leftxorxorleftxorleftleftxorleftleftxorxorxorleftleftleftxorxorxorleftxorxorleftxorleftleftleftleftxorxorxorleft将left用1替代,xor用0替代,得到顺序:
int temp[32] = { 1,0,0,1,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1 };密文可以看到是:
dword_402120 数组unsigned int dword_402120[32] = { 0x00004408, 0x000068D8, 0x00007AD8, 0x00004308, 0x00007BD8, 0x00004608, 0x00007B08, 0x000070D8, 0x00003308, 0x00007308, 0x000076D8, 0x00005CD8, 0x000076D8, 0x00006608, 0x00006908, 0x00006E08, 0x00004BD8, 0x000076D8, 0x00003FD8, 0x00006F08, 0x00005ED8, 0x000076D8, 0x00007408, 0x000046D8, 0x00005F08, 0x00006308, 0x00003408, 0x00007408, 0x000076D8, 0x000044D8, 0x00004CD8, 0x00007D08};
4、写出解密算法#include