平时看了一些CrackMe,算法都比较简单,这次拿到的这个算法自己觉得还是比较有难度,首先自己分析时并没有完全分析出算法的结论,后来参照答案才得到较完整的分析:
1.OD载入,F9运行,输入序列号,点击Check,弹出MessgaeBox提示错误的序列号,那么我们分别给MessageBoxA和MessageBoxW下断,重新载入OD,任意输入序列号,程序中断在调用MessgaeBoxA的地方,根据栈回溯找到调用MessgaeBox的地方为0x0040188E:
Crtl+G跟随到0x0040188E
定位到关键跳转分支:0x00401871:jnz short 0040189D
以及关键函数:0x401869 call 00401332
给这个函数下断点,可见当函数返回值为-1时,弹出失败的MessageBox
重新载入后,输入序列号,程序中断在0x00401869,F7跟进函数处理:
注意这里会判断输入的数据长度是否正确,当长度不等于43时便直接jnz到0x40157E,然后返回-1,这里为什么是43可以通过手工调试来发现,主要是指令repne scas ****在判断,
当我们输入的字符串等于43时便可以通过判断,继续向下分析:
这里是一个格式化输入,因此推断出正确的序列号格式应该为"XDSEC**-********-********-********-********"
下面的两个函数用来判断前两个字符(即%2s)是否分别在两个指定的字符串中:
设%2s为AB,函数0x00401656判断A是否在“XDSECJQLWARMZ”中,函数0x00401656判断B是否在“VYBFGHIKNOPTU”中,如果不存在跳转到0x0040157E并返回-1。
接下来的函数0x0040163A用来获取字符A在“XDSECJQLWARMZ“中的偏移,比如输入AB分别为”MH“,则函数0x0040163A返回11,然后从该偏移开始(包括偏移)将循环截取后面的字符串并写入内存地址为0x00405018的空间,比如这里会写入”MZXDSECJQLWAR“:
同样,下面也会将以B在字符串”VYBFGHIKNOPTU“中的偏移来循环截取字符串写入内存0x00405026:
接下来将会对后面4组%8s做判断:
这里面有两个函数,分别判断字符串%8s是否在前面截取的字符串中,通过调试,判断出后面四组字符串的输入格式为ABABABAB-ABABABAB-ABABABAB-ABABABAB
接下来是算法的核心部分:
这里总共有四个函数,其中前两个函数用来读取当前字符在指定字符串中的偏移(位置),后面的一个函数0040161A将会根据偏移来判断注册码是否正确,这里关键是对
mov dword ptr[esp+8],00403000的理解,这个位置貌似是一个固定的地址,里面写有一些dword,为了方便查看数据类型,我们用IDA来看看这段数据:
可以看到这段数据是一个数组,进一步分析该函数
可以看出a1是字符在“MZXDSECJQLWAR”中的偏移,a2是字符在“HIKNOPTUVYBFG”中的偏移,然后是计算出在数组00403000中的对应位置,如果是1则返回0。
可以看出00403000是一个13*13的2维数组,在计算出偏移为a1和a2后,会到该数组查询对应[a2][a1]的数据是否为1,注意这里是将a1和a2分别进行了调换。
如下例子:
0 1 2 3 4 5 6 7 8 9 10 11 12
H I K N O P T U V Y B F G
0 M 1 1 1 1 1 0 1 1 1 1 1 1 1
1 Z 1 1 0 0 1 1 1 0 0 0 0 1 1
2 X 0 1 1 1 1 0 1 1 1 1 1 1 1
3 D 1 1 0 0 1 1 1 1 0 1 1 1 1
4 S 1 1 0 0 1 0 1 0 0 1 1 1 1
5 E 1 1 1 1 1 1 1 0 0 1 1 0 0
6 C 1 1 1 1 1 1 1 1 1 1 1 0 0
7 J 0 1 0 1 1 1 1 0 0 0 1 1 1
8 Q 1 1 1 1 0 0 1 1 1 1 1 0 1
9 L 1 0 1 1 1 1 1 1 0 1 1 1 1
10 W 1 0 1 0 0 0 1 1 1 1 1 1 1
11 A 1 1 1 1 1 1 1 1 1 0 1 1 0
12 R 1 1 1 1 1 1 1 0 0 0 0 1 1
最后一个函数0401588用来判断当前字符位置是否由前一个字符位置移动而来。
该函数有四个参数:
参数a1,a2用来保存上一个元素的位置,a3,a4保存当前位置,每次数组元素下移一个位置,比如前面一个是MH(a[0][0]=1 a[0][0]=1),那么目前的就可以是MI(a[0][1]=1 a[1][0]=1),依次类推:XDSECMH-MHZHXHDH-SHSISKSN-ENCNCOCP-CTCUCVCY是随便猜测的一个Key。