pk8900 发表于 2017-12-28 20:24

[反汇编练习] 160个CrackMe之054(eKH.1.exe)算法分析及注册机编写

本帖最后由 pk8900 于 2017-12-28 20:34 编辑

      【适合破解新手的160个crackme练手】第54个eKH.1.exe,这个比较简单,前两个五星级的可以说难度很大,第52个用了三天多时间,完美反推写出注册机,参考帖子(https://www.52pojie.cn/thread-677861-1-1.html),第53个算法是弄清了,是64位的奇偶较验,用注册机穷举根本不现实,用了一星期的时间,也没有想到简便的算法,等注册机研究成功后再发贴了,今天就分享一下这个Crackme 054的算法及注册机过程。
【crackme简介】
       下载地址:http://pan.baidu.com/share/link?shareid=541269&uk=4146939145
       Borland Delphi 3.0编写,无壳,是一个用户名+序列号式验证方式,有提示文字。
标注为?,估计难度为1星。
工具:X64dbg,Ldr,注册编写:VS2013
【crackme截图】

【算法部分】
首先用Ldr载入,找到按钮事件地址:方法可以参照下图:

找到事件地址下断点,中断后跟踪,代码如下:
验证注册流程一:检查输入的用户名长度,不为空。
00427B6A | 8B 45 FC                  | mov eax, dword ptr ss:      | :"pk8900"用户名
00427B6D | E8 3E BC FD FF            | call ekh.1.4037B0                      | 取长度
00427B72 | 48                        | dec eax                              |
00427B73 | 7C 30                     | jl ekh.1.427BA5                        | 跳去失败
00427B75 | 8D 55 FC                  | lea edx, dword ptr ss:      |
00427B78 | 8B 83 EC 01 00 00         | mov eax, dword ptr ds:      |
00427B7E | E8 0D E2 FE FF            | call ekh.1.415D90                      |
00427B83 | 8B 45 FC                  | mov eax, dword ptr ss:      | :"12345678"
00427B86 | 50                        | push eax                               |
00427B87 | 8D 55 F8                  | lea edx, dword ptr ss:      |
00427B8A | 8B 83 DC 01 00 00         | mov eax, dword ptr ds:      |
00427B90 | E8 FB E1 FE FF            | call ekh.1.415D90                      |
00427B95 | 8B 45 F8                  | mov eax, dword ptr ss:      |
00427B98 | 5A                        | pop edx                              |
00427B99 | E8 82 FE FF FF            | call ekh.1.427A20                      | 关键算法
00427B9E | 3D 4E 61 BC 00            | cmp eax, 0xBC614E                      | 成功比较值:0xBC614E
00427BA3 | 7D 1E                     | jge ekh.1.427BC3                     |
00427BA5 | 6A 00                     | push 0x0                               |
00427BA7 | 68 08 7C 42 00            | push ekh.1.427C08                      | 427C08:"ERROR"
00427BAC | 68 10 7C 42 00            | push ekh.1.427C10                      | 427C10:"Wrong Serial Number !"
验证注册流程二:关键算法部分:共两个循环加密部分,先看第一部分:
00427A56 | 8B 45 FC                  | mov eax, dword ptr ss:      | 用户名
00427A59 | E8 52 BD FD FF            | call ekh.1.4037B0                      | 取长度
00427A5E | 8B F0                     | mov esi, eax                           |
00427A60 | 85 F6                     | test esi, esi                        |
00427A62 | 7E 3C                     | jle ekh.1.427AA0                     |
00427A64 | B8 01 00 00 00            | mov eax, 0x1                           |
00427A69 | 8B D0                     | mov edx, eax                           | 循环部分 起点
00427A6B | 8B 4D FC                  | mov ecx, dword ptr ss:      | :"pk8900"
00427A6E | 0F B6 4C 11 FF            | movzx ecx, byte ptr ds:   | 取用户名 +循环计数器位字符
00427A73 | 03 D9                     | add ebx, ecx                           | EBX累加
00427A75 | 71 05                     | jno ekh.1.427A7C                     |
00427A77 | E8 B4 AF FD FF            | call <ekh.1.sub_402A30>                |
00427A7C | C1 E3 08                  | shl ebx, 0x8                           | 左移 8位
00427A7F | 8B 0D 80 88 42 00         | mov ecx, dword ptr ds:       | 加密字符串1 &"LANNYDIBANDINGINANAKEKHYANGNGENTOT"
00427A85 | 0F B6 54 11 FF            | movzx edx, byte ptr ds:   | 取计算数 位置字符
00427A8A | 0B DA                     | or ebx, edx                            | 累加
00427A8C | 85 DB                     | test ebx, ebx                        |
00427A8E | 7D 0C                     | jge ekh.1.427A9C                     | 如果变负数则 乘 -1,转为正数
00427A90 | 6B D3 FF                  | imul edx, ebx, 0xFFFFFFFF            |
00427A93 | 71 05                     | jno ekh.1.427A9A                     |
00427A95 | E8 96 AF FD FF            | call <ekh.1.sub_402A30>                |
00427A9A | 8B DA                     | mov ebx, edx                           |
00427A9C | 40                        | inc eax                              | 累加计数器
00427A9D | 4E                        | dec esi                              |
00427A9E | 75 C9                     | jne ekh.1.427A69                     | 下一循环
00427AA0 | 81 F3 78 56 34 12         | xor ebx, 0x12345678                  | 异或 0x12345678
00427AA6 | 8D 55 F0                  | lea edx, dword ptr ss:       |
00427AA9 | 8B C3                     | mov eax, ebx                           |
00427AAB | E8 44 E9 FD FF            | call <ekh.1.sub_4063F4>                |
00427AB0 | 8B 45 F0                  | mov eax, dword ptr ss:       | :"1792442052"转十字制字符
这部分代码,取我们输入的用户名长度为循环次数,逐个取用户名字符加入累加值,左移8位,然后逐个取"LANNYDIBANDINGINANAKEKHYANGNGENTOT"字符累加,如果是负数则乘-1转为正数,循环完成后得到的值,与0x12345678异或,得到一个32位的数值。然后进行一下加密循环:
00427AAB | E8 44 E9 FD FF            | call <ekh.1.sub_4063F4>                |
00427AB0 | 8B 45 F0                  | mov eax, dword ptr ss:       | :"1792442052"转十字制字符
00427AB3 | E8 F8 BC FD FF            | call ekh.1.4037B0                      |
00427AB8 | 8B F0                     | mov esi, eax                           | 得到长度,进行循环
00427ABA | 85 F6                     | test esi, esi                        |
00427ABC | 7E 38                     | jle ekh.1.427AF6                     |
00427ABE | 8B C3                     | mov eax, ebx                           |
00427AC0 | B9 0A 00 00 00            | mov ecx, 0xA                           | A:'\n'
00427AC5 | 99                        | cdq                                    |
00427AC6 | F7 F9                     | idiv ecx                               | 除0xA(10)除余数
00427AC8 | 62 15 3C 7B 42 00         | bound edx, qword ptr ds:   |
00427ACE | 8A 92 84 88 42 00         | mov dl, byte ptr ds:   | edx+428884:"LANNY5646521"
00427AD4 | 8D 45 F0                  | lea eax, dword ptr ss:       |
00427AD7 | E8 FC BB FD FF            | call <ekh.1.sub_4036D8>                | 取字符串:第余数位
00427ADC | 8B 55 F0                  | mov edx, dword ptr ss:       |
00427ADF | 8D 45 F4                  | lea eax, dword ptr ss:      |
00427AE2 | E8 D1 BC FD FF            | call <ekh.1.sub_4037B8>                |
00427AE7 | 8B C3                     | mov eax, ebx                           |
00427AE9 | B9 0A 00 00 00            | mov ecx, 0xA                           | A:'\n'
00427AEE | 99                        | cdq                                    |
00427AEF | F7 F9                     | idiv ecx                               |
00427AF1 | 8B D8                     | mov ebx, eax                           |
00427AF3 | 4E                        | dec esi                              |
00427AF4 | 75 C8                     | jne ekh.1.427ABE                     |
00427AF6 | 8B 45 F4                  | mov eax, dword ptr ss:      | :"N5LNYYN54A"
这部分是将上个循环得到的数值转为字符,取长度为循环次数,每次除10取余,根据余数取字符串"LANNY5646521"中相应位的字符,组成一个字符串,就是正确的序列号。
算法部分分析完成,根据以上算法编写注册机代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

void main()
{
      long key_tmp = 0;
      char * key1 = "LANNYDIBANDINGINANAKEKHYANGNGENTOT";   //固定值,用于加密
      char * key2 = "LANNY5646521";   //固定值,用于加密
      char * yourName;
      char * serial=new char;
      memset(serial, 0, 260);
      yourName = new char;
      memset(yourName, 0, 260);
      cout << "输入用户名:";
      gets(yourName);
      if (strlen(yourName) <= 0)
      {
                cout << "用户名不能为空" << endl;
                return;
      }
      for (unsigned int x = 0; x < strlen(yourName); x++)
      {
                key_tmp += yourName;
                key_tmp = key_tmp << 8;
                key_tmp |= key1;
                if (key_tmp<0)
                {
                        key_tmp *= -1;
                }
      }
      key_tmp ^= 0x12345678;
      long tmp1=0;
      while (key_tmp)
      {
                serial = key2;
                tmp1++;
                key_tmp /= 10;
      }
      cout << "序列号为:" << serial << endl;

system("pause");
成功测试注册用户名:52pojie.cn 序列号:Y55565NL4A


分析过程有不对或不到位的地方,欢迎大家回贴交流,共同探讨。

pk8900 发表于 2017-12-28 20:52

ricroon 发表于 2017-12-28 20:46
对了上次下载了那个crackme的chm,avg报毒,在虚拟机里面打开chm下载了几个出来,没有报毒,可能是几个有病 ...

应该不会有病毒,毕竟很多大家都尝试过,不会有病毒和暗桩,适合练手,杀毒软件报的话可添加信任。

pk8900 发表于 2017-12-28 20:49

ricroon 发表于 2017-12-28 20:43
非常感谢,一登陆就看到了楼主的续作,收藏先

我也是打算从这160个Crackme开始,一点一点学习逆向和C++,学习逆向不能激进,太高深的东西只能等一点一点积累了,加油,兄弟,业余的不一定就比专业的差。

Zhenwu1080 发表于 2017-12-28 20:39

看不懂呀

ricroon 发表于 2017-12-28 20:43

非常感谢,一登陆就看到了楼主的续作,收藏先

ricroon 发表于 2017-12-28 20:46

对了上次下载了那个crackme的chm,avg报毒,在虚拟机里面打开chm下载了几个出来,没有报毒,可能是几个有病毒特征?

行者无涯 发表于 2017-12-28 21:54

行者无涯 发表于 2017-12-28 21:55

565400154 发表于 2017-12-29 10:34

谢谢楼主!!

Listen 发表于 2017-12-29 16:09


谢谢楼主分享
页: [1] 2 3
查看完整版本: [反汇编练习] 160个CrackMe之054(eKH.1.exe)算法分析及注册机编写