逆向游乐园第五关

预备知识

1.关于调试器和反编译工具简介

OLLYDBG是一个新的动态追踪工具,将IDA与SoftICE结合起来的思想,Ring 3级32位调试器,非常容易上手,己代替SoftICE成为当今最为流行的调试解密工具了。同时还支持插件扩展功能,是目前最强大的调试工具。
IDA PRO简称IDA(Interactive Disassembler),是一个世界顶级的交互式反汇编工具,有两种可用版本。标准版(Standard)支持二十多种处理器。高级版(Advanced)支持50多种处理器。
UPX(the Ultimate Packer for eXecutables)是一款先进的可执行程序文件压缩器,压缩过的可执行文件体积缩小50%-70%,这样减少了磁盘占用空间、网络上传下载的时间和其它分布以及存储费用。通过UPX压缩过的程序和程序库完全没有功能损失和压缩之前一样可正常地运行,对于支持的大多数格式没有运行时间或内存的不利后果。UPX支持许多不同的可执行文件格式包含Windows 95/98/ME/NT/2000/XP/CE程序和动态链接库、DOS程序、Linux可执行文件和核心。
WinHex是一个专门用来对付各种日常紧急情况的小工具。它可以用来检查和修复各种文件、恢复删除文件、硬盘损坏造成的数据丢失等。同时它还可以让你看到其他程序隐藏起来的文件和数据。总体来说是一款非常不错的16进制编辑器。得到ZDNetSoftwareLibrary五星级最高评价,拥有强大的系统效用。

2.PE查壳工具

PEiD(PE Identifier)是一款著名的查壳工具,其功能强大,几乎可以侦测出所有的壳,其数量已超过470种PE文档的加壳类型和签名。
ExEinfo PE是一款免费的Win32可执行程序检查器,它可以检查程序的打包方式,exe保护等,可以帮助开发人员对程序进行编译。

3.汇编指令

在这里插入图片描述

4.寄存器

EAX是“累加器”(accumulator),它是很多加法乘法指令的缺省寄存器。
EBX是“基地址”(base)寄存器,在内存寻址时存放基地址。
ECX是计数器(counter),是重复(REP)前缀指令和LOOP指令的内定计数器。
EDX则总是被用来放整数除法产生的余数。
ESI/EDI分别叫做“源/目标索引寄存器”(source/destination index),因为在很多字符串操作指令中,DS:ESI指向源串,而ES:EDI指向目标串。
EBP是“基址指针”(BASE POINTER),它最经常被用作高级语言函数调用的“框架指针”(frame pointer)。

5.Little-endian(小端序)

数据的高位字节存放在地址的高端,低位字节存放在地址低端。

实验目的

通过该实验了解调试工具和反编译工具的使用方法,能够通过分析样本中的详细信息,进行程序的爆破或者算法的还原突破程序的限制,本次实验主要针对VB编写的程序。

实验环境

在这里插入图片描述
服务器:Windows XP SP3,IP地址:随机分配
辅助工具:Ollydbg、PEiD 0.95、ExeinfoPE、IDA Pro v6.8、Delphi Decompiler、UPX UnPacker、WinHex
破解程序:bjanes.1、bjanes.2、blaster99

实验步骤一

首先利用侦壳子、工具对样本(三个CrackMe)进行侦测分析,判断是否存在保护,然后对于存在暗桩的程序进行一部处理,最后对算法过程等分析回溯。
首先,我们对程序进行查壳分析。
在这里插入图片描述
VB程序,我们用OD打开,也能看出,这是标准的VB。
在这里插入图片描述
运行一下,看看报错信息。
在这里插入图片描述
我们搜索字符串。
在这里插入图片描述
跟进错误信息,往上找到函数头部下断。
在这里插入图片描述
然后我们随意填写注册码,然后单步分析。
在这里插入图片描述
取字符串长度,判断是不是等于9,不等于就跳到注册码错误地方。
在这里插入图片描述
然后取字符串长度,对比ebp-18的值。Ebp-18是从1开始自增的,而且不能大于注册码长度,注册码长度要求是9位,也就是最大为9。我们继续往下看。
在这里插入图片描述
判断迭代的每位是不是大于‘9’。
在这里插入图片描述
再判断是不是大于30也就是‘0’。
综上就是检测注册码是不是纯数字,如果不是就好像影响
在这里插入图片描述

在这里插入图片描述
导致下方
在这里插入图片描述
004038AD处跳转到注册码错误。往下看:
在这里插入图片描述
此处是取ebp-18,也就是从一开始迭代的那个值,到9。让它与2进行异或运算。
在这里插入图片描述
然后在取注册码迭代到的当前位,入栈,通过AnsivalueBstr获取到它的Ansii码。然后通过vba8Str压入浮点运算器ST0,然后进行双精度浮点运算。减去48,值弹出到ebp-C8。
再此说一下,VB的所有算数运算,均为浮点运算。也就是说每位减去48。
在这里插入图片描述
随后我们来到了关键点,先将之前与2异或的密文转换为char。然后用vb的vbaVarTstNe进行不等比较。
在这里插入图片描述
如果不等,就返回FFFFF,相等则零。
Ebp-80是我们用户输入的当前位(注意,是浮点类型的)。
Ebp-D0是密文的当前位的char类型。
我们此处需要让其相等,也就是返回0值,作者是用的不等检测的相等。
在这里插入图片描述
往下看可以看到:

00403A01 | 66 85 FF              | test di,di                                    |
00403A04 | 75 1C                 | jne bjanes.1.403A22                           |

很明显,检测di是否为0。
上文用TstNe检测的结果返回给了eax,然后又给了edi。

004039B6 | FF 15 A0 10 40 00     | call dword ptr ds:[<&__vbaVarTstNe>]          | 两位进行比较
004039BC | 8B F8                 | mov edi,eax                                   | 此处关键点 FFFFFF

所以此处检测如果vbaVarTstNe返回的不为0,也就是当前位不与明文相等,则执行004033A04处的跳转。
在这里插入图片描述
如果执行了,就直接跳转到了注册码错误弹窗,而此处跳过了一个jmp,对就是00403A1D处的,他是构成一个while循环的关键,但是跳过了,就不再继续迭代下一位了,so我们可知vbaVarTstNe是用来检测相等的。而ebp-18在此自增+1。也就是从1一直加到9。
我们可得算法:
1~9与2进行每位异或加48,就是注册码了。
在这里插入图片描述
在这里插入图片描述

实验步骤二

首先我们对此程序进行查壳分析:
在这里插入图片描述
VB程序,没加壳,运行程序查看一下有哪些考点。
在这里插入图片描述
有一个弹窗,需要我们去掉。
在这里插入图片描述
有报错。
那么我们直接用VB的反编译工具进行查看,是否能够还原代码。
在这里插入图片描述
非常顺利,程序能够还原出来关键点,看样子这个程序很好搞定了,此处是From_Load的事件,它弹了一个MsgBox。
我们OD打开,直接找Private Sub Form_Load() '402C17这个402c17处,往下翻能看到调用这个对话框的指令。
在这里插入图片描述

00402CFE | E8 1D E4 FF FF        | call <blaster99.rtcMsgBox>                    | 关键Call Nop掉即可

我们将上述行nop掉,即可去除弹窗。
然后转过来,我们看主要程序考点,注册。它的按钮事件也被还原了。
在这里插入图片描述
然后,注册码似乎也被鲜明的显示了出来。

loc_004028E3: If (var_58 = "2G83G35Hs2") + 1 = 0 Then GoTo loc_004029DC
loc_00402991: var_44 = MsgBox("Danke, das Passwort ist richtig !", CLng(CLng(49)), "Glückwunsch !", 10, 10)

注册码就是2G83G35Hs2。
我们试一试:
在这里插入图片描述
Ok,完美,这个程序就这么被轻易搞定,主要是他还是固定注册码的,相对较为简单。

实验步骤三

首先我们进行外壳分析:
在这里插入图片描述
OK,是VB6.0的东西。我们可以继续使用VB Decompiler进行函数定位等。
在这里插入图片描述
很轻易的就容易发现这段程序的Check it按钮事件。
但是于此同时粗读代码,能看到此处有SmartCheck弹窗,一开始没理解什么意思……仔细看,是利用了time函数判断了一段代码的运行时常,如果超时则弹窗,那么这就明白了。这是反调试机制,因为使用调试器的时候,你大部分分析代码的时候使用了单步。他此处检测超时5s,当然程序自己运行不会产生暂停,自然不会超时,但是单步会造成了长时间的停顿。

loc_00404479: If CLng(Timer) <= 5 Then GoTo loc_0040452C

这句我们用od定位过去。
在这里插入图片描述

00404479 | 0F 8E AD 00 00 00     | jle bjcm30a.40452C                            |

跳过了smartcheck的弹窗,我们为了调试方便,可以强制跳转,使用jmp修改。
在这里插入图片描述
这样无论如何,都不对出现超时的Check了。此处多处一个nop,是因为jmp所占字节小于jle的长度,所以用nop补位,不影响。
在这里插入图片描述
在这里插入图片描述
好,我们在按钮事件头部下断点,进行一步步单步分析。
在这里插入图片描述
跳过冗长的初始化阶段。
在这里插入图片描述
此处有一个冗长单并没有什么卵用的for循环在浪费时间,我们直接在jmp下面f4跳过此处。(注意下方之前提到改过的时间检验跳,没改的注意强行跳过)
在这里插入图片描述
此处才是真正的算法的开端。
在这里插入图片描述
然后读取用户的输入。
在这里插入图片描述
检测长度是否小于5。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此处是统计与第一位相等的数量,与用户输入的长度-1,之间关系。
我们向下可以看到:

00404E27 | FF 15 6C 10 40 00     | call dword ptr ds:[<&__vbaVarTstEq>]          |

处的比较有何关联,当然此处是最后决定是否成功的关键。
所以以此点向上,可以回溯到真正的另一处算法循环。
在这里插入图片描述
从00404A7F开始差不多是真正的算法了。再一次获取输入的字符串长度然后给B0,然后获取其Hex的值给9C,然后给A8,当然这里不是关键,我们往下看。
在这里插入图片描述
然后A8又给了C0,最后去其字符串形式给E0,继续取用户输入的第一位的Hex然后给90。
在这里插入图片描述
此时到了算法关键的第一步,也就是比对的第一个值。取第一位的hex然后压入乘号,然后压入注册码长度,做乘法运算。值放在ecx中。
在这里插入图片描述
然后此处是把字符串的每位取Hex相加。
这个循环是比较字符串每位Hex值相加的结果与第一位Hex乘以字符串长度的值。
在这里插入图片描述
然后比较以上两种算法是否同时成立。
由此可以推出算法就是与第一位相同个数不能超过字符串长度-1且每位Hex相加和字符串长度和等于第一位Hex乘以字符串长度。
那么符合的自然是333242424:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值