用户
搜索
  • TA的每日心情
    开心
    2018-4-29 15:23
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    i春秋-脚本小子

    Rank: 2

    3

    主题

    6

    帖子

    81

    魔法币
    收听
    0
    粉丝
    0
    注册时间
    2018-4-29
    发表于 2020-1-3 23:14:36 11731

    0x00 前言

    之前写的First CrackMe中的程序是基于明码比较的,除爆破法与分析序列号生成算法,亦可使用WinHex直接查看内存得出正确序列号。本文所用软件是基于非明码比较的,即F1(Name)=F2(Key)。

    0x01 程序分析

    根据提示信息设断。

    使用OD打开程序,右击,Search for——>>All referenced text strings,可以看到如下字符串:

    其中有两处是错误提示信息,一处是正确提示信息,双击黄色方框内的正确提示信息来到代码处:

    由于现在不知道正确序列号及与其对应用户名,而且第一次就输入正确的概率微乎其微,所以我们在0x401369处设断。

    F9运行程序,输入用户名及序列号如下:

    单击"OK"按钮后来到断点处,F7一直执行完retn语句后停止:

    可以看到关键语句cmp eax,ebx,根据其上面的语句推断serial.0040137E返回值在eax中,serial.004013D8返回值在ebx中。

    serial.0040137E应该是实现F1(Name),serial.004013D8实现F2(Key)。

    0x02 F1(Name)算法分析

    Ctrl+G输入40137E来到子程序入口处:

    下面是笔者在分析算法时所作记录:

    根据上述分析,粗略写出C语言实现代码:

    #include<stdio.h>
    #include<string.h>
    
    #define LENGTH 6
    
    int main(void)
    {
        char Name[LENGTH] = "erfze";
        int i, chr=0,res=0;
        for (i = 0; i < strlen(Name); ++i)
        {
            chr = Name[i];
            if (chr > 'A' && chr < 'Z')
                continue;
            else
                chr = chr - 0x20;
            Name[i] = chr;
            res += chr;
        }
        res ^= 0x5678;
    }

    0x03 F2(Key)算法分析

    Ctrl+G输入04013D8来到子程序入口处:

    下面是笔者在分析算法时所作记录:

    根据上述分析,粗略写出C语言实现代码:

    #include<stdio.h>
    #include<string.h>
    
    #define LENGTH 6
    
    int main(void)
    {
        char Key[LENGTH] = "12345";
        int i, a = 0xA,  d = 0,chr=0;
        for (i = 0; i < strlen(Key); ++i)
        {
            chr = Key[i]-0x30;
            d = d * a + chr;
        }
        d ^= 0x1234;
    }

    0x04 编写KeyGen

    0x03中:

    for (i = 0; i < strlen(Key); ++i)
     {
     chr = Key[i]-0x30;
     d = d * a + chr;
     }

    该循环的功能是将Key由字符串表示形式转为数字表示形式,再加上异或运算可逆,只需将F1(Name)算法实现的最后加上res^=0x1234即可根据Name生成序列号。完整代码及运行结果如下:

    #include<stdio.h>
    #include<string.h>
    #define LENGTH 6
    int main(void)
    {
     char Name[LENGTH] = "erfze";
     int i, chr=0,res=0;
     for (i = 0; i < strlen(Name); ++i)
     {
     chr = Name[i];
     if (chr > 'A' && chr < 'Z')
     continue;
     else
     chr = chr - 0x20;
     Name[i] = chr;
     res += chr;
     }
     res ^= 0x5678;
     res ^= 0x1234;
     printf("%d\n",res);
    }

    输入以验证之:

    学习了
    My blog :http://www.e-wolf.top
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册