吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2887|回复: 24
收起左侧

[原创] 破解练习-CRACKME011

  [复制链接]
逸聆君 发表于 2023-2-11 18:44

011-注册算法分析

一、工具和调试环境

  • PE信息查看工具:Die
  • 动态调试工具:x64dbg
  • 系统环境:win10 1909

二、分析用户名/注册码的算法

2.1运行程序

通过点击按钮输入Serial,正确的话状态就会变为REGISTRIERT

011-01.png

2.2查壳

Die查壳,无壳,vb程序

2.3详细分析

老办法,上x64dbg,搜索字符串看看

011-02.png

好家伙,没看到UNREGISTRIERT,倒是看到一大堆REGISTRIERT。看了几个,验证过程大致一样,于是就选择了第一个跟进去看。

011-03.png

011-04.png

基本算法就是:将输入的每个字符的ascii码值和首个字符相加(必须是数值),然后将相加之和得到的结果转换为十六进制的字符串,最后拼接在一起,组成的字符串(首次拼接的时候,拼接到‘0’后面)和上图框出的字符串一样就注册成功。

由于最后的字符串每个字符必须是十六进制数,所以每个取值范围只能在0~F之间。上图中的明显不符合,有R,K

011-05.png

转到引用界面,经过一番删选,只有上图框出来的那一个合适。为:0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C。此处又经过一番折腾,发现无论如何都无法满足。最后跟进到上面唯一正确提示的地方(之前分析的是第一个的,粗略看了下以为全部都一样),找到其算法位置

011-06.png

发现唯一的差别是取的前两个字符相加,不是之前的首个字符。

至此,基本算法确定:将输入的每个字符的ascii码值和前两个字符相加(必须是数值),然后将相加之和得到的结果转换为十六进制的字符串,最后拼接在一起,组成的字符串(首次拼接的时候,拼接到‘0’后面)和上图框出的字符串一样就注册成功。

三、算法核心代码模拟

char* GetKey10()
{
    // 0817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C
    char szName[] = "817E747D7A7D7C7F82836D74747A7F7E7B7C7D826D817E7B7C";

    static char szKey[60] = {};

    int j = 0;
    for ( j = 0; j < 100; j++)
    {
        char szTmp[3] = {};
        itoa(j, szTmp, 10);

        if (szTmp[0] + j == 0x81 && szTmp[1] + j == 0x7e)
        {
            break;
        }

    }

    for (int i = 0; i < strlen(szName); i += 2)
    {
        char szTmp[3] = {};

        strncpy(szTmp, &szName[i], 2);

        int nTmp = atoi(szTmp);
        char* szEnd = nullptr;
        nTmp = strtol(szTmp, &szEnd, 16);

        szKey[i / 2] = nTmp - j;

    }

    return szKey;
}

四、API总结

rtcLeftCharVar

// 获取指定字符串前面指定个数的字符组成的新字符串
// 栈传参
Variant* rtcLeftCharVar(Variant* pDesStr, Variant* pSrcStr, int nCnt);

rtcR8ValFromBstr

// 将字符串转换为双精度浮点数(遇到非数值字符会截断)
// 栈传参
double rtcR8ValFromBstr(char* pStr);

rtcMidCharBstr

// 从变体(字符串类型)字符串中指定位置开始获取指定个字符组成的新字符串
// Variant* pSrcStr 源字符串
// int nIdx         开始的位置(从1开始计算)
// Variant* pCnt    取多少个字符
// 通过栈传递参数
// 返回新的字符串的缓冲区的首地址
char* rtcMidCharBstr(Variant* pStr, int nIdx, Variant* pCnt);

rtcHexBstrFromVar

// 将变体(双精度浮点类型)转换为其十六进制组成的字符串
// 通过栈传递参数
// 返回字符串的缓冲区的首地址
char* rtcHexBstrFromVar(Variant* pDouble);

免费评分

参与人数 6威望 +1 吾爱币 +24 热心值 +6 收起 理由
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
hahaerlx + 1 + 1 热心回复!
14foto + 1 热心回复!
wtb9168 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
18685157041 + 1 + 1 热心回复!
coder9527 + 1 + 1 热心回复!

查看全部评分

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

野男人 发表于 2023-2-11 19:16
还是要留下足迹;
erkelee 发表于 2023-2-11 21:17
qq277618 发表于 2023-2-11 21:45
zjh889 发表于 2023-2-12 00:18
好东西,谢谢楼主!辛苦了!
nj2004 发表于 2023-2-12 00:33
感谢分享!学习了
shading 发表于 2023-2-12 03:13
谢谢楼主!辛苦了!
km5110 发表于 2023-2-12 06:44
收下了,学习学习
vipzzc 发表于 2023-2-12 09:41
这个可以
debug_cat 发表于 2023-2-12 09:43

收下了,学习学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-24 00:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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