Bootstrap

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

[反汇编练习] 160个CrackMe之003。

本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注册机的东西。

其中,文章中按照如下逻辑编排(解决如下问题):

1、使用什么环境和工具

2、程序分析

3、思路分析和破解流程

4、注册机的探索


1、工具和环境:

WinXP SP3 + 52Pojie六周年纪念版OD + PEID + 汇编金手指。

160个CrackMe的打包文件。

下载地址: http://pan.baidu.com/s/1xUWOY  密码: jbnq

注:

1、Win7系统对于模块和程序开启了随机初始地址的功能,会给分析带来很大的负担,所以不建议使用Win7进行分析。

2、以上工具都是在52PoJie论坛下的原版程序,NOD32不报毒,个人承诺绝对不会进行任何和木马病毒相关内容。

image_thumb2_thumb

 

2、程序分析:

想要破解一个程序,必须先了解这个程序。所以,在破解过程中,对最初程序的分析很重要,他可以帮助我们理解作者的目的和意图,特别是对于注册码的处理细节,从而方便我们反向跟踪和推导。

和上一节一样,打开CHM,选择第二个Afkayas,保存下来。运行程序,程序界面如下:

image

这是一个标准的Name/Serial注册码方式,二话不说,来个伪码测试:

Name: 3333     Serial: 44445555

点击OK,弹出了一个错误对话框,You Get Wrong,Try again!

3、思路分析和破解流程:

首先,将程序从OD打开,这次的程序会提示可能有压缩内容,SO,我们不得不使用PEID看看是否有壳,PEID查看情况如下:

image

有压缩内容,但是没有壳,很好,放心地使用OD打开,直接点是。

按照经验,有对话框提示的程序可以通过堆栈查找调用的位置。方法如下:输入伪码,点击OK,弹出错误对话框,此时不要关闭这个对话框,切换到OD,点击暂停程序,然后Ctrl+K到堆栈视图,如下:

image

更具体的分析就不说了,参看002,直接最后一个rtcMsgBox,右键->show call。

vba相关函数请参考这篇文章

将代码直接向上翻看,找到了关键的跳转,JE,代码如下:

00408665   .  66:85F6       test si,si
00408668   .  8945 94       mov dword ptr ss:[ebp-0x6C],eax
0040866B   .  894D AC       mov dword ptr ss:[ebp-0x54],ecx
0040866E   .  8945 A4       mov dword ptr ss:[ebp-0x5C],eax
00408671   .  894D BC       mov dword ptr ss:[ebp-0x44],ecx
00408674   .  8945 B4       mov dword ptr ss:[ebp-0x4C],eax
00408677      74 62         je short 004086DB                        ;  // 爆破的关键
00408679   .  8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;  msvbvm50.__vbaStrCat
0040867F   .  68 C06F4000   push 00406FC0                            ;  UNICODE "You Get It"
00408684   .  68 DC6F4000   push 00406FDC                            ;  ASCII "\r"
00408689   .  FFD6          call esi                                 ;  <&MSVBVM50.__vbaStrCat>
0040868B   .  8BD0          mov edx,eax
0040868D   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
00408690   .  FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;  msvbvm50.__vbaStrMove
00408696   .  50            push eax
00408697   .  68 E86F4000   push 00406FE8                            ;  UNICODE "KeyGen It Now"
0040869C   .  FFD6          call esi
0040869E   .  8945 CC       mov dword ptr ss:[ebp-0x34],eax
004086A1   .  8D45 94       lea eax,dword ptr ss:[ebp-0x6C]
004086A4   .  8D4D A4       lea ecx,dword ptr ss:[ebp-0x5C]
004086A7   .  50            push eax
004086A8   .  8D55 B4       lea edx,dword ptr ss:[ebp-0x4C]
004086AB   .  51            push ecx
004086AC   .  52            push edx
004086AD   .  8D45 C4       lea eax,dword ptr ss:[ebp-0x3C]
004086B0   .  6A 00         push 0x0
004086B2   .  50            push eax
004086B3   .  C745 C4 08000>mov dword ptr ss:[ebp-0x3C],0x8
004086BA   .  FF15 24B14000 call dword ptr ds:[<&MSVBVM50.#595>]     ;  msvbvm50.rtcMsgBox
004086C0   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
004086C3   .  FF15 A8B14000 call dword ptr ds:[<&MSVBVM50.__vbaFreeS>;  msvbvm50.__vbaFreeStr
004086C9   .  8D4D 94       lea ecx,dword ptr ss:[ebp-0x6C]
004086CC   .  8D55 A4       lea edx,dword ptr ss:[ebp-0x5C]
004086CF   .  51            push ecx
004086D0   .  8D45 B4       lea eax,dword ptr ss:[ebp-0x4C]
004086D3   .  52            push edx
004086D4   .  8D4D C4       lea ecx,dword ptr ss:[ebp-0x3C]
004086D7   .  50            push eax
004086D8   .  51            push ecx
004086D9   .  EB 60         jmp short 0040873B
004086DB   >  8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;  msvbvm50.__vbaStrCat
004086E1   .  68 08704000   push 00407008                            ;  UNICODE "You Get Wrong"
004086E6   .  68 DC6F4000   push 00406FDC                            ;  ASCII "\r"
004086EB   .  FFD6          call esi                                 ;  <&MSVBVM50.__vbaStrCat>
004086ED   .  8BD0          mov edx,eax
004086EF   .  8D4D E8       lea ecx,dword ptr ss:[ebp-0x18]
004086F2   .  FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;  msvbvm50.__vbaStrMove
004086F8   .  50            push eax
004086F9   .  68 28704000   push 00407028                            ;  UNICODE "Try Again"
004086FE   .  FFD6          call esi
00408700   .  8945 CC       mov dword ptr ss:[ebp-0x34],eax
00408703   .  8D55 94       lea edx,dword ptr ss:[ebp-0x6C]
00408706   .  8D45 A4       lea eax,dword ptr ss:[ebp-0x5C]
00408709   .  52            push edx
0040870A   .  8D4D B4       lea ecx,dword ptr ss:[ebp-0x4C]
0040870D   .  50            push eax
0040870E   .  51            push ecx
0040870F   .  8D55 C4       lea edx,dword ptr ss:[ebp-0x3C]
00408712   .  6A 00         push 0x0
00408714   .  52            push edx
00408715   .  C745 C4 08000>mov dword ptr ss:[ebp-0x3C],0x8
0040871C   .  FF15 24B14000 call dword ptr ds:[<&MSVBVM50.#595>]     ;  msvbvm50.rtcMsgBox

爆破就不用说了,直接选中JE语句,右键->Binary->Fill with NOPs. 试一试,OK,爆破成功。


4、注册机的探索:

这个程序和002基本一样的,在跳转附近无任何和Name/Serial相关的内容,所以,向上找到这段代码的开头,下断,一路F8记录重要信息。

PS:由于这个代码太长,只将重要片段拿出来。查找开头时不要急,代码真的很长。需要特别注意和Name/Serial相关的部分。

开头下断位置:

004080F0   > \55            push ebp
004080F1   .  8BEC          mov ebp,esp
004080F3   .  83EC 0C       sub esp,0xC
004080F6   .  68 56104000   push <jmp.&MSVBVM50.__vbaExceptHandler>  ;  SE handler installation
004080FB   .  64:A1 0000000>mov eax,dword ptr fs:[0]

获取Name的位置:


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]
004081F2   .  50            push eax                                 ;  // eax=3333地址
004081F3   .  8B1A          mov ebx,dword ptr ds:[edx]
004081F5   .  FF15 F8B04000 call dword ptr ds:[<&MSVBVM50.__vbaLenBs>;  msvbvm50.__vbaLenBstr
004081FB   .  8BF8          mov edi,eax                              ;  // eax=4
004081FD   .  8B4D E8       mov ecx,dword ptr ss:[ebp-0x18]
00408200   .  69FF 385B0100 imul edi,edi,0x15B38                     ;  // edi=edi*0x15B38
00408206   .  51            push ecx
00408207   .  0F80 B7050000 jo 004087C4
0040820D   .  FF15 0CB14000 call dword ptr ds:[<&MSVBVM50.#516>]     ;  msvbvm50.rtcAnsiValueBstr
00408213   .  0FBFD0        movsx edx,ax                             ;  // edx = 第一个字符的ANSI
00408216   .  03FA          add edi,edx                              ;  // edi=edi+edx
00408218   .  0F80 A6050000 jo 004087C4
0040821E   .  57            push edi
0040821F   .  FF15 F4B04000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>;  msvbvm50.__vbaStrI4
00408225   .  8BD0          mov edx,eax                              ;  // eax = 355603 文本
00408227   .  8D4D E0       lea ecx,dword ptr ss:[ebp-0x20]
0040822A   .  FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;  msvbvm50.__vbaStrMove
00408230   .  8BBD 50FFFFFF mov edi,dword ptr ss:[ebp-0xB0]
00408236   .  50            push eax                                 ;  eax=355603
00408237   .  57            push edi                                 ;  edi=0091C5B4
00408238   .  FF93 A4000000 call dword ptr ds:[ebx+0xA4]
0040823E   .  85C0          test eax,eax                             ;  // eax=0
00408240   .  7D 12         jge short 00408254

第一次计算(浮点数):

004082D7   .  FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;  msvbvm50.__vbaHresultCheckObj
004082DD   >  8B8D 58FFFFFF mov ecx,dword ptr ss:[ebp-0xA8]
004082E3   .  8B55 E8       mov edx,dword ptr ss:[ebp-0x18]
004082E6   .  52            push edx                                 ;  // edx=355603
004082E7   .  8B19          mov ebx,dword ptr ds:[ecx]
004082E9   .  FF15 74B14000 call dword ptr ds:[<&MSVBVM50.__vbaR8Str>;  msvbvm50.__vbaR8Str
004082EF   .  D905 08104000 fld dword ptr ds:[0x401008]              ;  // 10.0
004082F5   .  833D 00904000>cmp dword ptr ds:[0x409000],0x0
004082FC   .  75 08         jnz short 00408306
004082FE   .  D835 0C104000 fdiv dword ptr ds:[0x40100C]             ;  // 5.0, 做除法==2。0
00408304   .  EB 0B         jmp short 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                                 ;  // 将值给eax=3100
00408316   .  A8 0D         test al,0xD
00408318   .  0F85 A1040000 jnz 004087BF
0040831E   .  DEC1          faddp st(1),st                           ;  // 加法,355603 + 2
00408320   .  DFE0          fstsw ax
00408322   .  A8 0D         test al,0xD
00408324   .  0F85 95040000 jnz 004087BF
0040832A   .  DD1C24        fstp qword ptr ss:[esp]
0040832D   .  FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;  msvbvm50.__vbaStrR8
00408333   .  8BD0          mov edx,eax                              ;  // eax = 355605 字符串
00408335   .  8D4D E4       lea ecx,dword ptr ss:[ebp-0x1C]
00408338   .  FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;  msvbvm50.__vbaStrMove
0040833E   .  899D 34FFFFFF mov dword ptr ss:[ebp-0xCC],ebx
00408344   .  8B9D 58FFFFFF mov ebx,dword ptr ss:[ebp-0xA8]
0040834A   .  50            push eax
0040834B   .  8B85 34FFFFFF mov eax,dword ptr ss:[ebp-0xCC]          ;  // 355605
00408351   .  53            push ebx
00408352   .  FF90 A4000000 call dword ptr ds:[eax+0xA4]
00408358   .  85C0          test eax,eax                             ;  // eax=0,ecx=" "
0040835A   .  7D 12         jge short 0040836E

第二次计算(浮点数):

004083E3   .  FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;  msvbvm50.__vbaHresultCheckObj
004083E9   >  8B8D 58FFFFFF mov ecx,dword ptr ss:[ebp-0xA8]
004083EF   .  8B55 E8       mov edx,dword ptr ss:[ebp-0x18]          ;  // 355605
004083F2   .  52            push edx
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]             ;  // 355605 * 3 = 1066815.0
00408401   .  83EC 08       sub esp,0x8
00408404   .  DC25 18104000 fsub qword ptr ds:[0x401018]             ;  // 1066815 - 2 = 1066813
0040840A   .  DFE0          fstsw ax                                 ;  // ax = 3900
0040840C   .  A8 0D         test al,0xD
0040840E   .  0F85 AB030000 jnz 004087BF
00408414   .  DD1C24        fstp qword ptr ss:[esp]
00408417   .  FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;  msvbvm50.__vbaStrR8
0040841D   .  8BD0          mov edx,eax                              ;  // eax=1600133
0040841F   .  8D4D E4       lea ecx,dword ptr ss:[ebp-0x1C]
00408422   .  FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;  msvbvm50.__vbaStrMove
00408428   .  899D 2CFFFFFF mov dword ptr ss:[ebp-0xD4],ebx
0040842E   .  8B9D 58FFFFFF mov ebx,dword ptr ss:[ebp-0xA8]
00408434   .  50            push eax                                 ;  1066813
00408435   .  8B85 2CFFFFFF mov eax,dword ptr ss:[ebp-0xD4]
0040843B   .  53            push ebx
0040843C   .  FF90 A4000000 call dword ptr ds:[eax+0xA4]
00408442   .  85C0          test eax,eax
00408444   .  7D 12         jge short 00408458

第三次计算(浮点数):

004084CD   .  FF15 18B14000 call dword ptr ds:[<&MSVBVM50.__vbaHresu>;  msvbvm50.__vbaHresultCheckObj
004084D3   >  8B8D 58FFFFFF mov ecx,dword ptr ss:[ebp-0xA8]
004084D9   .  8B55 E8       mov edx,dword ptr ss:[ebp-0x18]
004084DC   .  52            push edx
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]             ;  // 1066813.0 - (-15.0) = 1066828
004084EB   .  83EC 08       sub esp,0x8
004084EE   .  DFE0          fstsw ax
004084F0   .  A8 0D         test al,0xD
004084F2   .  0F85 C7020000 jnz 004087BF
004084F8   .  DD1C24        fstp qword ptr ss:[esp]
004084FB   .  FF15 48B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrR8>;  msvbvm50.__vbaStrR8
00408501   .  8BD0          mov edx,eax                              ;  // 1066828
00408503   .  8D4D E4       lea ecx,dword ptr ss:[ebp-0x1C]
00408506   .  FF15 94B14000 call dword ptr ds:[<&MSVBVM50.__vbaStrMo>;  msvbvm50.__vbaStrMove

我们的Serial出现了:

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]          ;  // 1066828
004085DB   .  DD9D 1CFFFFFF fstp qword ptr ss:[ebp-0xE4]
004085E1   .  51            push ecx
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 004085F9
004085F1   .  DCBD 1CFFFFFF fdivr qword ptr ss:[ebp-0xE4]            ;  // 做除法
004085F7   .  EB 11         jmp short 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                                 ;  // 把结果送入ax
0040860C   .  A8 0D         test al,0xD
0040860E   .  0F85 AB010000 jnz 004087BF
00408614   .  FF15 34B14000 call dword ptr ds:[<&MSVBVM50.__vbaFpR8>>;  msvbvm50.__vbaFpR8
0040861A   .  DC1D 28104000 fcomp qword ptr ds:[0x401028]
00408620   .  DFE0          fstsw ax                                 ;  //ax=20
00408622   .  F6C4 40       test ah,0x40                             ;  // ah=40
00408625   .  74 07         je short 0040862E

后面做的除法运算和取反,为了处理esi的值,然后做为JE的条件。我们到这里其实就可以试试算出来的字符串“1066828”是否是正确的?哈哈,他肯定是的啦!

00408665   .  66:85F6       test si,si
00408668   .  8945 94       mov dword ptr ss:[ebp-0x6C],eax
0040866B   .  894D AC       mov dword ptr ss:[ebp-0x54],ecx
0040866E   .  8945 A4       mov dword ptr ss:[ebp-0x5C],eax
00408671   .  894D BC       mov dword ptr ss:[ebp-0x44],ecx
00408674   .  8945 B4       mov dword ptr ss:[ebp-0x4C],eax
00408677      74 62         je short 004086DB                        ;  // 爆破的关键
00408679   .  8B35 14B14000 mov esi,dword ptr ds:[<&MSVBVM50.__vbaSt>;  msvbvm50.__vbaStrCat
0040867F   .  68 C06F4000   push 00406FC0                            ;  UNICODE "You Get It"
00408684   .  68 DC6F4000   push 00406FDC                            ;  ASCII "\r"
00408689   .  FFD6          call esi                                 ;  <&MSVBVM50.__vbaStrCat>

至此,序列号的生成过程已经分析完毕。过程中设计到的常量都是使用[0040100A]等固定地址得到的固定值,不用理会,我们可以直接使用。

小结一下:先计算出Name的长度nLen,然后edi=edi*0x15B38+cName, cName是Name第一个字符的ANSI码。然后,计算浮点数10.0/5.0=2.0, edi转换为浮点数,加上2.0,然后结果再乘以3.0,然后减去2,然后再减去-15,得到的值转换为文本,即为正确的序列号。

C/CPP代码:

// CrackMe160.cpp : 定义控制台应用程序的入口点。
// 003

#include "stdafx.h"
#include <stdio.h>
#include "iostream"

char buff[100] = {0};
int _tmain(int argc, _TCHAR* argv[])
{
	printf("160CrackMe-003 Name/Serial\r\n\r\n");
	printf("Name:");
	gets_s(buff,100);
	int nLen = strlen(buff);
	if ( nLen > 0 )
	{
		int nRet = nLen * 0x15B38;
		nRet += buff[0];
		double dRet = (double)nRet;
		dRet += (10.0/5.0);
		dRet *= 3.0;
		dRet -= 2;
		dRet -= -15;
		printf("Serial:%d\r\n",(int)dRet);
	}else{
		printf("Input error!\r\n");
	}
	system("pause");
	return 0;
}

image

转载于:https://www.cnblogs.com/bbdxf/p/3780283.html

;