Crackme044

程序观察

程序是用户名序列号验证机制,用户名字段至少要6个字符。

使用 Delphi 编写,没有加壳。

事件查看

使用 IDR 加载程序,虽然加载的时候报错了,但是还能看出来程序有两个事件。

我们使用另外一个工具加载程序,就可以看到两个事件的地址了。

程序分析

使用 OD 载入程序,来到地址00421BB4处,这里是注册按钮点击事件的代码区域,向下分析代码

长度比较

程序首先获取输入的 name 和 serial,然后求得 name 的长度,长度不小于6才能继续执行

循环计算

然后程序建立循环,循环次数为固定的6次,程序根据用户名计算出来一个值


需要注意的是,如果输入的用户名不是全是数字的话,那么最后计算出来的序列号是固定的;只有用户名是字母的时候,序列号才不一样。

字符串拼接

程序首先将用户名的长度乘以 0x4A7E,然后将结果转为字符串形式

然后将循环计算的结果也转为字符串

最后将两个字符串使用 "-" 拼接在一起

进行校验

将拼接后的字符串和我们输入的序列号进行比较

注册机

注册机并不难写,但是自己写的话很繁琐,所以我直接 copy 了别的大佬的代码来用,具体代码在下面。

最后生成的序列号的是由3部分组成的,分别是是两个字符串和一个 "-"。
但其实 "-" 后面的部分很简单就能算出来,就是用户名长度乘以固定值在转为10进制。
如果用户名全为数字的话,前面的部分也是固定的 "46"。所以如果用户名是一个6位数字的话,序列号就固定为 "46-114420"。

#include 
#include 


int main()
{
    char username[20] = { 0 };
    printf("请输入用户名:");
    scanf_s("%s", username, 20);
    int usernameLen = strlen(username);
    if (usernameLen<6)
    {
        printf("用户名长度必须大于等于6");
    }
    //大写转小写
    for (int i=0;i='A'&&username[i]<='Z')
        {
            username[i] += 32;
        }
    }

    int v13 = 0;
    int TotalSum = 0;
    int i = 0;                                      // i初始化为零
    do
    {
        switch ((username[i- 1]))// 根据username[i]的值给v13赋值
        {
        case 0x61u:
            v13 = 0x18;
            break;
        case 0x62u:
            v13 = 0x25;
            break;
        case 0x63u:
            v13 = 0x42;
            break;
        case 0x64u:
            v13 = 0xC;
            break;
        case 0x65u:
            v13 = 0xD;
            break;
        case 0x66u:
            v13 = 6;
            break;
        case 0x67u:
            v13 = 0x36;
            break;
        case 0x68u:
            v13 = 0x2B;
            break;
        case 0x69u:
            v13 = 0x17;
            break;
        case 0x6Au:
            v13 = 0x2F;
            break;
        case 0x6Bu:
            v13 = 0x13;
            break;
        case 0x6Cu:
            v13 = 0x82u;
            break;
        case 0x6Du:
            v13 = 0x9Bu;
            break;
        case 0x6Eu:
            v13 = 0x92u;
            break;
        case 0x6Fu:
            v13 = 3;
            break;
        case 0x70u:
            v13 = 0x63;
            break;
        case 0x71u:
            v13 = 0x21;
            break;
        case 0x72u:
            v13 = 0x42;
            break;
        case 0x73u:
            v13 = 0x5C;
            break;
        case 0x74u:
            v13 = 0x29;
            break;
        case 0x75u:
            v13 = 0xC7u;
            break;
        case 0x76u:
            v13 = 0x66;
            break;
        case 0x77u:
            v13 = 0x58;
            break;
        case 0x78u:
            v13 = 0xA;
            break;
        case 0x79u:
            v13 = 0x28;
            break;
        case 0x7Au:
            v13 = 0x50;
            break;
        default:
            v13 = 0x5D;
            break;
        }
        TotalSum += v13;                          // 循环累加v13的值
        ++i;
        //这里记得超出范围清掉高位
        if (TotalSum>0xFF)
        {
            TotalSum &= 0x00FF;
        }
    } while (i != 6);

    printf("%d-%d\n", TotalSum,0x4A7E*usernameLen);
    system("pause");
    return 0;
}

大佬博客地址

相关文件在我的 Github

你可能感兴趣的:(windows)