吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2546|回复: 23
收起左侧

[原创] 练习笔记之160Crackme-033

[复制链接]
xiaoyu2032 发表于 2022-8-18 21:42
本帖最后由 xiaoyu2032 于 2022-8-18 21:42 编辑

160CM-033

1. 爆破

  首先拖入PE看一下,应该是个汇编程序(ExeInfoPE检测为unknown,DetectItEasy检测为delphi(delhi反汇编工具无法反汇编),PEID检测为汇编)。直接拖进OD中,查找关键字符串也可以找到。这里我们用F12暂停法,打开注册界面,输入用户名和密码,然后确定,弹窗错误提示对话框后,在OD中按F12暂停,然后Alt+K进入堆栈调用列表中,再最后一个调用处双击,就找到了弹窗的调用程序,然后F8单步跟踪到返回,就可以到401245位置,该处调用就是错误弹窗函数。

03.png

  往上看,可以看到一个比较和一个判断跳转,这个跳转就是关键跳转,将je该为jmp,爆破就完成了。

2. 算法分析

  从图1中的代码可以看出,程序验证过程一目了然:先获取用户名字符串,然后调用校验算法1计算得到结果1;再获取密码字符串,然后调用校验算法2计算得到结果2,最后比较结果1和结果2是否相等,相等则提示成功,否则提示失败。

  先分析用户名校验算法,用IDA打开程序,找到算法子程序40137E,按F5得到伪代码,如下图:

01.png

  从伪代码中可以看出,算法先一次判断用户名字符串中的字符是否在A~Z之间,小于A,则弹窗报错,大于Z,将其ASCII值减32(即转换成大写字母),全部转换成大写字母后,再调用子程序4013C2,将所有字母的ASCII码值相加,最后在和0x5678进行异或运算(上述过程如果功力不够静态分析不大确定,在OD中跟踪一下程序执行过程也就很容易确定下来)。

  接着分析密码校验算法,同样用IDA打开程序,找到算法子程序4013D8,按F5得到伪代码,如下图:

02.png

  从伪代码中可以发现,IDA生成的伪代码有点问题,漏掉了与0x1234进行异或的计算过程。*i-48也就是字符的ASCII码减去数字0的ASCII码值,也即得到输入数字所代表的数值,v2=(*i-48)+10*v2,整个过程起始就是将数字字符串转化为其对应的数值。最后再与0x1234进行异或计算。

  将上述校验过程编写成校验算法如下,输入数据与程序本身的计算结果进行验证,可以证明算法无误。

// 160CrackMe-033.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <math.h>

int _tmain(int argc, _TCHAR* argv[])
{
        char name[20];
        char code[20];
        int i,j;
        int k;
        printf("请输入用户名(长度≤20):");
        scanf_s("%s", name, 20);
        printf("请输入密码(长度≤20):");
        scanf_s("%s", code, 20);
        //未做用户名输入校验,只允许输入字母
        for (i = 0; i<strlen(name); i++)
        {
                name[i] = toupper(name[i]);
        }
        k = 0;
        for (i = 0; i<strlen(name); i++)
        {
                k = k + name[i];
        }
        printf("用户名字符和:%d \n",k);
        k = k ^ 0x5678;
        printf("用户名校验输出:%x \n", k);

        j = 0;
        for (i = 0; i<strlen(code); i++)
        {
                j = (code[i]-48) + 10 * j;
        }
        printf("密码异或前的结果:%d \n", j);
        j = j ^ 0x1234;
        printf("密码校验输出:%x \n", j);
        system("pause");
        return 0;
}

  至于注册机的算法,由于密码的校验算法相当于输入数字字符串的数值与0x1234的异或结果,因此注册码的求解过程可以直接用用户名校验算法得到的结果,与0x1234进行异或,得到的数值就是注册码。具体算法程序如下:

// 160CrackMe-033.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <math.h>

int _tmain(int argc, _TCHAR* argv[])
{
        char name[20];
        char code[20];
        int i,j;
        int k;
        printf("请输入用户名(长度≤20):");
        scanf_s("%s", name, 20);
        //未做用户名输入校验,只允许输入字母
        for (i = 0; i<strlen(name); i++)
        {
                name[i] = toupper(name[i]);
        }
        k = 0;
        for (i = 0; i<strlen(name); i++)
        {
                k = k + name[i];
        }
        k = k ^ 0x5678;
        k = k ^ 0x1234;
        printf("注册码为:%d \n", k);
        system("pause");
        return 0;
}

  输入用户名abc,可以计算得到注册码为17546,输入程序中,验证成功。

04.png

3. 总结

  这道题验证过程清晰简单,算法也不难,借助IDA、OD这两个软件,分析起来还是比较顺利的。

  其中关于注册码的计算,默认注册码为数字字符串的话,可以如上直接异或后得出,但由于程序没有限制只能输入数字字符串,因此将其中的数字用字母代替,也是可以算得注册码的,比如最后一个数字用字母h替代,则可以得到1749h这样一个注册码,有很多个解。

免费评分

参与人数 7威望 +1 吾爱币 +25 热心值 +7 收起 理由
抱薪风雪雾 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
acing + 1 用心讨论,共获提升!
bmpt + 1 + 1 我很赞同!
AG9000 + 1 + 1 我很赞同!
peiwithhao + 1 + 1 用心讨论,共获提升!
cjcmxc + 1 + 1 我很赞同!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

iawyxkdn8 发表于 2022-8-19 08:09

我大体看了一下,很想了解,仔细又看了一下,还不如大体看一下。总结,看不懂!
lxf100 发表于 2022-8-18 21:46
14762655378 发表于 2022-8-18 21:54
我大体看了一下,很想了解,仔细又看了一下,还不如大体看一下。总结,看不懂!
gbk38866 发表于 2022-8-18 22:26
看不懂,先灌个水!
Pro111 发表于 2022-8-18 23:11
这个可以啊
戰龍在野 发表于 2022-8-18 23:13
谢谢分享谢谢你的坚持
tohyueyun 发表于 2022-8-18 23:27
写到好详细
dadaliya 发表于 2022-8-18 23:42
写的真好!!!
a12b19 发表于 2022-8-18 23:47
看了楼主的帖子。打算去自己练一下。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-24 10:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表