软件保护壳技术专题 - 反汇编引擎的构建

libdasm:开源跨平台反汇编工具库 libdasm 是一款广泛应用于二进制分析领域的开源反汇编引擎。它能够将二进制机器码转换成汇编语言,从而使得研究者能够更加深入地了解程序的结构和行为。libdasm 提供了强大的代码还原功能,允许开发者和安全研究人员从编译后的二进制文件中提取有用信息。反汇编引擎是计算机科学中的一个基础工具,它的核心作用是将机器语言指令转换成汇编语言,使得人类能够阅读和分析。在软件逆向工程、安全分析、恶意代码检测等领域,反汇编引擎都扮演着不可或缺的角色。 阅读详情
 
反汇编引擎在稍微系统一点的软件上都有应用。要写反汇编引擎首先要知道每个平台的编码规则。当然我们要了解的就是INTEL的IA-32编码规则了。这里发下牢骚,INTEL的编码说真的一点也不清爽。要做反汇编引擎RISC(精简指令集)指令集要简单的多,像IA-32这种CISC(复杂指令集)写起来要稍微比前者麻烦点。
 
<LOADing 正文, Please Wait... ^_^>
目录:
1 --- 什么是指令
2 --- 什么是prefix(前缀)
3 --- 什么是opcode
4 --- 什么是ModRM
5 --- 什么是SIB
6 --- 总结一下
 
正文:
 
1) 什么是指令
我们通常编写应用程序的指令通常就是两种,一种就是X86指令,一种就是X87指令(浮点指令)。统一都被称为x86指令,大家用汇编写应用程序的就是了。
类似 mov ecx, dword ptr [4*eax+12345678h]这种就是了。其实这是给人看的,给计算机看那实际上是8B0C85 78563412。前者只不过是否则的一个记号而已。我们写反汇编引擎的目的就是分析后面的数字将其翻译成前者。这后面的数字串是有一定格式的。这个格式是:
[前缀][opcode][ModRM][SIB][偏移][立即数]这6个部分,它们之中除了opcode是必须的,这个区域也可以当做是指令,其余的几个区域可以看做是修饰和补充它的。但是他们的顺序是不变的。
这6个区域的顺序不能颠倒。而且大家还要记住的是只要有SIB前面肯定是ModRM,但是有ModRM不一定有SIB.SIB可以说是对ModRM的一个补充.而后面的偏移域也是在ModRM出现才有可能出现,否则也不出现,但是有ModRM也不一定有偏移。后面文章中有详细解释。最后的立即数是跟的opcode走的。有些opcode要度 有些不需要读。现在这个规则记住,后面就好理解了。
例如我们上面的 8B0C85 78563412 这条指令, 这条指令是没有前缀的 8B 是它的opcode
0C是它的ModRM,85是它的SIB, 78563412 是偏移。
8B这个代表的就是mov, 0C代表使用 ecx, dword ptr [XXXX], 而85就是XXXX = 4*eax+12345678h。 这里我们稍微了解一下。 后面慢慢的讲解。  
 
2 --- 什么是prefix(前缀)
这区域可以看做是一个副词来形容opcode(动词). 这样比喻感觉挺合适的。
这个区域就以下几个,所以可以很轻松的从指令中分辨出他们。
LOCK(F0h): 这个前缀在常用中出现几率几乎为0,他是为了在多处理器的条件下确保唯一指令访问
共享内存用的。
REPNZ(F2h):这个和F3h只在串指令中出现。用于做循环使用。
REPZ(F3h)
 
CS(2Eh):这到GS都是用来进行换段来用的。我们写壳用到最多的应该是FS了从FS寄存器获取PEB
等。反汇编看一下一般指令的第一个字节就都是64h了。
SS(36h)
DS(3Eh)
ES(26h)
FS(64h)
GS(65h)
 
66:这个前缀是用做指令长度切换的。如果你当前是在32位下那么它将你切换到16位下,如果是16位反之,记住他是切换不是改变。。。 因为我们通常是在32下工作所以可以直接默认它是改变到16位下的。这样写反汇编引擎的时候会方便一些。例如:mov eax, 1 他的编码是 B8 01000000, 如果是mov ax, 1那么的编码为 66 B8 0100 可以看到前面多了一个66的作用。
但是如果要操作8位数 例如 mov al, 1就是B0 01了。 INTEL的设计师们将操作1个字节数的指令都统一给它们设计一套opcode.而16位和32位的就相同了。其中用66开始切换
67:这个前缀也很强大,它也是用作切换的,不过是地址的切换,道理和66一样。这个前缀是影响SIB位的。下文SIB一节会有详细的解释。
 
这些前缀就介绍完了,还有一个要说明的是,前缀不一定是一个的。有可能是多个例如 LOCK REP STOSB这样。一般最多也就两个。很少有比两个再多的。 大多数情况下至少99%都是一个前缀。  
 
3 --- 什么是opcode
在上一节我把opcode形容为动词,这个一点也不过分,它其实就是指令。翻看INTEL的官方文档可以看到N条指令。当然有些指令可能是我们这辈子都用不上的。这节需要了解的是opcode不一定为1,有可能一条指令有2到3个opcode.例如浮点指令FRNDINT就为D9 FC两个opcode。ModRM有
时候也为opcode进行扩充,例如80h这个opcode 它在ModRM的RO位不同时也表示不同的指令。
这个规则在ModRM节将讲到。记住以上两条,这节的任务也就算达成了。  
 
4 --- 什么是ModRM
如果把opcode看做是动词,ModRM可以看做是做宾语的名词。是谓语的作用对象。
ModRM只有一个1字,不可能有多了。1个字节可以分为三个部分2 : 3 : 3. 最高的两位为Mod.
中间的3位是R/O,最后的3位是R/M. 在附件的IA-32 Architecture Instruction Set Reference A-M.pdf的2.1.3节的表2-1,2-2就是ModRM的规则图了。2-1是16位下的, 2-2是32位下的。
这个切换通过67前缀了。16位的时候用2-1。这里需要说明的是16位情况下的ModRM是没有SIB对它进行补充的。我们通过32位的图来了解一下吧。
我们解释一条吧。其余的都和这个类似
就拿刚才的mov ecx, dword ptr [4*eax + 12345678h]吧. 它的ModRM是0C。换成2 : 3 : 3的
形式就为00 : 001 : 100
这里Mod和R/M可以看做是一组
R/O可以看做是一组
大家可以查表了R/O == 001 这里代表的是ECX寄存器。(在图的右上的那个框框中查R/O)
Mod == 00 R/M == 100可以看到是[--][--] 这个是什么东西? 需要解释一下。[--][--]这个代表
使用SIB,disp32代表32位的偏移,disp8代表8位的偏移,disp16表示16位的偏移。
如果是其他的情况直接使用对应的符号就好了。如果出现[--][--]了那么我们就该查SIB表了
现在我们就把它当做[XXXX],所以这时可以解释为 mov ecx, [XXXX]。 这里就差生一个小问题了,mov [XXXX], ecx 这样的指令是怎么产生的。 其实他俩个ModRM都一样,不同的是opcode
可以试的反汇编一下就可以知道。opcode还决定R/O和R/M的操作顺序,这里指的是操作顺序,在
编码方面R/O永远在R/M前面。
R/O还有一个作用是对指令的补充,例如add byte ptr [eax], 8 这种。他的编码为8000 01
80是它的opcode 00是它的ModRM. 我们分解后得知 Mod = 00 R/O = 000 R/M = 000
这个时候Mod 和 R/M起作用查表得知为[eax], 而R/O则是对80的补充 可以这样解释 当opcode = 80h, R/O = 00的时候这个指令表示为add 从eax指向的内存中取出一个字节与一个字节相加并存入eax指向的内存中。例如当opcode = 80h R/O = 010 的时候 他表示adc byte ptr [eax], 1了。而为什么是操作1个字节,这个都是opcode决定的 ModRM只是对它的补充。  
 
5 --- 什么是SIB
SIB是对ModRM的补充了。可以把它看做是形容宾语中名词的形容词.
当在32位ModRM表中查到"[--][--]"一样的符号时候就是要读取SIB的时候了。
当Mod == 00 01 10 RM == 100 时,那么它的下一个字节就是SIB了。
SIB和ModRM一样是2 : 3 : 3的形式 最高的两位是Scaled 中间的3位是Index 最后的3位是Base
我们继续刚才没有分析完的mov ecx [XXXX], 这个时候它的SIB是85 也就是10 : 000 : 101
Scaled = 10 Index = 000 Base = 101
查表可以得知[4*eax+*] 这个*就是Base = 101的时候进行选择的了
观察表中Base所在的表格。当Base = 101的时候是*符号 其余的都是寄存器的字样 唯独没有ebp. 这个*号其实是代表 ebp 和 偏移的。 这里有个规则 如果Mod == 00 时 它就表示读取一个4字节的偏移。 如果Mod == 01 和 10的时候 它就代表ebp. Mod == 11的时候是没有SIB的
SIB可以这样的解释 Scaled是比例00表示2的0次方 01表示2的1次方 10表示2的2次方 11表示2的3次方。Index可以想成是寄存器,观察表Index中没有esp寄存器取而代之的是none,用汇编可以写一下类似 mov eax, dword ptr [4*esp]之类的语句汇编器会通知你是无效的指令。
就是这里的原因。如果Index == 100(none)那么就忽略这个值,直接从Base中取出对应的寄存器或偏移。Base顾名思义是一个基值。之间的关系是相加。所以合成后就是[4*eax+12345678h]。看过SIB的表后也就可以理解为什么[X*reg] 中的X只能取2,4,8了。  
 
6 --- 总结一下
终于把该说的都说完了。这样可以想一下IA-32的编码规则就是一个动宾短语。
什么时候该使用ModRM 什么时候R/O是辅助编码 什么时候读立即数 读立即数读多少个字节。
这些都是opcode本身决定的。所以要做反汇编引擎重要的还是对opcode这个大集合一一进行解码。
这里只讨论了IA-32的编码形式,没讨论IA-32e(64位)的编码形式,目前来讲对于写一个32位反的汇编器这些足够了。
附件中是今天下午刚写好的反汇编引擎。支持X86 和 X87(浮点)。整体来说比较清爽。
头文件与源文件加起来也只有795行,使用也很简单。
它是一个静态库,包含到你应用程序后。使用InitDisassemblEngine后
然后使用DisassemblEngine 进行反汇编了 它的第一个参数是要反汇编的内存指针,第二个参数
是一个结构,用来将分析好的指令按格式填充到这个结构中。在头文件中有这个结构的定义。这个函数最后返回这条指令的长度。
如果有什么BUG希望各位能帮我调出来并且EMAIL给我。。。
上传的附件
文件类型: rarDissamblEngine.rar (2008-10-10 20:55, 1.7 KB, 38 次下载)
文件类型: rarDissamblEngine_src.rar (2008-10-10 20:55, 3.5 KB, 42 次下载)
EXE软件反汇编、查壳工具 EXE软件反汇编、查壳工具 PE 查看器 等反编译必备工具 立即下载

相关推荐

跟着团子学SAP CO:熟练使用结果分析码实现各个场景下收入成本的匹配(一) KKA2/CJ88

PS模块中对财务顾问最难的点在于项目结算,特别是销售型的项目结算。针对客户型项目结算我列举了以下常见的收入成本匹配的一些场景: (1)在项目执行过程中会多次开票,但由于各期成本浮动很大(如前期可能只涉及一些人工、中期全是比较金额较大的材料费),所以希望开票的时候能通过合理的一些指标进行主营业务成本与主营业务收入的匹配。 (2)项目过程中会多次开票,开票确认主营业务收入时,直接将累计发生的实际成本结转为主营业务成本。 (3)项目过程中虽多次开票,但不确认收入,所有发生的实际成本月末计算为在制品,最后项目一次性

Lucas1211的博客 9534

反汇编基本原理与x86指令构造

反汇编基本原理与x86指令构造 概要:旨在讲述程序的二进制代码转换到汇编。即反汇编的基本原理。以及 x86 架构的 CPU 的指令构造,有这个基础后就能够自己编写汇编程序了,也能够将二进制代码数据转换成汇编助记指令。当然,把本文当作手冊的阅读指导也是能够的。本文还讲述了 DEBUG 工具的部分功能。32位平台下有一个 DEBUG32 版本号能够配合 DOSBOX 工具执行在 Windos...

weixin_34348111的博客 559

彻底清理Easy Connect残留:从服务到驱动的完整卸载指南

在企业网络接入场景中,远程客户端常因内核驱动、系统服务和网络过滤组件导致卸载残留,进程无法结束、文件被锁定、注册表项顽固存在。其原理在于驱动挂载网络协议栈,服务守护进程,卸载时资源占用导致清理不彻底。彻底清理的技术价值在于恢复系统纯净、避免网络异常和软件冲突。典型应用场景包括企业办公机、个人笔记本更换或重装客户端。本文针对深信服Easy Connect,提供从停止服务、删除驱动到清理注册表和虚拟网卡的分步操作链路,并给出验证方法和避坑经验。

weixin_31292729的博客 241

8086(16位)汇编指令与机器码转换原理

在上一节,我们讲了X86指令基本格式。在8086架构下,是不存在SIB字节的,因此,我们重点关注ModR/M。

百里杨的博客 6597

SAP ABAP实战:如何用CVI_EI_INBOUND_MAIN批量更新BP邮箱(附完整代码)

本文深入解析了SAP ABAP中CVI_EI_INBOUND_MAIN函数在业务伙伴(BP)邮箱地址批量维护场景下的应用。通过详细讲解数据结构构建、关键参数(如任务参数'5')配置及完整代码示例,为开发者提供了一套高效、稳定的批量更新解决方案,并分享了性能优化与错误处理的最佳实践。

weixin_29228781的博客 77

SAP SD信贷管理实战:从配置到风险控制的完整指南(附后台路径)

本文详细解析了SAP SD信贷管理的完整配置流程与风险控制策略,涵盖信贷控制范围设置、风险分级机制及动态控制配置。通过实战案例和后台路径指引,帮助企业实现从客户信用评估到实时监控的全流程管理,有效降低坏账风险并优化资金安全。

3a9bq4r8t2y的博客 212

反汇编引擎的工作原理

OllyDBG和IDA都有一个很重要的功能:反汇编 在X86平台下使用的汇编指令对应的二进制机器码为Intel 指令集一Opcode,Intel指令手册中描述的指令由6部分组成: Irsinucton Prefixes 指令前缀 Opcode 指令操作码 Mode R/M 操作数类型 SIB Displacement 辅助Mode R/M,计算偏移地址 Immedate 立即数   ...

做一个快乐学习者 2932

基于STM32F103与AD8232的便携式心电监测系统设计与实现

本文详细介绍基于STM32F103微控制器与AD8232心电传感器模块的便携式心电监测系统设计与实现。系统通过ADC采集心电信号,结合软件滤波算法处理基线漂移和工频干扰,并利用OLED屏幕实时显示波形,具有低成本、高实用性的特点,适用于健康监测与嵌入式学习。

m5n6o7的博客 737

上古神器:十六位应用程序 Debug 的基本使用

在 Debug 中,A 命令即 Assemble 的简写,该命令用于以汇编语言的形式在内存中写入机器指令。Debug 是一个在 MS-DOS 和一些 Windows 系统中提供的命令行工具,用于 诊断程序在运行时产生的错误、异常或意外行为,并据此采取措施来解决问题,以确保程序能够按照预期的方式运行。在早期的 MS-DOS 和 Windows 系统中,Debug 是一个非常有用的工具,尤其是对于 底层(系统级编程) 程序员来说。

两个月亮 957

滚动时域优化方法

滚动时域优化(Receding Horizon Optimization, RHO),也被广泛称为模型预测控制(Model Predictive Control, MPC),是一种用于动态系统优化和控制的。其核心思想是“在每个当前时刻k,控制器只考虑未来一个(称为“预测时域”或“优化时域”,长度N)内的系统行为。(通过测量或估计得到)。(描述状态如何随输入和干扰变化)。(如果有,可能基于历史数据或假设)。在这个有限的未来时域[k, k+N-1]上,求解一个。这个优化问题的目标是找到一个。

m0_69522810的博客 2297

GD32F307 USB主机模式 外接U盘升级 调试问题记录

在移植USB驱动做主机读U盘时遇到的问题。 问题1、移植USB驱动完成后,插入U盘,一直在 usbh_core_task 的默认case 和测试case中反复执行无法执行到后面的连接及以后得步骤。 问题2、在 usbh_core_task 函数中,一直卡在枚举的case,无法执行下面操作。具体卡在urb_wait的while循环无法跳出。

LGC_764385701的博客 1949

反汇编引擎diStorm3

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34291004的博客 322

Unity游戏开发客户端Unity基础

Unity游戏开发客户端面经 之 Unity 篇

Sea3752的博客 2万+

壳与软件保护

2.3壳与软件保护"壳"是一段先丁被保护的程序运行的一段程序,在这段程序中对原有程序的代码及数据进行斗『i应的还原解龠操作。它们附加在原程序上通过Windows加载器载入内存后,先于原始程序执行,得到控制权,执行过程中对原始程序进行解密,还原,还原完成后再把控制权交还给原始程序,执行原来的代码部分'。加壳程序的…般运行过程如图2-3所示。按照"壳"的目的和作用,它可以分为两类:一类是压缩壳,另'类是加密壳。第一类压缩壳主要通过琏缩文件的代码和数据来减小程序的体积。而保护壳则用上了各种反跟踪技术保护程序不被

attilax的专栏 4291

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

基于虚拟机的软件保护技术

导读 基于虚拟机的软件保护技术不确定是否首先由vmprotect提出,但vmprotect毫无疑问是将这项技术大力推广至人所周知。现在基于虚拟机的软件保护技术已经成为现代软件安全防护的必备功能之一。 本文并不打算对vmprotect或其它某款软件安全套件进行深入讨论,而着眼于研究基于虚拟机的软件保护技术的起源、思想和实现。 现有软件保护技术概述 传统的软件保

Jack__CJ的博客 1075

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

自己的反汇编引擎——Intel指令编码(1)

自己写的反汇编总结

bilibili的博客 1776

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

深入解析软件世界的 “壳”:保护与隐藏的艺术

壳,其实和现实中动物的壳有着异曲同工之妙。动物的壳是为了保护柔软的肉体,而软件的壳则是开发者用来保护软件代码、防止被轻易破解和盗版的一种技术手段。想象一下,你辛辛苦苦写了一个软件,结果没几天就被别人破解,代码被随意盗用,这得多糟心。壳的出现,就是为了给软件穿上一层 “防护服”,增加破解的难度。它主要通过对软件代码进行一系列复杂操作来实现保护。常见的操作有压缩、加密、虚拟化,还会配合花指令、反调试等技术。这些手段会让静态分析变得困难重重,如果是强度更高的壳,动态分析也会举步维艰。

m0_57836225的博客 1264

软件保护壳专题 - 代码乱序引擎的构建

文章转自:看雪学院http://bbs.pediy.com/archive/index.php?t-96640.html 目录 0. 1. 2. 3. 4. 正文 0.什么是乱序 乱序就是打乱原来的流程。 很多朋友逆向程序时,会把一个程序直接丢到IDA里会出现一副流程图。我们现在要做的就是把这副 流程图打乱。但是并不影响原先流程的逻辑。乱序的原理其实比较简单。说白了就是做

zplove003的专栏 1413

Windows可执行文件(PE文件)壳的设计过程

PE文件壳的设计过程 标题:pe文件壳的设计过程 作者:baccon(PEDIY论坛),或chenxiang(软件发布者) 时间:2013年10月26日星期六

个人博客 4153

CTF逆向基础----花指令总结

什么是花指令? 花指令实质就是一串垃圾指令,它与程序本身的功能无关,并不影响程序本身的逻辑。在软件保护中,花指令被作为一种手段来增加静态分析的难度,花指令也可以被用在病毒或木马上,通过加入花指令改变程序的特征码,躲避杀软的扫描,从而达到免杀的目的,本文将介绍一些常见的花指令的形式,花指令一般被分为两类,被执行的和不会被执行的。 不会被执行的花指令 花指令虽然被插入到了正常代码的中间,但是并不意味着它一定会得到执行,这类花指令通常形式为在代码中出现了类似数据的代码,或者IDA反汇编后为jmupout(xxxx

一位非著名不专业的Re选手 1万+
上一篇: 用文档化方法列举系统模块
下一篇: PE感染逆向之修复
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值