做过逆向的朋友应该会很熟悉IDA和Windbg这类的软件。IDA的强项在于静态反汇编,Windbg的强项在于动态调试。往往将这两款软件结合使用会达到事半功倍的效果。可能经常玩这个的朋友会发现IDA反汇编的代码准确度要高于Windbg,深究其原因,是因为IDA采用的反汇编算法和Windbg是不同的。下面我来说说我所知道的两种反汇编算法。(转载请指明来自breaksoftware的csdn博客)

1 线性扫描(Linear sweep)

线性扫描是一种非常基础的反汇编算法。看到“线性”二字,我们脑海里可能会立马浮现出一个指针对一段内存中数据从开始到最后进行一次遍历的场景。而实际上这种算法的确是如此执行的。像windbg就是使用这种反汇编算法的。反汇编步骤是:

A 位置指针lpStart指向代码段开始处

B 从lpStart位置开始尝试匹配指令,并得到指令长度n

C 如果B成功,则反汇编(Intel风格或者AT&T风格)从lpStart之后n个数据;如果失败,则退出

D 位置指针lpStart赋值为lpStart+n,即上条指令的结尾

E 判断lpStart是否超过了代码段结尾处,如果超出则结束。如果不超出则进入B流程。

在A、E这两个过程中,我们需要提前确定代码开始处和结束处。一般来说,在windows平台上,我们可以根据PE文件的可选头标准域中BaseOfCode结合DataDirectory中相关信息可以算出来代码开始位置,从PE文件可选头标准域中SizeOfCode得到代码段总大小,从而确定结尾位置。

在B这个过程,对于不同指令集存在细微的差别。现在简要说下主要两种指令集:

RISC全称是Reduced Instruction Set Computing,即精简指令集。该指令集有个非常重要的特定——指令长度相同,这样反汇编匹配不会出现回溯现象。

CISC全称是Complex Instruction Set Computer,即复杂指令集。该指令集一个重要的特点是和RISC正好相反的——指令长度可变,这样反汇编匹配会出现回溯现象。

可以发现线性扫描的一大特点就是简单方便,但是它存在一个问题:它无法知道整个程序的执行流。使用过IDA的朋友会发现,在我们使用IDA打开一个PE文件时,IDA会给我们显示一个UML类型的执行流程图。而Windbg就没有这样的功能。为什么?就是因为线性扫描有不知执行流这个缺陷。

既然知道了缺陷,那么在充满极客的安全领域,自然有人会去研究和利用。我们可以利用这个缺陷,让Windbg这类使用线性反汇编算法的工具分析出错误的结果。

我们开始一个思考个过程:看如上ABCDE流程,我们可以发现特别“悬”的一个操作就是确定lpStart。因为只要lpStart确定错误,那么分析出来的结果肯定是不对的。的确,线性扫描算法就是存在这样一个致命的问题。那如何利用呢?

a 在一条可以改变执行流的有效指令后插入无效信息

这儿所说的指令包括jmp,ja等跳转,以及ret等改变EIP的指令。

我们先看个跳转指令例子

int _tmain(int argc, _TCHAR* argv[])
{int i = argc;if ( argc > 1 ) {i++;}__asm{jz positionjnz position_emit 0xE8position:}i++;return 0;
}

我们使用jz position、jnz position使程序的执行流肯定走到position处,从而我们在jnz position这条有效指令后插入的0xE8是个无效数据。这样我们将触发线性扫描出错

我们可以看到插入的0xE8(call指令)影响了分析结果,因为线性扫描在扫描004017fb~004017fc时发现是有效的jne指令,于是它傻乎乎的认为004017fd开始的就是下一条指令开始处。正确的结果我们看IDA的反汇编结果

我们再看一个ret的例子

int _tmain(int argc, _TCHAR* argv[])
{__asm{push xxxret_emit 0xE8xxx:}printf("1");return 0;
}

因为push xxx使得栈顶为xxx,而ret将pop出xxx,并将EIP改成xxx,让程序从xxx初开始执行。这样我们又构造了一个无效数据0xE8。我们看看Windbg和IDA的反汇编结果

Windbg

IDA(此处IDA有点智能,它判断了下ret之后的EIP是否为一个固定地址)

b 正常的流程识别错误

编译器在将处理我们代码时是有策略的,比如当我们switch中case比较多的时候(我在我的环境测试时发现好像要超过2个case),switch case逻辑会使用跳转表来表达。举个例子

int switchfun(int nvalue){switch(nvalue) {case 0:case 1: {nvalue++;}break;case 2: {nvalue += 2;}break;case 3: {nvalue += 3;}break;default: {nvalue = 0;};}return nvalue;
}


        可以见到这就是使用了跳转表。我们可以看到0040177C位置是一组数据。如果我们将这个跳转表放在0040174A处,将原来0040174A的逻辑后移,并修正相关偏移,是不是我们就让Windbg分析出错呢?是的,可是为了构造这样的结构,我得对我的代码做改动,且要修改生成的二进制文件。

int switchfun(int nvalue){{__asm nop;...__asm nop;}switch(nvalue) {case 0:case 1: {nvalue++;}break;case 2: {nvalue += 2;}break;case 3: {nvalue += 3;}break;default: {nvalue = 0;};}return nvalue;
}

我们人为插入多个nop,为我们之后方便修改二进制文件提供空间,同时可以减少计算偏移的量。对二进制文件修改如下


我将从B7C到B92的数据拷贝到以前是一串90(nop)开始处的B34。并紧跟这串数据,将BC4开始的跳转表数据拷贝过来,同时修正跳转表的偏移(C4->4A)。程序可以正确执行,我们看windbg的反汇编结果。

错了吧!

我们再看看IDA的反汇编结果

可以见到IDA分析是正确的。

经过如上分析,是不是你觉得IDA比Windbg好呢?其实也不一定。线性扫描的一个大优点就是它可以把所有代码都反汇编掉,而IDA使用的递归下降(recursive descent)算法并不一定会将所有代码都反汇编掉,我会在下一篇博文说明如何利用IDA这个缺陷,来隐藏我们不想被反汇编的逻辑。

反汇编算法介绍和应用——线性扫描算法分析相关推荐

  1. (转)反汇编算法介绍和应用——线性扫描算法分析

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/breaksoftware/articl ...

  2. 反汇编算法介绍和应用——递归下降算法分析

    上一篇博文我介绍了Windbg使用的线性扫描(linear sweep)反汇编算法.本文我将介绍IDA使用的递归下降(recursive descent)反汇编算法.(转载请指明来源于breaksof ...

  3. 2020-11-21(线性扫描反汇编算法和递归下降扫描反汇编算法)

    push ebp jmp addr1 db 0xE8 addr1: mov abp,esp sub esp,0x100 根据线性扫描反汇编算法,当反汇编器解析完jmp addr1指令后,会接着从下一个 ...

  4. 0.IDA-基本的反汇编算法

    1.线性扫描 原理: 一条指令结束,另一条指令开始 关键: 确定起始位置  流程: 从起始,逐条反汇编指令,直到完成整个代码段 优点: 可覆盖程序的所有代码段 缺陷: 如果代码段中混有数据! gdb ...

  5. 0.IDA的反汇编算法方式

    1.线性扫描 原理: 一条指令结束,另一条指令开始 关键: 确定起始位置 流程: 从起始,逐条反汇编指令,直到完成整个代码段 优点:        可覆盖程序的所有代码段 缺陷:        如果代 ...

  6. 时间排序python_算法导论 第八章 线性时间排序(python)

    比较排序:各元素的次序依赖于它们之间的比较{插入排序O(n**2) 归并排序O(nlgn) 堆排序O(nlgn)快速排序O(n**2)平均O(nlgn)} 本章主要介绍几个线性时间排序:(运算排序非比 ...

  7. 知识图谱学习笔记-风控算法介绍

    一.风控算法的评估 1.搭建风控模型 数据(KG)-特征工程-模型 特征工程: 申请人相关特征:年龄.收入.工作性质等等 从知识图谱提取出的特征: 1)从规则提取出来的特征:申请人是不是第一次借款(0 ...

  8. 十八、Apriori算法介绍

    1. 关联规则挖掘 关联规则挖掘定义 大多数关联规则挖掘算法通常采用的一种策略是,将关联规则挖掘任务分解为如下两个主要的子任务: 频繁项集产生(Frequent Itemset Generation) ...

  9. 分布式块存储QoS限速算法介绍与实践以及对上层应用的影响

    分布式块存储QoS限速算法以及对上层应用的影响 QoS限速算法介绍 令牌桶 Token Bucket 漏桶 Leaky Bucket Leaky bucket as a meter Leaky buc ...

最新文章

  1. 数字化?智能化?中国企业智能制造现状究竟如何 李炳积 工信头条 昨天
  2. 计算机怎么远程桌面,电脑远程桌面如何连接 电脑远程桌面连接方法【详解】...
  3. 信息学奥赛一本通 1021:打印字符 | OpenJudge NOI 1.2 08
  4. Asp.Net 常用工具类之Office—Excel导出(4)
  5. 诞生一年来,V 语言还好吗?
  6. 简单高效搞定---迁移学习
  7. Python网络编程(2)-粘包现象及socketserver模块实现TCP并发
  8. 排序算法-冒泡排序(入门级别)
  9. 关于XP和win7 的IIS发布问题
  10. 2021-05-23 自学Java第三天 唉 怎么感觉自制力不是很强啊 感觉有些慢了 慢慢来吧
  11. Unity3D中2D图片动画进行帧动画播放
  12. 苹果iOS/iPadOS 15.2 Beta 1发布 app隐私报告?
  13. 测试开发3年,我决定去读个名校硕士
  14. 基于JAVA和MYSQL数据库实现的图书资料管理信息系统
  15. 基于动态时间规整(DTW)的孤立字语音识别
  16. Bootstrap3基础 table-responsive 响应式表格
  17. SWOOLE进阶-06网络IO模型-阻塞模型
  18. 有关非居民企业就来源于中国境内的所得缴纳企业所得税问题
  19. java之详解坦克大战_Java之详解坦克大战游戏(一)
  20. rt-thread 使用心得

热门文章

  1. 使用Python和OpenCV进行拍摄截图
  2. docker 镜像容器导入导出、查看日志、拷贝文件命令
  3. STM32控制OLCD显示中英文(NB-IoT专栏—基础篇6)
  4. HDU1811 Rank of Tetris 拓扑排序+并查集 OR 差分约束最短路+并查集
  5. 机器学习(8)朴素贝叶斯算法(20条新闻分类)
  6. 杀死本地80端口被占用的进程,还你一片宁静乐土
  7. sgSpeedMode.js判断360浏览器是“兼容模式”,提示使用“极速模式”
  8. 解决360浏览器偶发性会闪屏一下黑色的背景
  9. VSCode设置合并行快捷键
  10. UE5真实环境设计入门学习教程