已阅读5页,还剩70页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件保护技术 备课笔记步山岳 计算机工程系第1章 基础知识 1.1文本编码方式美国信息交换标准码(ASCII: American Standard Code for Information Interchange)是一个七位的编码标准,包括26个小写字母、26个大写字母、10个数字、32个符号、33个控制代码和一个空格,总共128个代码。如“1”的ASCII码是31H(48D),“A”的ASCII码是41H(65D),“a”的ASCII码是61H(97D)。由于计算机通常用一个“字节( byte)”8位二进制的存储单位来进行信息交换,因此,ASCII码在计算机中用8位来表示,最高位补0。其他字符集,是对ASCII码的扩展,例如ANSI(American National Standards Institute)、Symbol、OEM等字符集是8位字符集,值在127以下的部分是和ASCII相同。Unicode也是ASCII的一个扩展。在Unicode用两个字节来表示,是一种双字节编码机制的字符集,可表示65536个字符,使用065535之间的双字节无符号整数对每个字符进行编码,本书把Unicode称宽字符(Widechars)在Unicode中,所有的7位ASCII码都被扩充为16位,高位扩充的是零。如“pediy”,它的ASCII码是:0x70 0x65 0x64 0x69 0x79 其Unicode码的十六进制是: 0x0070 0x0065 0x0064 0x0069 0x0079Intel处理器存放数据时,低位字节存入低地址,高位字节存入高地址。注意:内存地址编号是“上(左)”为低地址编号,“下(右)”为高地址编号,看图1.1。 1.2 Windows API函数 1.2.1什么是API函数1什么是API函数?API函数是提供应用程序运行所需要的窗口管理、图形设备接口、内存管理等各项服务功能的函数,提供这些功能以函数库的形式组织在一起,形成了Windows应用程序编程接口(API Application Programming Interface),简称WinAPI。看图1.2,Win API子系统将API调用转换成Windows操作系统的系统服务调用,在它的下面是Windows的操作系统核心,而它的上面则是Windows应用程序。可以说Win API是构筑Windows框架的核心基石。API函数从Windows 1.0支持不到450个函数,到现在己有几千个函数。2API函数在计算机或操作系统的什么地方?API函数在计算机或操作系统的什么地方:动态链接库DLL(Dynamic-Link Library),Windows运转的核心就是“动态链接”。3什么是动态链接库DLL?DLL就是包含了若干个函数、类和资源的库文件,它可以被其它可执行文件(如.EXE文件和其它DLL文件)动态调用。4动态链接库的优点使用DLL的使多个应用程序,甚至是不同语言编写的应用程序可以共享一个DLL文件,真正实现了“资源共享”,同时,节省内存,减少交换操作,节省磁盘空间。DLL自己不能直接执行,但其他程序可以调用 DLL 中的一个实例。在静态链接中,链接器从静态链接库获取所有被引用的函数,并将库同代码一起放到可执行文件中。占用内存等。5API函数分类Windows将完成不同功能的API函数分类放到不同DLL中,如:Kernel32.dll:包括进程与线程控制、内存管理、文件访问等,提供操作系统核心功能服务;User32.dll:负责处理用户接口,包括键盘和鼠标输入、窗口和菜单管理等;Gdi32.dll:图形设备接口,允许程序在屏幕和打印机上显示文本和图形;Kernel、User和GDI是Windows三个主要的动态链接库。Advapi32.dll:包括对象安全性、注册表操作;COMCTL32.DLL:通用控件;COMDLG32.DLL:公共对话框;SHELL32.DLL:用户界面外壳;DIBENG.DLL:图形引擎;NETAPI32.DLL:网络。6DLL文件位置在Windows NT/2000/XP中,这些DLL文件通常位于系统安装目录里的WindowsSYSTEM或WindowsS YSTEM32子目录中。1.2.2 什么是句柄句柄(Handle)是Windows用来标识被应用程序所建立或使用的对象的唯一整数值(32位,长整型Long)。Windows使用各种各样的句柄标识诸如应用程序实例,窗口,控件,位图,GDI对象等。应用程序几乎总是通过调用一个Windows函数来获得一个句柄,之后其他的Windows函数就可以使用该句柄,以引用相应的对象。举例说明。当一个进程被初始化时,系统要为它分配一个句柄表,句柄值是放入进程的句柄表中的索引。当调试一个应用程序并且观察内核对象句柄的实际值时,会看到一些较小的值,如1,2等。句柄的值可能随时变更。如,在Windows 2000中,返回的值用于标识放入进程的句柄表的该对象的字节数,而不是索引号本身。因此,在Windows的不同版本下调试程序时,句柄值的表达形式是不同的。在编程时,不必关心句柄值的大小。1.2. 3常用Win32 API函数 1 知道常用Win32 API函数的重要性由于Win32程序大量调用系统提供的API函数,而Win32平台上的调试器,如SoftICE等,恰好有针对API函数设置断点的强大功能,因而掌握常用的API函数具体用法会给跟踪调试程序带来极大的方便,学会使用API函数也是高级程序所必备条件。详细的Win 32 API参考文档可以从MSDN中获得。2API函数是区分字符集的API函数是区分字符集的:A表示ANSI,是单字节方式;W表示Widechars即Unicode,是宽字节方式,以方便处理双字节字符。用字符串作参数的每个Win32函数在操作系统中都有两种方式的版本。例如,编程时使用MessageBox函数,而在USER32.DLL中,有两个入口点,一个名为MessageBoxA (ANSI版),另一个名为MessageBoxW(宽字符版)。但程序员通常不必关心这个问题,程序中只需要使用MessageBox时,开发工具中的编译模块会根据设置自动决定采用MessageBoxA还是MessageBoxW。3常用Win32 API函数(1)GetWindowText函数此函数在USER32.DLL用户模块中,它的作用是取得一个窗体的标题文字,或者一个文本控件的内容。函数原型:int GetWindowText( HWND hWnd /获取文字的那个窗口或文本控件的句柄 LPTSTR lpString /预定义一个存放字符的起始缓冲区地址 int nMaxCount /lpString复制最大字符数,即缓冲区的长度 ); 16位:GetWindowText 32位:ANSI版是GetWindowTextA,Unicode版是GetWindowTextW。API函数的数据类型:HWND:Windows句柄,Handle to a windowLPTSTR:定义一个32位的指针,指向16位字符串,可以兼容8位字符串。A 32-bit pointer to a character string that is portable for Unicode and DBCS(Double-byte Character Set)(2)GetDlgItem函数此函数在USER32.DLL用户模块中,它的作用是获取指定对话框的句柄。(3) GetDlgItemText函数此函数在USER32.DLL用户模块中,它的作用是获取对话框文本。(4)GetDlgItemInt函数此函数在USER32.DLL用户模块中,它的作用是获取对话框整数值。(5)MessageBoxEx函数此函数是在USER32.DLL用户模块中,创建和显示信息框。函数原型:int MessageBoxEX(HWND hWnd, / HWND:窗口句柄,获取窗口句柄LPCTSTR lpText, / LPCTSTR:LPCTSTR:定义一个32位的指针(LP),/指向16位常数(C)字符串,/可以兼容8位字符串。/定义一个消息框中文字的起始地址LPCTSTR lpCaption, /定义一个消息框标题起始地址UINT uType / UINT:无符号整型,定义一个消息框类型,无符号整型 WORD wLanguageID / WORD:字型,定义一个语言标识);API函数的数据类型:HWND:Windows句柄LPCTSTR:定义一个32位的指针(LP),指向16位常数(C)字符串,可以兼容8位字符串。UINT:无符号整型,可以是16位或32位,A 16-bit unsigned integer on Windows versions 3.0 and 3.1; a 32-bit unsigned integer on Win32.WORD:16位无符号整型数,A 16-bit unsigned integer,其中wLanguageId保留,inReserved。ANSI版是MessageBoxExA,Unicode版是MessageBoxExW。(6)MessageBox函数此函数是在USER32.DLL用户模块中,创建和显示信息框。常用MessageBox1.3 Windows 2000/XP与Unicode ANSI与Unicode字符串相互转换Unicode影响到计算机工业的每个部分,对操作系统和编程语言的影响最大。Windows NT系统核心完全是用Unicode函数工作的,既支持Unicode,也支持ANSI,如果在调用Windows函数并使用ANSI字符串,那么系统首先要将字符串转换成Unicode,然后再将Unicode传递给操作系统。如果希望函数返回ANSI函数,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给应用程序。Unicode在Windows 2000/XP下执行效率比ANSI要高,看教材P9例。1.4 Windows消息机制1什么是事件和消息?“事件”是“对象”可识别的动作,通过“事件”产生消息。“消息”是通知“对象”执行的动作,是面向对象程序设计中的一个重要概念。2Windows消息驱动方式Windows是一个消息(Message)驱动式系统,Windows消息提供应用程序与应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消息的响应和处理来完成。实现消息(Message)驱动的基石是面向对象程序设计方法。Windows系统中有两种消息队列:一种是系统消息队列,另一种是应用程序消息队列。计算机的所有输入设备由Windows监控。当一个事件发生时,Windows先将输入的消息放入系统消息队列中,再将输入的消息拷贝到相应的应用程序队列中,应用程序中的消息循环从它的消息队列中检索每个消息并且发送给相应的窗口函数中。事件将消息放入系统消息队列将消息拷贝到相应的应用程序队列中应用程序将每个消息按顺序发送给相应的函数。值得注意的是消息的非抢先性,即不论事件的急与缓,总是按到达的先后排队(一些系统消息除外),这就使得一些外部实时事件可能得不到及时的处理。由于Windows本身是由消息驱动的,所以调试程序时跟踪一个消息会得到相当底层的答案。3常用消息处理函数(1)SendMessage函数调用一个窗口的窗口函数,将一条消息发给那个窗口。除非消息处理完毕,否则该函数不会返回。LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);LRESULTA 32-bit value returned from a window procedure or callback function.WPARAMA value passed as a parameter to a window procedure or callback function: 16 bits on Windows versions 3.0 and 3.1; 32 bits on Win32.LPARAMA 32-bit value passed as a parameter to a window procedure or callback function.(2)PostMessage函数将一条消息投递到指定窗口的消息队列4常用消息(1)WM_COMMAND消息当用户从菜单或按钮中选择一条命令、或者一个控件时发送给它的父窗口、或者当一个快捷键被释放时发送WM_COMMAND消息。WM_COMMAND wNotifyCode = HIWORD(wParam); wID = LOWORD(wParam); hwndCtl = (HWND) lParam;消息参数Parameters HIWORD:Value of the high-order word of wParam LOWORD:Value of the low-order word of wParam.wNotifyCode:Specifies the notification code if the message is from a control. If the message is from an accelerator, this parameter is 1. If the message is from a menu, this parameter is 0. wID :菜单、控件、快捷键标识,Specifies the identifier of the menu item, control, or accelerator. hwndCtl :控件句柄,Handle to the control sending the message if the message is from a control. Otherwise, this parameter is NULL. Visual C+的winuser.h文件里定义了WM_COMMAND消息对应的十六进制是0x0111。(2)WM_DESTROY消息当一个窗口被破坏时发送。(3)WM_GETTEXT消息 应用程序发送一条WM_GETTEXT消息,拷贝一个对应窗口的文本到一个呼叫程序提供的缓冲区。(4)WM_LBUTTONDOWN消息当光标在一个窗口的客户区并且用户按下鼠标左键时,WM_LBUTTONDOWN消息被发送。如果鼠标动作未被捕获,这条消息被发送给光标下的窗口;否则,被发送给己经捕获鼠标动作的窗口。1.5 Windows注册表介绍1什么是Windows注册表注册表是Windows的核心数据库,含有各种参数,直接控制Windows的启动、硬件驱动程序的装载、应用程序的各种状态信息和数据等。2注册表逻辑结构注册表被组织成主键、子键、项、项值的树型结构,就像磁盘文件系统的目录结构一样,如图1.4所示。每个键都包含一组特定的信息,每个键的键名都是和它所包含的信息相关联的。 3注册表的根主键注册表的根主键不能被删除,也不能添加新的根主键,它们的结构含义如下:(1)HKEY_ CLASSES_ROOT简称HKCR,这个主键包含了文件扩展名和COM组件类的注册信息。(2)HKEY- CURRENT_USER简称HKCU ,这个主键包含了与当前登录用户相关的软件配置和参数。(3)HKEY _LOCAL _MACHINE简称HKLM,这个主键中存放的是用来控制系统和软件的设置。其中HKLMSOFTWARE子键存储了一些Windows系统级软件配置信息。另外,还存储了第三方应用程序的系统级设置,如应用程序中文件和目录路径,以及有关使用许可证和期限的信息。(4)HKEY_USERS简称HKU,它包含了关于动态加载的用户配置文件和默认的配置文件的信息,同时还包含了出现在HKEY CURRENT USER中的信息。(5)HKEY_CURRENT_CONFIG包含了启动时由本地计算机系统使用的硬件配置文件的相关信息。4注册表数据类型每个注册表项或子项都可以包含称为值项的数据。有些值项存储每个用户的特殊信息,而其他值项则存储应用于计算机所有用户的信息。值项包括三部分:值的名称、值的数据类型和值本身。表1-2列出当前由系统定义和使用的数据类型。5注册表相关函数注册表相关函数在ADVAPI32.DLL用户模块中。(1) RegOpenKeyEx()函数,它的作用是打开子键;函数原型:LONG RegOpenKeyEx( HKEY hKey, / HKEY:注册表主键句柄,获得注册表主键句柄LPCTSTR lpSubKey, / LPCTSTR:定义一个32位的指针(LP),指向16位常数(C)字符串,/可以兼容8位字符串。获取子键名的地址 DWORD ulOptions, / DWORD:双字,保留 REGSAM samDesired, / REGSAM:注册表主键安全访问掩码,确定对注册表进行何种操作,如读、写等。 PHKEY phkResult,/ PHKEY:PHKEY,获取子键句柄地址);HKEY :注册表主键句柄(2) RegQueryValueEx函数,它的作用是获取一个项的设置值,函数原型:LONG RegQueryValueEx ( HKEY hKey, / HKEY:注册表主键句柄。需要查找的主键句柄或标准项名 LPTSTR lpValueName, / LPTSTR:字符型指针,需要查找的子键名地址 LPDWORD lpReserved, / LPDWORD:双字型指针,保留,必须为0 LPDWORD lpType, / 存放子键类型的缓冲区地址 LPBYTE lpData, / LPBYTE:字节型指针,存放返回结果的缓冲区地址 LPDWORD lpcbData /存放返回结果字节长度的缓冲区地址); 其中LPDWORD:Pointer to a DWORD(3)RegSetvalueEx函数,它的作用是设置指定项的值,函数原型见教材。了解程序是如何操作注册表的将有助于加深对注册表的认识,在跟踪分析注册表操作时更加得心应手。用Win32 API操作Windows注册表的基本步骤如下:(1)用RegOpenKeyEx()打开想要操作的主键,获得一个句柄。(2)将句柄传递给RegQueryValueEx(),RegSetValueEx()等函数来读、写相应的键值。(3)操作完毕之后用RegCloseKey()关闭先前获得的句柄。6如何使用API函数在VC的控制台下程序示例1(获得windows的ID号)演示、解释、验证。7 注册表分析软件注册表分析软件有两大类:一类是注册表读写监视软件,另一类是注册表比较软件。(1)注册表“监视员”Regmon它将与注册表数据库相关的一切操作(如读取、修改、出错信息等)全部记录下来供用户参考,并允许用户对记录的信息进行保存、过滤、查找等处理。(2)注册表照相机RetoSnapRegSnap是一款分析Windows注册表及系统配置文件更改的工具。RegSnap的原理非常简单,在不同的时间段对注册表“拍照”,然后比较“拍照”结果,进而分析出注册表与系统文件的变化。(3)注册表比较工具RegShot, 能快速地帮助发现注册表的变化。1.6保护模式简介1.6.1汇编语言复习1寄存器的作用寄存器(Register)是CPU内部的元件,寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快,寄存器的用途: (1)可将寄存器内的数据执行算术及逻辑运算。 (2)存于寄存器内的地址可用来指向内存的某个位置,即寻址。 (3)可以用来读写数据到电脑的周边设备。对于8088/8086汇编语言,一定要熟悉AX,BX,CX,DX,SI,DI,SP和BP这些16位的寄存器。2数据寄存器组AX,BX,CX,DX称为数据寄存器组,AX:累加寄存器,常用于运算;BX:基址寄存器,常用于地址索引;CX:计数寄存器,常用于计数;DX:数据寄存器,常用于数据传递。它们既可作16位寄存器使用,又可按高8位和低8位作8位寄存器使用。因此,又可将这4个寄存器分为两小组:H组(AH, BH, CH,DH)和L组(AL,BL,CL,DL)。3段寄存器组CS,SS,DS,ES称为个段寄存器组,在386中又称段选择器。CS寄存器指示当前代码段首地址,规定了现行程序段所在的存储区首地址;SS寄存器指示当前堆栈段首地址;DS寄存器指示当前数据段首地址;ES指示当前附加数据段首地址;DS和ES规定了现行程序中所用数据的存储区首地址。4指令指示器IP寄存器又称指令指示器,它总是用来保存下一次将要从主存中取出指令的偏移地址(EA),其值为该指令到所在段段首址的字节距离。与CS配合使用,可跟踪程序的执行过程;5变址寄存器组BP, SI,DI,SP称为指示器变址寄存器组,它们一般用来对堆栈操作,存放操作数在堆栈中的偏移地址。BP对堆栈操作,称基址指针寄存器,某一存储单元的偏移地址,可用作SS的一个相对基址位置;SI称源变址寄存器,串操作指令中用作取源操作数的指示器,可用来存放相对于DS段之源变址指针;DI称目的变址寄存器,在串操作指令中用作送目的操作数的指示器,可用来存放相对于 ES 段之目的变址指针。SI和DI也可作一般指示器和变址寄存器;当SI、DI和BP不用作指示器和变址寄存器时,也可作数据寄存器使用;但这时它们只能用来作16位寄存器。SP是专用的堆栈指示器,存放的是当前堆栈段中栈顶的偏移地址,可指向目前的堆栈位置,不能作数据寄存器使用,与SS配合使用。6在80386中寄存器在80386中,这些寄存器被扩展到了32位,即EAX,EBX,ECX,EDX,ESI,EDI,ESP和EBP,增加了两个附加数据段寄存器:FS和GS 。在64位CPU中,这些寄存器被扩展到了64位,即RAX,RBX,RCX,RDX,RSI,RDI,RSP和RBP,增加了8个通用寄存器R8-R15。所有寄存器都具有字节、字、双字和四字4个级别。7状态寄存器PSW(Program Flag)程序状态字寄存器,是一个16位寄存器,由条件码标志(flag)和控制标志构成,如下所示:O(OF:Overflow Flag)溢出标志。溢出时为1,否则置0。S(SF:Sign Flag)符号标志。结果为负时置1,否则置0.Z(ZF:Zero Flag)零标志,运算结果为0时ZF位置1,否则置0.C(CF:Carry Flag)进位标志,进位时置1,否则置0.A(AF:Auxiliary carry Flag)辅助进位标志,记录运算时第3位(半个字节)产生的进位置。有进位时1,否则置0.P(PF:Parity Flag)奇偶标志。结果操作数中1的个数为偶数时置1,否则置0.控制标志位:D(DF:Direction Flag)方向标志,在串处理指令中控制信息的方向。I(IF:Interrupt Flag)中断标志。T(TF:Trap Flag)陷井标志。1.6.2保护模式简介一般来说,80x86(80386及其以后的各代CPU)可在实模式、保护模式和虚拟86模式三种模式下运转。1实模式实模式就是古老的MS-DOS的运行环境,只能利用这些32位寄存器的前16位,而后面的16位就浪费了。实模式将整个物理内存看成分段的区域,程序代码和数据位于不同区域,系统程序和用户程序没有区别对待,而且每一个指针都是指向“实在”的物理地址。实模式下地址空间要分为代码、数据、附加数据、堆栈等4个部分。实模式下的寻址方式是“段基址段偏移”,如0000:1200,段的默认大小为64KB(216=64KB),寻址空间 1M(20根地址线,220=1M),寄存器长度16位,所有段都是可读/写的,惟有代码段是可执行的,段的特权级为0。2保护模式一切程序都可以用线性地址(不分段)访问自己所拥有的4G(232,因为32位指针可以拥有从0x00000000-0xFFFFFFFF之间的任何一个值。)或64G(236)的内存空间,但是不能访问其他程序的空间, 如果有程序要访问不该访问的内存,就会出系统错误,CPU就用中断通知操作系统,这样的进程会被操作系统发现,并杀死, 不会影响其他程序。实际是CPU和操作系统一起保护了程序的内存, 因此叫做保护模式。物理内存地址不能直接被程序访问,程序内部的地址(虚拟地址)要由操作系统转化为物理地址去访问,任何其他进程根本没有办法访问不属于自己的物理内存区域。实际上内存是不可能有4个G的, 而且是每个程序都要有4G的空间. 为了为每个程序都提供4G内存, 386及以后的CPU采用“页”的方式来管理内存, 把内存分为一个个的页, 页的物理地址与每个程序虚拟的4G线性地址用一个表格保存。在保护模式下,CPU的寻址方式与实模式不同,在保护方式下内存是“线性”的,因为这时段寄存器(CS,SS,DS,ES)里面存放的不再是段基地址,而是存放着段选择子,这个值是不直接参与寻址的,只是全局描述符表(Global Descriptor Table,简称GDT)或本地描述符表(Local Descriptor Table,简称LDT)的一个指针,不同段寄存器有不同的属性(读、写、执行、特权级等),如图1.10所示。(1)段选择子:在Win32中段选择子是CS、DS、ES等,主要用来存放指向全局描述符表GDT或本地描述符表LDT的一个指针。(2)全局描述符表GDT:包括操作系统所使用的代码段、数据段、堆栈段、任务等描述,如段的基地址、属性(读、写、执行、特权级等)、段界限,见图1.10。GDT存在段描述苻寄存器GDTR中。(3)本地描述符表LDT:包括每个任务所使用的代码段、数据段、堆栈段、任务等描述,如段的基地址、属性(读、写、执行、特权级等)、段界限,见图1.10。LDT存在段描述苻寄存器LDTR中。 通过段选择子的内容,在全局描述表里面找到相应的段描述内容,实际上段选择子相当于书的索引(指向)目录,目录就是GDT,在目录下面有章,每一章(段)能指示从书的哪一页开始(Base address),看到第几页(Offset)。尽管如此,在看保护模式内存结构时,仍请记住段偏移量的概念,不妨把段寄存器看做是对保护模式中的选择子的一个模拟。 3虚拟86模式在Windows 9x下,如果开一个MS-DOS窗口,即运行一个DOS应用程序,那么该程序就运行在虚拟86模式下。4虚拟内存虚拟内存( Virtual Memory )不是真正的内存,它通过映射(Map)的方法,使可用的虚拟地址( Virtual Address )达到4GB(16位机,实模式为1M,每个应用程序可以被分配2 GB的虚拟地址,剩下的2 GB留给操作系统自己用。在Windows NT中,应用程序甚至可有3GB的虚拟地址,虚拟内存的实现方法和过程是:(1)当一个应用程序被启动时,操作系统就创建一个新进程,并给每个进程分配2 GB的虚拟地址(不是内存,只是地址);(2)虚拟内存管理器(Virtual Memory Manager)将应用程序的代码映射到那个应用程序的虚拟地址中的某个位置,并把当前所需要的代码读取到物理地址中(注意:虚拟地址和应用程序代码在物理内存中的位置是没有关系的);(3)如果使用动态链接库,DLL也被映射到进程的虚拟地址空间,在需要的时候才被读入物理内存;(4)其他项目(例如数据、堆栈等)的空间是从物理内存中分配的,并被映射到虚拟地址空间中;(5)应用程序通过使用它的虚拟地址空间中的地址开始执行,然后虚拟内存管理器把每次的内存访问映射到物理位置。如果看不明白上面的步骤也不要紧,但要明白以下几点:(1)应用程序是不会直接访问物理地址的;(2)虚拟内存管理器通过虚拟地址的访问请求,控制所有的物理地址访问;(3)每个应用程序都有相互独立的4GB的寻址空间,不同应用程序的地址空间是隔离的; (4)DLL程序没有自己的“私有”空间,它们总是被映射到其他应用程序的地址空间中,作为其他应用程序的一部分运行。使用虚拟内存的好处是:简化了内存的管理,并可弥补物理内存的不足;可以防止多任务环境下各个应用程序之间的冲突。1.6.3 保护模式的权限级别1保护模式的权限级别在保护模式下,所有的应用程序都有权限级别(Privilege Level,简写为PL),这个权限级别按优先次序分为四等:0,1,2和3,其中3特权级别最低,0特权级别最高(相对于普通用户来说)。特权级环如图1.11所示。每一特权级都有各自独立的程序堆栈,以避免与共享栈区有关的保护问题。同一级别的程序允许访问同一级别或外层级别的数据段。如果试图访问内层级别的数据段则是非法的,并引起异常。如果应用程序拥有第0级的权限,或者说它是运行在Ring 0的应用程序,它就可以执行所有的指令并访问所有数据;如果应用程序拥有的权限级别是第3级,它能执行的指令是有限的,能访问的数据也是有限的。特权级的典型用法是,把操作系统的核心部分放在0级,操作系统的其余部分放在1级,而应用程序放在3 级,留下的2级供中间软件使用。操作系统核心层是运行在Ring 0级的,而Win32子系统,(提供API函数,如动态链接库KERNEL32.DLL, USER32.DLL和GDI32.DLL)是运行在Ring 3级的,以提供与应用程序的接口。2Windows 2000/XP体系结构图1.12是Windows 2000/XP体系结构简图,核心态工作在Ring 0级,用户态工作在Ring3级。HAL是一个可加载的核心模块HAL.dll(硬件抽象层),它为运行在Windows 2000/XP上的硬件平台提供低级接口。Windows 2000/XP的执行体是NTOSKRNL.EXE(windowssystem32)的上层(内核是其下层)。用户层导出,并且可以调用的函数接口在NTDLL.DLL中,通过Win32 API或一些其他的环境子系统对它们进行访问。另外,用户的应用程序也是运行在Ring 3级的(就是用Visual C+, Borland C+, VisualBasic, Delphi, Borland C+ Builder等SDK工具开发的应用程序),也就是说享有的权限是最低的,受到保护模式的“保护”。该类应用程序没有权限去破坏操作系统,只能通过使用Win32 API接口函数与系统打交道。如想控制系统,就必须取得0特级权,比如后面接触到的调试工具SoftICE就是工作在0特级权上的。注意,Windows 9X 操作系统只使用了0级和3级,以便于移植到精简指令集的计算机上,如RS4000等,这些处理器一般只有两个特权级,即系统级和用户级。习题一1.什么是API函数?什么是DLL函数?什么是句柄?2.解释GetWindowText、MessageBoxEX、RegOpenKeyEx函数原形?3.当一个事件发生时,Windows系统处理消息过程?4. 什么是实模式、保护模式和虚拟86模式?第2章 代码分析技术在进行软件汉化、解密和计算机病毒分析工作中,一个首要问题是对软件进行代码分析,这就需要掌握一定的代码分析能力。2.1认识PE格式1什么是可执行文件的格式一个文件的组织形式2微软操作系统的可执行文件格式分类在Win 16平台上(如Windows 3.x),可执行文件是NE格式在Win32平台上(包括Windows 95/98/ME/NT/2000/XP/CE),可执行文件是PE(Portable Executable)格式。3PE格式看图2.1,PE文件使用的是一个平面地址空间,所有代码和数据都被合并在一起(在NE格式中,分为代码段、数据段、附加数据段、堆栈段,可画图说明),组成一个很大的结构,文件的内容被分割为不同的区块Section(又称区段、节等),块中包含代码或数据,各个块按页边界来对齐,块没有大小限制,是一个连续结构。每个块都有它自己在内存中的一套属性,比如:这个块是否包含代码、是否只读或可读/写等。每一个区块都有不同的名字,这个名字用来表示区块的功能。各种块的含义如下。 .text:编译或汇编结束时产生的块,是可执行文件的指令代码; .rdata:是运行期只读数据块; .data:是初始化的数据块; .idata:包含其他外来DLL的函数及数据信息块,即输入表; .rsrc:包含模块的全部资源,如图标、菜单、位图等。4可执行文件在磁盘的存储结构可执行文件在磁盘中的存储结构是按照可执行文件的PE格式结构存放的。5可执行文件在内存的存储结构PE文件的在内存中的数据结构与在磁盘上的结构是一致的,如图2.1所示。装载一个可执行文件到内存中,主要就是将一个PE文件的某一部分映射到地址空间中。这样,PE文件的数据结构在磁盘和内存中是一样的。Windows加载器遍历PE文件并决定文件的哪一部分被映射,这种映射方式是将文件较高的偏移位置映射到较高的内存地址中。磁盘文件一旦被装入内存中,其某项的偏移位置可能与原始的偏移位置不同。6PE文件相关名词解释(1)入口点(Entry Point) PE文件执行时的入口点(Entry Point),即程序在执行时的第一行代码的地址。(2)文件偏移地址(File Offset)当PE文件储存在磁盘上时,各数据块的地址相对与该文件头的地址称做文件偏移地址( File Offset )或物理地址(RAW Offset)。文件偏移地址从PE文件的第一个字节开始计数,起始值为0,用十六进制工具(如Hex Workshop,WinHex等)打开文件所显示的地址就是文件偏移地址。(3)虚拟地址(Virtual Address,VA)由于Windows程序运行在386保护模式下,所以程序访问存储器所使用的逻辑地址称为虚拟地址,如代码区段的在内存中的开始地址。与实地址模式下的分段地址类似,虚拟地址也可写成“段:偏移量”的形式,这里的段是指段选择子。例如,“0167:00401000”就是这种表示方法,其中: 0167:这是段选择子,其数据保存在CS段选择器里。同一程序在不同系统环境下, 此值可能不同,一般也不需要关心此值。 00401000:此处表示内存的虚拟地址,一般来说,同一程序的同一条指令在不同系统环境下,此值相同。(4)基地址(ImageBase)文件执行时将被映射到指定内存地址中,这个初始内存地址称为基地址,即文件装入到内存的起始地址。这个值是由PE文件本身设定的,按照默认设置,用Visual C+建立的EXE文件基地址是0x00400000,DLL文件基地址是0x10000000,但是,可以在创建应用程序的EXE文件时改变这个地址,方法是在链接应用时使用链接程序的BASE选项。 (5)相对虚拟地址 相对虚拟地址(Relative Virtual Address,简称RVA)是内存中相对于PE文件装入地址(基地址)的偏移量。它们之间的关系如下:相对虚拟地址(RVA)虚拟地址(VA)-基地址(ImageBase )例如,某个EXE文件从地址0x400000处装入,并且它的代码区块开始于0x401000,代码区块的RVA将是:(RVA)0x1000(虚拟地址)0x401000 -(基地址)0x4000007PE编辑工具PE编辑工具用来查看PE文件结构。用任何一款 PE编辑工具(如LordPE,光盘toolsPE_toolsEditorLordPE)来查看实例PE_Offset.exe文件的块表结构。单击LordPE的“PE Editor”打开PE_Offset文件,如图2.2、图2.3所示,见教材P23。8PE文件区块对齐方式(1)PE文件区块在内存中对齐方式(存放的最小单位)PE文件被映射到内存时,每个区块至少占用一个内存页,所以每个区块的第一个字节对应于某个内存页。在x86系统中,每个内存页的大小是4 KB,即0x1000个字节(212),所以在x86系统中,PE文件每个区块在内存中按0x1000倍数的偏移位置开始存放。(2)PE文件区块在磁盘中对齐方式(存放的最小单位)PE文件在磁盘上时,每个区块至少占用0x200,所以,每个区块按0x200的倍数的文件偏移位置开始。例如,本例文件的.text区块在磁盘文件中的起始偏移位置是0x400,当PE文件被装入内存后,将放在装入地址之上的0x1000位置处。同样,.rdata区块在磁盘文件的0x800偏移处,PE文件被装入内存后,将放在装入地址之上的0x2000字节处。PE文件每个区块的大小必定等于磁盘或内存对齐值的整数倍,而区块的实际代码或数据的大小不一定刚好是这么多,所以在不足的地方一般以0x00来填充,这就是区块间的间隙。9文件偏移地址与虚拟地址转换PE文件被映射到内存后,同一数据相对于文件头的偏移量在内存中和磁盘文件中可能是不同的,这样就存在着文件偏移地址与虚拟地址的转换问题。在图2.4中,磁盘文件中.text块起始端与文件头的偏移量为add1,映射到内存后,.text起始端与文件头(基地址)的偏移量为add2。这里,addl的值就是文件偏移地址(File Offset ),add2的值就是相对虚拟地址(RVA)。假设它们的差值为k,则文件偏移地址与虚拟地址关系如下: File Offset=RVA-k File Offset=VA-Image Base-k式中: File Offset:文件偏移地址,文件在磁盘中的块起始端相对与文件头的地址。 Image Base:基地址,文件头(DOS头部)地址 RVA:相对虚拟地址,文件在内存中的块起始端相对与文件头的地址偏移量。 VA:虚拟地址:文件在内存中的块起始端相对与文件头的地址。在同一区块中,各代码或数据地址的偏移量是相等的,可用上面的公式对此区块中任一File Offset与VA进行转换。但在不同区块中,各代码或数据地址的偏移量不一定相等,因为在磁盘与内存中各区块是以一个页边界为开始的,而不同区块在磁盘与内存中的差值不一样。表2-1是PE Offset文件各区块在磁盘与内存中的起始地址差值。不同的文件各区块在磁盘与内存中的起始地址差值不一定相同。例如,PE Offset中某一虚拟地址(VA)= 0x401112,要求计算它的文件偏移地址(File Offset).0x401112在.text块中,此时k0XC00,故File OffsetVA-ImageBase-k0x401112-0x400000-0xC000x512注意计算时,要按8位16进制进行。LordPE等工具可以实现RVA-Offset之类的转换,单击图2.2的“FLU”按钮打开“文件位址计算器( File Location Calculator)”,见图2.5。2.2代码指令(汇编代码的机器码解释)在软件分析过程中,经常需要计算转移指令机器码或修改指定的代码。虽然有许多工具可以做这些事,但掌握其原理和技巧是很有必要的。2.1.1 转移指令机器码的计算 1. 转移指令机器码组成根据转移的距离,转移指令有以下类型。(结合表2.2)(1)短转移(Short jump):无条件转移和条件转移的机器码都是两个字节。转移范围是-128到+127字节,如jmp:EBxx,EB00表示jmp的短转移机器码,xx表示转移地址。(2)长转移(Long jump):无条件转移的机器码是5个字节,条件转移的机器码是6字节。这是因为条件转移要用2字节表示其转移类型,其他4个字节表示转移偏移量(-3276832767),如je:0F84xxxxxxxx,0F8400000000表示je的长转移机器码,xxxxxxxx表示转移地址。无条件转移仅用一个字节就可表示其转移类型(jmp),其他4个字节表示转移偏移量,如jmp E9 xxxxxxxx。(3)子程序调用指令(call): call指令调用有两类。一类是类似于长转移(Long jump);另一类其调用的参数涉及到寄存器、堆栈等值。如call dword ptr eax。段间间接调用,子程序入口的偏移地址是以eax中的值为地址中的值,子程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 水电合同范本
- 加建合同范本
- 华东理工大学短期培训教师协议书
- 2024至2030年纬密箱齿轮项目投资价值分析报告
- 2024年芥辣玉带豆项目可行性研究报告
- 2024年白格拉辛双硅纸项目可行性研究报告
- 2024年棉混纺纱项目可行性研究报告
- 农业合作社股东分红协议书
- 农业发展MBA培训协议书
- 债务清偿协议书
- 8安全记心上 (3)
- 感染性心内膜炎ppt课件
- 青春期人际交往
- 职工环保教育培训档案最新版本
- 2022年导管相关性血流感染(CRBSI)监测规范及操作手册
- 剪纸英文介绍paper cutting(课堂PPT)
- 研究生课件graphpad prism7作图教程
- 入行论32课(课堂PPT)
- RSlogix500编程PPT课件
- 培训讲义电子版yunsdr相关02提高部分ver
- 通江县房地产市场调研报告
评论
0/150
提交评论