吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5877|回复: 24
收起左侧

[会员申请] 申请会员ID:沉默的小光【申请通过】

[复制链接]
吾爱游客  发表于 2016-4-14 17:06
1、申 请 I D:沉默的小光
2、个人邮箱:liangjin0414@163.com
3、原创技术文章:对160个CrackMe之007的探究
之前在论坛里看到“[反汇编练习] 160个CrackMe之xxx”系列贴子(链接http://www.52pojie.cn/forum.php?mod=viewthread&tid=265379),加上自己一直想学习反汇编,于是下载该帖子中的资源,开始尝试自己破解资源下载请参照原帖。
之所以写这个帖子,是因为这是第一个完全由我自己发现的破解思路,计算出一个可以通过程序验证的注册码。
下面开始:
首先打开这个程序
1.PNG
点击Help按钮,它会告诉你,这个crackMe只能通过填码的方式,不能修改原文件(之前6个都是通过修改原文件达到目的的),这对于刚开始研究的我无疑是一个挑战。
点Cancella,是直接删除Codice的值,通过尝试发现,Codice只能输出1~0x7FFFFFFF之间的数,点Register没有任何反映。
开始破解,照之前的经验:
打开OD,附加到这个程序上
2.PNG
点击键盘Alt+E,进入模块查看页面
选择aLoNg3_x模块,右键,跟随入口,进入到这个模块的代码里来
之前已经用工具检查过,这个程序是没有带壳的,因此直接找就好
和以前一样:右键,选择中文搜索引擎,选择搜索ASCII字串
不出所料:找到不少字符串。
3.PNG
选择见过的两个“You MUST insert a valid Long Integer Value in the Code Editor... Thank you :)”,跟入对比后发现这两个位置代码结构类似
这是一个弹框的提示信息,跟着这个字串地址下面的是一个call,说明这个call是一个类似C语言API里的MessageBox的函数,给所有的这个函数写上注释
操作这个字串的地址的上一条语句是一条跳转语句
004430F2  |.  837D FC 00    cmp [local.1],0x0
004430F6  |.  74 3A         je XaLoNg3x_.00443132
说明上面是判断字串是否符合规定的判断,在这条JE语句上下断点,输入符合规定的数字

断下了,往下单步跟,发现一个判断语句
00442FBE  |.  84C0          test al,al
00442FC0      74 30         je XaLoNg3x_.00442FF2
EAX寄存器通常用来作返回值用的,于是怀疑这个判断语句作用,选中je那条语句右键-》二进制-》用NOP填充,下好断点

再次运行程序,填好数字,点下register按钮,到被修改的这一句里断下,一句一句单步步过,同时观察crackMe是否有变化(由第6个crackMe得到的经验)
到了执行过
[Asm] 纯文本查看 复制代码
00442FCA  |.  E8 6101FEFF   call aLoNg3x_.00423130                   ;  ;显示/隐藏

这句后,register按钮消失了,变成这样:
4.PNG
通过这样,推测这是一句显示/隐藏按钮的语句
给所有的这样的call写上注释(ctrl+F,填刚才的命令,ctrl+L一个一个地写注释)
可以发现总共有5个这样的地方,通过对参数分析(register对应的参数ebx+0x2CC,again对应ebx+2B8,edx为0消失,为1显示),能发现
5.PNG
有一个“落单”的call,从它的参数来看,是让again消失的
6.PNG
可以发现这已经是第二步了。其它4个call都是成对出现的,从参数上看,它们是恰好相反的,这和点register和点again按钮反映相反完全相同
下面我们要计算出注册码,就要把上面的
[Asm] 纯文本查看 复制代码
00442FBE  |.  84C0          test al,al
00442FC0      74 30         je XaLoNg3x_.00442FF2

“变成”非0。
人00442FBE上一句call那里下断点,断下后,从寄存器中的值可以看到ecx为Nome的指针,而edx为codice的十六进制数据,还有一个参数不知道有什么作用,暂时不管,从这个call跟进去
发现local.2被赋值成Nome,local.1被赋值成codice
7.PNG
下面通过一个判断(判断Nome是几位,少于5位直接失败)后是一堆对计算,
结构是一个两重循环:
[Asm] 纯文本查看 复制代码
004429F6  |> /8B45 F8       /mov eax,[local.2]                       ;  nome
004429F9  |. |E8 3610FCFF   |call aLoNg3x_.00403A34                  ;  getStringLength
004429FE  |. |83F8 01       |cmp eax,0x1
00442A01  |. |7C 1D         |jl XaLoNg3x_.00442A20
00442A03  |> |8B55 F8       |/mov edx,[local.2]                      ;  nome
00442A06  |. |0FB65432 FF   ||movzx edx,byte ptr ds:[edx+esi-0x1]    ;  取第esi位字符
00442A0B  |. |8B4D F8       ||mov ecx,[local.2]                      ;  nome
00442A0E  |. |0FB64C01 FF   ||movzx ecx,byte ptr ds:[ecx+eax-0x1]    ;  取第eax位
00442A13  |. |0FAFD1        ||imul edx,ecx                           ;  edx = edx * ecx
00442A16  |. |0FAFD7        ||imul edx,edi
00442A19  |. |03DA          ||add ebx,edx
00442A1B  |. |48            ||dec eax
00442A1C  |. |85C0          ||test eax,eax
00442A1E  |.^|75 E3         |\jnz XaLoNg3x_.00442A03
00442A20  |> |46            |inc esi
00442A21  |. |FF4D F4       |dec [local.3]
00442A24  |.^\75 D0         \jnz XaLoNg3x_.004429F6


ebx成了累加器,通过对这个二重循环分析,翻译成C语言代码如下:
[C] 纯文本查看 复制代码
do
        {
                $eax = strlen(nome);
                do
                {
                        $edx = nome[$esi-1];
                        $ecx = nome[$eax-1];
                        $edx *= $ecx;
                        $edx *= $edi;
                        $ebx += $edx;
                        $eax--;
                }while($eax>0);
                $esi++;
                length--;
        }while(length>0);


其实就是照抄啦。
[Asm] 纯文本查看 复制代码
00442A26  |> \8BC3          mov eax,ebx
00442A28  |.  99            cdq
00442A29  |.  33C2          xor eax,edx
00442A2B  |.  2BC2          sub eax,edx
00442A2D  |.  B9 2A2C0A00   mov ecx,0xA2C2A
00442A32  |.  99            cdq
00442A33  |.  F7F9          idiv ecx
00442A35  |.  8BDA          mov ebx,edx                              ;  ebx = edx
00442A37  |.  8B45 FC       mov eax,[local.1]                        ;  codice
00442A3A  |.  B9 59000000   mov ecx,0x59
00442A3F  |.  99            cdq
00442A40  |.  F7F9          idiv ecx                                 ;  codice/0x59
00442A42  |.  8BC8          mov ecx,eax                              ;  eax为商,edx为余数
00442A44  |.  8B45 FC       mov eax,[local.1]                        ;  codice被除数
00442A47  |.  BE 50000000   mov esi,0x50
00442A4C  |.  99            cdq
00442A4D  |.  F7FE          idiv esi                                 ;  codice/0x50
00442A4F  |.  03CA          add ecx,edx
00442A51  |.  41            inc ecx                                  ;  ecx = -1
00442A52  |.  894D FC       mov [local.1],ecx                        ;  ecx = -1
00442A55  |.  3B5D FC       cmp ebx,[local.1]                        ;  ebx = edx


加上程序后面继续处理的,最后是判断ebx和ecx是不是相等,相等的话就成功了。试了好几次,ebx都是0,按代码计算来看,要解出这样一个方程

x%0x50+x/0x59=-1
这样的x是找不到的。对ebx的值跟进发现它来自我们不明白含义的那个参数
[Asm] 纯文本查看 复制代码
00442FB4  |.  A1 30584400   mov eax,dword ptr ds:[0x445830]

对这个地址下内存写入断点,对经过几次尝试,我们修改Nome,Codice或是点register都不会使这个内存的值修改
但是当我输出了一个超过上界的数,如“11111111111”(11个1),再点register,发现被内存断点断下了,再看这个地址的值已经被修改成0x221B了
经过多次试验,发现输入了一个超过上界的数之后虽然会有弹窗,但是会使这个内存地址的值被修改,而且是本次点击后才计算会影响下次的点击结果
最后还是以输入“11111111111”生成的0x221B来进行计算,当然还是利用C语言
[C++] 纯文本查看 复制代码
#include<stdio.h>
#include<string.h>
void main()
{
        int codice=28774115;
        char nome[100]; 
        strcpy(nome,"asdfasf");
        int length = strlen(nome);
        int local2 = (int)nome;
        int $eax,$edx,$ebx,$ecx,$esi,$edi;
        $eax = 0x221B;
        $edi = $eax;
        $ebx = 0;
        $esi = 1;
        do
        {
                $eax = strlen(nome);
                do
                {
                        $edx = nome[$esi-1];
                        $ecx = nome[$eax-1];
                        $edx *= $ecx;
                        $edx *= $edi;
                        $ebx += $edx;
                        $eax--;
                }while($eax>0);
                $esi++;
                length--;
        }while(length>0);
        $eax = $ebx;
        _asm{
                mov eax,$eax
                mov ebx,$ebx
                mov ecx,$ecx
                mov edx,$edx
                mov esi,$esi
                mov edi,$edi
                
                mov eax,ebx
                cdq
                xor eax,edx
                sub eax,edx
                mov ecx,0xA2C2A
                cdq
                idiv ecx
                mov ebx,edx
                mov eax,codice
                mov ecx,0x59
                cdq
                idiv ecx
                mov ecx,eax
                mov eax,codice
                mov esi,0x50
                cdq
                idiv esi
                add ecx,edx
                inc ecx

                mov $ecx,ecx
                mov $ebx,ebx
        }
        printf("ecx:\t%x\n",$ecx);
        printf("ebx:\t%x\n",$ebx);
}

使用这段代码时会发现,增大codice的值会使ecx最终值变大,减小时会使ecx变小,经过几次尝试发现

使用codice=28774115时正好相同
8.PNG
按照上面的方法重新测试之后发现果然可行,弹出again,Nome里的字段变灰
9.PNG
对again下断点发现它和register走的是同一个计算函数,还真是again。
再次相同操作之后,成功。
10.PNG
在做一个注册机的话,在C语言那块利用二分法来自动计算一下codice的值,按照上述步骤再操作一遍就OK了。

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

Hmily 发表于 2016-4-14 17:44
ID:沉默的小光
邮箱:liangjin0414@163.com

申请通过,欢迎光临吾爱破解论坛,期待吾爱破解有你更加精彩,ID和密码自己通过邮件密码找回功能修改,请即时登陆并修改密码!
登陆后请在一周内在此帖报道,否则将删除ID信息。

ps:登录后把文章整理一下重新发到脱壳破解区吧。
ASD1518833577 发表于 2016-4-14 17:58
lzhp529 发表于 2016-4-14 17:59
思念灬给了谁 发表于 2016-4-14 18:03
萌新路过帮顶
樱花-盛开 发表于 2016-4-14 18:13
哇哦 果然厉害!
沉默的小光 发表于 2016-4-14 18:14
感谢Hmily,今后我会尽量分享我自己的成果,大家一同努力进步。顺便报道。

免费评分

参与人数 2热心值 +2 收起 理由
xiaolei7172 + 1 用心讨论,共获提升!
希望不多丶就是 + 1 欢迎欢迎!!

查看全部评分

lilililininini 发表于 2016-4-14 18:19
围观大牛
wangqiustc 发表于 2016-4-14 18:22
一开始还没有看懂
沉默的小光 发表于 2016-4-14 18:29
wangqiustc 发表于 2016-4-14 18:22
一开始还没有看懂

其实就是找到一个新方法来破解那个crackme了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-13 14:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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