吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5399|回复: 14
收起左侧

[原创] [反汇编练习] 160个CrackMe之154(The_q.2)算法分析及注册机编写

  [复制链接]
pk8900 发表于 2018-3-10 12:08
本帖最后由 pk8900 于 2018-3-10 12:15 编辑

    经过半年多的断断续续的研究 【适合破解新手的160个crackme练手】已经进行到第154个,还有几个就要进行完了,今天把这个Crackme的算法分析写一下,因为论坛里没有搜索到详细分析的帖子。
【crackme简介】
       下载地址1:https://pan.baidu.com/s/1cySNkj9uENG_ppK80BmjUQ 密码:8d77
        MASM32 / TASM32编写,无壳,点击help菜单下Register,是一个Name+Code验证方式,界面两个文本框,OK按钮和Cancel按钮。【初试】在Crackme中输入任意用户名和序列号,点OK按钮,没有反应,估计只能正确时才会有提示。
      分析工具:IDA + X64dbg,注册机编写:VS2013
【crackme截图】
Image 1.png
【算法分析过程】
X64dbg中载入,搜索字符串,发现:"         C00L !! U found a correct Serial ! =)\n\r Tell Me how by e-mail to : Phrozen_q@cyberdude.com ",转到代码位置,发现如下代码:
[Asm] 纯文本查看 复制代码
004012C9 | E8 52 01 00 00               | call <the_q..GetDlgItem>                             |
004012CE | 68 A9 21 40 00               | push the_q..4021A9                                   |
004012D3 | 6A 28                        | push 0x28                                            |
004012D5 | 6A 0D                        | push 0xD                                             |
004012D7 | 50                           | push eax                                             |
004012D8 | E8 73 01 00 00               | call <the_q..SendMessageA>                           |
004012DD | A2 D1 21 40 00               | mov byte ptr ds:[0x4021D1], al                       |
004012E2 | 3C 00                        | cmp al, 0x0                                          |
004012E4 | 74 67                        | je the_q..40134D                                     |
004012E6 | 90                           | nop                                                  |
004012E7 | 90                           | nop                                                  |
004012E8 | 90                           | nop                                                  |
004012E9 | 90                           | nop                                                  |
004012EA | 3C 08                        | cmp al, 0x8                                          |
004012EC | 73 09                        | jae the_q..4012F7                                    |
004012EE | 90                           | nop                                                  |
004012EF | 90                           | nop                                                  |
004012F0 | 90                           | nop                                                  |
004012F1 | 90                           | nop                                                  |
004012F2 | E8 5F 00 00 00               | call <the_q..sub_401356>                             |
004012F7 | 6A 00                        | push 0x0                                             |
004012F9 | 6A 00                        | push 0x0                                             |
004012FB | 6A 66                        | push 0x66                                            |
004012FD | FF 75 08                     | push dword ptr ss:[ebp+0x8]                          |
00401300 | E8 21 01 00 00               | call <the_q..GetDlgItemInt>                          |
00401305 | A3 D2 21 40 00               | mov dword ptr ds:[0x4021D2], eax                     |
0040130A | 3C 00                        | cmp al, 0x0                                          |
0040130C | 74 3F                        | je the_q..40134D                                     |
0040130E | 90                           | nop                                                  |
0040130F | 90                           | nop                                                  |
00401310 | 90                           | nop                                                  |
00401311 | 90                           | nop                                                  |
00401312 | E8 5E 00 00 00               | call <the_q..sub_401375>                             |
00401317 | E8 A5 00 00 00               | call <the_q..sub_4013C1>                             |
0040131C | 85 C0                        | test eax, eax                                        |
0040131E | 74 2D                        | je the_q..40134D                                     |
00401320 | 90                           | nop                                                  |
00401321 | 90                           | nop                                                  |
00401322 | 90                           | nop                                                  |
00401323 | 90                           | nop                                                  |
00401324 | 6A 00                        | push 0x0                                             |
00401326 | 68 9F 21 40 00               | push the_q..40219F                                   | 40219F:"Correct !"
0040132B | 68 3A 21 40 00               | push the_q..40213A                                   | 40213A:"         C00L !! U found a correct Serial ! =)\n\r Tell Me how by e-mail to : [url=mailto:Phrozen_q@cyberdude.com]Phrozen_q@cyberdude.com[/url] "
00401330 | FF 75 08                     | push dword ptr ss:[ebp+0x8]                          |
00401333 | E8 06 01 00 00               | call <the_q..MessageBoxA>                            |

程序调用:GetDlgItem和SendMessageA获取Name框文本内容,调用GetDlgItemInt获取Code框输入的数值,输入任意Name和Code后,进行跟踪,发现在上段代码中:
       一、sub_401356子程序对输入的Name长度小于8的话,则在用户名后追加字符0,1,2......到Name长度为8终止。
       二、sub_401375子程序对输入的Name进行加密操作处理,流程为:第一字符累加第8字符,第二字符累加第7字符,第三字符累加第6字符,第4字符累加第5字符,然后用累加完的1-4字符复制到5-8字符,最后将1-8字符分别与"PhroZenQ"字符异或,加密过程完成。
[C++] 纯文本查看 复制代码
void  sub_401375( char * yourname)
{
        for (int x = 0; x < 4; x++)
        {
                yourname[x] += yourname[7 - x];
        }
        for (int x = 4; x < 8; x++)
        {
                yourname[x] = yourname[x - 4];
        }
        char * s1 = "PhroZenQ";
        for (int x = 0; x < 8; x++)
        {
                yourname[x] ^= s1[x];
        }
}

      三、sub_4013C1是验证子程序,验证流程如下图:
Image 2.png
通过上图验证流程,进行注册机的反推,将Name值加密后分组,应使P1和P2的值相等,P2的值是由Key1循环右移P1的低8位值得来,也就是说P2的值(Key1循环右移X次后),值等于P1,即P2的低8位值一定是X,否则无法实现P1=P2,通过比较X的值,匹配后再进一步算出Code,如果从00-0FF都匹配不上,则该Name无法成功算出Code。
       根据分析结果,注册机实现如下:
[C++] 纯文本查看 复制代码
#include<iostream>
using namespace std;
void  sub_401375( char * yourname)//用户名加密处理
{
        for (int x = 0; x < 4; x++)
        {
                yourname[x] += yourname[7 - x];
        }
        for (int x = 4; x < 8; x++)
        {
                yourname[x] = yourname[x - 4];
        }
        char * s1 = "PhroZenQ";
        for (int x = 0; x < 8; x++)
        {
                yourname[x] ^= s1[x];
        }
}
long ror(unsigned long a1, int x1)//循环右移x1次
{
        unsigned long ret = a1;
        long a2 = 0;
        for (int x = 0; x < x1; x++)
        {
                a2 = (ret & 1) << 31;
                ret = ((ret & 1) << 31) | (ret >> 1);
        }
        return ret;
}
long rol(unsigned long a1, int x1)//循环左移x1次
{
        unsigned long ret = a1;
        for (int x = 0; x < x1; x++)
        {
                ret = ((ret & 0x80000000) >>31) + (ret << 1);
        }
        return ret;
}
void main()
{
        char * Enter_yourname = new char[260];
        memset(Enter_yourname, 0, 260);
        cout << "Enter your name:";
        gets_s(Enter_yourname, 260);
        char s1 = 0x30;

        int a;
        while (strlen(Enter_yourname) < 8)
        {
                a = strlen(Enter_yourname);
                Enter_yourname[a] = s1;
                Enter_yourname[a+1] = 0;
                s1++;
        }
        cout << Enter_yourname << endl;
        sub_401375(Enter_yourname);
    // cout << "Enter your serial:";//原程序流程部分
        unsigned long serial;
        //cin >> serial;//原程序流程部分
        unsigned long * key1 = (unsigned long *)&Enter_yourname[1];
        unsigned long * key2 = (unsigned long *)&Enter_yourname[5];
        // unsigned long k1 = rol(serial, Enter_yourname[0] & 0xFF) ^ *key2;//原程序流程部分
        // unsigned long k2 = ror(*key1, k1 & 0xff);//原程序流程部分
        //cout << hex << uppercase << k1 << "    " << k2 << endl;//原程序流程部分
        unsigned long tmp=0,tmp1=0;
        unsigned long the_key = 0;
        for (int x = 0; x <= 255; x++)
        {
                tmp = ror(*key1, x);
                if ((tmp & 0xFF) == x)    //判断低8位值是否等于X,若相等则进一步反推,得出CODE值
                {
                        tmp ^= *key2;
                        the_key = ror(tmp, Enter_yourname[0] & 0xFF);
                        break;
                }
        }
        if (the_key != 0)
                cout << "your serial is:" << the_key << endl;
        else
                cout << "not found serial!" << endl;
cout<<"auto head...hello!"<<endl;
system("pause");
}

通过注册机测试,并不是所有的name都能得到CODE,能通过的用户名有:PhroZenQ,P......
52pojie,52pojie.cn,O等
提供两组测试:name:52pojie.cn  Code:3679130504       name:PhroZenQ    Code:3793889001
注册成功截图如下:
Image 3.png
程序Name长度有效位数为9位,多余部分不参与加密与验证。
整个分析过程完成,如有不对的地方还请路过的大神指正。

免费评分

参与人数 6威望 +1 吾爱币 +11 热心值 +5 收起 理由
liphily + 1 谢谢@Thanks!
Hmily + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
KNulL0 + 1 + 1 谢谢@Thanks!
Sound + 8 + 1 已经处理,感谢您对吾爱破解论坛的支持!
无书。 + 1 + 1 热心回复!
wgz001 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

flyyi 发表于 2018-3-10 12:27
感谢大佬
kk1212 发表于 2018-3-10 12:29
反汇编练习资料丰富  学习完这些基本上就上路了
wgz001 发表于 2018-3-10 13:44
cnshr00t 发表于 2018-3-10 13:59
谢谢分享
NoDocCat 发表于 2018-3-10 14:00
谢谢楼主
无书。 发表于 2018-3-10 14:15
多谢,学习了,最近也在学破解
胖子哦 发表于 2018-3-10 14:25

多谢,学习了,最近也在学破解
夜曲 发表于 2018-3-10 14:33
多谢,先收藏一下。
刘留留 发表于 2018-3-11 02:17
正在学习中,谢谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-22 16:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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