反汇编与软件逆向.ppt

上传人:xt****7 文档编号:2396611 上传时间:2019-11-23 格式:PPT 页数:67 大小:2.41MB
返回 下载 相关 举报
反汇编与软件逆向.ppt_第1页
第1页 / 共67页
反汇编与软件逆向.ppt_第2页
第2页 / 共67页
反汇编与软件逆向.ppt_第3页
第3页 / 共67页
点击查看更多>>
资源描述
反汇编与逆向技术,课程目录,一、软件逆向概述,二、基础知识,三、常用工具,四、逆向破解实战,五、总结,1.1软件逆向的概念,软件逆向概述,可执行文件,突破软件限制,汇编层分析算法,软件源代码,软件逆向概述,1.2软件逆向的一般步骤,1、研究保护方法,去除保护功能,2、反汇编目标软件,定位功能函数,3、分析汇编代码,4、修改汇编代码或还原高级源代码,软件逆向概述,1.3软件逆向的应用,软件破解,软件汇编级BUG调试,病毒分析,漏洞分析,基础知识,2.2、汇编语言基础知识,2.3、可执行文件结构,2.5、软件保护(选),2.1、数据结构基础知识,2.4、Windows启动与程序装载,数据结构基础,2.1.1栈的结构,数据结构基础,2.1.2栈的工作原理,汇编基础,2.2.1汇编语言概述 汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。,简单概括:,1、汇编语言是机器语言的符号表示,与硬件相关,2、个人电脑运行的是基于X86处理器架构的汇编语言,3、最终程序的运行都是一条条指令的运行,汇编基础,2.2.2汇编语言与其它语言的转换,32位,汇编基础,2.2.3常见汇编指令,Add eax,ecx eax寄存器的值加上ecx寄存器的值,结果保存在eax寄存器,Sub eax,ecx eax寄存器的值减去ecx寄存器的值,结果保存在eax寄存器,cmp eax,ebx eax寄存器的值与ebx寄存器的值比较,如相等z标志置1否则置0,Jnz eax Jnz不为0时跳转,即z标志为0时跳转到eax表示的地址处继续执行,Call eax 先将下条指令的地址压栈,再跳转到eax表示的地址处执行,mov eax,ecx 将ecx寄存器的值保存在eax寄存器中,Ret 将当前栈顶的值取出,存放到EIP中,并继续执行,正常情况下:call指令一般在子函数调用时使用,ret指令在子函数返回时使用,汇编基础,2.2.4常用寄存器,EAX 累加器,在加法、乘法指令中用到的寄存器,或存放函数返回值,EBX 基地址寄存器,在内存寻址时存放基地址,ECX 计数器,在循环中一般会使用,EDX 存放整数除法产生的余数,ESI/EDI:源/目标索引寄存器,在很多字符串操作中ESI指向源,EDI指向目标,EBP 基址指针,一般用来存放函数的起始地址,ESP 始终指向栈顶,EIP 存放下条指令的地址,汇编基础,2.2.5一个函数的反汇编代码(Debug版),int add(int low,int high) int sum=0; int i=low; for(i;i=high;+i) sum+=i; return sum; ,push ebp mov ebp,esp sub esp,0x10 mov dword ptr ss:ebp-0x4,0x0 mov eax,dword ptr ss:ebp+0x8 mov dword ptr ss:ebp-0x8,eax jmp short 00401352 mov eax,dword ptr ss:ebp-0x8 add dword ptr ss:ebp-0x4,eax inc dword ptr ss:ebp-0x8 mov eax,dword ptr ss:ebp-0x8 cmp eax,dword ptr ss:ebp+0xC jle short 00401349 mov eax,dword ptr ss:ebp-0x4 leave retn,可执行文件结构,2.3.1程序的编译与链接,源文件经过编译,生成目标文件(在Windows中是*.obj文件,在Linux中是*.o文件)。目标文件再用链接器链接(和库文件一起组合)生成最终的可执行文件,可执行文件结构,2.3.3 PE文件的结构,系统的主要功能就是执行程序,对可执行文件的学习,可以更加深入的了解系统的运行机制,在Windows系统中,可执行文件的结构如下:,区块间隙,0填充,文件尾,文件头,文件,内存,基地址,可执行文件结构,2.3.2可执行文件分类,在Linux中,系统不是根据文件的扩展名来查找对应的程序,而是根据文件中二进制的标记字段,其可执行文件为ELF文件(Executable and Linkable Format),在Windows系统中,可执行文件如*.exe文件、*.dll文件都统称为PE(Portable Executable)文件,PE文件按照一定的标准进行字段组织,使之能正确的被系统装载和执行,PE文件和ELF文件都是基于Unix的COFF文件演化而来,后面我们主要介绍Windows的PE文件结构,及Windows下的反汇编分析,软件逆向概述,PE文件结构,2.2.3.1 PE文件结构的DOS头部,typedef struct _IMAGE_DOS_HEADER / DOS .EXE header WORD e_magic; / Magic number,标志,为MZ WORD e_cblp; / Bytes on last page of file WORD e_cp; / Pages in file WORD e_crlc; / Relocations WORD e_cparhdr; / Size of header in paragraphs WORD e_minalloc; / Minimum extra paragraphs needed WORD e_maxalloc; / Maximum extra paragraphs needed WORD e_ss; / Initial (relative) SS value WORD e_sp; / Initial SP value WORD e_csum; / Checksum WORD e_ip; / Initial IP value WORD e_cs; / Initial (relative) CS value WORD e_lfarlc; / File address of relocation table WORD e_ovno; / Overlay number WORD e_res4; / Reserved words WORD e_oemid; / OEM identifier (for e_oeminfo) WORD e_oeminfo; / OEM information; e_oemid specific WORD e_res210; / Reserved words LONG e_lfanew; / PE文件头的文件偏移 IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;,PE文件结构,2.2.3.2 PE文件结构的PE头部,typedef struct _IMAGE_NT_HEADERS DWORD Signature; /PE头标志,为PE IMAGE_FILE_HEADER FileHeader; /文件头 IMAGE_OPTIONAL_HEADER32 OptionalHeader; /可选头 IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;,Signature字段为PE文件的标志,十六进制固定为0x5035, FileHeader为文件头,存放了一些关于文件的属性,如创建时间。 OptionalHeader名字叫可选头,实质是必须的,并且存放了很多重要的信息,如程序的基地址、程序的执行入口等。,PE文件结构,2.2.3.2 PE文件结构的PE头部,typedef struct _IMAGE_FILE_HEADER WORD Machine; /运行平台 WORD NumberOfSections; /区块数量 DWORD TimeDateStamp; /文件创建时间 DWORD PointerToSymbolTable; /指向符号表 DWORD NumberOfSymbols; /符号表中符号个数 WORD SizeOfOptionalHeader; /可选头的大小 WORD Characteristics; /文件属性 IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;,Characteristics属性字段标记了文件的很多信息,如可执行文件是EXE还是DLL、可执行文件是否为系统文件、是否是32位字的机器等,PE文件结构,2.2.3.2 PE文件结构的PE头部,PE可选头部保存了可执行文件中最多的重要信息,最后一个元素数据目录表,保存了程序中导出、导入表、数据、异常处理等的地址,PE文件结构,2.2.3.3 PE文件结构的区块表,typedef struct _IMAGE_SECTION_HEADER BYTE NameIMAGE_SIZEOF_SHORT_NAME; / 节表名称,如“.text” union DWORD PhysicalAddress; / 物理地址 DWORD VirtualSize; / 虚拟大小 Misc; DWORD VirtualAddress; / 节区的 RVA 地址 DWORD SizeOfRawData; / 在文件中对齐后的尺寸 DWORD PointerToRawData; / 在文件中的偏移量 DWORD PointerToRelocations; / 在OBJ文件中使用,重定位的偏移 DWORD PointerToLinenumbers; / 行号表的偏移(供调试使用地) WORD NumberOfRelocations; / 在OBJ文件中使用,重定位项数目 WORD NumberOfLinenumbers; / 行号表中行号的数目 DWORD Characteristics; / 节属性如可读,可写,可执行等 IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;,PE文件结构,2.2.3.4 PE文件结构的导入表,可执行文件文件使用来自其他动态链接库的代码和数据时,称为导入,当PE文件装入内存时,Windows加载器的工作之一就是定位所有被导入的函数和数据并且让正在被装入的文件可以使用那些地址。这个过程是通过PE文件的导入表(Import Table)来完成的,导入表中存放的是函数名和其驻留的动态链接库信息。,在数据目录表的第二个元素存放的是导入表的地址,每引用一个动态链接库文件,就会有一个对应的导入表结构来描述,导入表结构如下:,typedef struct _IMAGE_IMPORT_DESCRIPTOR union DWORD Characteristics; / 表示结尾时此字段为0 DWORD OriginalFirstThunk; /指向导入名字表INT的RVA数组首地址 ; DWORD TimeDateStamp; DWORD ForwarderChain; / -1 if no forwarders DWORD Name; /动态链接库名称 DWORD FirstThunk; /指向导入地址表的首地址 IMAGE_IMPORT_DESCRIPTOR;,PE文件结构,2.2.3.4 PE文件结构的导入表,PE文件在装入内存前的导入表结构如下:,INT,IAT,PE文件结构,2.2.3.4 PE文件结构的导入表,PE文件在装入内存后的导入表结构如下:,INT,IAT,PE文件结构,PE文件结构,2.2.3.5 PE文件结构的导出表,当创建一个DLL文件时,实际上创建了一组能让EXE或其它DLL调用的一组函数,此时PE装载器根据DLL文件中输出信息修正被执行文件的IAT。当一个DLL函数能被EXE或另一个DLL文件使用时,它被称为导出了。其中导出信息保存在导出表中,DLL文件通过导出表向系统提供导出函数名、序号和入口地址等信息。,在数据目录表的第一个元素存放的是导出表的地址,其结构如下:,PE文件结构,2.2.3.5 PE文件结构的导出表,PE文件结构,更多PE文件知识推荐,Windows启动与程序装载,2.4.1 Windows启动过程,计算机开机后,先执行的是系统固件,即BIOS或EFI(Windows 8以后的主要引导方式),系统固件在完成了对硬件的基本检测之后,将控制权交给磁盘上的引导程序,磁盘引导程序再执行操作系统的加载程序,在Vista后加载程序是WinLoad.exe,系统加载程序首先会对CPU做必要的初始化工作,如切换到保护模式、启用分页机制等。然后通过启动配置文件(Boot.ini或BCD),得到Windows系统的系统目录并加载系统的内核文件,即NTOSKRNL.EXE。当加载这个文件时,会检查它的导入表所依赖的其它文件,包括内核调试通信的硬件扩展DLL等。,然后加载程序会读取注册表,加载其中定义的启动类型(SERVICE_BOOT_START(0))的驱动程序,如磁盘驱动程序等。,完成了上述操作后,系统加载程序会从内核文件的PE头中找到入口函数,并调用这个函数,函数名为:KiSystemStartup,Windows启动与程序装载,2.4.1 Windows启动过程,KiSystemStartup函数的主要过程为如下三步:,第一,调用HalInitializeProcessor()函数初始化CPU,第二,调用KdInitSystem()初始化内核调试引擎,第三,调用KiInitializeKernel()开始内核初始化,这个函数会调用KiInitSystem()来,初始化系统的全局数据结构。,KdInitSystem()函数会初始化系统的一些与调试相关的全局变量,如:,KdPitchDebugger(bool):当系统启动选项包含 /NODEBUG时设置为真,kdDebuggerEnabled(bool):当系统启动选项包含 /DEBUG或/DEBUGPORT且不包含/NODEBUG时设置为真,KiDeubgRoutine(function):指向内核处理回调函数,调试启动时指向kdpTrap,否则指向kdpStub,软件逆向概述,Windows系统启动过程,Windows启动与程序装载,2.4.2windows程序运行原理,Windows程序运行在保护模式下,也就是每个程序都有自己独立的空间,在Win32系统中,每个程序都有独立的4G空间,即地址0x00000000到地址0xFFFFFFFF。,为了高效的调度和执行操作系统的各种服务,Windows会把操作系统和内核数据和代码映射到系统中所有进程的进程空间中,因此4G的空间包括两个部分:用户空间和系统空间(低2G为用户空间,高2G为系统空间),0x00000000,0x7FFFFFFF,0x80000000,0xFFFFFFFF,用户空间,系统空间,进程1,进程2,进程3,进程4,线程,线程,线程,线程,线程,线程,线程,系统模块,驱动程序,Windows启动与程序装载,2.4.2windows程序运行原理,进程就是运行中的程序,在Windows中,一个进程的创建主要在于为进程分配了两个结构:EPROCESS和PEB,在Windows内核中,对进程的操作大都是对EPROCESS结构的操作。进程的EPROCESS结构存放在系统空间中,而PEB结构通过在系统创建后映射在用户空间。,我们可以这样理解为:整个系统内核为一个进程,它存放了应用层各个进程的信息,而内核加载的每一个驱动程序为内核进程的一个线程,共享内核数据。,Windows启动与程序装载,2.4.2windows程序运行原理,EPROCESS结构几乎包括了进程的所有关键信息,比如与调试密切相关的DebugPort (用户态调试端口)和ExceptionPort(异常端口)、进程中所有线程列表的表头、PEB、进程的token结构(访问令牌,用于权限控制)地址等。,PEB(进程环境快)包含了大部分进程的用户态信息,比如BeingDebugged表示是否在被调试,NumberOfHeaps表示堆的个数等。,EPROCESS的详细结构如下:,PEB的详细结构如下:,Windows启动与程序装载,2.4.2windows程序运行原理,Windows中一个程序的装载过程如下:当双击打开一个EXE文件时,主要的过程如下:,1、Windows资源管理器调用CreateProcess()函数,并传入参数:可执行文件路径,用于创建一个进程,该函数返回一个进程句柄。,也就是说,正常双击打开的程序的父进程都是Windows资源管理器,2、CreateProcessA函数实质调用了CreateProcessInternalA函数,在这个函数中,主要对传 进来的参数进行转换,将ANSI字符转成Unicode字符,接着调用CreateProcessInternalW,在应用层,CreateProcessInternalW完成主要的进程创建与资源分配工作,Windows启动与程序装载,2.4.2windows程序运行原理,CreateProcessInternalW函数的主要功能如下:,CreateProcessW,创建标志、检测参数,NtOpenFile,NtCreateSection,各种检测与验证,NtCreateProcessEx,二进制方式打开可执行文件,并对PE文件的相关字段、区块进行解析,创建虚拟内存映像,包括PE中各种关键字段的有效性,开始进入内核创建进程,Windows启动与程序装载,2.4.2windows程序运行原理,NtCreateProcessEx进入内核后由内核函数PspCreateProcess完成下面的创建进程工作:,PspCreateProcess,初始化一切进程管理相关的字段 (非常多),创建内核进程块(KPROCESS),创建和初始新进程地址空间,结束进程地址空间的创建,建立PEB,完成创建过程(设置返回、开启审计),进程创建完后,程序还不能运行,接着内核为进程创建一个主线程,Windows启动与程序装载,2.4.2windows程序运行原理,PspCreateProcess函数返回后,进程的EPROCESS、PEB结构都已经创建,进程的地址空间 也已经创建并初始化,接着调用NtSetInformationProcess设置进程的优先级和默认处理模式,接着调用BaseCreateStack函数创建了栈,并在调用BaseInitializeContext等对线程上下文进 行初始化后,最后调用NtCreateThread创建线程,NtCreateThread,初始化一切与线程相关的字段: 如创建TEB、初始化信号量、加入线程队列等 (非常多),触发APC,到用户层,进入内核:PspCreateThread,CALL OEP(程序入口),LdrInitializeThunk初始化所需的DLL,进入内核,完成初始化,再次返回应用层调用 BaseProcessStart,CALL main函数,软件保护,2.5.1壳的原理,壳是最早出现的一种专用加密软件技术,现在越来越多的软件都加壳保护,EXE原文件,加壳后,壳,壳,运行映射到内存,软件保护,2.5.1壳的原理,壳一般都包含了压缩和加密的功能,壳对可执行文件的代码、数据(导入表、资源等)进行加密,并改变了程序的原始执行入口点,将其指向壳的入口代码。程序运行时,先执行壳的代码,壳的代码中,对加密和压缩的数据进行解压等操作,再跳转到程序的原始OEP处执行。,因此对于加密壳和压缩壳,我们只要定位到了程序的原始OEP,然后将剩下的内存映像还原到文件,就可以成功脱壳。,软件保护,2.5.2虚拟机壳,一个虚拟机引擎由编译器、解释器、VPU Context组成,再配上一个或多个指令系统。虚拟机运作的时候,先把已知的X86指令根据自定义的指令系统转换成字节码,放在PE文件中,然后将源处代码删掉,改变成如下的代码进入虚拟机执行循环: Push bytecode Jmp VstartVM 因此虚拟机保护与普通加壳保护不同,用调试器加载后得到的汇编代码是非常难以理解的。,可以看出虚拟机技术是以效率换安全的,往往一条原始的汇编指令经过VM后会膨胀至几十倍甚至几百倍,执行速度大大降低,因此VM保护一般提供SDK只将重要的函数代码保护起来。但是目前由于CPU的速度足够快,对于一般的程序,即使全部VM保护也不会太多影响程序性能,软件保护,2.5.3软件脱壳,寻找OEP,外壳保护的程序运行时,首先会执行外壳程序,外壳负责把原来的程序在内存中解压还原,并把控制权交给解压的真正程序,再跳到原来程序的入口点,一般的壳在这里会有一个明显的分界线,这个解压后程序的真正入口点称为OEP。,A、根据跨段指令寻找OEP,绝大多数PE加壳程序再被加密的程序中加上一个或多个区块,当外壳代码处理完毕后,会跳到程序本身的代码上,所以依据跨段的转移指令就可以找到真正的入口点。,B、根据内存访问断点找OEP,外壳首先将原来的压缩代码解压缩,并放到对应的区块上,处理完毕将跳到代码段执行,因此可以对代码所在的区块下内存访问断点,最终调试分析在OEP执行时断下。,软件保护,2.5.3软件脱壳,C、根据堆栈平衡原理找OEP,编写加壳软件时,必须保证外壳初始化的现场环境与原程序的现场环境是相同的,加壳软件初始化时保存各寄存器的值,外壳执行完毕时,再恢复各寄存器的内容,最后跳到原程序执行,如果外壳在保护各寄存器的值后,对ESP寄存器设置硬件访问断点,那么再恢复时,外壳程序断下,此处离OEP也就不远了。,D、根据编译语言特点找OEP,各种语言编译的文件的入口点都有自己的特点,同一种编译器其入口代码都很类似,都一段启动代码,编译器编译程序时,自动连接到程序中去,完成必要的初始化工作后,再调用main函数,执行完后,启动代码再次获得控制权,进行一次初始化清除工作。,抓取内存映像,在加密外壳中,破坏原程序的导入表是必有的功能,因为为了保证程序能正常运行,必须对原程序的导入表重新构造。同时外壳程序可能使用一些技术来防止对输入表的重建。,重建导入表,抓取内存映像,也称为转存,英文称为Dump。就是把内存指定地址的映像文件读取出来,然后用文件等形式保存下来。脱壳时,一般在OEP处进行Dump,因为此时程序的各种变量都还没有初始化,与文件中存放的内容一致。同时外壳程序可能使用一些Anti-Dump技术来防止转存,2.5.3软件脱壳,软件保护,2.5.4软件反调试,软件保护,软件保护的手段还有很多,如文件完整性校验、内存映像校验、信息隐藏、化指令、代码混淆等。好的软件保护都要与反跟踪调试技术结合在一起,否则软件就等于直接裸露在解密者的面前,这里的解密者泛指调试器、监控工具等。,反调试例子: 在内核层进程的EPROCESS结构中,有一个DebugPort字段,当进程是被调试打开时,这个字段指向了一个调试对象,否则为0,那么我们加载驱动程序找到我们进程的这个字段,并将字段清0,就可以禁止任何调试器的调试,在应用层进程的PEB结构中,有一个字段BeingDebugged标志,当检测到这个字段为真时,直接退出程序。,软件保护,上述的反调试方法和手段只是一个简单的例子,更进一步的反调试检测参考:,常用工具,3.1 ollyDbg调试器,OllyDbg(简称OD)是由Oleh Yuschuk编写的一款具有可视化界面的用户模式调试器,可以在目前各种Windows版本上运行。ollyDbg结合了动态调试和静态分析,具有GUI界面,非常容易上手,并且对异常的跟踪处理相当灵活,这些特性使得OllyDbg成为调试Ring3级程序的首选工具。,同时OllyDbg具有强大的插件接口,各种插件的使用使得这款动态调试软件的功能越来越强大。,OllyDbg常用的快捷键使用如下:F9运行程序、F8单步运行、F7跟踪单步运行 ALT+E查看调用模块、ALT+M查看内存模块、ALT+B查看断点、ALT+C查看CPU指令,反汇编窗口,寄存器窗口,栈窗口,数据窗口,当前指令所需的数据值,常用工具,3.1 WinDbg调试器,Windbg是在windows平台下,强大的用户态和内核态调试工具。相比较于Visual Studio,它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能,却比VS更为强大。它的另外一个用途是可以用来分析dump数据。,WinDbg在调试内核时一般会使用双机调试方式,被调试的系统可以在虚拟机或物理机 上运行,常用工具,3.1 IDA静态反汇编工具,IDA Pro 是DataRescue公司出品的一款交互式反汇编工具,它功能强大,操作复杂,要完全掌握它需要很多知识。IDA最主要的特性是交互式和多处理器。操作者可以通过对IDA的交互操作来指导IDA更好的反汇编。 IDA支持的文件类型非常丰富,除了常见的PE格式,还支持UNIX、Java、Mac和.NET等平台文件格式,当打开一个文件时,它会自动识别文件的格式。,IDA具有强大的注释系统,可以自定义结构体和注释,当程序中对注释字段的引用时,会动进行注释,方便反汇编的分析。,常用工具,3.1 IDA静态反汇编工具,对汇编代码的调用流程以图形的方式显示:,常用工具,3.1 IDA静态反汇编工具,生成反编译高级语言代码:,逆向破解实战,这里以看雪论坛2017年CTF秋季赛第二题为例,这是一个控制台程序如下:,逆向破解实战,当密码输入错误时提示信息如下,接着就退出程序:,逆向破解实战,我们用OD附加程序,搜索提示的字符串,定位到如下反汇编窗口:,这里的JNZ(不为0跳转)跳过了注册的部分,到了注册失败的部分继续执行。,逆向破解实战,mov dword ptr ds:0x41B034,0x2 #将地址0x41B034处写入2 call ctf2017_.00401050 call ctf2017_.00401090 #调用三个子函数 call ctf2017_.004010E0 mov eax,dword ptr ds:0x41B034 #将地址0x41B034处的值写到eax寄存器 test eax,eax jnz short ctf2017_.0040103F,#判断eax不是0就跳转,第一个子函数地址为0x00401050,我们跟进查看汇编代码:,逆向破解实战,通过反汇编窗口右边的自动注释和控制台的输出我们可以知道:这个子函数的功能就是在控制台输出了两行字符串,接着接受输入一行字符串,输入的字符串保存在了找中(输入了123456789测试)。,我们接着动态跟踪第二个子函数:,我们主要找与地址0x41B034有关的,在子函数下面: mov edx,0x543F30 xor edx,0x158F04 mov eax,dword ptr ds:edx dec eax mov dword ptr ds:edx,eax,0x543F30与0x158F04异或的值正好是0x41B034,因此这个子函数后面代码的意思就是把地址0x41B034的值减去1。,逆向破解实战,那么我们可以想到,要保证密码正确,地址0x41B034的值还必须减1,那么另一个减1的地方可能在第三个子函数中:,果然在第三个子函数中,也有对地址0x41B034减1的操作。,逆向破解实战,因此只要这两个子函数对地址0x41B034的减1操作都执行,就可以破解成功。,那么现在要做的是保证这两个子函数的JNZ跳转都不执行,第二个子函数的第一个JNZ跳转的条件为:,mov eax,ecx #ecx为输入的5-8字节的ASCII码 sub eax,edx #edx为输入的1-4字节的ASCII码 je short ctf2017_.004010D7 mov local.3,eax imul eax,eax,0x5 add ecx,eax cmp ecx,0x8F503A42,如果设输入的1-4字节b,5-8字节为a,要保证不跳转,必须满足:,0x5 * ( a - b ) + a = 0x8F503A42,逆向破解实战,同理,要保证地址0x41B034处为0必须同时满足:,0x5 * ( a - b ) + a = 0x8F503A42 0xD * ( a - b ) + b = 0xEF503A42 0x11 * ( a - b ) + a = 0xF3A94883 0x7 * ( a - b ) + b = 0x33A94883,通过计算发现这样的输入无解!,逆向破解实战,于是又想到我们的输入保存在栈中,这样可能导致输入的值过长时覆盖返回地址,然后直接跳到输出正确的地方执行,当前面刚输入123456789时,程序的栈内容如下:,如果再多输入两个字符就可以覆盖返回地址,而执行输出成功的地方是0x0040102F,由于字符串尾部以0x00结束,因此我们可以输入字符覆盖40101C得到40102F 但是40102F无法输入,因为不存在10和2F的ASCII码,因此可能是覆盖返回地址跳转到另一个地方,逆向破解实战,用OD打开程序,看到有如下地方:,这里属于代码段,但是存在大量无法解析的代码,地址为0x00413131,即我们输入 12345678900011A就可以跳转到这里去执行。,逆向破解实战,跳到这里后全是花指令(无实际意思的指令,扰乱分析),但是大概可以知道关键信息就掺杂在花指令中。,逆向破解实战,略过花指令,抽取运算相关的代码,与前面类似得到一个方程组:,4*(a-b)+a0xEAF917E2=0,3*(a-b)+a0xE8F508C8=0,3*(a-b)c-0xC0A3C68=0,计算得到 : a=0x7473754A 字符串为 tsuJ = Just b=0x726F6630 字符串为 rof0 = 0for c=0x6E756630 字符串为 nuf0 = 0fun,因此得到的正确的输入字符串为Just0for0fun11A,逆向破解实战,测试结果如下:,总结,软件逆向是一个熟能生巧的过程,除了学习别人的经验技巧之外,更多的是 需要不断的练习。 软件逆向过程是比较枯燥的,必须要有足够的耐心和细心。 相对于软件破解,软件功能和算法逆向是更高级逆向技巧的,需要逆向人员 有扎实的编程功底,如果希望在逆向领域有更大的进步,提升自己的编程水 平是十分必要的,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!