新160个CrackMe分析-第1组:1-10(下)

发布者:极安御信
发布于:2022-09-08 11:24

目录:

•001-前言

•002-abexcm5

•003-CrueheadCM3

•004-AcidBytes.2

•005-Andrénalin.1


•006-ArturDents-CrackMe2

•007-reg

•008-Afkayas.1

•009-Boonz-KeygenMe1

•010-ceycey

1-5(关注上期文章)

6. 006-ArturDents-CrackMe2

算法难度:

爆破难度:

信息收集

运行情况:

经典的用户名序列号授权验证:

   


查壳与脱壳:

无壳:

   

查字符串:

有两个提示信息,可以作为分析的入口点:


   

查导入表:

很直观,获取用户输入,进行验证,然后弹出对话框提示信息


   

调试分析

首先获取Name,然后判断Name长度是否符合要求:


   

然后获取输入的Serial,与使用Name生成的Serial进行比对验证,弹框提示


   

暴力破解

算法分析

注册码生成算法,没啥好说的

  #include


int main()

{

    char Buffer[100] = { 0 };

    std::cin >> Buffer;


    for (int i = strlen(Buffer),j=0; i >0; i--,j++)

    {

        Buffer[j] = Buffer[j] - i;

    }

    std::cout << Buffer << std::endl;

}

总结

平平无奇的最简单CM

7. 007-reg

算法难度:

爆破难度:

信息收集

运行情况:

经典的用户名+序列号授权验证:


   

查壳与脱壳:

Delphi编写的32位GUI程序,无壳


   

查字符串:

大概看了一下,字符串里有个reg.dll,但CM文件只是单一的exe,可能存在释放文件

 


调试分析

对于Delphi程序,除了直接强行分析之外,还可以借助Delphi辅助分析工具:IDR(吾爱论坛上有)

因为是窗口程序,所以查窗口的相关内容:


   

直接查看点击Ok按钮的内容:大概就是把用户输入的用户名和序列号写入到了reg.dll文件中,也就是说这是个dll后缀的文本文件


   

提示语是重启软件后验证注册码,说明这是一种重启验证,在启动的时候进行校验

那么接下来查看创建窗口时的代码:


   

这个调用的函数:sub_0045D0F4,这应该就是一个校验函数,根据返回al的值是否为0,来进行判断跳转,这个跳转应该是关键跳了


   

暴力破解

修改关键跳:


   

然后跑起来:


   

算法分析

接下来看看具体校验call做了哪些事情:sub_45D0F4

首先获取参数之后,计算SN长度,SN长度需要是16个字符:


   

然后接下来是个循环,遍历SN每个字符,检查合法字符,这里允许的字符是0-9数字和A-F字母


   

然后紧接着进行一顿处理,处理用户名得到一个加密编码后的值


   

值通过x86dbg动态调试观察:计算的结果是8B45677A3AEBE84C


   

然后接下来,程序连续走了两趟相同的操作,分别是对刚刚通过用户名计算出来的结果和我们输入的SN,然后将结果进行对比,返回


   

这里具体生成用户名对应SN的代码过于复杂,暂时还写不出来注册机,但这里程序在分析过程中会出现SN真码明文,这里也就到此结束了,使用该SN打开程序:


   

总结

Delphi程序逆向练习,借助工具IDR可以很方便的识别Delphi函数,这个CM使用了经典的重启验证,让验证函数在窗口创建前进行验证,注册机较为复杂,暂时还写不出来

 参考资料

[1] 新160个CrackMe算法分析-007-Reg_哔哩哔哩_bilibili

8. 008-Afkayas.1

算法难度:

爆破难度:

信息收集

运行情况:

输入用户名,序列号,点OK进行验证


   

查壳与脱壳:

无壳,程序由VB5.0编写


   

调试分析

这个程序以前做CM的时候分析过,以x86dbg+IDA进行逆向分析的,详情见参考

这次就直接拖VBDec里用专门的VB反编译软件进行分析

这个程序有用的代码就一个OK按钮的点击事件,总共就这么几行:


   

很神奇一点就是,这点之前没发现,这里藏了一个文本框,我就说代码里咋三个文本框呢,这个是用来保存数据的


   

算法分析

有几行看不懂啥意思,直接x86dbg动态跟踪看看效果,整体注释:

  Private Sub OK_Click() '402310

  loc_004023D3: call var_8004 = var_C4(Me, Me, 0, 0, 0)             // 获取用户名输入

  loc_00402415: var_8008 = Len(var_C4(Me, Me, 0, 0, 0).MousePointer)        // 计算用户名长度

  loc_0040242D: var_800C = Asc(CrackMe.Text1.Text)              // 取用户名首字符的ASCII码

  loc_0040243F: call var_8010 = global_004040E0(var_8008*97531+var_800C)    // 97531*用户名长度+首字符的ASCII码,结果转换成字符串

  loc_00402458: CrackMe.RegSerial.Text = var_8010               // 设置这个文本框的值

  loc_004024DE: call var_8014 = var_C0(Me)

  loc_0040258B: If (CrackMe.Serial.Text = "AKA-" & var_C0(Me).MousePointer) + 1 Then  // 判断输入的序列号是否为AKA-拼接刚刚计算的值

  loc_004025C4:   var_8028 = MsgBox("You Get It" & vbCrLf & "KeyGen It Now", 0, var_4C, var_5C, var_6C)

  loc_004025E5: Else

  loc_0040261C:   var_8034 = MsgBox("You Get Wrong" & vbCrLf & "Try Again", 0, var_4C, var_5C, var_6C)

  loc_0040263B: End If

  loc_00402652: GoTo loc_0040269E

  loc_0040269D: Exit Sub

  loc_0040269E: ' Referenced from: 00402652

End Sub

总结

依然是很简单的一次VB逆向

[1] 160个Crackme系列-002-Afkayas.1 - 我可是会飞的啊 (kn0sky.com)

9. 009-Boonz-KeygenMe1

算法难度:

爆破难度:

信息收集

运行情况:

神奇的审美,用户名+序列号验证程序


   

查壳与脱壳:

无壳程序


   

查字符串:

有一些提示字符串,提示输入正确失败的,还有错误提示:Name需要是4-50个字符长


   

调试分析

本次的目标是分析出算法写注册机,所以就没有爆破环节了

从提示字符串Hello,Mr. Goodboy入手开始分析,交叉引用找到校验函数:



先后获取了用户输入的Name和Serial,然后进入校验函数

   

算法分析

校验函数就是算法的所在

首先判断用户名长度是否合法,长度4--50内


   

接下来进行第一组计算,结果保存起来


   

然后进行第二组运算:圈出来的三行纯属干扰,无用


   

然后进行第三组运算:


   

然后再往下就是拼接字符串进行比对的环节了:


   

已经知道Serial是怎么算的了,接下来写注册机

注册机代码

  #define _CRT_SECURE_NO_WARNINGS

#include


int main()

{

    char name[50] = { 0 };

    char serial[50] = { 0 };

    int nameLength = 0;


    std::cin >> name;

    nameLength = strlen(name);

    if (nameLength < 4 || nameLength > 50) {

        std::cout << "Name Length Invalid" << std::endl;

        return 0;

    }


    // 第一轮计算

    unsigned int res_1 = 0;

    for (auto a = 0; name[a];a++) {

        char tmp = name[a];

        tmp -= 0x19;

        res_1 -= tmp;

    }


    // 第二轮计算

    unsigned int res_2 = res_1 * res_1 * res_1;


    // 第三轮计算

    unsigned int res_3 = 0x40e0f8 * 0x40e0f8 - 0x40e0f8;


    sprintf(serial, "Bon-%lX-%lX-%lX", res_1,res_2,res_3);

    std::cout << serial << std::endl;

    return 0;

}

  计算结果:

  Name = 1234

Serial = Bon-FFFFFF9A-FFEFCEA8-41720F48

程序运行结果:


   

总结

非常简单的序列号校验算法分析,中间的干扰是无用计算,忽视即可

10. 010-ceycey

算法难度:

爆破难度:

信息收集

运行情况:

输入密码登录:


   

查壳与脱壳:

有UPX壳,使用ESP定律大法即可,这里不再啰嗦


   

脱壳后:可以看到是Delphi5写的GUI程序


   

调试分析

抄起IDR就是干,明文硬编码密码:ULTRADMA............................................................,如果输入错误,则点击按钮无事发生,输入正确会弹窗


   

没啥可爆破和算法分析的:


   

总结

可以当成一次Upx脱壳练习


声明:该文观点仅代表作者本人,转载请注明来自看雪