吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9771|回复: 20
收起左侧

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

  [复制链接]
pk8900 发表于 2017-12-28 20:24
本帖最后由 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截图】
Image 001.png
【算法部分】
首先用Ldr载入,找到按钮事件地址:方法可以参照下图:
Image 002.png
找到事件地址下断点,中断后跟踪,代码如下:
验证注册流程一:检查输入的用户名长度,不为空。
[Asm] 纯文本查看 复制代码
00427B6A | 8B 45 FC                  | mov eax, dword ptr ss:[ebp-0x4]        | [ebp-4]:"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:[ebp-0x4]        |
00427B78 | 8B 83 EC 01 00 00         | mov eax, dword ptr ds:[ebx+0x1EC]      |
00427B7E | E8 0D E2 FE FF            | call ekh.1.415D90                      |
00427B83 | 8B 45 FC                  | mov eax, dword ptr ss:[ebp-0x4]        | [ebp-4]:"12345678"
00427B86 | 50                        | push eax                               |
00427B87 | 8D 55 F8                  | lea edx, dword ptr ss:[ebp-0x8]        |
00427B8A | 8B 83 DC 01 00 00         | mov eax, dword ptr ds:[ebx+0x1DC]      |
00427B90 | E8 FB E1 FE FF            | call ekh.1.415D90                      |
00427B95 | 8B 45 F8                  | mov eax, dword ptr ss:[ebp-0x8]        |
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 !"

验证注册流程二:关键算法部分:共两个循环加密部分,先看第一部分:
[Asm] 纯文本查看 复制代码
00427A56 | 8B 45 FC                  | mov eax, dword ptr ss:[ebp-0x4]        | 用户名
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:[ebp-0x4]        | [ebp-4]:"pk8900"
00427A6E | 0F B6 4C 11 FF            | movzx ecx, byte ptr ds:[ecx+edx-0x1]   | 取用户名 +循环计数器位字符
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:[0x428880]       | 加密字符串1 &"LANNYDIBANDINGINANAKEKHYANGNGENTOT"
00427A85 | 0F B6 54 11 FF            | movzx edx, byte ptr ds:[ecx+edx-0x1]   | 取计算数 位置字符
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:[ebp-0x10]       |
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:[ebp-0x10]       | [ebp-10]:"1792442052"转十字制字符

这部分代码,取我们输入的用户名长度为循环次数,逐个取用户名字符加入累加值,左移8位,然后逐个取"LANNYDIBANDINGINANAKEKHYANGNGENTOT"字符累加,如果是负数则乘-1转为正数,循环完成后得到的值,与0x12345678异或,得到一个32位的数值。然后进行一下加密循环:
[Asm] 纯文本查看 复制代码
00427AAB | E8 44 E9 FD FF            | call <ekh.1.sub_4063F4>                |
00427AB0 | 8B 45 F0                  | mov eax, dword ptr ss:[ebp-0x10]       | [ebp-10]:"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:[0x427B3C]     |
00427ACE | 8A 92 84 88 42 00         | mov dl, byte ptr ds:[edx+0x428884]     | edx+428884:"LANNY5646521"
00427AD4 | 8D 45 F0                  | lea eax, dword ptr ss:[ebp-0x10]       |
00427AD7 | E8 FC BB FD FF            | call <ekh.1.sub_4036D8>                | 取字符串:第余数位
00427ADC | 8B 55 F0                  | mov edx, dword ptr ss:[ebp-0x10]       |
00427ADF | 8D 45 F4                  | lea eax, dword ptr ss:[ebp-0xC]        |
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:[ebp-0xC]        | [ebp-C]:"N5LNYYN54A"

这部分是将上个循环得到的数值转为字符,取长度为循环次数,每次除10取余,根据余数取字符串"LANNY5646521"中相应位的字符,组成一个字符串,就是正确的序列号。
算法部分分析完成,根据以上算法编写注册机代码如下:
[C++] 纯文本查看 复制代码
#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[260];
        memset(serial, 0, 260);
        yourName = new char[260];
        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[x];
                key_tmp = key_tmp << 8;
                key_tmp |= key1[x];
                if (key_tmp<0)
                {
                        key_tmp *= -1;
                }
        }
        key_tmp ^= 0x12345678;
        long tmp1=0;
        while (key_tmp)
        {
                serial [tmp1] = key2[key_tmp % 10];
                tmp1++;
                key_tmp /= 10;
        }
        cout << "序列号为:" << serial << endl;

system("pause");

成功测试注册用户名:52pojie.cn 序列号:Y55565NL4A
Image 003.png

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

免费评分

参与人数 4威望 +1 吾爱币 +13 热心值 +4 收起 理由
Poner + 1 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
565400154 + 1 + 1 我很赞同!
朱朱你堕落了 + 1 + 1 厉害了!膜拜楼主。
ricroon + 1 + 1 看了楼主几篇文章,自己还是做不出来,这就是实力的差距,工作之余慢慢研究

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 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

谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 14:31

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表