破除Hide The IP的网络验证
 
文/图 Layper
 
玩了那么久的**,还没有认真的尝试网络验证**。一直都觉得网络**很麻烦,搞定Hide The IP这款软件给了我很大的信心,只要方法得当,**此类软件也是非常简单的。下面大家就看我是怎么*****它的。
 
准备工具:OD、PEiD、EasyPHP、dede等。
 
使用dede生成MAP文件
 
首先用PEiD侦壳,非常好,竟然没有加壳,免去了脱壳的麻烦,如图1所示。这款软件是用Delphi 7.0编写的。我们用**Delphi的利器dede来“看看”它。
 
 
 

破除Hide The IP的网络验证

 


图1
 
用dede载入Hide The IP后,dede开始处理程序,处理完成之后,会跳出“转储成功”消息框,按“确定”按钮就会出现如图2所示的提示框,点击“yes”。因为这个功能是帮助我们扩展分析Delphi程序的单元和类及其他,获取更多的信息对我们是大有益处的,所以要选择“yes”。同样,后面的“识别标准VCL过程”也是选择“yes”,这也是非常重要的,如图3所示。
 
 
 

破除Hide The IP的网络验证

 


图2
 
 
 

破除Hide The IP的网络验证

 


图3
 
dede是专门为逆向Delphi(除.net程序外)而设计的,对Delphi程序的符号、函数识别率很高(dede这个功能只有IDA能与之一较天下)。本文dede是用来辅助OD的,如果一开始就用OD来**,你会发觉困难多了。
 
dede经过较长时间分析后,终于出现了如图4所示的结果,点击“Done”之后,接下来就是用dede为OD分析做准备了:导出“map”文件,如图5所示。map文件能够帮助我们创建包含有用的识别信息,包括事件处理和控件参考。在OD中,我们使用插件“GODUP”即可导入,如此在OD中进行分析就不会困难了。
 
 
 

破除Hide The IP的网络验证

 


图4
 
 
 

破除Hide The IP的网络验证

 


图5
 
 
 
使用OD分析软件
 
这款软件是有时间限制的,输入假的注册信息后,会出现如图6所示的错误提示,在OD中点击右键,选择“查找->所有参考文本串”,会找到以下的错误提示信息:
 
 
 

破除Hide The IP的网络验证

 


图6
 
 
 
文本字串参考位于 HideTheI:CODE,条目 6502
 
地址=004EEECB
 
文本字串=ASCII "Invalid registration."
 
 
 
双击来到CPU窗口处:
 
004EEECB . B>mov ecx, 004EF118 ;ASCII "Invalid registration.来到这里
 
向上看找到是从004EED31分支跳转到这个出错的,所以断点应该在004EED31之前,我下在004EEC58处。
 
004EEC58   .  5>push  ebp ;在这里下断
 
004EEC59   .  8>mov  ebp, esp
 
004EEC5B   .  B>mov  ecx, 8
 
如果大家跟踪过Delphi文件就知道,Delphi程序有许多库函数,如果人工识别是非常困难的,而用前面的map文件来解析反汇编代码,则会使它更具可读性。
 
在OD中选择“插件->GODUP Plugin->Map Loader”中的“Load labels”和“Load comments”,载入刚才用dede生成的“hide the ip.map”文件,这样GODUP插件就会导入map文件中解析出来的标签和注释了。我们来分析一下解析后的代码。
 
 
 
004EEC58 >push  ebp ; <[email protected]
;控件Button1的Click函数开始
004EEC59  mov  ebp, esp
004EEC5B  mov  ecx, 8
004EEC60  push  0
004EEC62  push  0
004EEC64  dec  ecx
004EEC65  jnz  short 004EEC60
004EEC67  push  ebx
004EEC68  push  esi
004EEC69  push  edi
004EEC6A  mov  ebx, eax
004EEC6C  xor  eax, eax
004EEC6E  push  ebp
004EEC6F  push  <->[email protected]>
004EEC74  push  dword ptr fs:[eax]
004EEC77  mov  dword ptr fs:[eax], esp
004EEC7A  mov  dl, 1
004EEC7C  mov  eax, dword ptr [416D8C]
004EEC81 >call  00403B38  ;  ->System.TObject.Create(TObject;Boolean);
004EEC86  mov  dword ptr [ebp-4], eax
004EEC89  mov  dl, 1
004EEC8B  mov  eax, dword ptr [416D8C]
004EEC90 >call  00403B38  ;  ->System.TObject.Create(TObject;Boolean);
004EEC95  mov  esi, eax
004EEC97  lea  edx, dword ptr [ebp-C]
004EEC9A >mov  eax, dword ptr [ebx+300>;  *TForm3.Edit1:TEdit
004EECA0 >call  004478D8 ;->Controls.TControl.GetText(TControl):TCaption;
;得到E-mail的邮箱地址[email protected]
004EECA5  mov  ecx, dword ptr [ebp-C]
004EECA8  lea  eax, dword ptr [ebp-8]
004EECAB  mov  edx, 004EEFEC;ASCII "email="
004EECB0 >call  00404C48; ->[email protected]
;把“email=”和[email protected]”连接成“email= [email protected]
004EECB5  mov  edx, dword ptr [ebp-8]
004EECB8  mov  eax, dword ptr [ebp-4]
004EECBB  mov  ecx, dword ptr [eax]
004EECBD >call  dword ptr [ecx+38] ; ->TStringList.Add(string)
004EECC0  lea  edx, dword ptr [ebp-14]
004EECC3 >mov  eax, dword ptr [ebx+304>;*TForm3.Edit2:TEdit
004EECC9 >call  004478D8 ; ->Controls.TControl.GetText(TControl):TCaption;
;获取Serial key的***1357924680
004EECCE  mov  ecx, dword ptr [ebp-14]
004EECD1  lea  eax, dword ptr [ebp-10]
004EECD4  mov  edx, 004EEFFC ;ASCII "ser="
004EECD9 >call  00404C48 ;->[email protected]
;连接字符串成ser=1357924680
004EECDE  mov  edx, dword ptr [ebp-10]
004EECE1  mov  eax, dword ptr [ebp-4]
004EECE4  mov  ecx, dword ptr [eax]
004EECE6 >call  dword ptr [ecx+38] ;->TStringList.Add(string)
004EECE9  xor  eax, eax
004EECEB  push  ebp
004EECEC  push  <->[email protected]>
004EECF1  push  dword ptr fs:[eax]
004EECF4  mov  dword ptr fs:[eax], esp
004EECF7  lea  eax, dword ptr [ebp-18]
004EECFA  push  eax
004EECFB >mov  eax, dword ptr [ebx+31C>;*TForm3.ip1:TIdHTTP
;注意这里开始使用TIdHTTP控件了,这个是我判断它用网络验证的依据
004EED01  mov  ecx, dword ptr [ebp-4]
004EED04  mov  edx, 004EF00C ;ASCII http://www.hide-the-ip.com/checkreg.php
;这个是验证网页了
004EED09  call  0048077C
004EED0E  mov  edx, dword ptr [ebp-18]
;在这里多下个断点,因为004EED09处会引起一个异常,异常之后Shift+F9返回到这里,返回的字符串是“00FE0894, (ASCII "no")”
004EED11  mov  eax, esi
004EED13  mov  ecx, dword ptr [eax]
004EED15 >call  dword ptr [ecx+2C];->TStringList.SetTextStr(string)
004EED18  lea  ecx, dword ptr [ebp-1C]
004EED1B  xor  edx, edx
004EED1D  mov  eax, esi
004EED1F  mov  edi, dword ptr [eax]
004EED21 >call  dword ptr [edi+C];->TStringList.Get(Integer)
004EED24  mov  eax, dword ptr [ebp-1C];00FFC514, (ASCII "no")
004EED27  mov  edx, 004EF03C  ; ASCII "yes"
004EED2C >call  00404D48 ; ->[email protected];
;比较字符串是否是yes
004EED31  jnz  004EEEC4 ;不是则跳到出错

 
如果还未能确定是否有在线验证,保持前面OD设置的两个断点004EEC58和004EED0E,输入信息运行,再次下断在004EED0E后,我们在OD处下函数断点:Bp recv。
 
Recv是常用的网络**断点函数,recv()函数原型为:int recv(int sockfd,void *buf,int len,unsigned int flags);,其中Sockfd是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度;Flags也被置为0。Recv()返回实际上接收的字节数,当出现错误时,返回-1并置相应的errno值。
 
F9运行后断在下面的代码处。
 
71A2615A >  8BFF  mov  edi, edi
71A2615C  55  push  ebp
71A2615D  8BEC  mov  ebp, esp
71A2615F  83EC 10  sub  esp, 10
71A26162  53  push  ebx

 
Recv成功断在了71A2615A,这时我们看OD右下方的堆栈窗口。
 
 
 
0012F4DC   0046DAC2  /CALL到recv来自HideTheI.0046DAC0
0012F4E0   00000260  |Socket = 260
0012F4E4   001E4008  |Buffer = 001E4008
;此为缓冲区地址,以你的机子为准
0012F4E8   00008000  |BufSize = 8000 (32768.)
0012F4EC   00000000  \Flags = 0

 
在OD命令行输入“DD 001E4008”,然后保持recv断点不变,“Alt+F9”返回,这时可以看到OD左下方的数据窗口的数据变为如下所示的代码。
 
001E4008  50545448  HTTP
001E400C  312E312F  /1.1
001E4010  30303220   200
001E4014  0D4B4F20   OK.
往下拉动数据窗口可以看到这样的代码:
001E4108  746E6F43   Cont
001E410C  2D746E65   ent-
001E4110  65707954   Type
001E4114  6574203A   : te
001E4118  682F7478   xt/h
001E411C  0D6C6D74   tml.
001E4120  6E0A0D0A   ...n
001E4124  0000006F   o...
001E4128  00000000   ....

 
出现字符串“no”了,之后就会回到下一个断点004EED0E了。
 
从上面的代码我们可以看出:这款软件使用了网络验证;网络验证的页面是http://www.hide-the-ip.com/checkreg.php,连接起注册信息则为http://www.hide-the-ip.com/checkreg.php?email=layper%4012%2Ecom&ser=1357924680;验证之后要返回“yes”,如果是“no”则出错。
 
伪装服务器和验证页面
 
网络验证**主要是要找出主机的地址和验证页面,然后用一台机器来伪装成验证主机。这款软件的**我用伪装数据包来**,即先伪装服务器和验证页面获取伪装的数据包后,恢复原先的网络验证,在程序中直接修改数据包来进行**的。
 
既然知道了验证网址是www.hide-the-ip.com和验证页面是checkreg.php,我们就把自己的机器伪装成www.hide-the-ip.com,建立一个文件checkreg.php,把网络验证改为本机验证。一般伪装主机分三步走。
 
1)修改Hosts文件
 
在你的系统盘的路径“WINDOWS\system32\drivers\etc”下找到hosts,用记事本打开后,在里面添加一行:
 
127.0.0.1   www.hide-the-ip.com
 
修改之后保存,这样你的机器就会把www.hide-the-ip.com解析为自己的机器了,登录www.hide-the-ip.com就是登录本机了。
 
2)建立验证页面
 
用记事本新建一个文件,在里面输入:yes,保存为checkreg.php,验证页面就构造好了。
 
3)架构服务器
 
这款软件使用的页面是PHP文件,所以我们要在本机架构一台PHP服务器。在网上下载一个EasyPHP,把我们的checkreg.php文件保存到EasyPHP所在目录中的www文件夹中,接着运行EasyPHP.exe,单击“Apache”,选择“开始”,如图7所示,到这里我们就伪装完成了。
 
 
 

破除Hide The IP的网络验证

 


图7
 
再次跟踪验证部分
 
重新把Hide The IP载入OD之后,输入注册信息,再次断在004EEC58,F9或Shift+F9运行到断点004EED0E,我们再来看看是否有变化。
 
004EED0E  .>mov  edx, dword ptr [ebp-18]
;前面是“no”,现在是“yes”
004EED11  .>mov  eax, esi
004EED13  .>mov  ecx, dword ptr [eax]
004EED15 > .>call  dword ptr [ecx+2C] ;->TStringList.SetTextStr(string)
004EED18  .>lea  ecx, dword ptr [ebp-1C]
004EED1B  .>xor  edx, edx
004EED1D  .>mov  eax, esi
004EED1F  .>mov  edi, dword ptr [eax]
004EED21 > .>call  dword ptr [edi+C] ; ->TStringList.Get(Integer)
004EED24  .>mov  eax, dword ptr [ebp-1C] ;注意这里00FFD33C, (ASCII "yes")
004EED27  .>mov  edx, 004EF03C ;ASCII "yes"
004EED2C > .>call  00404D48 ;->[email protected];
004EED31  .>jnz  004EEEC4 ;这里不再跳转到出错

 
原本以为这样就可以完成**了,谁知下面又出现了一个拦路虎。
 
004EED37  lea  edx, dword ptr [ebp-20]
004EED3A >mov  eax, dword ptr [ebx+300] ;*TForm3.Edit1:TEdit
004EED40 >call  004478D8 ;->Controls.TControl.GetText(TControl):TCaption;
004EED45  mov  eax, dword ptr [ebp-20] ;00FFD450, (ASCII "[email protected]")
004EED48  push  eax
004EED49  mov  eax, dword ptr [4FAC70]
004EED4E  mov  eax, dword ptr [eax]
004EED50  mov  ecx, 004EF048 ;ASCII "Email"
004EED55  mov  edx, 004EF058 ; ASCII "Options"
004EED5A  mov  edi, dword ptr [eax]
004EED5C  call  dword ptr [edi+4]
004EED5F  lea  edx, dword ptr [ebp-24]
004EED62 >mov  eax, dword ptr [ebx+304] ;*TForm3.Edit2:TEdit
004EED68 >call  004478D8 ;->Controls.TControl.GetText(TControl):TCaption;
004EED6D  mov  eax, dword ptr [ebp-24] ;01000F58, (ASCII "1357924680")
004EED70  push  eax
004EED71  mov  eax, dword ptr [4FAC70]
004EED76  mov  eax, dword ptr [eax]
004EED78  mov  ecx, 004EF068 ;ASCII "Serial"
004EED7D  mov  edx, 004EF058 ;ASCII "Options"
004EED82  mov  edi, dword ptr [eax]
004EED84  call  dword ptr [edi+4]
004EED87  lea  ecx, dword ptr [ebp-28]
004EED8A  mov  edx, 1
004EED8F  mov  eax, esi
004EED91  mov  edi, dword ptr [eax]
004EED93 >call  dword ptr [edi+C] ;->TStringList.Get(Integer)
;这里出现异常

 
在004EED93处出现异常,不能到达成功的消息框。如果没有前面导入的map文件注释,我们可能就会在这里卡住了。
 
注意观察004EED93的注释“TStringList.Get(Integer)”,应该是获取字符串。往上看代码004EED21,也用了“TStringList.Get(Integer)”,这个是获取验证页面字符串“yes”的函数,那么004EDD93会不会也是用来获取验证页面字符串的函数,由于获取不到而出现异常导致出错呢?于是我把验证文件checkreg.php修改为:
 
yes
 
“黑防专用”
 
保存好之后再次输入信息验证,终于跳出了可爱的消息框,如图8所示。
 
 
 


图8
 
看看这时候在文件夹里生成了什么?生成了options.ini文件,其内容如下:
 
[Options]
 
[email protected]
 
Serial=1357924680
 
Expire="黑防专用"
 
Name=layper
 
经过上面的**过程,大家应该明白**有网络验证的软件有以下几点关键:
 
1)  寻找验证的主机域名和验证页面。
 
2)  改造host文件和架构服务器,使域名解析到相应IP(通常是改为本地主机)。
 
3)  根据程序提示构造验证页面。
 
4)网络验证的API断点常用bp recv,以获取缓冲区读取的数据。
 
Hide The IP是用Delphi编写的软件,**Delphi除了选择dede之外,还可以用导入map文件到OD的方法来降低分析代码的难度。顺便提一点,Hide The IP除了用网络验证方法**之外,用拦截ini函数方法构造ini文件**应该也是可行的,大家可以自己试试看!

相关文章: