适合新手的160个creakme(三)


先跑一下,这个程序应该是有定时器,多久之后自动开启,测试一下输入,序列号以字母方式输入会出现类型不匹配,之后程序自动退出

但是如果以数字方式输入序列号,则会出现,Try Again,所以这里序列号应该是一个数字

直接找Try Again这个字符串的位置,同上一题,在IDA中还是找不到,所以看Ollydbg,在地址4086f9处,这里是前一部分的标号为

004086DB loc_4086DB

应该是从下面这句跳转过来的

.text:00408677                 jz      short loc_4086DB

验证一下,将00408677处的jz改成jnz,74改75,然后输入序列号111,则可以发现成功了

剩下的就是算法了。

从这个位置往前找,标志位应该是下面这句设置的

.text:00408665                 test    si, si

再往前找,有下面两句影响了si的值

.text:0040862E                 xor     esi, esi

.text:00408653                 neg     esi
xor的操作由下面这段代码决定

.text:0040860A                 fnstsw  ax
.text:0040860C                 test    al, 0Dh        ;低位为0Dh
.text:0040860E                 jnz     loc_4087BF
.text:00408614                 call    ds:__vbaFpR8
.text:0040861A                 fcomp   ds:dbl_401028
.text:00408620                 fnstsw  ax
.text:00408622                 test    ah, 40h        ;也就是说ah不能为40h
.text:00408625                 jz      short loc_40862E
.text:00408627                 mov     esi, 1
.text:0040862C                 jmp     short loc_408630
.text:0040862E ; ---------------------------------------------------------------------------
.text:0040862E
.text:0040862E loc_40862E:                             ; CODE XREF: .text:00408625↑j
.text:0040862E                 xor     esi, esi      ;不能走到这里,esi被清零后就会跳到错误路径
.text:00408630
.text:00408630 loc_408630:                             ; CODE XREF: .text:0040862C↑j

往前找到判断函数为__vbaFpR8的返回值,它的高16位不能为40h,这个是浮点寄存器的值

__vbar8Str   将一个字符串转为双精度单精度浮点型(8个字节)的数值形式

.text:004085CE                 mov     eax, [ebp-18h]      ;可以看出函数局部变量值ebp-18h表示的是序列号字符串
.text:004085D1                 push    eax
.text:004085D2                 call    ds:__vbaR8Str      ;此时参数为unicode编码字符串"111",也就是输入的序列号字符串
.text:004085D8                 mov     ecx, [ebp-1Ch]      ;根据下面这个值又可以推测出这个地方局部变量的值
.text:004085DB                 fstp    qword ptr [ebp-0E4h]
.text:004085E1                 push    ecx            
.text:004085E2                 call    ds:__vbaR8Str      ;此时参数为unicode编码字符串"4533559"
.text:004085E8                 cmp     dword_409000, 0
.text:004085EF                 jnz     short loc_4085F9
.text:004085F1                 fdivr   qword ptr [ebp-0E4h]
.text:004085F7                 jmp     short loc_40860A

向上追到这里就可以分析出ebp-18h和ebp-1ch这两个局部变量的值,后面的浮点运算就是比较这两个值,只不过换了形式而已。直接将4533559作为序列号输入,发现直接就可以输出正确结果了。

关于字符串"4533559"的来源就是计算序列号的算法的结果。

过一下整个这段函数,其实只需要关注vbaR8Str、__vbaStrMove、__vbaStrR8这几个函数,其他函数可以直接过掉,整个流程就是不断的将字符串转成浮点数,进行操作之后又转回字符串。

整个算法流程如下: