黑客防线,在攻与防的对立统一中寻求突破!2001年创刊的黑客技术专业刊物!
plant

设为首页
收藏本站
联系我们
网站导航

黑客文章 - 加密解密 - 浏览 - [原创]初识逆向技术

[原创]初识逆向技术

黑客 发布日期:2009-4-21 1:11:02 共有 3860 人次浏览
[原创]初识逆向技术
适合读者:逆向爱好者、程序员
前置知识:基本汇编代码阅读能力
Icefire:通常所谓的软件逆向工程是指:跟踪复原(或仿制)软件的编程过程、修改软件的部分代码、添加或者删除软件的部分功能等等。然而,要想达到自如地对软件跟踪与修改,既需要过

适合读者:逆向爱好者、程序员

前置知识:基本汇编代码阅读能力

Icefire:通常所谓的软件逆向工程是指:跟踪复原(或仿制)软件的编程过程、修改软件的部分代码、添加或者删除软件的部分功能等等。然而,要想达到自如地对软件跟踪与修改,既需要过硬的跟踪与识别技术,更需要对软件的基本结构做出较为透彻了解。尤其是软件的PE结构更是逆向技术中需要掌握的。因为你需要达到的某种目的,可能条件并不具备,你不得不在软件中做出适当补充与完善。即使是条件具备,没有恰当地使用好,可能目的达不到,还会引起软件崩溃。从本期开始,我们将和大家一起,逐步系统地了解逆向技术,看看它的神秘究竟在那里!

初识逆向技术

/laoxuetong

逆向是很让人陶醉的一种技术,相信很多朋友都和我一样,喜欢研究它。当然,这就需要有几件上手的工具,以方便对软件进行跟踪与察看、修改与编辑。虽然各类工具非常多,但我推荐一下组合:

OllyDbg—Windows下优秀的跟踪调试软件。即可用于跟踪,也可以轻松地修改软件。

PEiD—性能不错的侦察软件。即可以用来查看软件编辑平台和侦查外壳,准备足够的插件还可以侦查软件的加密算法。

LordPE—PE文件查看与修改工具。条件不具备时你少不了它的帮助。

WinHexUltraEdit—文本编辑工具。可任选一种或其它的,主要用于编辑一些文本类资源。

好,下面我们选定一个软件《WinPatrol v8.1.2.0》,看看我们能作些什么?

 

软件简单介绍

WinPatrol网络安全工具,可以探测出蠕虫、间谍程序、木马等恶意的程序。界面如图1所示:

1

软件除了可以查看各种可能出现的项目及其相关信息外,你也可以设置对某一个项目的监视,用以跟踪监视可疑的病毒与木马的运行情况。软件启动后在任务栏会出现一只黑色的小狗,时不时掉转头来,煞是可爱。

软件运行有三种状态。它们分别是:未注册状态、注册于PLUS状态和注册于Professional状态。其中注册于PLUS状态和注册于Professional状态的界面略有不同,如图23所示:

 

2 注册于PLUS状态

 

3 注册于Professional状态

关于PLUS的注册方式,网上有现成的注册机,这里就不多说了。现在我想注册于Professional状态,那么我们能作些什么呢?

 

问题分析

通过对软件的跟踪发现,软件的注册验证并不复杂。有关代码如下:

读取名称:

00408CF1  PUSH 40                                      ; /Count = 40 (64.)

00408CF3  PUSH WinPatro.004276E0                       ; |Buffer = WinPatro.004276E0

00408CF8  PUSH 432                                     ; |ControlID = 432 (1074.)

00408CFD  PUSH ESI                                     ; |hWnd

00408CFE  CALL EDI                                     ; \GetDlgItemTextA

读取注册码:

00408D00  PUSH 20                                      ; /Count = 20 (32.)

00408D02  PUSH WinPatro.00427720                       ; |Buffer = WinPatro.00427720

00408D07  PUSH 430                                     ; |ControlID = 430 (1072.)

00408D0C  PUSH ESI                                     ; |hWnd

00408D0D  MOV EBX,EAX                                  ; |转移名称长度

00408D0F  CALL EDI                                     ; \GetDlgItemTextA

判断:

00408D11  LEA EAX,DWORD PTR DS:[EBX-1]                 ;  名称长度-1

00408D14  TEST EAX,EAX

00408D16  JLE SHORT WinPatro.00408D33

00408D18  JMP SHORT WinPatro.00408D20

00408D1A  LEA EBX,DWORD PTR DS:[EBX]

00408D20  CMP BYTE PTR DS:[EAX+4276E0],20              ;  名称最后一位是空格么?

00408D27  JNZ SHORT WinPatro.00408D30

00408D29  DEC EAX

00408D2A  TEST EAX,EAX

00408D2C  JG SHORT WinPatro.00408D20

00408D2E  JMP SHORT WinPatro.00408D33

00408D30  LEA EBX,DWORD PTR DS:[EAX+1]                 ;  还原名称长度

00408D33  MOVSX EAX,BYTE PTR DS:[427721]               ;  取出注册码第二位

00408D3A  ADD BL,40                                    ;  名称长度+0x40=注册码第二位

00408D3D  MOVZX EDX,BL

00408D40  CMP EAX,EDX                                  ;  比较

00408D42  JE SHORT WinPatro.00408D9B                   ;  相等则跳

00408D44  PUSH 200

00408D49  LEA ECX,DWORD PTR SS:[ESP+D0]

00408D50  PUSH ECX

00408D51  PUSH 26C

00408D56  CALL WinPatro.0041A290                       ; 读取注册不成功消息

00408D5B  XOR EDX,EDX

00408D5D  MOV DX,WORD PTR DS:[42C100]

00408D64  ADD ESP,0C

00408D67  LEA EAX,DWORD PTR SS:[ESP+CC]

注册不成功消息:

00408D6E  PUSH EDX                                     ; /LanguageID

00408D6F  PUSH 40040                                   ; |Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL|40000

00408D74  PUSH WinPatro.00427DC0                       ; |Title = "WinPatrol Professional"

00408D79  PUSH EAX                                     ; |Text

00408D7A  PUSH ESI                                     ; |hOwner

00408D7B  CALL DWORD PTR DS:[<&USER32.MessageBoxExA>]  ; \MessageBoxExA

00408D81  POP EDI

00408D82  POP ESI

00408D83  XOR EAX,EAX

00408D85  POP EBX

00408D86  MOV ECX,DWORD PTR SS:[ESP+2C0]

00408D8D  CALL WinPatro.0041B575

00408D92  ADD ESP,2C4

00408D98  RETN 10

00408D9B  CALL WinPatro.0041B060                       ;  相等跳到这里--读写注册表

00408DA0  TEST EAX,EAX

00408DA2  JE WinPatro.00408F6F

00408DA8  PUSH 200

00408DAD  LEA ECX,DWORD PTR SS:[ESP+D0]

00408DB4  PUSH ECX

00408DB5  PUSH 26D

00408DBA  CALL WinPatro.0041A290                       ;  读取注册有效的信息

00408DBF  XOR EDX,EDX

00408DC1  MOV DX,WORD PTR DS:[42C100]

00408DC8  ADD ESP,0C

00408DCB  LEA EAX,DWORD PTR SS:[ESP+CC]                ; 

注册成功消息:

00408DD2  PUSH EDX                                     ; /LanguageID

00408DD3  PUSH 40040                                   ; |Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL|40000

00408DD8  PUSH WinPatro.00427DC0                       ; |Title = "WinPatrol Professional"

00408DDD  PUSH EAX                                     ; |Text

00408DDE  PUSH ESI                                     ; |hOwner

00408DDF  CALL DWORD PTR DS:[<&USER32.MessageBoxExA>]  ; \MessageBoxExA

从上可以看出,注册码的第二位应该是“名称长度+0x40。如果是,则可以注册成PLUS版。如果不是,则不能注册。通过仔细跟踪看到,注册码并没有由注册名计算而来,所以也就是非明码比较范畴。这类软件一般不宜做内存注册机。

那么,这种情况下能不能让软件自动显示正确的注册码呢?经过思索和试验,发现也完全可做到。

 

准备工作

要显示注册码,需要一个消息盒,这东西通常需要调用API。请出LordPE来看一看,看软件为我们实现目标准备了相应条件没有。启动LordPE,如图4所示:

4

PE编辑器,打开需要查看的文件,如图5所示:

5

单击 打开,出现第一个对话框,如图6所示:

6

选择目录,出现第二个对话框,如图7所示:

7

点击导入表右侧的第一个按钮出现第三个对话框,如图8所示:

8

在这个对话框的上面查找USER32.DLL,则在下面出现这个文件中所有被使用的函数名称及其调用方法。如图9所示:

9

从图中可以看到,软件包含了对函数MessageBox的调用。这为我们制作自显示注册码方案提供极大方便了,不需要作过多的操劳了。

调用对话框函数MessageBox通常需要4个参数,其中两个默认状态下为0。另两个一个是对话框的标题一个是对话框要显示的内容。另外,在调用时还必须遵守PE格式文件的规则。否则,轻则不能跨平台使用,重则软件不能启动。请注意,这个软件调用的不是MessageBoxA,而是MessageBoxExA。主要区别在于增加了语系识别。这些问题在进行软件逆向时必须进行学习与研究,逐步掌握并融会贯通。这里我们暂时不讲了。

 

实施手术

调用MessageBox的反汇编代码的一般形式形如:

PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL

PUSH Address1                            ; |Title = "<消息盒标题>"

PUSH Address2                            ; |Text = "<消息盒内容>"

PUSH 0                                   ; |hOwner = NULL

CALL <JMP.&USER32.MessageBoxA>           ; \MessageBoxA

JMP Address3

JMP DWORD PTR DS:[<&USER32.MessageBoxA>] ;  USER32.MessageBoxA

其中Address1对应着你的标题资源在内存中的位置,一般情况下地址是固定的。Address2对应着需要现实的内容在内存中的位置,大多数情况下地址是动态的,要根据情况加以利用。Address3是显示完毕后,应该返回到软件相应位置的地址,是固定的。值得注意的是,最后的两个跳转的顺序不能颠倒,否则软件不能正确地工作。

在添加这些代码时,上述三个地址可以先随意输入,等将代码输入完成、标题地址设置好、跳转地址找好再集中处理。而第二个跳转的地址可将软件已使用的地址复制过来(见未注册提示框位置)。当然,也可以根据PeiD中显示的地址计算。

好,现在选择合适的跳转点。因为软件需要用到名称长度,所以应该选择在恢复名称长度的位置跳转,即:

00408D30  LEA EBX,DWORD PTR DS:[EAX+1]                 ;  还原名称长度

00408D33  MOVSX EAX,BYTE PTR DS:[427721]               ;  取出注册码第二位

00408D3A  ADD BL,40                                    ;  名称长度+0x40=注册码第二位

因为这一行语句后面用到,所以必须在添加的代码里加上占用的代码部分。在程序后面的空余位置添加好代码,并将00408D33这一行改为:

JMP < 添加代码入口>

并且让:

Address2=<消息盒标题>

Address3=<消息盒内容>

而消息盒标题紧放在添加代码的后面。经过这样设计,我的代码及存放位置如图10所示:

10

紧随其后是标题数据。当你注册时,点击Apple后会出现如下图11所示的信息:

11

怎么样?注册码出来了吧。而且还已经真的替你注册了,是不是很爽?!

容易么?看来很容易。但又不容易!如果软件本身不带MessageBox函数,实现起来就有些麻烦。能办到么?当然能。甚至可以直接使用,但不能互相交流及跨平台使用。

我不止想做到这些,还想做一些其它的事情;我的软件加壳了,不脱壳能否实现一些附加功能;能添加菜单项么?能添加或删除图像么?没位置存放我所添加的内容了,等等,等等。只要你能跟着我们学习,都是可以实现的。不过要记住,这里研究的是逆向技术,非软件开发。所以你如果想在试用版上处理成正式版,那倒不如自己开发了。

逆向方法小结

l         检查或者添加MessageBox函数

l         准备好MessageBox函数的反汇编代码

l         准备好消息盒中显示的数据地址

l         准备好合适的跳转点

l         在选定的合适位置输入代码和数据

l         检验、调试所作的工作

l         收集相关API函数,已备不时之用

好,这次就讲到这里了。下次再见。

(文中涉及程序已收录到杂志配套光盘“杂志相关”栏目,按文章名查找即可)

所属分类: 加密解密     网摘收藏: Google 雅虎 百度 POCO 365key 和讯 天极