命令行程序,给出了flag的输入格式。
这种混淆把本来连接在一起的代码分割成很多个handler。通过设置一个控制码CtrlCode和一个巨大的switch-case结构来把这些handler关联在一起。 图中的红线表示一次次的比较CtrlCode。绿线表示相等后的跳转路线。蓝色表示handler的代码块。
有三种形式: 1.设置唯一的CtrlCode值 这种Handler起衔接的作用。可以直接判断出下一个执行的handler。
2.预设两个CtrlCode值,无法直接判断是跳转到eax或者ecx
3.预设两个CtrlCode值,比上一种更隐蔽
混淆过的代码直接调试起来很麻烦。可以在switch-case的入口处对CtrlCode设置一个条件记录断点,把所有的CtrlCode记录下来,再根据CtrlCode去查对应的handler。
根据IDA Strings窗口中的提示成功的字符串的交叉引用可以找到成功的handler,进而找到该handler的CtrlCode,进而在其他handler中搜索到设置该CtrlCode的位置。 提示成功的handler(CtrlCode为0xAD1C95B5h):
搜索该CtrlCode,得到一个handler(CtrlCode为0xE7210A91):
输入为"0x1x2x3x4x5x6x7x8X"时条件记录断点记录下来的结果: 可以看到,在提示成功的的上一层handler中,CtrlCode并没有被设置为成功的CtrlCode。
如要跳到成功的handler,需要[esi+3053h]=0,以此类推,往前回溯,找到两个关键的handler:
1、PowerMod也被混淆过,注意到其中调用了一个库函数__aullrem。google了一下查到是大数取模。 aullrem意为unsigned long long remainder。还一个字符'a'不知道代表什么。猜测是幂模算法,黑盒测试了一下,确认了猜测。 底数m为0x65757832,N为FFA1CF8F,运算结果为0x6E616B34。
2.以输入作为索引从data_array中取数,累加起来作为PowerModCheck的指数
整理一下条件:
开始以为要利用幂的数学性质求解。后来一想:即使求出满足条件的s,还是要在351个数中找9个来满足这个和的条件,搜索空间还是一样大,不可行。
注意到这351个数绝大多数都是10的倍数,感觉不像是随机生成的,就拿去做质因数分解。发现基本都有[2,3,5,7,11,13,17,31]这8个因子。有的数包含全部这8个因子,有的缺其中一个。于是按照最大公约数的不同,把这351个数分成了9类。再尝试把这9类数分别除以它们的最大公约数,看看得出的结果:
每一类都是1-x的完整排列,看到这作者的意图就很明显了,可以合理的推测:分别从这9类数中取一个,就能找到满足条件的s。
跑出来flag是:17x27x60x97x133x161x243x292x309X
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2018-10-4 13:09
被mratlatsn编辑
,原因: