160个CrackerMe之34
本帖最后由 Martin 于 2015-6-8 10:46 编辑160个CrackerMe之34练手一、开篇看了这么多大牛的教程,我也来一个简单的教程,仅供大家学习,交流如果有不对的地方请大家指教。这次分析的是160个CrackerMe的第34个程序,首先我们先打开程序观察一下程序运行状况,以及有什么特征。并没有让你输入注册信息的,比如注册码等地方,File菜单下面就有一个exit退出,Help里面就是一个About菜单。也就是单纯的靠输入注册码是根本就找不到突破口,好那么这样我们就将程序载入进去看一下。载入程序后,我们就可以清晰的看到一个方法名称叫CreateFileA创建文件。我们可以联想到一个问题就是这个程序是一个从文件读取秘钥的,好的,这样我们就找到了一个可以突破的口。接下来我们就要看一下这个文件名字和路径到底是什么。单步跟踪下。我们可以看到堆栈中出现 0012FFA8004020D7|FileName ="CRACKME3.KEY"
也就是这个FileName叫做CRACKME3.KEY,这是我们就能想到这个文件创建在程序的根目录下面,文件名字叫CRACKME3.KEY。这是我们不用着急去创建这个文件我们单步跟踪下。 这就说明不存在该文件。这是下面的jmp直接跳到了读取文件以及对文件内容的判断的方法。 这里面的40103C这里的Call是调用显示窗体上面的文字内容,这里显示的是CrackMe v3.0- Uncrcaked 这个就是图一上面的标题。接下来我们就来创建一个KEY文件,看一下运行情况。单步走一下我们可以清晰的看到跳过验证文件是否存在的地方。 这时候我们就往下拉就可以看到文件读取的方法,ReadFile函数。我们在文件KEY中输入了123456789这是还是但不运行,看一下读取的数据。 在这里有一个比较Cmp 18也就是说这个注册码是由18个组成的。如果不等于18 就会跳转到上面40103C未注册的位置。这时候我们就将Key文件里面的123456789变到123456789123456789这样就是18个组成,接下来我们就继续从新单步走一下试一下,这时候就发现这个jnz就没有跳转到上面未注册的地方。这是就会进入到注册码验证的地方如下图所示: 这是地址402008位置存放的是字符串,我们在数据中查看一下。 继续跟踪我们先来跟踪下最后的注册码到底是多少。 我们看到将402008压入到堆栈中,这时候我们就应该想到这个Call有些可疑,有可能是对注册码进行加密验证的地方,这时候我们F7跟进去看一下。果然是注册码加密的过程,整个加密的过程很简单。下面是算法分析的过程。
00401311/$33C9 xor ecx,ecx ;清空ecx
00401313|.33C0 xor eax,eax ;清空eax
00401315|.8B7424 04 mov esi,dword ptr ss: ;将123456789123456789给了esi
00401319|.B3 41 mov bl,0x41 ;将0x41给了寄存器bl
0040131B|>8A06 /mov al,byte ptr ds: ;一位一位的取出秘钥的内容
0040131D|.32C3 |xor al,bl ;异或每一个秘钥其中一个字节与bl
0040131F|.8806 |mov byte ptr ds:,al ;把上次内容放回到秘钥中
00401321|.46 |inc esi ;增加数组位数
00401322|.FEC3 |inc bl ;从0x41每次循环增加1
00401324|.0105 F9204000 |add dword ptr ds:,eax ;首先从0开始加最近一次xor后的内容相加。
0040132A|.3C 00 |cmp al,0x0 ;判断al是不是为0
0040132C|.74 07 |je short Cruehead.00401335 ;如果等0就跳走
0040132E|.FEC1 |inc cl ;增加cl,计数器,代表有多少个参与了计算
00401330|.80FB 4F |cmp bl,0x4F ;判断是不是等于4F,4f-41=E,说名只有14个参与计算
00401333|.^ 75 E6 \jnz short Cruehead.0040131B
00401335|>890D 49214000 mov dword ptr ds:,ecx ;这里应该是14=E
0040133B\.C3 retn
这是我们看到了4020F9的内容是657,这时候们来继续跟踪下,
跳出来之后看下这段代码
00401079|.8135 F9204000>xor dword ptr ds:,0x12345678 ;这里是将加完的值异或12345678
00401083|.83C4 04 add esp,0x4
00401086|.68 08204000 push Cruehead.00402008
0040108B|.E8 AC020000 call Cruehead.0040133C ;这里是获取14-18的秘钥内容
00401090|.83C4 04 add esp,0x4
00401093|.3B05 F9204000 cmp eax,dword ptr ds: ;计算出来的值与后四位进行比较
00401099 0F94C0 sete al ;如果相等就为1不相等为0
0040109C|.50 push eax
0040109D|.84C0 test al,al
0040109F|.^ 74 96 je short Cruehead.00401037 ;跳转到未注册位置
004010A1|.68 0E214000 push Cruehead.0040210E ;CrackMe v3.0
004010A6|.E8 9B020000 call Cruehead.00401346 ;这里是已注册的Title
首先先对累加后的值进行与0x1234578异或之后再与秘钥中的后四位进行比较,相等就通过,否则就失败。 这是后我们看到eax=39383736对应ascii码就是6789,计算后的值是1234502F,这时候我们可以用UE改一下两个字节的值, 改成这样之后直接运行程序我们就可以看到这个。啊哈,成功了。 变成了已注册。这时候我们就开始动手写注册机。C#写的一个简单的容易理解的。
class Program {
/// <summary>
/// 代码这样写纯属为了更好地理解,这里代码比较简陋仅供提供思路
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("请输入14个数字");
string RegKey = Console.ReadLine();
int key = 0x41; //这里对应汇编代码中的 mov bl,0x41
int key1 = 0x12345678; //这里对应汇编代码中的 xor dword ptr ds:,0x12345678
int AddSorurce = 0;
for (int i = 0; i < RegKey.Length; i++)//核心算法位置
{
AddSorurce += key ^ RegKey;
key++;
}
AddSorurce = AddSorurce ^ key1; //xor dword ptr ds:,0x12345678
Console.WriteLine("{0}", AddSorurce); //注意这里出来的是10进制的要转变成16进制就好了。
Console.ReadLine();
}
}
运行结果: 好吧,分析到此吧,此前还有一个简单教程,不是很难,没放出来稍后会放出来,160之29的cosh程序。喜欢的就加点分。毕竟写这个真不容易,此上皆为个人分析,如有雷同,纯属巧合。
支持下!学习了! 非常感谢如此细心教学 {:301_1003:}学习了,谢谢分享! 继续支持楼主 期待你的下一篇文章 楼主加油
来看看思路的说!!!{:301_1000:}
页:
[1]