160个crackme之011

逆向分析是一个考验耐心的事情,所以还是按照步骤一步一步来。

就比如这个程序,其实丢到OD动态调试的话还是比较容易的,但是丢到VB Decompiler里面发现看不太明白了哈哈。

才疏学浅,以作记录

0X00  首先还是打开程序咯,是一个点选数字和'*'、'#'的输入验证码的程序。

另外发现status显示未注册、也没有按钮,根据经验大概就是程序不停循环判断文本框内是否是正确的验证码。

然后成功之后将status变成REGISTERED。

0X01  那么进行爆破,这里我走了一点弯路。。我先进行了静态分析,找到了刚拿到的神器VB Decompiler进行反编译。

但还是分析出了一点代码的逻辑。

左边Command_Click分别对应了程序当中13个按键,分析代码很容易能看出来每个按键的功能。

那么重点应该就在于Timer当中了。

大致分析了一下确实没怎么看太懂。。

Private Sub Timer1_Timer() '404650
  loc_0040479F: var_48 = Text1.Text
  loc_004047D5: ebx = (var_48 = vbNullString) + 1
  loc_004047ED: If (var_48 = vbNullString) + 1 = 0 Then GoTo loc_00404814
  loc_00404806: Command13.Enabled = esi
  loc_00404810: If ebx >= 0 Then GoTo loc_0040484A
  loc_00404812: GoTo loc_00404838
  loc_0040482C: Command13.Enabled = True
  loc_00404836: If ebx >= 0 Then GoTo loc_0040484A
  loc_00404838: 'Referenced from: 00404812
  loc_00404844: ebx = CheckObj(ebx, var_00401E30, 140)
  loc_0040484A: 
  loc_00404870: var_48 = Text1.Text                              //var_48=serial
  loc_004048AA: var_44 = var_48                                  //var_44=serial
  loc_0040491D: For var_24 = 1 To Len(var_44) Step 1             //遍历serial中每一个字符
  loc_0040492F: 
  loc_00404931: If var_F8 = 0 Then GoTo loc_00404A60
  loc_0040494B: var_50 = CStr(Left(var_44, 1))                   //var_50=serial的第一个字符
  loc_0040499D: var_304 = Asc(Mid$(CStr(var_44), CLng(var_24), 1))   //var_304=第i个字符的ASCII码
  loc_004049E2: var_8C = Hex$((var_30C + var_CC))                //var_8C 没有看明白。。。不知道后面两个变量是干什么的
  loc_00404A0C: var_34 = var_34 & Hex$((var_30C + var_CC))
  loc_00404A55: Next var_24
  loc_00404A5B: GoTo loc_0040492F
  loc_00404A60: 'Referenced from: 00404931
  loc_00404A88: If (var_34 = "0817E747D7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C") = 0 Then GoTo loc_00404AD6
  loc_00404AAF: var_eax = Unknown_VTable_Call[ecx+00000054h]
  loc_00404AD6: 'Referenced from: 00404A88

截取了部分代码做了分析。大概就是对文本框的内容进行一系列操作,然后和下面出现的51个字符的字符串进行对比,正确就通过。

索性丢到OD当中进行动态分析

首先知道程序没有加壳,那么先搜索一下字符串发现了一些端倪

大概都是注册码吧。。。

我就随便跟进了一个,调用了_vbaVarTstEq比较,然后找到了关键跳转,下断点修改标志位。

最后爆破成功

0X02  那么接下来分析一下注册的算法吧

在OD动态调试下做一些批注

0040C061   .  50            push eax                                 ; /Step8 = NULL
0040C062   .  8D55 9C       lea edx,dword ptr ss:[ebp-0x64]          ; |
0040C065   .  51            push ecx                                 ; |/var18 = C7EF69B9
0040C066   .  52            push edx                                 ; ||retBuffer8 = 00000010
0040C067   .  FF15 30104000 call dword ptr ds:[<&MSVBVM60.__vbaLenVa>; |\__vbaLenVar
0040C06D   .  50            push eax                                 ; |End8 = NULL
0040C06E   .  8D85 3CFFFFFF lea eax,dword ptr ss:[ebp-0xC4]          ; |
0040C074   .  8D8D 48FEFFFF lea ecx,dword ptr ss:[ebp-0x1B8]         ; |
0040C07A   .  50            push eax                                 ; |Start8 = NULL
0040C07B   .  8D95 58FEFFFF lea edx,dword ptr ss:[ebp-0x1A8]         ; |
0040C081   .  51            push ecx                                 ; |TMPend8 = C7EF69B9
0040C082   .  8D45 DC       lea eax,dword ptr ss:[ebp-0x24]          ; |
0040C085   .  52            push edx                                 ; |TMPstep8 = 00000010
0040C086   .  50            push eax                                 ; |Counter8 = NULL
0040C087   .  FF15 38104000 call dword ptr ds:[<&MSVBVM60.__vbaVarFo>; \__vbaVarForInit
0040C08D   >  85C0          test eax,eax                             ;  设定循环
0040C08F   .  0F84 29010000 je Andréna.0040C1BE
0040C095   .  8D4D BC       lea ecx,dword ptr ss:[ebp-0x44]
0040C098   .  6A 07         push 0x7
0040C09A   .  8D55 8C       lea edx,dword ptr ss:[ebp-0x74]
0040C09D   .  51            push ecx
0040C09E   .  52            push edx
0040C09F   .  FFD3          call ebx                                 ;  msvbvm60.rtcLeftCharVar
0040C0A1   .  8D45 8C       lea eax,dword ptr ss:[ebp-0x74]
0040C0A4   .  8D4D B0       lea ecx,dword ptr ss:[ebp-0x50]
0040C0A7   .  50            push eax
0040C0A8   .  51            push ecx
0040C0A9   .  FFD6          call esi                                 ;  msvbvm60.__vbaStrVarVal
0040C0AB   .  50            push eax                                 ;  eax=name
0040C0AC   .  FF15 D8104000 call dword ptr ds:[<&MSVBVM60.#581>]     ;  msvbvm60.rtcR8ValFromBstr
0040C0B2   .  DD9D 34FFFFFF fstp qword ptr ss:[ebp-0xCC]             ;  将name转换成浮点数
0040C0B8   .  8D55 9C       lea edx,dword ptr ss:[ebp-0x64]
0040C0BB   .  8D45 DC       lea eax,dword ptr ss:[ebp-0x24]
0040C0BE   .  52            push edx
0040C0BF   .  50            push eax
0040C0C0   .  C745 A4 01000>mov dword ptr ss:[ebp-0x5C],0x1
0040C0C7   .  C745 9C 02000>mov dword ptr ss:[ebp-0x64],0x2
0040C0CE   .  FF15 AC104000 call dword ptr ds:[<&MSVBVM60.__vbaI4Var>;  msvbvm60.__vbaI4Var
0040C0D4   .  8D4D BC       lea ecx,dword ptr ss:[ebp-0x44]
0040C0D7   .  50            push eax
0040C0D8   .  8D55 B8       lea edx,dword ptr ss:[ebp-0x48]
0040C0DB   .  51            push ecx
0040C0DC   .  52            push edx
0040C0DD   .  FFD6          call esi                                 ;  msvbvm60.__vbaStrVarVal
0040C0DF   .  50            push eax
0040C0E0   .  FF15 4C104000 call dword ptr ds:[<&MSVBVM60.#631>]     ;  msvbvm60.rtcMidCharBstr
0040C0E6   .  8BD0          mov edx,eax                              ;  第一次取出了第一个字符
0040C0E8   .  8D4D B4       lea ecx,dword ptr ss:[ebp-0x4C]
0040C0EB   .  FF15 BC104000 call dword ptr ds:[<&MSVBVM60.__vbaStrMo>;  msvbvm60.__vbaStrMove
0040C0F1   .  50            push eax                                 ; /String = NULL
0040C0F2   .  FF15 20104000 call dword ptr ds:[<&MSVBVM60.#516>]     ; \rtcAnsiValueBstr
0040C0F8   .  0FBFC0        movsx eax,ax                             ;  计算ASCII码
0040C0FB   .  8985 B4FCFFFF mov dword ptr ss:[ebp-0x34C],eax
0040C101   .  8D8D 7CFFFFFF lea ecx,dword ptr ss:[ebp-0x84]
0040C107   .  DB85 B4FCFFFF fild dword ptr ss:[ebp-0x34C]            ;  大概转换成了十进制的浮点数
0040C10D   .  51            push ecx
0040C10E   .  C785 7CFFFFFF>mov dword ptr ss:[ebp-0x84],0x5
0040C118   .  DD9D ACFCFFFF fstp qword ptr ss:[ebp-0x354]            ;  第一次49,所以第二次50
0040C11E   .  DD85 ACFCFFFF fld qword ptr ss:[ebp-0x354]
0040C124   .  DC85 34FFFFFF fadd qword ptr ss:[ebp-0xCC]             ;  与之前转换的name相加
0040C12A   .  DD5D 84       fstp qword ptr ss:[ebp-0x7C]
0040C12D   .  DFE0          fstsw ax
0040C12F   .  A8 0D         test al,0xD                              ;  不知道在测什么。。可能是看看有没有异常,不管了
0040C131   .  0F85 45130000 jnz Andréna.0040D47C
0040C137   .  FF15 94104000 call dword ptr ds:[<&MSVBVM60.#572>]     ;  msvbvm60.rtcHexBstrFromVar
0040C13D   .  8985 74FFFFFF mov dword ptr ss:[ebp-0x8C],eax          ;  将结果转换成16进制数
0040C143   .  8D55 CC       lea edx,dword ptr ss:[ebp-0x34]
0040C146   .  8D85 6CFFFFFF lea eax,dword ptr ss:[ebp-0x94]
0040C14C   .  52            push edx
0040C14D   .  8D8D 5CFFFFFF lea ecx,dword ptr ss:[ebp-0xA4]
0040C153   .  50            push eax
0040C154   .  51            push ecx
0040C155   .  C785 6CFFFFFF>mov dword ptr ss:[ebp-0x94],0x8
0040C15F   .  FF15 84104000 call dword ptr ds:[<&MSVBVM60.__vbaVarCa>;  msvbvm60.__vbaVarCat
0040C165   .  8BD0          mov edx,eax                              ;  将每次得到的结果拼接到eax后面,第一位是0
0040C167   .  8D4D CC       lea ecx,dword ptr ss:[ebp-0x34]
0040C16A   .  FFD7          call edi                                 ;  msvbvm60.__vbaVarMove
0040C16C   .  8D55 B0       lea edx,dword ptr ss:[ebp-0x50]
0040C16F   .  8D45 B4       lea eax,dword ptr ss:[ebp-0x4C]
0040C172   .  52            push edx
0040C173   .  8D4D B8       lea ecx,dword ptr ss:[ebp-0x48]
0040C176   .  50            push eax
0040C177   .  51            push ecx
0040C178   .  6A 03         push 0x3
0040C17A   .  FF15 9C104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeS>;  msvbvm60.__vbaFreeStrList
0040C180   .  8D95 6CFFFFFF lea edx,dword ptr ss:[ebp-0x94]
0040C186   .  8D85 7CFFFFFF lea eax,dword ptr ss:[ebp-0x84]
0040C18C   .  52            push edx
0040C18D   .  8D4D 8C       lea ecx,dword ptr ss:[ebp-0x74]
0040C190   .  50            push eax
0040C191   .  8D55 9C       lea edx,dword ptr ss:[ebp-0x64]
0040C194   .  51            push ecx
0040C195   .  52            push edx
0040C196   .  6A 04         push 0x4
0040C198   .  FF15 14104000 call dword ptr ds:[<&MSVBVM60.__vbaFreeV>;  msvbvm60.__vbaFreeVarList
0040C19E   .  83C4 24       add esp,0x24
0040C1A1   .  8D85 48FEFFFF lea eax,dword ptr ss:[ebp-0x1B8]
0040C1A7   .  50            push eax                                 ; /TMPend8 = NULL
0040C1A8   .  8D8D 58FEFFFF lea ecx,dword ptr ss:[ebp-0x1A8]         ; |
0040C1AE   .  8D55 DC       lea edx,dword ptr ss:[ebp-0x24]          ; |
0040C1B1   .  51            push ecx                                 ; |TMPstep8 = C7EF69B9
0040C1B2   .  52            push edx                                 ; |Counter8 = 00000010
0040C1B3   .  FF15 C8104000 call dword ptr ds:[<&MSVBVM60.__vbaVarFo>; \__vbaVarForNext
0040C1B9   .^ E9 CFFEFFFF   jmp Andréna.0040C08D
0040C1BE   >  8D45 CC       lea eax,dword ptr ss:[ebp-0x34]
0040C1C1   .  8D8D 4CFFFFFF lea ecx,dword ptr ss:[ebp-0xB4]
0040C1C7   .  50            push eax                                 ; /var18 = NULL
0040C1C8   .  51            push ecx                                 ; |var28 = C7EF69B9
0040C1C9   .  C785 54FFFFFF>mov dword ptr ss:[ebp-0xAC],Andréna.0040>; |0817E7WOD7AFF7C7F82836D74RR7A7F7E7B7C7D826D81KE7B7C
0040C1D3   .  C785 4CFFFFFF>mov dword ptr ss:[ebp-0xB4],0x8008       ; |嗯,将拼接后得到的结果与指定内容进行比较
0040C1DD   .  FF15 5C104000 call dword ptr ds:[<&MSVBVM60.__vbaVarTs>; \__vbaVarTstEq
0040C1E3   .  66:85C0       test ax,ax
0040C1E6   .  74 4C         je short Andréna.0040C234                ; 关键跳转
0040C1E8   .  8B45 08       mov eax,dword ptr ss:[ebp+0x8]
0040C1EB   .  50            push eax
0040C1EC   .  8B10          mov edx,dword ptr ds:[eax]
0040C1EE   .  FF92 38030000 call dword ptr ds:[edx+0x338]
0040C1F4   .  50            push eax
0040C1F5   .  8D45 AC       lea eax,dword ptr ss:[ebp-0x54]
0040C1F8   .  50            push eax
0040C1F9   .  FF15 3C104000 call dword ptr ds:[<&MSVBVM60.__vbaObjSe>;  msvbvm60.__vbaObjSet
0040C1FF   .  8B08          mov ecx,dword ptr ds:[eax]
0040C201   .  68 BC1E4000   push Andréna.00401EBC                    ;  REGISTRIERT
0040C206   .  50            push eax
0040C207   .  8985 30FFFFFF mov dword ptr ss:[ebp-0xD0],eax
0040C20D   .  FF51 54       call dword ptr ds:[ecx+0x54]
0040C210   .  85C0          test eax,eax

这样逻辑就非常清晰了,当然分析中还是用了一些刚学到的小技巧,比如将十六进制存到eax当中的时候发现寄存器窗口无法查看。。

于是在OD的命令行dd eax就能很轻易地看到结果。

根据算法写出注册机即可,但是写的时候发现,逆出来的注册码不是由数字和‘*’、‘#’组成的。。。

这就很尴尬了,于是可以采用爆破的思路。

遍历出50位的注册码,按照算法步骤转换后与正确的验证码对比。找到能正确验证的情况。

但是。。好像运算量挺大的。。于是先搁置了。

总之程序还是把算法分析清楚了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章