汇编语言sub指令用法_VMP学习笔记之壳基础流程、X86指令Opcode快速入门

本文为看雪论坛优秀文章,介绍了加壳机相关测试,包括读取PE基本结构、获取API等。重点讲解了Opcode快速入门,涵盖各组成部分,还对指令前缀、OPcode、ModR/M和SIB字节进行详解,并给出实践参考书籍及相关指令示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

e49775db13787a866db596dc0b7f48b7.png

本文为看雪论坛优秀文章

看雪论坛作者ID:黑手鱼

【加壳方式】UPX 0.89.6 - 1.02 / 1.05 - 2.90 (Delphi)【编写语言】Borland Delphi 4.0 - 5.0【操作平台】Win7 32位【作者声明】以看雪作者waiWH的VMP还原系列为参考原型逆向分析壳基础流程

说明:
  • 加壳机的壳是秒杀壳,自行百度
  • HelloASM.exe是测试demo
  • 保护全关
769eb1fd3f0d27663de2c27e6ef5756d.pngf829965ab6abb20366f9b23f84cc3b5f.png635aa898bb58c6902ddbf9b284373158.png>>>>

1、读取PE 基本结构

定义的结构如下:

a9334b9c3c548c789f66775391513633.png>>>>

2、获取到壳要的各种API

b420d5e730595a12f482b6b1377bb844.png>>>>

3、将用户要VM的Opcode进行解析

(这个后面有详细说明)

0ba44b19d598a1eeb6a71ec6e0b0d294.png>>>>

4、定位到加密按钮

(1)使用DarkDe4.exed2f6baae6238da07ac7006efa109a29b.png(2)分析的设置是保护全关,所以ProtectOptions = 8ceea60b0597cbeed458e0837088eb1b8.png(3)分析关键函数sub_4A3414(最核心的函数)902b9d574e3495bdfce80bdc7f80277d.png>>>>

5、sub_4A3414函数分析

(1)偏移到新区段的起始地址049778dff43d085c4856a2f927e4c3a3.png(2)判断RVA合法性55005f1048edc10cbb642631e6840ec1.png(3)内存对齐后的总大小16211579016955d628521f20d959fbfa.png(4)根据保护等级选择使用哪个壳模板,并设置区段保护属性8ac524c323348764779e0ffed452a930.png(5)壳模板一共有6个fdab2b0372618ef172261ee1c25aa5ba.png(6)我们使用的是474974,到这里这篇章节就完成了8a4d7bf94b0ab231d9d022d2bbc3e0bf.pngX86指令之Opcode快速入门

>>>>

1、快速入门Opcode

Intel-64和IA-32架构指令编码是图2-1所示格式的子集。一条指令包括可选的指令前缀(顺序任意),主操作码(最多3字节),由ModR/M和SIB字节(可选)组成的地址格式描述符(如果需要的话),偏移量(可选)以及立即数(可选)。96797125e10d3335c975d4b07fe50874.png总结:a. 根据上图所示我们知道一条汇编指令分为以下几个部分:

1)Legacy Prefix(可选)

2)REX prefix(用于64位模式,这里不做讲解)

3)Opcode(必须有)

4)ModRM(可选)

5)SIB(可选)

6)Displacement(可选)

7)Immediate(可选)

b. Opcode结构顺序是不能被打乱的 >>>>

2、 指令前缀讲解(可选)

a. 基础理论知识指令前缀分为四组,每一组包含一些允许的前缀码。对于任何指令,前缀可以从这四组(组1,2,3,4)里的挑选,并且它们不区分次序。组1——锁定和重复前缀:
  • F0H - LOCK
  • F2H - REPNE/REPNZ,仅用于串操作和I/O指令,也可被用作某些指令的强制性前缀
  • F3H - REP或REPE/REPZ,仅用于串操作和I/O指令,也可被用作某些指令的强制性前缀
组2 —  段重载前缀:
  • 2EH—CS 段重载(用于任意分支指令时保留)
  • 36H—SS 段重载(用于任意分支指令时保留)
  • 3EH—DS 段重载(用于任意分支指令时保留)
  • 26H—ES 段重载(用于任意分支指令时保留)
  • 64H—FS 段重载(用于任意分支指令时保留)
  • 65H—GS 段重载(用于任意分支指令时保留)
分支提示:
  • 2EH—分支不被接受(仅用于Jcc指令中)
  • 3EH—分支被接受(仅用于Jcc指令中)
组366H—操作数大小重载前缀,也可被用作某些指令的强制性前缀。组467H—地址尺寸重载前缀LOCK前缀(F0H)在多处理器环境下强制执行独占共享内存操作。详见《Instruction Set Reference, A-M》第三章“LOCK – 断言LOCK#信号前缀”。 重复前缀(F2H,F3H)将会重复操作字符串的每一个元素。只有MOVS,CMPS,SCAS,LODS,STOS,INS,OUTS等字符串操作或I/O指令才能使用这些前缀。对Intel 64 或 IA-32 其他指令使用重复前缀和/或未定义的操作码是被保留的,将会引起不可预知的行为。 某些指令可能使用F2H,F3H作为强制性前缀来表示特定的功能.强制性前缀应当位于其他可选的前缀之后(例外的情形请查看第2.2.1节,”REX前缀”) 分支提示前缀(2EH,3EH)允许程序给处理器一个最有可能的执行分支提示.这些前缀只能用于条件指令(Jcc)。在Intel 64 或 IA-32 其他指令中使用分支预测前缀或者未定义的操作码是被保留的,将引起不可预知的行为。 操作数大小重载前缀允许程序在16位和32位操作数大小间切换。它们中任一个都可以是默认值,而使用这个前缀则选择非默认值。 某些SSE2/SSE3/SSSE3/SSE4和使用3字节操作码的指令可能使用66H作为强制性前缀来表示特定的功能。强制性前缀应当位于其他可选的前缀之后(例外的情形请查看第2.2.1节,”REX前缀”) 。66H前缀的其他用法是被保留的,将引起不可预知的行为。  地址尺寸重载前缀(67H)允许程序在16位和32位地址间切换。它们中的任何一个都可以是默认值,使用这个前缀选择非默认值。当指令中的操作数不在内存中,使用这个前缀或未定义的操作码时,操作被保留,可能引起不可预知的行为。 >>>>

3、 OPcode详解(必备)

主操作码,必须有。指令不定长1、2、3都有,例如8B C0    mov eax,eax 其中8B就是主操作码。例如90 NOP就是只有主操作码没有ModR/M和SIB字节的。 >>>>

4、ModR/M 和 SIB 字节(可选)

a. 基础知识(非常重要的字节)

许多涉及内存操作数的指令都有一个紧挨着主操作码的寻址格式说明字节(叫做ModR/M字节),ModR/M字节包含3个域信息:

(1)mod域与r/m域组成32个可能的值:8个寄存器和24个寻址模式。(2)reg/opcode域确定寄存器号或者附加的3位操作码。reg/opcode域的用途由主操作码确定。(3)r/m域确定一个寄存器为操作数或者和mod域一起编码寻址模式。有时候有些指令使用特定的mod域和r/m域组合来表示操作码信息。

某些ModR/M字节编码需要第二寻址字节(SIB)。基址+索引或者比例+索引形式的32位寻址需要SIB字节。SIB字节包括下列域:

  • scale 域指定比例因子。

  • index域指定索引寄存器号。

  • base 域指定基址寄存器号。

    ModR/M和SIB编码详见第2.1.5节。

 总结:SIB就是对ModR/M的补充辅助。这些都是可选的。 >>>>

5、针对前面内容进行实践

参考书籍

1、查ModRM、SIB表使用的是:参考文档:Intel开发者手册 第二卷 指令集手册 第2章

2、查OPcode使用的是:参考文档:IntelCPU机器指令中文版手册

(1)举例说明

26:C784C8 44332211 78563412    MOV DWORD PTR ES:[EAX+ECX*8+0x11223344],0x12345678

 (2)指令拆解a. Legacy Prefix(可选)26H—ES 段重载(用于任意分支指令时保留)b. Opcode(必须有)C73、ModRM(可选)844、SIB(可选)C85、Displacement(可选)443322116、Immediate(可选)78563412d0e47b862485f841e4ee7234863b8d52.png(3)解析Opcode找到主操作码(查表)e9bc289b842aa525dad15cca4ea8d9d5.png得到的是 MOV R/M32,IMM32 (4)分析ModRM(查表)ModRM结构如下:c3a8ef376e7e9c278ede32f5be5c6ab6.png转换成二进制如下:84=‭10000100‬1d54d95f6d281102990b97e01d83f20a.png

注:

1. “[--][--]”记号表示ModR/M 后跟随有一个SIB字节。

2. “disp32”记号表示ModR/M(或者SIB,如果出现的话) 后跟随一个32位的偏移量,该偏移量被加至有效地址。

3. “disp8” 记号表示ModR/M(或者SIB,如果出现的话)后跟随一个8位的偏移量,该偏移量将被符号扩展,然后被加至有效地址。

表2-3囊括了SIB 的256个可能值(十六进制形式)。可以作为基的通用寄存器通过表的上部列出,也列出了相应的base域值。表的主体的每行列出了索引(index SIB的3,4,5位)对应的寄存器及倍率因子(scaling factor SIBbyte的6,7位)。总结:a. ModRM.mod 提供寻址模式: 11 = register(寄存器)  11 != memory(地址)b. R/M = 100并且mod!=11 的时候表示存在SIB表 (5)分析SIB(查表)根据上文找到的地址发现是[--][--]”,表示有SIB表,结构如下:b94dd54a802a3db1cd6d7fd876537bb4.png转换成2进制如下:C8=‭11001000‬73ec6e0acf04ae42a963a90c41a0e04f.png

注:“[*]”记号表示:若MOD = 00B表示没有基,且带有一个32位的偏移量;否则表示disp8或disp32 + [EBP]。即提供如下的寻址方式:

MOD          有效地址

00    [scaled index] + disp32

01    [scaled index] + disp8 + [EBP]

10    [scaled index] + disp32 + [EBP]

44332211 - Displacement:此为小端模式,即为0x1122334478563412 - Immediate:小端模式,即为0x12345678综上,得到:MOV DWORD PTR ES:[EAX+ECX*8+0x11223344],0x12345678

788382877de098351b6c15eb03b758e7.gif

- End -

cce026b15c10e023fd3eae7ea7ec1127.png

看雪ID:黑手鱼  

https://bbs.pediy.com/user-585205.htm 

*本文由看雪论坛 黑手鱼 原创,转载请注明来自看雪社区

进阶安全圈,不得不读的一本书d6694db64c389c7264522927b610d0ad.png

03273469b9daf3c0dbb4f2182b34b18d.png

7351e8004935ef28044ebab9012e5481.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值