selph
selph
发布于 2022-07-09 / 394 阅读
3
1

新160个CrackMe练习:002-abexcm5

爆破难度:⭐

算法难度:⭐

信息收集

运行情况:输入序列化,输入错误会提示错误并退出程序,这是个验证序列号的程序

image.png

查壳:无壳

image.png

查字符串:有提示语,疑似硬编码的字符串

image.png

查导入表:使用了字符串操作类的函数,以及GetVolumeInformationA函数,不知道序列号生成跟这个有无关系

image.png

到现在已经知道了软件大概的运行流程:获取用户输入,对用户输入进行一些处理,然后弹框提示

逆向分析

IDA里选择MessageBoxA函数查交叉引用,跟踪到函数sub_401056中,这是CM的校验逻辑所在:

首先先获取用户输入,然后生成两个字符串:(注释写错了,应该是do-while循环而不是while循环)

image.png

然后把刚刚生成的两个字符串拼接到一起,生成序列号,与用户输入进行比对,序列号几乎是硬编码

image.png

暴力破解

验证逻辑是:生成序列号,通过与用户输入的比对来进行验证

暴力破解的思路是:修改跳转条件即可,把jz改成jmp即可:

image.png

算法分析

注册码生成算法:

#include <iostream>
#include <windows.h>

int main()
{
    char VolumeNameBuffer[MAX_PATH] = { 0 };
    DWORD VolumeSerialNumber = 0;
    DWORD MaximumComponentLength = 0;
    DWORD FileSystemFlags = 0;
    int i = 2;
    char Series[MAX_PATH] = { 0 };
  
    GetVolumeInformationA(
        0,
        VolumeNameBuffer,
        0x32u,
        &VolumeSerialNumber,
        &MaximumComponentLength,
        &FileSystemFlags,
        0,
        0);


    lstrcatA(VolumeNameBuffer, "4562-ABEX");
   
    do{
        VolumeNameBuffer[0]++;
        VolumeNameBuffer[1]++;
        VolumeNameBuffer[2]++;
        VolumeNameBuffer[3]++;
    } while (--i);

    lstrcatA(Series, "L2C-5781");
    lstrcatA(Series, VolumeNameBuffer);

    std::cout << Series << std::endl;
    system("pause");
    return 0;
}

效果:

image.png

总结

字符串拼接生成序列号,通过判断+跳转进行校验,很简单,没啥好说的

参考资料


评论