NewCrackMe | 018 CrackMe_0006

警告
本文最后更新于 2023-04-08,文中内容可能已过时。

NewCrackMe | 018 CrackMe_0006

查壳

无壳,是MASM编译的,说明是直接用汇编写的程序

破解

直接到入口点观察汇编

这里调用了DialogBoxParamA来调出DialogFunc

然后通过WM_COMMAND选择不同的按钮模块,其中0x3F0是About界面,0x3EE是check界面

所以check界面就是验证的逻辑部分

这个程序的验证逻辑分为了三个部分

第一部分是计算盘符序列号

程序获取了C盘和D盘的序列号,中间加了一段花指令,最后对两个序列号进行浮点数运算,获得sum1

第二部分是计算输入的name

首先将name每一位累乘起来,累乘是自己写的函数,定义如下

这个函数是将每位累乘之后,乘法的结果保存在EDX:EAX中,将高位和地位相加得到最后的结果sum2

sum2进行循环左移一位的操作,然后和sum1进行或运算得到sum3

第三部分是计算出series

程序硬编码了一个table,将sum3 % 16作为数组索引得到series,每次操作完对sum3 / 4,直到sum3 == 0

最后一部分就是比较输入的序列号是否和series相同

暴力破解

依旧是修改关键跳即可

生成注册码

下面的代码需要用MSVC编译

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <Windows.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>

// #define DEBUG

DWORD GetVolumeSerialNumber(const char* lpRootPathName) {
    DWORD serialNumber = 0;
    GetVolumeInformationA(lpRootPathName, NULL, 0, &serialNumber, NULL, NULL,
        NULL, 0);
    return serialNumber;
}

DWORD FloatCalculate(DWORD a1, DWORD a2) {
    DWORD res = 0;
    __asm {
        fwait;
        fninit;
        fild dword ptr[a1];
        fld st(0);
        fmulp st(1), st(0);
        fild dword ptr[a2];
        fld st(0);
        fmulp st(1), st(0);
        faddp st(1), st(0);
        fsqrt;
        fistp dword ptr[res];
    }
    return res;
}

void LshiftRotate(DWORD* a1, DWORD a2) {
    __asm {
        mov eax, DWORD PTR[a1];
        mov ecx, DWORD PTR[a2];
        rol DWORD PTR[eax], cl;
    }
}

int main() {
    const char* const_buffer = "071362de9f8ab45c";
    char buffer[32] = { 0 };
    char name[32] = "bronya";
    DWORD C_series, D_series;
    DWORD sum1, sum2 = 1, sum3;

    C_series = GetVolumeSerialNumber("C:\\");
    D_series = GetVolumeSerialNumber("D:\\");

    sum1 = FloatCalculate(C_series, D_series);

    LONGLONG sum2_1 = 1;

    for (int i = 0; name[i]; i++) {
        sum2_1 *= name[i];
        sum2 = sum2_1 & 0x00000000FFFFFFFF;
        sum2 += (sum2_1 & 0xffffffff00000000) >> 32;
    }

    LshiftRotate(&sum2, 1);

    sum3 = sum1 | sum2;
    sum3 &= 0x0FFFFFFF;

    int i = 0;

    do {
        buffer[i++] = const_buffer[sum3 % 0x10];
        sum3 /= 4;
    } while (sum3);

    std::cout << buffer << std::endl;

    return 0;
}

参考

0%