160CrackMe-003

本文最后更新于:2021-08-09 晚上

初探

打开程序看到需要输入用户名和序列号尝试输入后提示错误

分析

使用工具查看,发现未加壳,语言是VB。

用OD打开程序,直接搜素错误字符串即可定位。首先还是和002一样,先是获取长度然后进行一些操作再加上NAME[0]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
004081E3   .  FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;  Msvbvm50.__vbaHresultCheckObj
004081E9 > 8B95 50FFFFFF mov edx,dword ptr ss:[ebp-0xB0]
004081EF . 8B45 E4 mov eax,dword ptr ss:[ebp-0x1C] ; 获取输入的name
004081F2 . 50 push eax ; /String = 00004000 ???
004081F3 . 8B1A mov ebx,dword ptr ds:[edx] ; |
004081F5 . FF15 F8B04000 call dword ptr ds:[<&MSVBVM50.__vbaLenBs>; \获取name长度
004081FB . 8BF8 mov edi,eax
004081FD . 8B4D E8 mov ecx,dword ptr ss:[ebp-0x18]
00408200 . 69FF 385B0100 imul edi,edi,0x15B38 ; 长度乘以0x15B38
00408206 . 51 push ecx ; /String = 091C840A ???
00408207 . 0F80 B7050000 jo AfKayAs_.004087C4 ; |
0040820D . FF15 0CB14000 call dword ptr ds:[<&MSVBVM50.#516>] ; \获取输入name的第一次ascii码
00408213 . 0FBFD0 movsx edx,ax
00408216 . 03FA add edi,edx ; 长度计算后加上name[0]
00408218 . 0F80 A6050000 jo AfKayAs_.004087C4
0040821E . 57 push edi ; Msvbvm50.__vbaObjSet
0040821F . FF15 F4B04000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>; 转字符串(十进制)

然后将结果转为浮点数执行了几次操作。

第一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
004082E9   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  转为浮点数
004082EF . D905 08104000 fld dword ptr ds:[0x401008] ; 10
004082F5 . 833D 00904000>cmp dword ptr ds:[0x409000],0x0
004082FC . 75 08 jnz short AfKayAs_.00408306
004082FE . D835 0C104000 fdiv dword ptr ds:[0x40100C] ; 10/5
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
00408316 . A8 0D test al,0xD
00408318 . 0F85 A1040000 jnz AfKayAs_.004087BF
0040831E . DEC1 faddp st(1),st ; +2
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>; 转回去

第二次

1
2
3
4
5
6
7
8
9
004083F5   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  Msvbvm50.__vbaR8Str
004083FB . DC0D 10104000 fmul qword ptr ds:[0x401010] ; *3
00408401 . 83EC 08 sub esp,0x8
00408404 . DC25 18104000 fsub qword ptr ds:[0x401018] ; -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

第三次

1
2
3
4
5
6
7
8
004084DF   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  Msvbvm50.__vbaR8Str
004084E5 . DC25 20104000 fsub qword ptr ds:[0x401020] ; +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

最后的比较也是使用浮点数进行比较,用计算出结果除以我们输入,再与1进行比较。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
004085F1   .  DCBD 1CFFFFFF fdivr qword ptr ss:[ebp-0xE4]            ;  计算的serial/输入
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] ; 结果与1进行比较
00408620 . DFE0 fstsw ax ; 将寄存器的值传给AX
00408622 . F6C4 40 test ah,0x40 ; 比较ah值与0x40
00408625 . 74 07 je short AfKayAs_.0040862E ; 若不相等就会跳到清空esi处
00408627 . BE 01000000 mov esi,0x1 ; 相等esi赋值1
0040862C . EB 02 jmp short AfKayAs_.00408630
0040862E > 33F6 xor esi,esi ; 清空寄存器

这里 fcomp是比较后改变寄存器状态,然后再由fstsw指令将寄存器值传给ax

比较结果 C3 C0
ST(0)>源操作数 0 0
ST(0)<源操作数 0 1
ST(0)=源操作数 1 0
ST(0)不可比较 1 1

看一下FST寄存器,看到寄存器中的值,此时是输入等于计算的时候,看到FST是4000,C3是1

计算器转换一下看的仔细

注册机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "pch.h"
#include <iostream>
#include <Windows.h>
int main()
{
printf("输入name\n");
char name[20];
gets_s(name, 20);
int len = strlen(name);
int serial;
serial = len * 0x15B38;
serial += name[0];
serial = (serial + 2) * 3 - 2 + 15;
printf("serial:%d\n", serial);
return 0;
}

输入正确的serial


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!