# 160个CrackMe 003 Afkayas.2

CrackMe 003是002的加强版,我们看看加强在哪里。

OD运行,发现提示代码可能显示会出现问题,有压缩,用PEDI查一下,

发现程序并没有壳,这样即使有压缩,我们也可以手动脱掉。
首先,伪码检测:

进入OD,查找参考文本字符串,之后Call进去

向上大致查看一下程序的流程,然后找到函数的头部,F2下断,注意这个函数有点长,需要耐心一点

F9跑起来,输入我们的伪码,开始单步调试,还是同样的原则,先F8,遇到不认识的VB API函数就去查一下他是干什么的,我们需要做的是了解程序的流程,再遇到类似vbaobjset或者vbastrset等明显无关的函数时候可以过得稍微过得快一点,知道看到了熟悉的一段代码;

004081E9   > \8B95 50FFFFFF mov edx,dword ptr ss:[ebp-0xB0]
004081EF   .  8B45 E4       mov eax,dword ptr ss:[ebp-0x1C]
004081F2   .  50            push eax                                 ; /String = "444489"
004081F3   .  8B1A          mov ebx,dword ptr ds:[edx]               ; |
004081F5   .  FF15 F8B04000 call dword ptr ds:[<&MSVBVM50.__vbaLenBs>; \__vbaLenBstr
004081FB   .  8BF8          mov edi,eax                              ;  EDI=计算字符串的长度
004081FD   .  8B4D E8       mov ecx,dword ptr ss:[ebp-0x18]
00408200   .  69FF 385B0100 imul edi,edi,0x15B38                     ;  EDI=字符串长度乘以0x15B38
00408206   .  51            push ecx                                 ; /String = "蘦"
00408207   .  0F80 B7050000 jo AfKayAs_.004087C4                     ; |
0040820D   .  FF15 0CB14000 call dword ptr ds:[<&MSVBVM50.#516>]     ; \rtcAnsiValueBstr
00408213   .  0FBFD0        movsx edx,ax                             ;  计算第一个字符的ASCII码值
00408216   .  03FA          add edi,edx                              ;  EDI=字符串长度乘以0x15B38+第一个字符的ASCII码值
00408218   .  0F80 A6050000 jo AfKayAs_.004087C4
0040821E   .  57            push edi
0040821F   .  FF15 F4B04000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>;  msvbvm50.__vbaStrI4
00408225   .  8BD0          mov edx,eax                              ;  EDI结果转成10进制数
00408227   .  8D4D E0       lea ecx,dword ptr ss:[ebp-0x20]

这段汇编代码与CrackMe2中的代码的流程是一样的,算法就是

(name的长度)*0x15B38+第一个字符的ASCII码值)转成10进制字符串,这个简单。

之后,我们再向后看,肯定有不同的位置,发现出现了浮点数运算:

004082E9   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  _msvbvm50._vbaR8Str name转换成浮点数,结果在浮点寄存器里
004082EF   .  D905 08104000 fld dword ptr ds:[0x401008]              ;  将0401008中的硬编码实型存入st0
004082F5   .  833D 00904000>cmp dword ptr ds:[0x409000],0x0
004082FC   .  75 08         jnz short AfKayAs_.00408306
004082FE   .  D835 0C104000 fdiv dword ptr ds:[0x40100C]
00408304   .  EB 0B         jmp short AfKayAs_.00408311
00408306   >  FF35 0C104000 push dword ptr ds:[0x40100C]
0040830C   .  E8 578DFFFF   call <jmp.&MSVBVM50._adj_fdiv_m32>
00408311   >  83EC 08       sub esp,0x8
00408314   .  DFE0          fstsw ax                                 ;  将st0中的值复制到ax中

这里推荐一个介绍x86下的浮点数汇编的博客,很详细

inter x86 浮点寄存器笔记

我们继续对代码进行分析,到跳转条件前一共主要出现了四段浮点数的汇编部分:

第一部分:

004082E7   .  8B19          mov ebx,dword ptr ds:[ecx]
004082E9   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  _msvbvm50._vbaR8Str name转换成浮点数,结果在浮点寄存器里
004082EF   .  D905 08104000 fld dword ptr ds:[0x401008]              ;  将0401008中的硬编码实型存入st0
004082F5   .  833D 00904000>cmp dword ptr ds:[0x409000],0x0
004082FC   .  75 08         jnz short AfKayAs_.00408306
004082FE   .  D835 0C104000 fdiv dword ptr ds:[0x40100C]
00408304   .  EB 0B         jmp short AfKayAs_.00408311
00408306   >  FF35 0C104000 push dword ptr ds:[0x40100C]
0040830C   .  E8 578DFFFF   call <jmp.&MSVBVM50._adj_fdiv_m32>
00408311   >  83EC 08       sub esp,0x8
00408314   .  DFE0          fstsw ax                                 ;  将st0中的值复制到ax中
00408316   .  A8 0D         test al,0xD
00408318   .  0F85 A1040000 jnz AfKayAs_.004087BF
0040831E   .  DEC1          faddp st(1),st                           ;  ;将st(num)和st相加,用和来替换st(num),将st出栈
00408320   .  DFE0          fstsw ax
00408322   .  A8 0D         test al,0xD
00408324   .  0F85 95040000 jnz AfKayAs_.004087BF
0040832A   .  DD1C24        fstp qword ptr ss:[esp]
0040832D   .  FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;  msvbvm50.__vbaStrR8
00408333   .  8BD0          mov edx,eax

其实这部分并没有做什么实质上的工作,不过通过浮点数运算对内存中的数据进行改动(我们后面会发现这些内存地址都用了,但我们并不需要考虑这些,直接当做硬编码处理就可以了)。

第二部分:

004083F3   .  8B19          mov ebx,dword ptr ds:[ecx]
004083F5   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  msvbvm50.__vbaR8Str
004083FB   .  DC0D 10104000 fmul qword ptr ds:[0x401010]             ;  name=name*3
00408401   .  83EC 08       sub esp,0x8
00408404   .  DC25 18104000 fsub qword ptr ds:[0x401018]             ;  name=name-2
0040840A   .  DFE0          fstsw ax
0040840C   .  A8 0D         test al,0xD
0040840E   .  0F85 AB030000 jnz AfKayAs_.004087BF
00408414   .  DD1C24        fstp qword ptr ss:[esp]                  ;  结果存入堆栈
00408417   .  FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;  msvbvm50.__vbaStrR8
0040841D   .  8BD0          mov edx,eax

可以看到,这部分对输入的name进行了简单的浮点运算:name=name*3-2

第三部分:

  004084DD   .  8B19          mov ebx,dword ptr ds:[ecx]
004084DF   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  msvbvm50.__vbaR8Str
004084E5   .  DC25 20104000 fsub qword ptr ds:[0x401020]             ;  ;str+15
004084EB   .  83EC 08       sub esp,0x8
004084EE   .  DFE0          fstsw ax
004084F0   .  A8 0D         test al,0xD
004084F2   .  0F85 C7020000 jnz AfKayAs_.004087BF
004084F8   .  DD1C24        fstp qword ptr ss:[esp]
004084FB   .  FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;  msvbvm50.__vbaStrR8
00408501   .  8BD0          mov edx,eax

又对name进行了简单的操作,name=name-(-0x15);

第四部分:

 004085C8   .  FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;  msvbvm50.__vbaHresultCheckObj
004085CE   >  8B45 E8       mov eax,dword ptr ss:[ebp-0x18]
004085D1   .  50            push eax                                 ;  serial转换成浮点数
004085D2   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  msvbvm50.__vbaR8Str
004085D8   .  8B4D E4       mov ecx,dword ptr ss:[ebp-0x1C]
004085DB   .  DD9D 1CFFFFFF fstp qword ptr ss:[ebp-0xE4]
004085E1   .  51            push ecx                                 ;  我们输入的serila转化成浮点数
004085E2   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  msvbvm50.__vbaR8Str
004085E8   .  833D 00904000>cmp dword ptr ds:[0x409000],0x0
004085EF   .  75 08         jnz short AfKayAs_.004085F9
004085F1   .  DCBD 1CFFFFFF fdivr qword ptr ss:[ebp-0xE4]            ;  name/serial值存入st0
004085F7   .  EB 11         jmp short AfKayAs_.0040860A
004085F9   >  FFB5 20FFFFFF push dword ptr ss:[ebp-0xE0]
004085FF   .  FFB5 1CFFFFFF push dword ptr ss:[ebp-0xE4]
00408605   .  E8 888AFFFF   call <jmp.&MSVBVM50._adj_fdivr_m64>
0040860A   >  DFE0          fstsw ax
0040860C   .  A8 0D         test al,0xD
0040860E   .  0F85 AB010000 jnz AfKayAs_.004087BF
00408614   .  FF15 34B14000 call dword ptr ds:[<&MSVBVM50.__vbaFpR8>>;  msvbvm50.__vbaFpR8
0040861A   .  DC1D 28104000 fcomp qword ptr ds:[0x401028]            ;  ;判断name/serial==1?
00408620   .  DFE0          fstsw ax
00408622   .  F6C4 40       test ah,0x40

第四部分实现的就是上面步骤生成的serial与我们输入的serial进行比较,只不过利用了有一点迷糊性质的浮点数除法,判断结果是否等于1而已。

现在在name=12345的情况下我们得到的serial字符串:

OK,对现在分析得到的serial进行检验:

正确,好的,我们在总结一下算法

首先通过(name的长度)*0x15B38+第一个字符的ASCII码值)转成10进制字符串算出serial,然后serial*3-0x2+0x15算出serial。

写出注册机:(python)

str1=raw_input(‘input your name:‘)
length=str1.__len__()
c=ord(str1[0])
s=length*0x15B38+c
serial=s*3-0x2+0x15
print serial

结果:

检验:

最后,其实很简单,不过用浮点数汇编来迷惑罢了。

时间: 2024-10-28 04:25:53

# 160个CrackMe 003 Afkayas.2的相关文章

160个CrackMe 002 Afkayas.1

首先,同样的操作,PEID查壳: VB的程序,没有壳,OK,注意一下VB中的函数就可以了,这里推荐一个微博,总结了在逆向中常用到的VB的函数 VB程序逆向反汇编常见的函数 试着自己运行: OD运行起来,右键,查找,查找所有参考文本字符串,找到错误字符串的位置 看到我们的错误字符串了,You Get Wrong,并且在上面还发现了应该是正确的字符串,两个字符串相距不远,嗯嗯,这个题目应该不难(至少跳转会少些..) 双击字符串进入位置,发现了跳转指令 在跳转的位置F2下断,重新运行程序,输入我们瞎扯

[反汇编练习] 160个CrackMe之002

[反汇编练习] 160个CrackMe之002. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 1.工具和环境: WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指. 160个CrackMe的打包文件. 下载地址: ht

[反汇编练习] 160个CrackMe之020

[反汇编练习] 160个CrackMe之020. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大

[反汇编练习]160个CrackMe之001

原地址:http://www.cnblogs.com/lopezycj/archive/2012/05/16/unity3d_tuchao.html Unity3D吐槽1--FBX导入 Unity3d用了也不久,也就几个月时间.插件很丰富,但有的是在很贵.编辑器写脚本还是不错,挺喜欢的,写好了,就能用,只是有些数据修改了脚本就无法保存了,场景内脚本控制的变量数据.如果要改脚本,就得先记录,后处理. 从3ds max导出带有动作的fbx文件,放进Unity3d里发生了如下的如下的错误: Impor

[反汇编练习] 160个CrackMe之024

[反汇编练习] 160个CrackMe之024. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大

[反汇编练习] 160个CrackMe之023

[反汇编练习] 160个CrackMe之023. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大

[反汇编练习] 160个CrackMe之021

[反汇编练习] 160个CrackMe之021. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大

[反汇编练习] 160个CrackMe之015

[反汇编练习] 160个CrackMe之015. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大

[反汇编练习] 160个CrackMe之016

[反汇编练习] 160个CrackMe之016. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西. 其中,文章中按照如下逻辑编排(解决如下问题): 1.使用什么环境和工具 2.程序分析 3.思路分析和破解流程 4.注册机的探索 ---------------------------------- 提醒各位看客: 如果文章中的逻辑看不明白,那你一定是没有亲手操刀!OD中的跳转提示很强大