使用OllyDbg从零开始Cracking 第二十九章-P-CODE
使用OllyDbg从零开始Cracking 第三十章PCODE

第三十章-P-CODE-Part2(本章CrackMe支持库MSVBVM50.DLL)本章我们继续讨论P-CODE。
以下是我从JBDUC的教程里收集的一些操作码:6c → ILdRf 将指定操作数压入堆栈1b → LitStr5 将字符串压入堆栈fb → Lead030 → EqStr 比较两个字符串(与Lead0配合使用)2f → FFree1Str 释放内存空间1a → FFree1Ad 释放内存空间0f → VCallAd 通过虚拟机运行操作码1c → BranchF 条件跳转指令,如果栈顶的值为false则跳转(相当于汇编指令JNE/JNZ)1d → BranchT 条件跳转指令,如果栈顶的值为true则跳转(相当于汇编指令JE/JZ)1e → Branch 无条件跳转(嘿嘿,相当于汇编指令JMP)fc → Lead1c8 → End 终止程序(与Lead1配合使用)f3 → LitI2 将立即数压入堆栈f4 → LitI2_Byte 将指定数据转化为字节整型并压入堆栈70 → FStrI2 将栈顶的WORD型元素保存到内存单元中,然后执行出栈操作6b → FLdI2 将WORD型参数压入堆栈a9 → AddI2 栈顶两个WORD型元素相加,相加的结果置于栈顶ad → SubI2 栈顶两个WORD型元素相减,相减的结果置于栈顶b1 → MulI2 栈顶两个WORD型元素相乘,相乘的结果置于栈顶好了,以上列出了一些操作码以及相应的含义,这里还有一份<<P-Code_OPCODES>>文档,这份文档是关于VB P-CODE虚拟机的说明文档,其阐述了操作码的解析原理(但是并不全,嘿嘿)。
如果大家遇到了不熟悉的操作码的话,可以参考一下该文档,可能有帮助。
好了,这里我们首先来讲解clave2这个CrackMe,将其加载到ExDec看看都显示些什么。
这里我们可以看到开始于401CC0处,这里不能完全依然于ExDec,因为有时候它的分析不怎么准确,所以我们还是像上一章节一样手工来定位第一个操作码吧。
OllyDBG新手使用说明书

OllyDBG 新手使用说明书OLLYDBG完全教程(一)一、什么是 OllyDbg ?OllyDbg 是一种具有可视化界面的 32 位汇编 - 分析调试器。
它的特别之处在于可以在没有源代码时解决问题,并且可以处理其它编译器无法解决的难题。
Version 1.10 是最终的发布版本。
这个工程已经停止,我不再继续支持这个软件了。
但不用担心:全新打造的OllyDbg 2.00 不久就会面世!运行环境: OllyDbg 可以以在任何采用奔腾处理器的Windows 95、98、ME、NT或是 XP(未经完全测试)操作系统中工作,但我们强烈建议您采用 300-MHz以上的奔腾处理器以达到最佳效果。
还有, OllyDbg 是极占内存的,因此如果您需要使用诸如追踪调试[ Trace ]之类的扩展功能话,建议您最好使用 128MB以上的内存。
支持的处理器:OllyD 的数据格式,但是不支持SSE2 指令集。
bg 支持所有80x86、奔腾、 MMX、3DNOW!、 Athlon 扩展指令集、 SSE指令集以及相关配置:有多达百余个(天呀!)选项用来设置OllyDbg 的外观和运行。
数据格式: OllyDbg 的数据窗口能够显示的所有数据格式: HEX、ASCII 、UNICODE、 16/32 位有 / 无符号 /HEX 整数、32/64/80 位浮点数、地址、反汇编( MASM、IDEAL或是 HLA)、PE文件头或线程数据块。
帮助:此文件中包含了关于理解和使用 OllyDbg 的必要的信息。
如果您还有 Windows API帮助文件的话(由于版权的问题 win32.hlp 没有包括在内),您可以将它挂在 OllyDbg 中,这样就可以快速获得系统函数的相关帮助。
启动:您可以采用命令行的形式指定可执行文件、也可以从菜单中选择,或直接拖放到 OllyDbg 中,或者重新启动上一个被调试程序,或是挂接[ Attach ]一个正在运行的程序。
OllyDbg入门完全教程(完美排版)

OllyDbg完全教程目录第一章概述 (1)第二章组件 (5)一、一般原理[General prnciples] (5)二、反汇编器[Disassembler] (8)三、分析器[Analysis] (9)四、Object扫描器[Object scanner] (12)五、Implib扫描器[Implib scanner] (12)第三章 OllyDbg的使用 (13)一、如何开始调试[How to start debugging session] (13)二、CPU 窗口[CPU window] (14)三、断点[Breakpoints] (14)四、数据窗口[Dump] (15)五、可执行模块窗口[Executable modules window] (16)六、内存映射窗口[Memory map window] (17)七、监视与监察器[Watches and inspectors] (19)八、线程[Threads] (19)九、调用栈[Call stack] (20)十、调用树[Call tree] (21)十一、选项[Options] (21)十二、搜索[Search] (22)十三、自解压文件[Self—extracting (SFX) files] (22)十四、单步执行与自动执行[Step—by—step execution and animation] (23)十五、Hit跟踪[Hit trace] (23)十六、Run 跟踪[Run trace] (24)十七、快捷键 (26)十八、插件[Plugins] (29)十九、技巧提示[Tips and tricks] (29)第四章其他功能 (30)一、调试独立的DLL[Debugging of stand—alone DLLs] (30)二、解码提示[Decoding hints] (32)三、表达式赋值[Evaluation of expressions] (32)四、自定义函数描述[Custom function descriptions] (34)第一章概述OllyDbg 是一种具有可视化界面的32 位汇编—分析调试器。
外挂编写必备工具2OllyDBG (OD)入门系列

00440F70 |. EB 32 JMP SHORT CrackMe3.00440FA4
00440F72 |> 6A 00 PUSH 0
OllyDBG中各个窗口的功能如上图。简单解释一下各个窗口的功能,的反汇编代码,标题栏上的地址、HEX数据、反汇编、注释可以通过在窗口中右击出现的菜单界面选项->隐藏标题或显示标题来进行切换是否显示。用鼠标左键点击注释标签可以切换注释显示的方式。
ALT+F9:执行到用户代码。可用于从系统领空快速返回到我们调试的程序领空。(相当于SoftICE中的F11)
外挂编写必备工具2——OllyDBG(OD)入门系列2
OllyDBG入门系列(二)-字串参考
上一篇是使用入门,现在我们开始正式进入破解。今天的目标程序是看雪兄《加密与解密》第一版附带光盘中的镜像打包中的CFF Crackme #3,采用用户名/序列号保护方式。原版加了个UPX的壳。刚开始学破解先不涉及壳的问题,我们主要是熟悉用OllyDBG来破解的一般方法。我这里把壳脱掉来分析,附件是脱壳后的文件,直接就可以拿来用。先说一下一般软件破解的流程:拿到一个软件先别接着马上用OllyDBG调试,先运行一下,有帮助文档的最好先看一下帮助,熟悉一下软件的使用方法,再看看注册的方式。如果是序列号方式可以先输个假的来试一下,看看有什么反应,也给我们破解留下一些有用的线索。如果没有输入注册码的地方,要考虑一下是不是读取注册表或Key文件(一般称keyfile,就是程序读取一个文件中的内容来判断是否注册),这些可以用其它工具来辅助分析。如果这些都不是,原程序只是一个功能不全的试用版,那要注册为正式版本就要自己来写代码完善了。有点跑题了,呵呵。获得程序的一些基本信息后,还要用查壳的工具来查一下程序是否加了壳,若没壳的话看看程序是什么编译器编的,如VC、Delphi、VB等。这样的查壳工具有PEiD和FI。有壳的话我们要尽量脱了壳后再来用OllyDBG调试,特殊情况下也可带壳调试。下面进入正题:
OllyDBG完美教程

OllyDBG完美教程(超强入门级)关键词:OD、OllyDBG、破解入门、调试专用工具、反汇编一、OllyDBG 的安装与配置OllyDBG 1.10 版的发布版本是个 ZIP 压缩包,只要解压到一个目录下,运行 OllyDBG.exe 就可以了。
汉化版的发布版本是个 RAR 压缩包,同样只需解压到一个目录下运行 OllyDBG.exe 即可:OllyDBG 中各个窗口的功能如上图。
简单解释一下各个窗口的功能,更详细的内容可以参考 TT 小组翻译的中文帮助:反汇编窗口:显示被调试程序的反汇编代码,标题栏上的地址、HEX 数据、反汇编、注释可以通过在窗口中右击出现的菜单界面选项->隐藏标题或显示标题来进行切换是否显示。
用鼠标左键点击注释标签可以切换注释显示的方式。
寄存器窗口:显示当前所选线程的 CPU 寄存器内容。
同样点击标签寄存器 (FPU) 可以切换显示寄存器的方式。
信息窗口:显示反汇编窗口中选中的第一个命令的参数及一些跳转目标地址、字串等。
数据窗口:显示内存或文件的内容。
右键菜单可用于切换显示方式。
堆栈窗口:显示当前线程的堆栈。
要调整上面各个窗口的大小的话,只需左键按住边框拖动,等调整好了,重新启动一下 OllyDBG 就可以生效了。
启动后我们要把插件及 UDD 的目录配置为绝对路径,点击菜单上的选项->界面,将会出来一个界面选项的对话框,我们点击其中的目录标签:因为我这里是把 OllyDBG 解压在 F:\OllyDBG 目录下,所以相应的 UDD 目录及插件目录按图上配置。
还有一个常用到的标签就是上图后面那个字体,在这里你可以更改 OllyDBG 中显示的字体。
上图中其它的选项可以保留为默认,若有需要也可以自己修改。
修改完以后点击确定,弹出一个对话框,说我们更改了插件路径,要重新启动 OllyDBG。
在这个对话框上点确定,重新启动一下 OllyDBG,我们再到界面选项中看一下,会发现我们原先设置好的路径都已保存了。
第三章:OllyDbg的使用(上)

教程三:OllyDbg的使用(上)本章中我将会介绍OllyDbg的使用。
Olly有许多的功能,唯一学好它们的方式是实践和练习。
也就是说,本教程也只是给你一个简单的概述。
此教程不会涉及额外的内容,后面会进行重点讨论。
到最后,你应该会比较好的掌握Olly。
本章包含了一些文件。
你能够下载那些文件,以及可以在这里下载到次教程的PDF版本。
它们包括一个我们将在Olly中用到的二进制文件、一个Olly备忘单、我使用的外观上有些不同的Olly以及一个新的ini文件。
你可以用这个ini文件替换掉Olly默认的ini,可以给新人提供一些帮助(感谢伟大的Lena151做的这些)。
你可以从这里直接下载或者从教程页面下载。
如果你更愿意用原版的Olly,你可以从这里下载。
一、载入应用第一步是将目的二进制文件载入Olly。
你可以将二进制文件拖放到Olly的反汇编窗口,或者点击顶部工具栏中的载入图标选择目的文件。
我们这里载入“FirstProgram.exe”,可以从本网站下载。
Olly会进行分析(Olly的底部状态栏会显示分析进程)然后停在程序的入口点(EP):需要注意的第一件事是EP的地址是401000,就是图片中的第一列。
这是可执行文件的一个相当标准的起点(该可执行文件至少没有加过壳或混淆过)。
如果你的看起来不太一样,并且Olly没有停在401000,你可以尝试点击Appearance菜单,然后选择debugging options,点击“Events”标签,并且确保“WinMain(if location is known)”被勾选上。
然后重启应用。
让我们给“FirstProgram.exe”的内存空间占用情况来张快照。
点击“Me”图标(如果你使用的是不同版本的Olly的话应该是“M”):如果你看地址那一列,你会看到401000那行包含有大小1000、名称“FirstPro”(FirstProgram的简写形式)、区块名“.text”、包含里是“SFX,code”。
ollydbg的使用教程

ollydbg的使⽤教程教程四:OllyDbg的使⽤(下)⼀、简介此次教程我们继续学习Olly的使⽤。
我们将继续使⽤上⼀章的程序(我也会将它包含在下载⾥)。
你可以在tutorials中下载⽂件和PDF版的教程。
⼆、DLLS就像我前⾯说的,当你启动程序时,DLL被系统载⼊器载⼊。
这回我会细致的讲解。
DLL (Dynamic Link Libraries)是函数的集合,通常由Windows提供(当任何⼈都可以提供),其中含有很多Windows程序要⽤的函数。
这些函数可以让程序员更容易的完成⼀些乏味的重复性的任务。
例如,将字符串全部转换成⼤写是许多程序要实现的功能。
如果你的程序要多次使⽤该功能的话,你有三个选择:⼀是在你的程序中⾃⼰编码实现;问题是,你不知道你的下⼀个程序是不是也会⽤到该功能很多次。
你可能需要在你使⽤到的程序⾥复制粘贴很多次相同的代码。
⼆是创建⼀个⾃⼰的库,这样任何程序都可以调⽤。
这种情况下,你可以创建⼀个DLL,然后包含在程序中。
该DLL可能有像convertToUpper这样的通⽤函数以便于程序调⽤,因此你只需要写⼀次代码就⾏了。
这样做的另⼀个好处是,你可以说你为字符串转⼤写想到了⼀个很好的优化⽅案。
第⼀个例⼦中,你需要将代码拷贝到所有要⽤到该代码的程序中,但是在那个通⽤DLL例⼦中,你只需要修改DLL的代码,然后所有使⽤该DLL的程序都可以以最快的速度获益。
爽吧!这就是DLL产⽣的真正原因。
最后⼀个选择是,使⽤Windows提供的⼀堆DLL中包含的数千个函数中的⼀个。
这样做有很多好处。
第⼀个是,Microsoft的程序员已经花了多年时间来优化他们的函数,他们在很⼤程度上要⽐你⽜逼。
第⼆,你不需要将你的DLL包含在应⽤中,因为Windows操作系统已经内建了这些DLL。
最后,如果Windows决定修改他们的操作系统,你⾃⼰的DLL有可能和新系统不兼容。
同时,如果你使⽤Windows的DLL,它们肯定是兼容的。
OllyDbg的基本使用

OllyDbg的基本使⽤注:内容整理⾃《逆向⼯程核⼼原理》,结合我的OllyDbg版本修改了⼀些内容1. OllyDbg常⽤命令及其快捷键指令快捷键含义Restart Ctrl+F2重新开始调试Step Into F7执⾏⼀句OP code,若遇到CALL,进⼊函数代码内部Step Over F8执⾏⼀句OP code,若遇到CALL,仅执⾏函数⾃⾝,不跟随进⼊Run F9运⾏(遇到断点时暂停)Execute till return Ctrl+F9 执⾏函数代码内的命令,直到遇到RETN命令,⽤于跳出函数体Execute till cursor F4 执⾏到光标所在位置Comment; 添加注释User-defined comment⿏标右键菜单Search for-User defined comment查看⽤户输⼊的注释⽬录Label:添加标签User-defined label⿏标右键菜单Search for-User defined Label查看⽤户输⼊的标签⽬录Breakpoint F2设置或取消断点All referenced text strings ⿏标右键菜单Search for-All referenced textstrings查看代码中引⽤的字符串All intermodular calls⿏标右键菜单Search for-All intermodular calls查看代码中调⽤的所有API函数Name in all modules⿏标右键菜单Search for-Name in all modules查看所有API函数Edit data Ctrl+E编辑数据Assemble空格键编写汇编代码Copy to executable file⿏标右键菜单Copy to executable file创建⽂本副本(修改的项⽬被保留)2. 设置点的⽅法(这⾥我们假设⼤本营的地址为004010ED)①Goto命令执⾏Goto命令(Ctrl+G),在打开的对话框中输⼊004010ED,然后单击OK按钮,这样光标就会⾃动定位到004010ED处然后执⾏Execute till cursor(F4)命令,让调试流运⾏到该处②设置断点选中004010ED这⼀⾏(可以⼿动找,也可以使⽤上述Goto命令中的第⼀步),设置BreakPoint(F2),调试运⾏到断点处会暂停然后执⾏Run debugged application(F9)即可让调试直接运⾏到断点处暂停注:在OllyDbg菜单栏中选择View-Breakpoints(Alt+B),可以打开Breakpoints对话框,列出代码中设置的断点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第二十九章-P-CODE-Part1(本章的CrackMe需要支持库MSVBVM50.DLL)前面章节我们已经介绍了Visual Basic破解相关的基础知识,如果大家还想更加深入的研究VB应用程序破解的话,可以继续学习高级篇中的关于VB破解的相关内容。
(PS:就是我打包上传到百度网盘的西班牙破解文集系列)COCO写的VB破解教程就比较好,其中可能会涉及到比较复杂的处理技巧,拿来练习做好不过了。
还有一些其他优秀教程可供我们更加深入的研究VB Cracking。
接着下来我们将讨论下一个话题-P-CODE。
我们知道VB编写的应用程序有两种编译方式:一种是Native方式,我们前面章节已经讨论过了,两一种就是P-CODE方式-我们接下来将讨论的话题。
Native编译的代码和P-CODE的主要区别在于:Native是直接执行代码段中的代码的。
而对于P-CODE,如果我们使用之前那个Patch过的OD加载它,并且给代码段设置内存访问断点的话(实际上是内存执行断点),除非是直接调用API函数,否则不会断下来。
说明,该区段没有直接可供CPU执行的代码。
P-code,实际上是一组自定义的指令集,必须通过基于堆栈的虚拟机翻译为80X86上的指令集才能执行,即通过msvbvm50.dll和msvbvm60.dll这两个动态库来解释执行。
也可以理解为通过P-CODE告诉虚拟机将要进行什么操作。
例如:1e 表示执行无条件跳转(JMP)1e意味着执行无条件跳转,该无条件跳转是通过虚拟机(msvbvm50.dll,msvbvm60.dll)来执行的,也就是说P-CODE程序会读取代码段中的值,然后由这些值来告诉虚拟机需要执行什么操作。
这也就是为什么我们说P-CODE程序的代码段中没有可执行代码的缘故。
现在就让我们一起拿起“手术刀”来跟踪,剖析一个CrackMe的P-CODE的奥秘吧。
我们实验的这个CrackMe名字叫做clave1,这个CrackMe是我朋友JB DUC写的,用来介绍P-CODE相关的内容正好合适,我们需要找到该CrackMe的正确序列号。
很多人调试P-CODE可能喜欢用WKT,如果大家想了解WKT怎么调试P-CODE的话,可以看JB DUC关于P-CODE的破解教程,我们这里还是用OllyDbg来调试了,由于微软官方并没有提供操作码的清单,所以还会用到另外一个工具EXDEC-这个工具可以识别操作码的名称。
我们使用原版的OD,配置好反反调试插件,加载该CrackMe。
可以看到停在了入口点处。
说明一点,之前介绍的用于剔除Native程序的NAG窗口的4C法同样适用于P-CODE。
现在我们来看看跟Native的不同的地方:我们从入口点往下看,会发现没有几行代码。
我们只看到了大片的字节码,这里不要试图去分析这些字节码(毫无意义),我们应该还记得对于Native方式编译的VB应用程序,入口点往下还会有大量的代码吧。
也有相似的字节码,我们继续往下。
这里我们可以看到大段的代码,而P-CODE的程序的话OllyDbg可能也会显示处少量的代码,OD识别成了指令,但其实这些地方也是纯字节码。
我们继续来看刚刚那个P-CODE的CrackMe。
另外一个特征就是MethCallEngine这个API函数,该函数我们在P-CODE方式编译的VB应用程序中都能看到,所以我们甄别一个VB应用程序是不是以P-CODE方式编译的,一般有两步:1:看代码段中入口点以下是不是大片的字节码2:看有没有MethCallEngine这个函数。
好了,现在我们来看看字符串列表中有没有什么有价值的字符串。
貌似没看到什么有用的字符串。
好,那我们直接给JMP MethCallEngine这一行下一个断点吧。
接下来我们选中JMP MethCallEngine这一行,单击鼠标右键选择-Follow,转入MethCallEngine内部,接着在MethCallEngine入口点处设置一个断点。
运行起来。
弹出了注册窗口,等待我们输入序列号。
对于Native的VB程序,我们可以断API函数,但是P-CODE就搞不定了,但4C法对P-CODE 程序依然有用。
现在我们随便输入一个错误的序列号。
我们单击Registrar(西班牙语:注册)按钮。
断在了JMP MethCallEngine处,MethCallEngine函数对P-CODE进行初始化。
我们继续运行,断在了MethCallEngine的入口处,我们来看看它做了些什么。
我们可以看到跳转到了7413D243处。
现在我们用ExDec打开该CrackMe。
ExDec是一款专门针对P-CODE的反编译器。
我们来看看它显示了些什么。
我们可以看到将被读取的第一个字节是04,位于401BD0地址处,应该在第一次读取代码段指令的附近,我们可以给该字节设置一个内存访问断点。
我们单击Registrar按钮后就会断在了MethCallEngine处,我们给代码段设置内存访问断点。
运行起来的话,将断在了读取代码段的指令处,读取401BD0内存单元中04的指令应该就在附近,所以我们接着给该字节设置内存访问断点,继续运行,就能马上定位到。
我们按F9运行起来。
断了下来,这个时候我们给刚刚那个04字节设置内存访问断点,运行起来,又断了下来,我们可以看到ESI指向的就是401BD0内存单元。
(PS:这里下断点的顺序我换了次序,一次就可以定位到,作者10次才定位到)这里读取[ESI]的04字节值保存到AL中,这里是读取到的第一个P-CODE操作码。
接着我们来看看ExDec中显示的其他操作码。
我们将ExDec跟OD的数据窗口显示的内容对应起来看,会发现这些操作码并不连续,这是因为中间夹杂着操作码需要的参数。
正如你所看到的,这里正在读取第一个字节。
我们可以看到当前ESI指向了401BD0,下一行,ESI值递增1,以便读取操作码的参数。
接着我们就到了间接跳转JMP指令这里,这一行将去执行这个操作码(我们在ExDec中看到的04)。
我们可以看到一个陌生的操作码。
这里我们可以看到将执行操作码04(即FLdRfVar),就只有几行代码,也没实现什么很神奇的操作,嘿嘿。
还可以看到XOR EAX,EAX,然后就是读取后面操作码。
这里首先读取紧跟在04后面两个字节的参数。
通过MOVSX指令将FF74(这是个负数,前面汇编章节介绍过)保存到EAX中,我们继续跟踪。
EAX的值为-8C(十六进制),我们双击EAX值的话可以看到:我们可以看到FF74对应的十进制是-140也就是十六进制的-8C。
我们可以看到ExDec中显示的是8C。
接下来一行,操作码的参数值被加上EBP寄存器的值。
接下来一行使用PUSH指令将刚刚运算的结果压入堆栈。
这里相当于PUSH EBP - 8C (EBP - 8C:标识着堆栈中的局部变量),我的机器上,EBP的值为12F4E0,减去8C就得到了12F454。
即当前EAX中的值。
也就是使用PUSH指令压入堆栈中的值。
好,我们继续往下跟。
我们可以看到通过XOR EAX,EAX指令将EAX清零了,这就意味着操作码被清零了,该操作完成了,重置寄存器的值,然后接下来一行就可以读取下一个操作码了。
第二个操作码是21,在接下来的一行读取它。
操作码跟之前一样依然被是保存在AL。
现在ESI被加上3,指向当前操作码的参数,接着通过间接跳转JMP去执行操作码21。
我们来Google一下它的含义。
好,这里我们可以看到有些前辈做了注释,虽然我们不知道它具体是干什么用的,但是根据字面的意思来理解就是加载一个指针,并且指向一个数据项。
我们继续往下跟。
这里是将EBP + 8指向内存单元的内容读取出来并保存到EBP - 4C指向的内存单元中。
这个值在我的机器上是15B000,我们在数据窗口中定位到这个地址。
该地址中保存的是4022E8,我们继续在数据窗口中定位到4022E8。
这里我们可以推断出15B000其实是一个指针。
该指针指向了一张表,虽然对我们的破解起不到什么实质性的帮助,但起码我们还是看出一点门道了。
还有一点就是可以看出该操作码没有参数。
我们继续跟。
这里EAX又被清零了,下一行读取第三个操作码。
从ExDec中我们可以看出该操作码是0F。
VcallAd以上是0F这个操作码具体的解释,我们可以看到它有一个占两个字节的参数。
该参数我这里显示的0300,其表示句柄表中数据元素的偏移。
接下来是一个间接跳转JMP,我们跟进去看看。
又是读取EBP - 4C的内容,保存到EBX中。
这里我们可以看到是15B000,并使用PUSH指令压入到堆栈中。
接着是将参数值300保存到EAX中。
这里EBX的值为15B000(我们已经知道了它指向了一张表),该表起始地址为4022E8,我们姑且将这张表称之为Description Item Table。
这里由该表的起始地址偏移300。
表的起始地址偏移300就得到了4025E8,保存到EAX中。
该值指向了表的这里。
这里操作码0F就是根据参数值指明的偏移量来定位前一个操作码获取到的表中的数值。
这里是使用CALL指令间接调用EAX内存单元中保存的值处。
该值为7414C348,这里我们不跟进去,结果会被保存在堆栈中的。
我们直接按F8键单步步过这个CALL。
我们可以看到堆栈中保存了结果,我们需要弄明白它表示什么意思。
接下来的操作码是19,参数值是88,代表一个局部变量。
这里我们直接跟进。
我们看到这里。
通过MOVSX指令读取出占两个字节的参数值,将其保存到EAX中。
FF开头表明该参数值是一个负数。
该值对应的十六进制为-88,跟ExDec中显示的刚好对应起来了。
十进制的-139正好等于十六进制的-88。
接着ESI 加2,然后刚刚计算出的-88加上EBP的值,即将EBP - 88保存到EAX中。
这里我们可以看到到达了一个CALL处,根据堆栈的来看其有三个参数。
第一个参数是前一个操作码执行的结果,第二个参数我这里是12F458,即EBP - 88-表示一个局部变量。
第三个参数是-1。
这里我们不跟进这个CALL,直接按F8键单步步过这个CALL,看看会发生什么。
我们会发现堆栈发生了变化,ECX被清零了。
EBP-88内存单元保存了前一个操作码执行的结果。
接下来一个操作码是08,它也将局部变量EBP - 88作为参数。
我们跟进这个JMP。
这下面并不是我们之前看到的XOR EAX,EAX结束,而是OR EAX,EAX,接着使用条件跳转判断EAX是否为零。
我们来看看它具体干了些什么。
首先将操作码的参数FF78保存到EAX中,注意这里使用的是MOVSX,FF开头表示是负数,十六进制值为-88。
这一行是将EAX + EBP指向内存单元的值保存到EAX中,即EBP - 88这个局部变量的值。