-
-
[原创]2020 KCTF by lelfei
-
发表于: 2020-10-29 18:25 9399
-
注册码:10C7F30833B9C4563BF035C32D8C7709E040FCA64E211F34CD3FE773
说明:注册成功时输出“GOOD!”
设计说明:
0x00 这一题是这一段时间一些crackme想法的大集合,包含花指令、调试检查、内存校验、大数计算、溢出利用等等,如果能够理清各种干扰项,最后的算法其实比较简单。
0x01 自己写了一个大数计算类BigNum,数据位有0x20字节,实现了基本的加减乘除算法。有2个固定大数P=0x3FAFFA2B01B6BA9744C4B4E010010401和Q=0xFEA1BD9E6964129D8F5079E1,其中P共有4个DWORD组成,其中高位的3个DWORD分别是“INPUT:”、“GOOD!”、“ERROR!”的计算值,输出“INPUT:”等待用户输入。
0x02 用户输入注册码记为D,对D的前7位和后7位转换为数值记为sn1和sn2,对main()函数和调试检查函数分别计算内存校验,根据调试检查结果分别与这2个校验值进行异或。循环9次后,检查结果是否为P的第2、3个DWORD。
0x03 D转换为大数,取P的第一个DWORD记作E,计算D*E/0xE053D0F+P+Q记为F,计算F-P*Q记为m1,要求m1的数据位不超过0x10字节。
0x04 计算F*0x0E053D0F*25记为m2,再自加一次m2+m2会导致溢出覆盖掉P的长度位,导致P=1。
0x05 比较m1==P,即最终验证为D*E/0xE053D0F+P+Q-P*Q==1,正确则提示“GOOD!”。
0x06 程序源码中定义了4个花指令标志位:
#define JUNKCODE5() asm volatile("mov $0x55555555,%eax")
#define JUNKCODE7() asm volatile("mov $0x77777777,%eax;inc %eax;inc %eax;")
#define JUNKCODE9() asm volatile("mov $0x99999999,%eax;inc %eax;inc %eax;inc %eax;inc %eax;")
#define JUNKCODE11() asm volatile("mov $0xAAAAAAAA,%eax;mov $0xBBBBBBBB,%eax;inc %eax;")
在源码的main()和调试检测函数中添加了很多引用占位,编译后使用replace_byte.py把标志位替换成随机花指令。
0x07 由于替换花指令导致内存校验值发生变化,程序中使用了2个全局变量作为salt,需要在花指令替换完成后,调试时修改程序流程计算出校验值,再由校验值计算出2个salt手动patch到程序的数据段。
0x08 调试检测函数中有一个是硬件断点检查,程序源码中并没有调用设置硬件断点的函数SetDrxBreakPoint(),而是在编译之后手动patch到入口附近,代码为:
0040CA3A 50 push eax
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)