Yet another crackme (or rather keygenme).
Executables: Linux x64 Windows x64
It is just to be run with name
and serial number as command line arguments. Valid ones are:
2Z7A7-EK270-TMHR4-BHC71-CEB52-HELL0-HELL0-EONP9
2Z7A7-6I7R9-MZGO9-FDQJ3-JN0Q6-HELL0-HELL0-72KJ9The first serial number has E feature turned off, the second has E
feature turned on. There are two tasks: Easy: by patching, turn on/off
all 5 features. Medium: generate a serial number with arbitrary
features turned on/off. Good luck!
(它只是以名称和序列号作为命令行参数来运行。有效的有:
2Z7A7-EK270-TMHR4-BHC71-CEB52-HELL0-HELL0-EONP9
2Z7A7-6I7R9-MZGO9-FDQJ3-JN0Q6-HELL0-HELL0-72KJ9
第一个序列号关闭了E功能,第二个序列号打开了E功能。
有两个任务:
简单:通过补丁,打开/关闭所有5个功能。
介质:生成任意功能开启/关闭的序列号。
好运!)
hint:
https://down.52pojie.cn/Tools/Debuggers/x64dbg_2018-04-05.zip
https://stackoverflow.com/questions/5475790/how-to-disassemble-the-main-function-of-a-stripped-application
(1)简单:通过补丁,打开/关闭所有5个功能。
首先我们输入2Z7A7-6I7R9-MZGO9-FDQJ3-JN0Q6-HELL0-HELL0-72KJ9查看一下输出的结果
然后再观察一下2Z7A7-EK270-TMHR4-BHC71-CEB52-HELL0-HELL0-EONP9输出结果
发现最后一位会相反,而其他的都会全部相同,如果想要某一个全开,某一个全关的话,肯定不能改跳转,因为改完跳转之后两个结果的ABCD 功能始终会保持一样,所以我们发现在跳转前有一个and 常数 的操作,并且输入两个码会发现与常数进行AND的数据都不一样,所以我们可以通过控制and后的常数来进行控制跳转两个码对应的跳转。
我们发现2Z7A7-6I7R9-MZGO9-FDQJ3-JN0Q6-HELL0-HELL0-72KJ9与常数进行与运算的数据分别为F8、43、EF、5A、CF
而2Z7A7-EK270-TMHR4-BHC71-CEB52-HELL0-HELL0-EONP9是7A、EF、DB、1E、F4
所以我们将第一个常数改为和F8与运算之后为0但是和7A与运算后不为0的数据,可以改为0x40,其他四位同理进行修改
运行到下图所示的关键地方,对数据进行修改
将0x40改成0x2,0x1改成0x20,0x2改成0x10,0x8改成0x4,如下图所示:
之后进行保存,然后进行运行,结果如下图所示:
(2)中等:生成任意功能开启/关闭的序列号
第一步:
是从第一个HELLO开始到第二个HELLO结束做了比较,并且很容易可以发现这里如果输入别的数据将会报错说格式错误。
所以初步确定格式应该是xxxxxxxxxxxxxxxxxxxxxxxxxxxxx-HELL0-HELL0xxxxxx
第二步:
在IDA里找到如下所示的代码,发现它的功能是检测每隔5位是否为“-”符号,即从第六位开始:
所以格式可以进一步确定为
xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-HELL0-HELL0-xxxxx
然后会发现每五位会进行一次处理,处理的大致步骤是:
首先判断我们输入的是数字还是大写字母还是其他,如果输入其他的话就是非法的字符,会报错;
如果输入的是数字的话就减去0x30;
如果输入的是大写字母的话就减去0x37,然后所获得的值分别存入arr[4],arr[3],arr[2],arr[1],arr[0]中;
然后再进行Result=arr[4]+36*(arr[3]+36*(arr[2]+36*(arr[1]+36*arr[0]))))的操作,最后将Result存入到内存中去。
存到内存中的这一串数据在之后校验的过程中有重要作用.
假设这段数据的首地址为S
第三步:
我们在IDA中找到如图所示代码
这个判断是S[0]<<24+S[1]<<16+S[2]<<8+S[3]得到的数据和0XBEBAADDE进行比较,这里需要两个数据相等.所以前五位必须是2Z7A7
发现这里有一个很多判断条件的if语句,但是真正有用的判断只有v4<1,v3<1,v5<0x7e0,v5>0x834,v4>0xc,v3>0x1f和sub_1400010B0函数,这里的条件应该全部判断为假,即1<S[6]<0xc,
0x7E0<(S[4]<<8)+S[5]<0x834,
0x1<S[7]<0x1f
且函数sub_1400010B0运算后的数据得等于S[16-23]十六进制组成的数据
经过分析v4是S[6],v3是S[7],v5是S[4]<<8+S[5].
如果这里验证通过的话,就会执行开启和关闭功能的代码:
用S[8]和0x40进行与运算,判断是否开启A功能,同理S[9],S[10],S[11],S[12]均会进行这样的操作.
所以综合分析后:
11111-22222-33333-44444-55555-HELL0-HELL0-66666
1处必须填入2Z7A7
2处填入的数据必须满足得到的S[3]=0xBE0x7E0<(S[4]<<8)+S[5]<0x834,
3处填入的数据满足1<S[6]<0xc,0x1<S[7]<0x1f
4,5处填入的数据就是根据需求对功能进行选择
在6处填入的数据就需要满足整串数据的校验码符合等于S[16-23]十六进制组成的数据