Crack on win

Table of Contents

1. OD设置

1.1. 领空

调试程序必须与OD处于同一物理机 所谓领空,实际上是指:在某一时刻,CPU 的 CS:IP(EIP) 所指向的某一段代码的所有者所在的区域。 程序里经常要调用函数,有的函数属于dll或其他,比如Windows系统自带的函数MessageBoxA,当单步步入这个函数时(就是进入到MessageBoxA)函数里面进行跟踪时,就进入了非程序领空(不是你当前程序自己写的函数,而是调用其它人的(这里是Win32系统的))或者说系统领空,当跳出MessageBoxA函数后,就又回到了你在调试的程序中,那么当前CPU将执行你要调试的程序的指令,此时领空就是你要调试的程序。 OD里进入非程序领空后,Alt+F9从系统领空返回到我们调试的程序领空。(相当于 SoftICE 中的 F12)

1.2. 定位

通过“中文搜索引擎”定位汇编代码

1.3. 跳转

注意“>”跳转符号,红线跳转成立,灰线跳转不成立 选中跳转目的行,代码行下方出现“跳转来自 xxx”时,右键-转到jxx来自xxxxx,可跳转至跳转起始 暂停调试时,双击寄存器窗口eip可跳转至执行指针处代码

1.4. 调试跑飞

若程序卡在call,未执行下一步,则可在下一行下断,t按钮-右键-恢复所有线程

1.5. 字符串被VM加密

先使程序运行,使字符串加载至内存,点击m按钮,右键-查找-ascii

1.6. 字符串长短修改

1.6.1. 长改短

用00填充

1.6.2. 短改长

搜索000000处,填入需要字符串后更改地址立即数

1.7. 保存方法

  1. 选择修改代码
  2. 右键-复制到可执行文件-选择
  3. 右键-保存文件

1.8. 加壳程序

带壳程序执行至“db xx”处代表已到达至壳内oep代码部分,此时需右键-分析-从模块处删除分析

1.9. PE文件

PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件

1.10. OD的各个窗口

1.10.1. 反汇编窗口

地址栏[Address] - 显示距双击地址处的相对地址。再次双击基地址,则恢复为标准地址显示模式; 十六进制数据栏[Hex dump] - 设置或取消非条件断点; 反汇编栏[Disassembly] - 调用汇编器,修改命令; 注释栏[Comment] - 增加或修改与命令相关的注释。

1.10.2. 信息窗口

用于解码反汇编窗口中选中的第一个命令的参数,信息窗口也会显示隐含的参数。

1.10.3. 数据窗口

用于显示内存或文件的内容。可以从以下预处理格式中选择一种显示方式:字节[byte]、文本[text]、整数[integer]、浮点数[float]、地址[address],反汇编[disassembly]、PE头[PE Header]。

1.10.4. 寄存器窗口

用于显示和解释当前所选线程的CPU寄存器中的内容。该窗口同样允许修改寄存器,并可以跟进地址到其它CPU窗口。

1.10.5. 堆栈窗口

用于显示当前线程的堆栈。当被调试程序暂停运行时,堆栈窗口一般会自动滚动将当前ESP指向的地址放在窗口的第一条。并且这个地址被高亮显示。在某些情况下禁止滚动会更方便一些,可以通过在堆栈窗口右键单击[锁定堆栈]来禁止堆栈自动滚动。

1.10.6. 其他窗口

  1. L

    日志窗口

  2. E

    显示程序运行使用的模块

  3. M

    显示我们程序映射到内存的信息

  4. T

    显示程序的线程窗口

  5. W

    Windows显示程序窗口

  6. H

    句柄窗口

  7. C

    回到Ollydbg主窗口,CPU窗口

  8. P

    如果程序经过了修改,这里显示修改的信息

  9. K

    显示调用堆栈的窗口信息

  10. B

    显示程序普通断点的列表窗口

  11. R

    Reference 参考窗口,显示我们在 OllyDbg 中搜索的结果。

  12. 显示 RUN TRACE(RUN 跟踪)命令的结果

1.11. 怎样设置实时调试

当然,我们不一定会用到实时调试,除非特殊情况。因为如果我们运行的程序出现崩溃时。 选项 -> 实时调试设置 -> 设置OllyICE为实时调试器

1.12. 在 OllyDbg 中关联插件

OllyDbg 允许你使用插件,这样会对解决问题有所帮助 首先下载插件,解压插件文件夹,为插件建立一个文件夹(可以在任意位置) 选项->界面选项 我们看到作为插件路径的目录已被指定,即 OllyDbg.exe 所在的目录,可以把插件放在那里

1.13. OllyDbg 中最常用的快捷键

F7 执行一行代码,遇到 CALL 等子程序时会进入其中,进入后首先会停留在子程序的第一条 指令上。 F8 执行一行代码,遇到 CALL 等子程序不进入其代码。 这两个键的功能有所不同,以后将会看到。 F2 在显著行设置断点,再次按 F2 删除断点。

1.14. 硬件断点与内存断点

内存断点是通过把相应位置指令替换成int3来实现的。硬件断点是通过设置CPU相应硬件寄存器来阻止程序继续运行的。因为修改程序代码你想怎么改就怎么改。所以内存断点你可以设置很多个。而硬件寄存器数量有限,所以只能设置几个(目前大多数是4个)因为修改的是程序的代码,所以内存断点很容易被程序自身检测到。而硬件断点则很难被发现。

1.15. 命令行程序调试

菜单文件打开,参数栏填入参数

2. 限制破解

2.1. NOP法

将jnz等条件跳转更改为nop空指令(右键-二进制-用nop填充)

2.2. JMP法

将jnz等条件跳转更改为jmp无条件跳转,地址需要补足0x

2.3. 壳内寻找注册码

  1. 输入要跟随的表达式,一般为401000起,到达oep
  2. 字符串搜索定位
  3. 在定位处断点,并同时选择插件-API断点设置工具-常用断点设置-常用断点-GetStartupInfoA(取初始断点)
  4. 单步进行至右下角堆栈窗口出现“GetStartupInfoA”,确保此时点选b进入断点列表,初始断点反汇编代码非“add byte”
  5. 激活第三步定位的断点
  6. 注意寄存器与堆栈内容,根据输入的假码寻找真码

2.4. 绕过自校验

2.4.1. 文件大小自校验

在程序脱壳后,可能会对文件大小进行校验导致无法运行,此时需要绕过自校验

  1. 设置API断点-文件-GetFileSize,F9运行,直至堆栈窗口显示“GetFileSize”
  2. 在堆栈窗口该行右键-反汇编窗口中跟随
  3. 调用GetFileSize处下断,取消GetFileSize本身断点
  4. 重载-更改退出跳转

2.5. 关键CALL与关键跳

  1. 确定判断注册与否的关键跳,在其上附近寻找关键call,断点进入call函数
  2. 根据关键跳所判断的寄存器值,在call函数内修改直接赋值寄存器,例“mov eax,1 回车 retn”

2.5.1. 寻找关键call

  1. 判断最终提取数据所在地址在哪个寄存器
  2. 寄存器窗口找到寄存该地址的寄存器,右键数据窗口中跟随
  3. 数据窗口右键下硬件写入断点
  4. 若是最终比较数据存在于某个常量地址中,则右键-查找所有常量,更改所有赋值或者比较

如果修改常量cmp判断失败,也需要下硬件写入断点,修改常量赋值call

2.6. VMP壳内爆破

VMP特征:PEiD什么都没找到,ep段-节查看器有.vmp0与.vmp1

  1. 输入要跟随的表达式,一般为401000起,到达oep
  2. 字符串搜索定位
  3. 在定位处断点,通过修改代码使得程序进入注册成功流程
  4. 若程序没有重启验证,则破解成功

2.7. VMP壳内寻找注册码

若程序为重启读取配置文件验证注册,可用此法

  1. OD调试,设置API断点-文件-ReadFile(此步为冗余操作)
  2. 断下后输入要跟随的表达式-401000,到达oep
  3. 字符串搜索定位
  4. 在定位处断点,同时取消系统断点ReadFile,运行程序
  5. 单步查找正确注册码

2.8. API断点MessageBoxA

若字符串加密,可用此法

  1. 在下方Command内输入BP MessageBoxA
  2. 运行后断下,此时继续向下执行,跳出user32模块
  3. 判断进入该弹窗或者绕过该流程的关键跳,若没有,则继续向下执行跳出当前call
  4. 更改代码并保存

2.9. API断点GetPrivateProfileStringA

若注册信息存储于ini配置文件,重启验证注册,则可用此法

  1. 在下方Command内输入BP GetPrivateProfileStringA
  2. 运行后断下
  3. 菜单栏-调试-执行到用户代码
  4. 单步至程序领空内出现关键跳,在堆栈窗口内寻找真码

2.10. 万能断点解决重启验证

无法用字符串定位断下,或者系统api不可用时可用此法

  1. F9运行程序,反汇编窗口右键-查看-模块‘user32’
  2. 反汇编窗口右键-查找-二进制字串
  3. 在HEX处输入万能断点特征码[只适用在xp系统]“F3 A5 8B C8 83 E1 03 F3 A4 E8”
  4. 在关键验证操作之前下断
  5. 获取真码信息

2.11. VB之tcMsgBox

VB程序无法使用普通系统API,可用此法 VB程序特征为OD载入后第二行有MSVBVM字样

  1. 设置API断点-VB APIs-rtcMsgBox
  2. 断下之后运行至程序领空
  3. 寻找关键跳并破解

2.12. 去除NAG(提示注册窗口)

  1. od打开,弹窗之后暂停
  2. 点击K,进入调用堆栈
  3. 找到“USER32.MessageBoxExA”,右键-显示调用
  4. 下断,重载程序
  5. 或者菜单栏-调试-执行到用户代码,关闭弹窗
  6. 往上查找跳过NAG的关键跳,如果直到retn下的段首还没找到,就跳出call继续查找

2.13. 单步F8跟踪破解

单步调试时若F8单步跑飞,则可重新在call处下断F7进入

2.14. 制作内存补丁

keymake-其他-制作内存补丁-浏览选择程序-添加

  1. 修改地址-对应反汇编窗口的地址
  2. 长度-对应反汇编窗口机器码长度除以2
  3. 原始指令-对应反汇编窗口机器码
  4. 修改指令-对应修改后的机器码,长度需要与原始指令对齐
  5. 生成

2.15. 修改dll

如果主exe中无法找到相应位置,e按钮进入dll文件查找修改 需要注意打补丁时dll的基址

2.16. 易语言破解

2.16.1. push窗体法

  1. 输入要跟随的表达式,一般为401000起,到达oep
  2. 右键查找-二进制字符串,输入“FF 25”,到达易语言体
  3. 往上查找“push 0x52xxxxxx”,此处即为初始窗体
  4. 右键查找-命令,输入“push 10001”,查找其他窗体,往下查找“push 0x52xxxxxx”,记录窗体地址
  5. 修改初始窗体地址为新发现窗体地址,保存,打开即为新窗体
  6. 若保存后的push窗体埋了暗桩自动退出,则可设置程序退出断点,菜单栏-插件-API断点设置-常用断点设置-常用断点-程序退出,断下之后堆栈窗口在“返回到xx来自xx”处右键-反汇编窗口中跟随

2.16.2. 文本比较特征码

8B 54 24 04 8B 4C 24 08 85 D2 75 0D 33 C0 85 C9 74 06 80 39 00 74 01 48 C3 85 C9 75 09 33 C0

二进制字符串定位之后,在retn处下断,获取正确返回值,回到call调用处,“mov eax 0或者1”更改eax值

2.16.3. 非独立编译

需要f9运行后,e按钮进入选择正确模块调试

2.17. 网络验证的本地破解

F8单步之后程序一直运行不断可能是因为网络请求

2.18. VB通用技巧

2.18.1. 脚本下断

运行脚本-打开-VB程序按钮事件

2.18.2. FFFF关键跳

FFFF为VB程序用于判断的数值,有FFFF比较必有关键跳

2.18.3. 系统调用

通过“右键-查找-所有模块间的调用”替代程序退出(_vbaEnd)等系统api

2.18.4. p-code

p-code代码无限循环,可使用smartcheck或者vb decompiler分析定位获得地址,然后通过例如修改if(1C)为ifnot(1D)的方法爆破

2.19. 按钮事件特征码

2.19.1. VB

查找二进制字符串

816C24

在特征码下的jmp处下断

2.19.2. Delphi & BC++

查找二进制字符串

740E8BD38B83???FF93???

在特征码下的call处下断

2.19.3. MFC

查找所有命令

sub eax,0a

在特征码下的je跳转处回车,在第一个call处下断,f7进入到达核心代码

2.19.4. VC++

查找所有命令

sub eax,0a

在特征码下的je跳转处回车,在第一个call处下断,f7进入,f8两次jmp到达核心代码

2.19.5. 易语言

查找二进制字符串

FF55FC5F5E

或使用(e-debug) call处下断,f7进入call

2.20. 飘零网络验证破解

飘零山寨需查找到asp地址与密钥,密钥在asp前,以01开始,第二位为位数,例如“01 00 00 00 02 00 00 00 03 00 00 00 03 00 00 00” 飘零定时器事件与按钮事件重叠,会干扰调试,需配合XueTr

  1. 直接运行程序
  2. XueTr-进程-右键-查看-查看进程定时器,右键移出两个定时器
  3. 直接打开OD,菜单-文件-附加-选中附加,e按钮回到程序领空
  4. 右键-中文搜索-智能搜索,分析完毕后回到反汇编窗口可看到相应字符串对应中文注释

2.20.1. 飘零金盾3.0山寨

  1. 搜索“初始化成功”字符串,定位后查找版本号,如“10000008”,以及一长串加密地址字符串,后接密钥与asp文件名
  2. 解密地址,修改并加密后修改,注意客户端后的独立密钥对需要跟服务器密钥对对应

2.20.2. 飘零金盾蓝屏特征码

  1. 55 8B EC BB 06 00 00 00
  2. 55 8B EC EB 10 56 4D 50 72 6F 74 65 63 74 20 62 65 67 69 6E 00 BB 06 00 00 00
  3. 在段首retn

2.20.3. 飘零金盾通杀特征码

55 8B EC 81 EC 10 00 00 00 68 24 00 00 00 找到后往下把连续的两个jnz改成je

2.21. 可可网络验证破解

2.21.1. 特征

包含注册、充值、查询卡号

2.21.2. 山寨服务器

  1. 搜索密钥
    1. 软件密钥与产品编号

      搜索字符串,定位到长度异常长的字符串,上一串较短字符串即为软件密钥 定位到软件密钥关联汇编代码,上一行“mov dword ptr xxx, 软件编号”获取16进制编号

    2. 通信密钥与算法密钥
      1. 下按钮事件断点“FF 55 FC 5F 5E”
      2. 登录
      3. CTRL+F8自动步进,直至软件卡住,在卡住的call处下断,重载锁定服务器连接函数
      4. F7进call,查找“push 0x9”,在下一行下断
      5. f7进call,在连续两个push处第二个“push dword ptr dsxxx”处下断,f9运行,数据窗口中跟随数值
      6. 找到密钥,为“_ksreg_”所分隔,类似“通讯密钥_kereg_算法密钥_ksreg_网址”
      7. ip重定向山寨

2.22. 封包发送与接收

跟随表达式“recv”接包,“send”发包

2.22.1. 下断

尽量不要在第一行下断,可在条件跳转处或者段尾下断

2.22.2. 获取返回值

ctrl+f9到段尾,堆栈窗口右键-数据窗口中跟随

2.22.3. 打补丁

在找到的返回值数据窗口处右键-下内存访问断点,找到地址,修改相应程序领空变量

2.23. 特征码定位

vm代码(“VMProtect begin”到“VMProtect end”之间)的命令会变化不能定位,可取先后代码 call对应机器码后若跟着8位地址机器码,则地址机器码需用????????代替 右键复制二进制 得到的二进制字符串可用于二进制字符串查找定位

2.24. 灰色按钮

菜单-插件-API断点设置工具-常用断点设置-限制程序功能函数-全选

2.25. 禁止调试

提示safengine请关闭调试和监控工具 重载-取消,再次重载-取消,shift+f9

2.26. 格盘破解

在数据窗口中右键查找二进制字符串“format”,用00填充

2.27. 启动退出或删除

若启动后直接退出或删除,则可于运行后迅速f12暂停,单步至退出或删除的call,修改以跳过

2.28. 系统api无法断点

可能因为覆写了函数,可按k进入列表,右键显示调用,段尾下断

2.29. 错误:修改过的重定位

若保存提示请确定更新重定位,则需在call外部修改寄存器值

3. 其他辅助程序

3.1. 修改图标,标题按钮字符串

PE Explorer

3.2. 查壳

PEiD

3.3. 查编写语言

DiE64

3.4. 抓包

封包助手,WPE,SRSniffer

3.4.1. Charles

  1. 抓包记录网址
  2. 定位到需要的网址,右键断点
  3. 断下后修改数据Execute放行

3.5. APIHook

Inline Patch生成器

4. 脱壳

4.1. ESP定律法

原理:维持堆栈平衡 壳程序运行后,首先运行壳部分,然后将原程序还原到内存中并将控制权返还。而大部分压缩壳在运行壳程序时都会将原程序做一个堆栈保护,壳程序运行完成后将原程序还原到内存时会将原先保存的环境恢复供原程序使用,这样我们就可以很轻易的找到OEP。

4.1.1. 关联壳

ASPack,NSPack、UPX

4.1.2. 适用范围

程序用OD载入后,第一行为pushad,第二行寄存器前八行仅有esp为红色,则可用esp定律脱壳

4.1.3. 步骤

  1. OD自带法
    1. F8执行一次
    2. 在ESP一行右键-数据窗口跟随
    3. 在数据窗口HEX栏从第一位开头选择多个
    4. HEX栏右键-断点-硬件访问(byte需选择一位,word需选择两位,dword需选择4位)
    5. 运行至硬件断点后,F8单步至出现“db xx”,右键-分析-从模块处删除分析
    6. 删除硬件断点
    7. 右键-用OllyDump脱壳调试程序-重建输入表-脱壳-另存为
    8. 右键-用OllyDump脱壳调试程序-不重建输入表-脱壳-另存为
    9. 留下可以正常运行的程序
  2. LordPE与ImportREC法
    1. 执行至上一方法第6步,右键-用OllyDump脱壳调试程序-获取入口点修正地址
    2. LordPE滚动至最下,右键目标进程-修正镜像大小,右键-完整转存
    3. ImportREC最上,选择目标进程,OEP处粘贴第一步得到的地址,自带查找IAT(Import Address Table导入地址表)
    4. 获取输入表
    5. 显示无效函数
    6. 右键剪切删除无效函数
    7. 修复转存文件-选择第二步转存的文件

4.1.4. bc++脱壳

  1. 顺序操作至LordPE完整转存
  2. 查找IAT,到达OEP之后找到离OEP最近的call,选中回车,向上找到段首
  3. 在段首右键-数据窗口中跟随-内存地址,在数据窗口右键-长型-地址,此时在注释栏对应到函数名
  4. 点击M,获取段地址,用数据窗口的段首地址减去段地址,获得IAT
  5. ImportREC最上,选择目标进程,OEP处粘贴入口点修正地址,自带查找IAT,修改RVA为上一步得到的地址,大小改为1000,
  6. 获取输入表
  7. 显示无效函数
  8. 右键删除无效函数
  9. 修复转存文件-选择LordPE转存的文件

4.2. 单步跟踪法

  1. f8单步向下
  2. 若跑飞导致程序直接运行,则重载后F7进入跑飞的call
  3. 遇到红色向上跳转直接在下行f4
  4. 注意popad关键字
  5. 比较常见oep特征,判断是否到达oep,若到达,右键脱壳

4.3. 两次断点法

  1. 选项-调试设置(alt+o)异常-全都打上√,忽略所有异常
  2. alt+m 或 点M找到程序领空中与程序名相同的段中的.rsrc数据段,f2在访问上设置中断下断
  3. shift+f9 忽略所有异常运行,断下
  4. alt+m 或 点M找到程序领空中与程序名相同的段中的401000,下断
  5. shift+f9 忽略所有异常运行,断下
  6. f8单步向下,注意popad,注意大跳转(亦即跳转目的地址与当前地址相差大于50的跳转),到达oep
  7. 中途遇到异常中止的call入口则可直接f4跳过继续下一行

4.4. 最后一次异常法

  1. 菜单-选项-调试设置-异常-取消所有选框
  2. 重复shift+f9忽略异常运行,记录到程序打开为止的执行次数
  3. 重复shift+f9至最后一次异常,堆栈窗口找到第二行“SExxxxx”,右键-反汇编窗口处跟随,f2下断
  4. shift+f9忽略异常运行并断下,f8单步,注意popad与大跳转,到达oep

4.5. sfx脱壳法

  1. 菜单-选项-调试设置-异常-选中所有选框,菜单-选项-调试设置-sfx-字节方式跟踪真正入口处
  2. 重载程序
  3. 脱壳

多次分析可能导致代码出错,此时需要删除od目录下udd文件夹内文件

4.6. 模拟跟踪法

需要配合其他脱壳方法

  1. 选项-调试设置(alt+o)异常-全都打上√,忽略所有异常
  2. alt+m 或 点M找到程序领空中与程序名相同的段中的.rsrc数据段,f2在访问上设置中断下断
  3. shift+f9 忽略所有异常运行,断下
  4. alt+m 或 点M找到程序领空中与程序名相同的段中的401000或者01001000,下断
  5. shift+f9 忽略所有异常运行,断下
  6. 点m找到程序领空中“sfx,输入表”对应的地址,如01013000,在Command处输入“tc eip<01013000”,回车跟踪
  7. 脱壳

4.7. 出口标志脱壳法

  1. 右键-查找-命令,输入popad,取消选中“整个块”
  2. f4运行至此处
  3. 若f4后跑飞,则继续查找下一个popad
  4. f8单步至oep,脱壳

4.8. 一步到oep法

  1. 载入程序,运行程序
  2. 在堆栈窗口找到“程序名.xxxxx”,右键-反汇编窗口处跟随
  3. 右键-分析-从模块中删除分析
  4. 在堆栈窗口找到“程序名.xxxxx”所在段的段首,右键-反汇编窗口处跟随
  5. 在反汇编窗口处向上找到段首oep,右键-数据窗口中跟随,在数据窗口中右键-断点-硬件执行,重载运行,到达oep
  6. 脱壳,若od自带无法脱壳,则用lordpe脱壳,ImpREC修复输入表

4.9. 易语言花指令

花指令即junkcode,为进行混淆的垃圾代码,多数显示“未知命令,非法使用寄存器”

  1. PEiD-插件-PEiD通用脱壳器-检测入口点-“->”
  2. 若上一步没有找到,则PEiD-插件-通用OEP查找工具,获得OEP地址后在OD内输入要跟随的表达式,右键-断点-硬件执行
  3. 运行,断下,脱壳
  4. 若调试时遇见“未知命令,非法使用寄存器”,菜单-插件-EJunkCode-MainDlg-Size:999,运行去花,从模块中删除分析

5. 常见OEP特征

5.1. delphi:

55            PUSH EBP
8BEC          MOV EBP,ESP
83C4 F0       ADD ESP,-10
B8 A86F4B00   MOV EAX,PE.004B6FA8

5.2. bc++

bc++程序脱壳后无法打开,需要手动查找IAT范围,不能使用ImportREC

00401000 > /EB 10 JMP SHORTXXXXXXX.00401012
00401002 |66:623A BOUND DI,DWORD PTR DS:[EDX]
00401005 |43 INC EBX
00401006 |2B2B SUB EBP,DWORD PTR DS:[EBX]
00401008 |48 DEC EAX
00401009 |4F DEC EDI
0040100A |4F DEC EDI
0040100B |4B DEC EBX
0040100C |90 NOP
0040100D -|E9 AC334800 JMP 008843BE
00401012 \A1 9F334800 MOV EAX,DWORD PTR DS:[48339F]
00401017 C1E0 02 SHL EAX,2
0040101A A3 A3334800 MOV DWORD PTR DS:[4833A3],EAX
0040101F 52 PUSH EDX
00401020 6A 00 PUSH 0
00401022 E8 11110800 CALL
00401027 8BD0 MOV EDX,EAX
00401029 E8 3A1B0600 CALLXXXXXXX.00462B68
0040102E 5A POP EDX
0040102F E8 981A0600 CALLXXXXXXX.00462ACC
00401034 E8 6F1B0600 CALLXXXXXXX.00462BA8
00401039 6A 00 PUSH 0
0040103B E8 782E0600 CALLXXXXXXX.00463EB8
00401040 59 POP ECX
00401041 68 48334800 PUSHXXXXXXX.00483348
00401046 6A 00 PUSH 0
00401048 E8 EB100800 CALL
0040104D A3 A7334800 MOV DWORD PTR DS:[4833A7],EAX
00401052 6A 00 PUSH 0
00401054 E9 6B900600 JMPXXXXXXX.0046A0C4
00401059 > E9 A62E0600 JMPXXXXXXX.00463F04

delphi与bc++均可使用dede定位代码,具体步骤如下:

5.2.1. dede定位

  1. 用dede载入,选择NO、NO
  2. 点击过程
  3. 通过模块名分析对应功能,点击查看相关事件,双击事件可查看事件代码,记录需要定位事件的RVA地址,在OD中跟随表达式

5.3. vc++

55            PUSH EBP
8BEC          MOV EBP,ESP
83EC 44       SUB ESP,44
56            PUSH ESI

5.4. E语言

这个和C极度像,要分清

0040389F >/$ 55 PUSH EBP
004038A0 |. 8BEC MOV EBP,ESP
004038A2 |. 6A FF PUSH -1
004038A4 |. 68 F8724000 PUSH CrackMe.004072F8
004038A9 |. 68 04554000 PUSH CrackMe.00405504 ; SE 处理程序安装
004038AE |. 64:A1 0000000>MOV EAX,DWORD PTR FS:[0]
004038B4 |. 50 PUSH EAX
004038B5 |. 64:8925 00000>MOV DWORD PTR FS:[0],ESP
004038BC |. 83EC 58 SUB ESP,58
004038BF |. 53 PUSH EBX
004038C0 |. 56 PUSH ESI
004038C1 |. 57 PUSH EDI
004038C2 |. 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
004038C5 |. FF15 48704000 CALL DWORD PTR DS:[< &KERNEL32.GetVersion>; kernel32.GetVersion
004038CB |. 33D2 XOR EDX,EDX
004038CD |. 8AD4 MOV DL,AH
004038CF |. 8915 94BA4000 MOV DWORD PTR DS:[40BA94],EDX
004038D5 |. 8BC8 MOV ECX,EAX
004038D7 |. 81E1 FF000000 AND ECX,0FF
004038DD |. 890D 90BA4000 MOV DWORD PTR DS:[40BA90],ECX
004038E3 |. C1E1 08 SHL ECX,8
004038E6 |. 03CA ADD ECX,EDX
004038E8 |. 890D 8CBA4000 MOV DWORD PTR DS:[40BA8C],ECX
004038EE |. C1E8 10 SHR EAX,10
004038F1 |. A3 88BA4000 MOV DWORD PTR DS:[40BA88],EAX
004038F6 |. 33F6 XOR ESI,ESI
004038F8 |. 56 PUSH ESI
004038F9 |. E8 7A030000 CALL CrackMe.00403C78
004038FE |. 59 POP ECX
004038FF |. 85C0 TEST EAX,EAX
00403901 |. 75 08 JNZ SHORT CrackMe.0040390B
00403903 |. 6A 1C PUSH 1C

5.5. vc6.0

55                 push ebp
8BEC               mov ebp,esp
6A FF              push -1

5.6. vc7.0

6A 70              push 70
68 50110001        push hh.01001150
E8 1D020000        call hh.010017B0
33DB               xor ebx,ebx

5.7. vb

00401166  - FF25 6C104000   JMP DWORD PTR DS:[<&MSVBVM60.#100>]      ; MSVBVM60.ThunRTMain
0040116C >  68 147C4000     PUSH PACKME.00407C14
00401171    E8 F0FFFFFF     CALL <JMP.&MSVBVM60.#100>
00401176    0000            ADD BYTE PTR DS:[EAX],AL
00401178    0000            ADD BYTE PTR DS:[EAX],AL
0040117A    0000            ADD BYTE PTR DS:[EAX],AL
0040117C    3000            XOR BYTE PTR DS:[EAX],AL

或省略第一行的JMP

00401FBC >  68 D0D44000        push dumped_.0040D4D0
00401FC1    E8 EEFFFFFF        call <jmp.&msvbvm60.ThunRTMain>
00401FC6    0000               add byte ptr ds:[eax],al
00401FC8    0000               add byte ptr ds:[eax],al
00401FCA    0000               add byte ptr ds:[eax],al
00401FCC    3000               xor byte ptr ds:[eax],al
00401FCE    0000               add byte ptr ds:[eax],al

5.8. dasm:

00401000 >/$  6A 00         PUSH 0                                   ; /pModule = NULL
00401002  |.  E8 C50A0000   CALL <JMP.&KERNEL32.GetModuleHandleA>    ; \GetModuleHandleA
00401007  |.  A3 0C354000   MOV DWORD PTR DS:[40350C],EAX
0040100C  |.  E8 B50A0000   CALL <JMP.&KERNEL32.GetCommandLineA>     ; [GetCommandLineA
00401011  |.  A3 10354000   MOV DWORD PTR DS:[403510],EAX
00401016  |.  6A 0A         PUSH 0A                                  ; /Arg4 = 0000000A
00401018  |.  FF35 10354000 PUSH DWORD PTR DS:[403510]               ; |Arg3 = 00000000
0040101E  |.  6A 00         PUSH 0                                   ; |Arg2 = 00000000
00401020  |.  FF35 0C354000 PUSH DWORD PTR DS:[40350C]               ; |Arg1 = 00000000 

或者另一种:

00401025 >/$ 6A F6 PUSH -0A
00401027 |. E8 A0000000 CALL
0040102C |. A3 00304000 MOV DWORD PTR DS:[403000],EAX
00401031 |. 6A F5 PUSH -0B
00401033 |. E8 94000000 CALL
00401038 |. A3 04304000 MOV DWORD PTR DS:[403004],EAX
0040103D |. 6A 01 PUSH 1
0040103F |. 68 00104000 PUSH EchoLine.00401000
00401044 |. E8 8F000000 CALL
00401049 |. 6A 07 PUSH 7
0040104B |. FF35 00304000 PUSH DWORD PTR DS:[403000]

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注