pk8900 发表于 2017-12-17 23:20

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

本帖最后由 pk8900 于 2017-12-17 23:22 编辑

  今晚,继续研究 了【适合破解新手的160个crackme练手】,本文内容为第49个CrackMe: DueList.4.exe,虽然很简单,但论坛没有关于这个CrackMe的帖子,于是写了这篇帖子,分享一下我的分析过程及注册机编写方法。
【crackme简介】
       下载地址:http://pan.baidu.com/share/link?shareid=541269&uk=4146939145
       MASM32 / TASM32编写,无壳,是一个用户名序列号式验证方式,输入用户名,序列号点击CHECK按钮,有提示英文:Your registration info is invalid... Note that most of the special chars may raise registration problems!。
      分析工具:X64dbg
【crackme截图】

【算法分析过程】
       这个难度不大,按星级估计算是1星的吧,因为有提示字符,可以直接从字符串入手,找到关键代码位置如下:
00401127 | 6A 00                     | push 0x0                               | LONG_PTR lParam = 0x0
00401129 | 6A 00                     | push 0x0                               | UINT_PTR wParam = 0x0
0040112B | 6A 0E                     | push 0xE                               | UINT Msg = WM_GETTEXTLENGTH
0040112D | 6A 03                     | push 0x3                               | int nIDDlgItem = 0x3
0040112F | FF 75 08                  | push dword ptr ss:            | HANDLE hDlg
00401132 | E8 41 02 00 00            | call <duelis.SendDlgItemMessageA>      | SendDlgItemMessageA
00401137 | A3 AF 21 40 00            | mov dword ptr ds:, eax       |
0040113C | 83 F8 00                  | cmp eax, 0x0                           |
0040113F | 0F 84 D5 00 00 00         | je duelis.40121A                     |
00401145 | 83 F8 08                  | cmp eax, 0x8                           |
00401148 | 0F 8F CC 00 00 00         | jg duelis.40121A                     | 用户名<=8位
0040114E | 8B F0                     | mov esi, eax                           |
00401150 | 6A 00                     | push 0x0                               | LONG_PTR lParam = 0x0
00401152 | 6A 00                     | push 0x0                               | UINT_PTR wParam = 0x0
00401154 | 6A 0E                     | push 0xE                               | UINT Msg = WM_GETTEXTLENGTH
00401156 | 6A 04                     | push 0x4                               | int nIDDlgItem = 0x4
00401158 | FF 75 08                  | push dword ptr ss:            | HANDLE hDlg
0040115B | E8 18 02 00 00            | call <duelis.SendDlgItemMessageA>      | SendDlgItemMessageA
00401160 | 83 F8 00                  | cmp eax, 0x0                           |
00401163 | 0F 84 B1 00 00 00         | je duelis.40121A                     |
00401169 | 3B F0                     | cmp esi, eax                           | 序列号和用户名位数必须相同
0040116B | 0F 85 A9 00 00 00         | jne duelis.40121A                      |
00401171 | 68 60 21 40 00            | push duelis.402160                     | LONG_PTR lParam = 0x402160 用户名变量
00401176 | 6A 08                     | push 0x8                               | UINT_PTR wParam = 0x8
00401178 | 6A 0D                     | push 0xD                               | UINT Msg = WM_GETTEXT
0040117A | 6A 03                     | push 0x3                               | int nIDDlgItem = 0x3
0040117C | FF 75 08                  | push dword ptr ss:            | HANDLE hDlg
0040117F | E8 F4 01 00 00            | call <duelis.SendDlgItemMessageA>      | SendDlgItemMessageA
00401184 | 68 79 21 40 00            | push duelis.402179                     | LONG_PTR lParam = 0x402179 序列号变量
00401189 | 6A 10                     | push 0x10                              | UINT_PTR wParam = 0x10
0040118B | 6A 0D                     | push 0xD                               | UINT Msg = WM_GETTEXT
0040118D | 6A 04                     | push 0x4                               | int nIDDlgItem = 0x4
0040118F | FF 75 08                  | push dword ptr ss:            | HANDLE hDlg
00401192 | E8 E1 01 00 00            | call <duelis.SendDlgItemMessageA>      | SendDlgItemMessageA
00401197 | B9 FF FF FF FF            | mov ecx, 0xFFFFFFFF                  |
0040119C | 41                        | inc ecx                              |
0040119D | 0F BE 81 60 21 40 00      | movsx eax, byte ptr ds:| ecx+402160:"pkabcd"
004011A4 | 83 F8 00                  | cmp eax, 0x0                           | 用户名字符不能为空
004011A7 | 74 32                     | je duelis.4011DB                     |
004011A9 | BE FF FF FF FF            | mov esi, 0xFFFFFFFF                  |
004011AE | 83 F8 41                  | cmp eax, 0x41                        | 41:'A'
004011B1 | 7C 67                     | jl duelis.40121A                     |
004011B3 | 83 F8 7A                  | cmp eax, 0x7A                        | 7A:'z'
004011B6 | 77 62                     | ja duelis.40121A                     | A到Z之间的字符
004011B8 | 83 F8 5A                  | cmp eax, 0x5A                        | 5A:'Z'
004011BB | 7C 03                     | jl duelis.4011C0                     |
004011BD | 83 E8 20                  | sub eax, 0x20                        | 小写转为大写
004011C0 | 46                        | inc esi                              | 增加计数器,0开始
004011C1 | 0F BE 96 17 20 40 00      | movsx edx, byte ptr ds:| esi+402017:"A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9"
004011C8 | 3B C2                     | cmp eax, edx                           |
004011CA | 75 F4                     | jne duelis.4011C0                      | 循环查找用户名字符在字符串中对应的位置
004011CC | 0F BE 86 3C 20 40 00      | movsx eax, byte ptr ds:| esi+40203C:"SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF"
004011D3 | 89 81 94 21 40 00         | mov dword ptr ds:, eax   | 用上一循环查找的位置取字符串2中的字符,并保存
004011D9 | EB C1                     | jmp duelis.40119C                      |
004011DB | FF 35 AF 21 40 00         | push dword ptr ds:         |
004011E1 | 68 94 21 40 00            | push duelis.402194                     | 402194:加密处理得到的注册码
004011E6 | 68 79 21 40 00            | push duelis.402179                     | 402179:我们输入的注册码"123456"
004011EB | E8 54 00 00 00            | call <duelis.sub_401244>               | 比较
004011F0 | 83 F8 01                  | cmp eax, 0x1                           |
004011F3 | 0F 84 DE FE FF FF         | je duelis.4010D7                     | 跳去正确的提示信息。
004011F9 | EB 1F                     | jmp duelis.40121A                      |
004011FB | 83 7D 10 01               | cmp dword ptr ss:, 0x1       |
004011FF | 0F 84 22 FF FF FF         | je duelis.401127                     |
      经过对上段代码下断分析,程序的注册算法为:SendDlgItemMessageA 函数参数UINT Msg = WM_GETTEXTLENGTH,取用户名长度,不能超过8位,注册码长度必须和用户名长度相同。
然后调用SendDlgItemMessageA函数,参数UINT Msg = WM_GETTEXT,来获输入的用户名和注册码字符串,对输入的用户名逐个字符进行处理和判断,字符ASC值不能小于‘A’,不能大于‘z’,大于'Z'的话减去0x20,相当于小写转大写,当然ASCII表中Z后的6个字符是个例外,然后在字符串1("A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9")中查找用户名字符的位置,跟据这个位置取第二个字符串("SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF")中相应位置的字符,并组成最终的正确注册码,接下来就是比较注册码,并跳转到相应的提示信息。
【注册机编写】
   收集了以上信息后,就可以着手编写注册机了。
      C++代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <string>
using namespace std;
void main()
{
      char * yourName;
      char * serial;
      string key1 = "A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9";
      char * key2 = "SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF";
      yourName = new char;
      memset(yourName, 0, 260);
      serial = new char;
      memset(serial, 0, 260);
      cout << "Enter your name:";
      gets(yourName);
      if (strlen(yourName) == 0 || strlen(yourName)>8)
      {
                cout << "用户名必须小于等于8位!" << endl;
                system("pause");
                return;
      }
      for (unsigned int x = 0; x < strlen(yourName); x++)
      {
                if (yourName<'A' || yourName>'z')
                {
                        cout << "用户名必须为A-z之间的字符!" << endl;
                        system("pause");
                        return;
                }
                if (yourName > 'Z')
                        yourName -= 0x20;
                serial = key2)];
      }
cout<<"your Code is:"<<serial<<endl;
system("pause");
附注册成功截图:

papadave 发表于 2017-12-18 14:22

厉害了我的哥

vc123 发表于 2017-12-18 16:21

不错,谢谢分享,看看

lovejingqing 发表于 2017-12-18 19:18

不错,谢谢分享,看看

chen123456 发表于 2017-12-20 11:47

就算是有一定基础的,看看还是有收获的。

ziye 发表于 2017-12-20 16:11

厉害了,大神。。。。。。。。。。。。。

wenwen520 发表于 2019-4-20 09:20

这个题的难度没有上一个题的难度大
页: [1]
查看完整版本: [反汇编练习] 160个CrackMe之049(DueList.4.exe)算法分析及注册机编写