
本文为看雪论坛优秀文章
看雪论坛作者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
- 保护全关



1、读取PE 基本结构
定义的结构如下:

2、获取到壳要的各种API

3、将用户要VM的Opcode进行解析
(这个后面有详细说明)

4、定位到加密按钮
(1)使用DarkDe4.exe


5、sub_4A3414函数分析
(1)偏移到新区段的起始地址





1、快速入门Opcode
Intel-64和IA-32架构指令编码是图2-1所示格式的子集。一条指令包括可选的指令前缀(顺序任意),主操作码(最多3字节),由ModR/M和SIB字节(可选)组成的地址格式描述符(如果需要的话),偏移量(可选)以及立即数(可选)。
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指令,也可被用作某些指令的强制性前缀
- 2EH—CS 段重载(用于任意分支指令时保留)
- 36H—SS 段重载(用于任意分支指令时保留)
- 3EH—DS 段重载(用于任意分支指令时保留)
- 26H—ES 段重载(用于任意分支指令时保留)
- 64H—FS 段重载(用于任意分支指令时保留)
- 65H—GS 段重载(用于任意分支指令时保留)
- 2EH—分支不被接受(仅用于Jcc指令中)
- 3EH—分支被接受(仅用于Jcc指令中)
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节。
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(可选)78563412



注:
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表,结构如下:

注:“[*]”记号表示:若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- End -

看雪ID:黑手鱼
https://bbs.pediy.com/user-585205.htm
*本文由看雪论坛 黑手鱼 原创,转载请注明来自看雪社区
进阶安全圈,不得不读的一本书
﹀
﹀
﹀
