吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5081|回复: 14
收起左侧

[原创] 160 个 Crackme 之 066 -- figugegl.2 算法分析和注册机实现

[复制链接]
solly 发表于 2019-11-19 00:50
有一段时间没有发贴了,这次发一个非常简单的,萌新可以来看看。
160 个 CrackMe 之 066 -- figugegl.2 是一个 LCC-Win32 编译的 CrackMe,LCC 是一个小巧的 C 语言编译环境,编写简单的 C 程序比较方便,开发环境的体积很小,并且包括了资源编辑器。


先看看 CrackMe 的信息:
00.png
节的信息如下:
01.png
可见,该 CrackMe 没有加壳,编译器是 LCC Win32。


直接用OD载入,显示如下:
10.png
前面是 SEH 处理代码,后面一个内部过程调用,这个调用相当于 C 语言的 main() 函数。


跟随进入 main() 函数,如下图所示:
11.png
开始部分就是命令行参数处理,继续向下看,如下图所示:
12.png
在调用 KERNEL32.GetModuleHandleA() 后,就是 Windows 程序的入口函数了,即 WinMain() 函数。


再跟随这个 WinMain() 函数,如下图所示:
13.png
由上图可见,通过以下代码,生成一个对话框应用程序:
[Asm] 纯文本查看 复制代码
00401298  |.  6A 00           push    0                                ; /lParam = NULL
0040129A  |.  68 4F144000     push    0040144F                         ; |DlgProc = figugegl.0040144F
0040129F  |.  6A 00           push    0                                ; |hOwner = NULL
004012A1  |.  6A 64           push    64                               ; |pTemplate = 64
004012A3  |.  57              push    edi                              ; |hInst
004012A4  |.  E8 F7020000     call    <jmp.&USER32.DialogBoxParamA>    ; \DialogBoxParamA

可以看到,DlgProc = 0x0040144F,通过 OD 的右键菜单“跟随立即数”,就可来到这个 DlgProc 了,如下图所示:
14.png
可以看到处理 WM_CLOSE, WM_INITDIALOG, WM_COMMAND 消息的代码,我们主要关心其处理 WM_COMMAND 代码,如图所示的所选代码部分,就是一个 Case 跳转,其参数 EAX = 0 ~ 3,共4种情况。
静态分析就到这里,我们先运行 CrackMe 看看,直接 F9,弹出 CrackMe 界面如下:
15.png
先输入假码注册,如上图所示,点“CHECK”。来到前面静态分析的 Case 跳转处,如下图所示:
16.png
可以看到,分成4个部分,在数据区,可以看到用到的 4 个地址。点击“CHECK”按钮时,EAX = 0x00000001,这就表示 CHECK 按钮的 ControlID 为 0x00000001。
上图显示,“CHECK”的处理代码如下:
[Asm] 纯文本查看 复制代码
004014A1   .  FF75 08           push    dword ptr [ebp+8]
004014A4   .  E8 FCFEFFFF       call    004013A5                         ;  注册验证函数
004014A9   .  59                pop     ecx
004014AA   .  31C0              xor     eax, eax
004014AC   .  40                inc     eax
004014AD   .  EB 56             jmp     short 00401505

其中,只有一个 call 004013A5 调用,接着直接返回 eax=1。跟随进入 call 调用,如下图所示:
17.png
这个过程就是注册码的算法代码,其中算法在上图所选择的代码内,算法也很简单。主要代码如下:
[Asm] 纯文本查看 复制代码
004013C2  |.  89C6              mov     esi, eax                         ;  名字的长度值
004013C4  |.  EB 06             jmp     short 004013CC
004013C6  |>  C64435 EB 20      /mov     byte ptr [ebp+esi-15], 20       ;  在name后添加 0x20,空格
004013CB  |.  46                |inc     esi
004013CC  |>  83FE 14            cmp     esi, 14                         ;  len < 20
004013CF  |.^ 7C F5             \jl      short 004013C6                  ;  长度<20,添加空格
004013D1  |.  31F6              xor     esi, esi                         ;  int i=0
004013D3  |>  0FB67C35 EB       /movzx   edi, byte ptr [ebp+esi-15]      ;  name[i]
004013D8  |.  0FB65435 F5       |movzx   edx, byte ptr [ebp+esi-B]       ;  name[i+10]
004013DD  |.  89F8              |mov     eax, edi
004013DF  |.  31D0              |xor     eax, edx                        ;  xor值 = name[i]^name[i+10]
004013E1  |.  B9 0A000000       |mov     ecx, 0A                         ;  10
004013E6  |.  99                |cdq
004013E7  |.  F7F9              |idiv    ecx
004013E9  |.  83C2 30           |add     edx, 30                         ;  dl = (xor值 % 10) + '0'
004013EC  |.  885435 D6         |mov     byte ptr [ebp+esi-2A], dl       ;  serial[i] = dl
004013F0  |.  46                |inc     esi
004013F1  |.  39CE              |cmp     esi, ecx                        ;  i<10
004013F3  |.^ 7C DE             \jl      short 004013D3                  ;  循环

分析如下:
1、通过 GetDlgItemTextA() 取得界面上输入的用户名;
2、如果用户名长度不够20个字符,则在后面添加空格字符,直到长度达到20个字符;
3、取名字第1到10字符,依次与名字的第11到20字符异或运算;
4、将异或运算后的结果与10求余,并加上0x30,实际上就是生成一个'0'~'9'范围的数字字符。
5、将前面生成的10个数字字符组成序列号(但这个数字并不一定是真正的序列号,看下面説明)。
6、CrackMe 并没有用上面生成的序列号与界面上输入的序列号进行字符串比较,而是先转换成整数再进行比较的。如上图所示,是通过库函数 strtoul() 函数转换的,不过,前面代码生成的序列号有10位数字,当大于最大无符号整数范围(0xFFFFFFFF,也就是 4294967295)时,会返回最大无符号整数(0xFFFFFFFF)。这个时候,我们输入的就不能是前面1~5步生成的序列号了,而是一个常数:4294967295。
如下图所示:
18.png
前5步生成的序列号是:8359659000,明显这个数字已超出 4294967295 了,即溢出了。
19.png
通过 strtoul()转换后,EAX 返回的是 0xFFFFFFFF,也就是 4294967295 了,明显已经是不正确的值了。
转换计算的序列号以后, CrackMe 通过调用 GetDlgItemInt() 函数,从界面取回输入的序列号,然后与转换后的序列号比较,如下图所示:
20.png
比较后,根据结果会跳转到下面显示正确与否的提示。
21.png
如上图所示,两个序列号不相等,结果是失败,显示信息如下:
22.png
我们根据前面的分析,重新输入新的序列号:4294967295。如下图所示:
23.png
再点“CHECK”,来到序列号比较处,如下图所示:
24.png

这次是一样的了,都是 0xFFFFFFFF,即 4294967295 了。F9 继续,这次提示如下了:
25.png
表明这次序列号输入正确。
前面测试的是一个异常的序列号,下面我们看看正常的序列号,如下图所示,先把 name 改一下:
26.png
点击“CHECK”,再次来到序列号比较的代码处:
27.png
可以看到,这次转换正常了,没有溢出了,序列号是 3966900000,小于 4294967295,转换正常了。
F9 运行,返回界面。输入正确的序列号,如下图所示:
28.png
重新点击“CHECK”,再一次来到序列号对比的代码处:
29.png
可以看到,这次是相等的了,F9后,提示如下,表明序列号正确:
30.png
分析完毕!!!
下面代码是根据前面分析的算法写出的注册机:
[C++] 纯文本查看 复制代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int getSN(char * name);

int main(int argc, char** argv) {
    char name[256] = {0};
    printf("Input your name: ");
    gets(name);

	getSN(name);
	return 0;
}

int getSN(char * name) {
    int n=strlen(name);
	for (int i=n; i<20; i++) {
        name[i] = 0x20;    /// padding
    }
		
	unsigned long long check = 0;
	for (int i=0; i<10; i++) {
		check = check * 10 + (name[i] ^ name[i+10]) % 10;
	}
	if(check>>32) {
	    printf("Serial: 4294967295\n"); /// overflow, Max: 0xFFFFFFFF
	} else {
		printf("Serial: %lu\n", check); /// normal case
	}
        
    return 0;
}

使用 Dev-C++ 调试通过。

免费评分

参与人数 6威望 +1 吾爱币 +11 热心值 +6 收起 理由
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
浮生xs若梦 + 1 + 1 用心讨论,共获提升!
笑海的星星 + 1 + 1 我很赞同!
孤竹 + 1 我很赞同!
joneqm + 1 + 1 用心讨论,共获提升!

查看全部评分

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

 楼主| solly 发表于 2019-11-19 10:16

这个 Crackme 已是相当的简单了。如果不写贴,不写注册机,三~五分钟不到就可找到码了。
 楼主| solly 发表于 2019-11-19 10:19
hfxiang 发表于 2019-11-19 10:09
这个好像是太专业了,学习起来有困难

这个就是一个裸*奔的结构清晰的货,已是很简单的了。。。
头像被屏蔽
w780628d 发表于 2019-11-19 06:52
gunyao 发表于 2019-11-19 09:24
学习一下,给楼主点个赞
hfxiang 发表于 2019-11-19 10:09
这个好像是太专业了,学习起来有困难
孤竹 发表于 2019-11-19 11:12
虽然我看不懂,评分支持一下
笑海的星星 发表于 2019-11-19 14:09
有看没有懂,最基础的还没看懂
Dabingpeng 发表于 2019-11-19 18:22
支持一下
霖僡 发表于 2019-11-19 20:29
高手简单,初学难!赞!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-15 18:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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