第十四章-硬编码序列号寻踪-Part2 首先我来解答一下上一章留下的那个CrackMe。 用OD加载名为mielecrackme1的CrackMe。断在了入口点处,我们单击鼠标右键选择-Searchfor-Name(label)in current module看看该CrackMe使用了哪些API函数。 下面是找到的API函数列表: 其中有几个API函数比较重要,GetWindowTextA:获取用户输入的序列号。lstrcmpA,上一章最后提到的,用于字符串的比较。MessageBoxA:用于显示一条消息,提示是正确或者错误的序列号。 我们可以给这几个API设置断点,当我们输入错误的序列号的时候,就会断下来。但这里我们使用更加简单,快速的做法,我们来看看程序中使用的字符串。 我们通过在反汇编窗口中单击鼠标右键选择-Search for-All referenced text strings打开字符串列表窗口。 我们可以看到上面列表中有提示成功以及失败的字符串。如果我们在该字符串上面双击鼠标左键,就可以来到MessageBoxA调用代码附近。现在我们在”You entered the right password!”字符串上面双击鼠标左键。 来到了比较关键的地方。 首先是GetWindowTextA获取用户输入的序列号,然后lstrcmpA将输入序列号与正确的序列号进行比较,相同的话就MessageBoxA显示”You entered the right password”的提示框,如果不相同就MessageBoxA提示”Maybe,you should try again,it’s sooo easy!!”的提示框。 所以我们给lstrcmpA函数设置一个断点,看看是如何进行比较的。 按F9键运行起来。 我们在弹出的窗口中随意输入一个序列号,例如:这里我们输入989898。 单击Check按钮,就会断在我们刚刚设置的断点处。 我们可以看到OD中显示的参数,进行比较的两个字符串,分别是”989898”和”cannabis”。 我们按F8键单步步过这个API调用。 EAX中存放的返回值为FFFFFFFF,意味着比较的两个字符串不相同。 因为比较的结果不为零,所以零标志位Z不置位。JNZ跳转就会实现。(记住:JNZ当零标志位Z置0跳转,置1不跳转) 跳转实现以后就弹出一个错误消息框。所以,与我们输入序列号进行比较的”cannabis”就是正确的序列号。我们继续运行程序。 单击OK,我们回到主窗口,输入正确的序列号”cannabis”。 单击Check按钮,依然断在了我们设置的断点处。 可以看到待比较的两个字符串是相同的,按F8键单步步过这个API函数。 因为两个字符串是相同的,所以EAX中保存的返回值为0,并且零标志位Z置1。 现在JNZ跳转将不会实现。 我们直接运行程序,将会弹出一个显示序列号正确的消息框。 这就是第13章遗留下的CrackMe。正确的序列号是”cannabis”。 我们再来看一个更加复杂的硬编码的CrackMe(比之前的两个复杂)。 这个CrackMe并不是序列号直接进行比较。用OD加载这个名为”crakmeeasy”的CrackMe。 我们像之前一样查看API列表,该列表中有GetDlgItemTextA,我们给这个函数设置一个断点。 我们在命令栏窗口中输入bp GetDlgItemTextA。 我们现在按F9键运行程序并输入序列号。 随便输入一个错误的序列号 单击Check按钮,断在我们刚刚设置的断点处。 我们来看看堆栈中参数。 这里我们可以注意到Buffer参数:用于保存用户输入的序列号,我们在这个参数上单击鼠标右键选择-Follow in Dump。 这里缓冲区是空的,因为该函数还没有执行,我们选择主菜单项-Debug-Execute till return。 执行到函数返回。 我们按下F7键,返回到主程序代码中。 我们可以看到,缓冲区里面保存了错误的序列号。 这里我们看到了一长串数字字符串。有些人可能会问这是正确的序列号吗?呵呵,我也不知道。 这里EAX保存了401222这个常量地址,该地址指向一个固定的字符串。 单步一行,EAX就等于401222了。 MOVEDX,DWORD PTR DS:[EAX] 等价于: MOVEDX,DWORD PTR DS:[401222] 该指令将401222地址处内容保存到EDX中,OD中的提示窗口中提示为10445678951字符串的首4个字节。 我们按F7键将401222处内容保存EDX中(寄存器中保存的数值和内存中的存放顺序是相反的)。 下一条指令将EDX的内容保存到[EBP-30]堆栈空间中。 OD的提示窗口显示,[EBP-30]在我的机器上是240f9e4,我们在数据窗口中转到该地址。 我们按F7键将EDX的内容保存到[EBP-30]内存单元中。 于是 将常量数字字符串的接下来4个字节保存到EDX中。 OD的显示窗口显示,[EAX+4]的对应的地址为401226,按F7键,接下来的4个字节被保存到EDX中。 然后和之前的赋值一样。 实际上就是将4个字节的内容从一块内存区域拷贝到另一块内存区域。 现在是最后的4个字节的拷贝。 拷贝完毕。 接下来是调用memset,我们在OD中来看看其参数。 这里有(n,c,s)3个值。 s:待填充的内存单元的起始地址 n:需要填充的字节数 c:待填充的值 我们在堆栈中来看看上述参数:以240f9f0为起始地址长度为8的内存单元填充零。 按F8键单步,我们可以看到一240f9f0为起始地址的8个字节的内存区域被填充零了。 接下来调用的是lstrlen函数,用于计算字符串的长度。 堆栈中的内容如下: 是计算起始起始地址为240f0e4的字符串的长度(我们知道这个字符串地址)。 按F8键执行lstrlen,EAX中保存字符串的长度。 我们可以看到长度为0B,即十进制的11,就是常量数字字符串的长度。 这里将EAX的值减去1保存到EDX中,EDX就等于0A了。 接下来将EDX(值为0A)与[EBP - 10](值为0)进行比较。 如果0小于0A,就会跳转到401360。 这一行,将我们输入的错误序列号保存到EAX中,我们按F7键执行,可以看到EAX中保存了错误的序列号”98989898”。 下一条指令,EDX清零。 接下来一行 EAX保存了我们输入的错误序列号的首地址,EDX的初始值为零,现在创建一个循环,EAX + EDX,然后EDX依次递增来获取我们输入序列号的每一个字节。 我们知道MOVSX指令将指定字节保存到EDX中,如果该字节是正数,高位补零,如果该字节为负数高位补1. 这里,将错误序列号的第一个字节保存EDX中,我们单步执行,可以看到EDX值变成了39。 下一条指令是LEA. EDX的值为39,减去14,然后将结果保存到EAX中。 EAX中保存的结果为25。 下一条指令是将EBP-30的值(我的机器为240f9e4)保存到EDX中。 按F7键。 EDX就保存了常量数字字符串的首地址。 我们可以看到ECX被作为一个循环变量初始化为零, 这里我们看到ECX已经被赋值为了零,然后EDX + ECX就指向了常量数字字符串的第一个字节,我们来看看OD解释窗口的信息。 31对应的ASCII码为’1’,为常量数字字符串的第一个字符。 这里就进行比较了 EAX保存了我们输入的错误字符串的第一个字符39减去14的结果,这里为25,EDX保存了常量数字字符串的第一个字节31。 因此,我们可以看到的 CMPEAX,EDX 实际上是 CMP 错误的序列号的第一个字节-14 ,常量数字字符串的第一个字节 CMP 25,31 由于这两个操作数的差值不为零,所以零标志位Z不会置1,JNZ跳转就会实现。 我们输入的是一个错误的序列号,如果输入的是一个正确的序列号的话,那么比较的结果就是正确的。 CMP (正确序列号的第一个字节值-14),31 判断两者相等的条件为: 正确序列号的第一个字节值-14 = 常量数字字符串的第一个字节 所以 正确的序列号的第一个字节值 = 常量数字字符串第一个字节值+ 14 正确的序列号的第一个字节值 = 31 + 14 正确的序列号的第一个字节值 = 45,该ASCII码对应的字符为”E”。 所以序列号的第一个字母为E。 以上字符校验过程重复进行,直到所有字符都校验完毕。 第一个字节值 = 常量数字字符串第一个字节值+14 第二个字节值 = 常量数字字符串第二个字节值+14 第三个字节值 = 常量数字字符串第三个字节值+14 依次类推。 我们用这个公式来计算序列号(正确序列号字节值 = 常量数字字符串对应字节值 + 14)的每个字符。 31 +14 = 45 对应字符 E
30 + 14 = 44 对应字符 D
34 + 14 = 48 对应字符 H
34 + 14 = 48 对应字符 H
35 + 14 = 49 对应字符 I
36 + 14 = 4A 对应字符 J
37 + 14 = 4B 对应字符 K
38 + 14 = 4C 对应字符 L
39 + 14 = 4D 对应字符 M
35 + 14 = 49 对应字符 I
31 + 14 = 45 对应字符 E 因此,正确的序列号为: EDHHIJKLMIE 我们删除之前设置过的断点,然后在主窗口中输入正确的序列号。 单击check按钮。 这个CrackMe就完成了。 这个CrackMe相比之前的要复杂一点,但是我觉得稍加练习也是可以很容易的解决它的。 好了,这里有一个名为Splish的CrackMe,大家尝试一下找到它的序列号。
本系列文章汉化版转载看雪论坛
感谢原作者:RicardoNarvaja(西班牙人)
感谢热心翻译的朋友: 1~3章译者:BGCoder 4~58章译者:安于此生
全集配套程序下载地址:
|