Shark恒 发表于 2015-1-20 16:12

使用OllyDbg从零开始Cracking 第十四章-硬编码序列号寻踪-Part2

                      第十四章-硬编码序列号寻踪-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:等价于:MOVEDX,DWORD PTR DS: 该指令将401222地址处内容保存到EDX中,OD中的提示窗口中提示为10445678951字符串的首4个字节。我们按F7键将401222处内容保存EDX中(寄存器中保存的数值和内存中的存放顺序是相反的)。下一条指令将EDX的内容保存到堆栈空间中。 OD的提示窗口显示,在我的机器上是240f9e4,我们在数据窗口中转到该地址。我们按F7键将EDX的内容保存到内存单元中。于是将常量数字字符串的接下来4个字节保存到EDX中。OD的显示窗口显示,的对应的地址为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)与(值为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(西班牙人) 原作者个人主页:http://www.ricardonarvaja.info/
感谢热心翻译的朋友:1~3章译者:BGCoder4~58章译者:安于此生
全集配套程序下载地址:链接: http://pan.baidu.com/s/1eQzTWfo 密码: vytv


hackysh 发表于 2022-2-8 15:54

这2节内容, 得多学习一下

别管我了行 发表于 2022-3-1 03:32

weiran324 发表于 2022-3-31 23:28

学习,,,,

行行行行行行 发表于 2022-4-4 21:45


[快捷回复]-感谢楼主热心分享!

MoeRay 发表于 2022-4-5 00:58


[快捷回复]-感谢楼主热心分享!

曾经沧海 发表于 2022-11-15 23:03

比较实用,谢谢分享!

Wayne 发表于 2022-11-16 09:55

曾经沧海 发表于 2022-11-17 22:16

感谢分享宝贵经验

曾经沧海 发表于 2023-4-3 09:53

过来和大神学习来了!
页: [1] 2
查看完整版本: 第十四章-硬编码序列号寻踪-Part2