目录

第一篇 基础篇

第1章 基础知识 2

1.1 文本字符 2

1.1.1 字节存储顺序 2
1.1.2 ASCII与Unicode字符集 2

1.2 Windows操作系统 4 1.2.1 Win API简介 4 1.2.2 常用Win32 API函数 5 1.2.3 什么是句柄 7 1.2.4 Windows 9x与Unicode 7 1.2.5 Windows NT/2000/XP与Unicode 8 1.2.6 Windows消息机制 9 1.3 保护模式简介 10 1.3.1 虚拟内存 10 1.3.2 保护模式的权限级别 11 1.4 认识PE格式 12

第二篇 调试篇

第2章 动态分析技术 16

2.1 OllyDbg调试器 16

2.1.1 OllyDbg界面 16
2.1.2 OllyDbg的配置 18
2.1.3 加载程序 19
2.1.4 基本操作 20
2.1.5 断点 30
2.1.6 插件 38
2.1.7 Run trace 39
2.1.8 Hit trace 40
2.1.9 符号调试技术 40
2.1.10 OllyDbg常见问题 42

2.2 SoftICE调试器 43

第3章 静态分析技术 44

3.1 文件类型分析 44 3.1.1 PEiD工具 44 3.1.2 FileInfo工具 45 3.2 静态反汇编 45 3.2.1 反汇编引擎 45 3.2.2 IDA Pro简介 46 3.2.3 IDA的配置 46 3.2.4 IDA主窗口界面 48 3.2.5 交叉参考 49 3.2.6 参考重命名 49 3.2.7 标签的用法 50 3.2.8 进制的转换 50 3.2.9 代码和数据转换 51 3.2.10 字符串 51 3.2.11 数组 53 3.2.12 结构体 53 3.2.13 枚举类型 57 3.2.14 堆栈变量 58 3.2.15 IDC脚本 59 3.2.16 FLIRT 62 3.2.17 插件 63 3.2.18 其他功能 63 3.2.19 小结 64 3.3 可执行文件的修改 64 3.4 静态分析技术应用实例 67 3.4.1 解密初步 67 3.4.2 逆向工程初步 69

第4章 逆向分析技术 71

4.1 启动函数 71

4.2 函 数 72

4.2.1 函数的识别 72
4.2.2 函数的参数 73
4.2.3 函数的返回值 78

4.3 数据结构 80

4.3.1 局部变量 80
4.3.2 全局变量 81
4.3.3 数组 83

4.4 虚函数 84

4.5 控制语句 86

4.5.1 IF-THEN-ELSE语句 86
4.5.2 SWITCH-CASE语句 87
4.5.3 转移指令机器码的计算 89
4.5.4 条件设置指令(SETcc) 91
4.5.5 纯算法实现逻辑判断 92

4.6 循环语句 93

4.7 数学运算符 94

4.7.1 整数的加法和减法 94
4.7.2 整数的乘法 94
4.7.3 整数的除法 95

4.8 文本字符串 97

4.8.1 字符串存储格式 97
4.8.2 字符寻址指令 98
4.8.3 字母大小写转换 98
4.8.4 计算字符串的长度 99

4.9 指令修改技巧 99

第三篇 解密篇

第5章 常见的演示版保护技术 102

5.1 序列号保护方式 102

5.1.1 序列号保护机制 102
5.1.2 如何攻击序列号保护 104
5.1.3 字符串比较形式 105
5.1.4 注册机制作 106

5.2 警告(Nag)窗口 111

5.3 时间限制 113

5.3.1 计时器 113
5.3.2 时间限制 114
5.3.3 拆解时间限制保护 114

5.4 菜单功能限制 115

5.4.1 相关函数 115
5.4.2 拆解菜单限制保护 116

5.5 KeyFile保护 116

5.5.1 相关API函数 116
5.5.2 拆解KeyFile保护 117

5.6 网络验证 121

5.6.1 相关函数 121
5.6.2 网络验证破解一般思路 121

5.7 CD-Check 126

5.7.1 相关函数 127
5.7.2 拆解光盘保护 128

5.8 只运行一个实例 128

5.8.1 实现方法 128
5.8.2 实例 129

5.9 常用断点设置技巧 129

第6章 加密算法 131

6.1 单向散列算法 131

6.1.1 MD5算法 131
6.1.2 SHA算法 136
6.1.3 小结 139

6.2 对称加密算法 139

6.2.1 RC4流密码 140
6.2.2 TEA算法 141
6.2.3 IDEA算法 144
6.2.4 BlowFish算法 151
6.2.5 AES算法 155
6.2.6 对称加密算法小结 167

6.3 公开密钥加密算法 167

6.3.1 RSA算法 168
6.3.2 ElGamal公钥算法 173
6.3.3 DSA数字签名算法 179
6.3.4 椭圆曲线密码编码学(Elliptic Curve Cryptography) 180

6.4 其他算法 186

6.4.1 CRC32算法 186
6.4.2 Base64编码 187

6.5 常见的加密库接口及其识别 188

6.5.1 Miracl大数运算库 189
6.5.2 FGInt 190
6.5.3 其他加密算法库介绍 191

第四篇 语言和平台篇

第7章 Delphi程序 194

7.1 DeDe反编译器 194

7.2 按钮事件代码 197

7.3 模块初始化与结束化 197

第8章 Visual Basic程序 200

8.1 基础知识 200

8.1.1 字符编码方式 200
8.1.2 编译模式 200

8.2 自然编译(Native) 201

8.2.1 相关VB函数 201
8.2.2 VB程序比较方式 201

8.3 伪编译 206

8.3.1 虚拟机与伪代码 206
8.3.2 动态分析VB P-code程序 208
8.3.3 伪代码的综合分析 211
8.3.4 VB P-code攻击实战 213

第9章 .NET平台加解密 218

9.1 .Net概述 218

9.1.1 什么是.Net 218
9.1.2 几个基本概念 218
9.1.3 第一个.Net程序 219

9.2 MSIL与元数据 220

9.2.1 PE结构的扩展 220
9.2.2 .Net下的汇编MSIL 226
9.2.3 MSIL与元数据的结合 228

9.3 代码分析技术 230

9.3.1 静态分析 230
9.3.2 动态调试 232
9.3.3 代码修改 234

9.4 代码保护技术及其逆向 235

9.4.1 强名称 235
9.4.2 名称混淆 238
9.4.3 流程混淆 241
9.4.4 压缩 243
9.4.5 加密 247
9.4.6 其他保护手段 253

9.5 深入.Net 254

9.5.1 反射与CodeDOM 254
9.5.2 Unmaganed API 256
9.5.3 Rotor、MONO与.Net内核 258

第五篇 系统篇

第10章 PE文件格式 262

10.1 PE的基本概念 263

10.1.1 基地址 264
10.1.2 相对虚拟地址 264
10.1.3 文件偏移地址 265

10.2 MS-DOS头部 265

10.3 PE文件头 266

10.3.1 Signature字段 266
10.3.2 IMAGE_FILE_HEADER结构 267
10.3.3 IMAGE_OPTIONAL_HEADER结构 268

10.4 区块 272

10.4.1 区块表 272
10.4.2 各种区块的描述 274
10.4.3 区块的对齐值 276
10.4.4 文件偏移与虚拟地址转换 276

10.5 输入表 278

10.5.1 输入函数的调用 278
10.5.2 输入表结构 279
10.5.3 输入地址表(IAT) 281
10.5.4 输入表实例分析 281

10.6 绑定输入 285

10.7 输出表 286

10.7.1 输出表结构 287
10.7.2 输出表结构实例分析 288

10.8 基址重定位 289

10.8.1 基址重定位概念 289
10.8.2 基址重定位结构定义 290
10.8.3 基址重定位结构实例分析 291

10.9 资源 292

10.9.1 资源结构 292
10.9.2 资源结构实例分析 295
10.9.3 资源编辑工具 297

10.10 TLS初始化 297

10.11 调试目录 297

10.12 延迟装入数据 298

10.13 程序异常数据 299

10.14 .Net头部 299

10.15 编写PE分析工具 300

10.15.1 文件格式检查 300
10.15.2 FileHeader和OptionalHeader内容的读取 300
10.15.3 得到数据目录表信息 302
10.15.4 得到区块表信息 302
10.15.5 得到输出表信息 303
10.15.6 得到输入表信息 304

第11章 结构化异常处理 306

11.1 基本概念 306

11.1.1 异常列表 306
11.1.2 异常处理的基本过程 307
11.1.3 SEH的分类 308

11.2 SEH相关数据结构 308

11.2.1 TEB结构 308
11.2.2 EXCEPTION_REGISTRATION结构 311
11.2.3 EXCEPTION_POINTERS、EXCEPTION RECORD、
11.2.3 CONTEXT 313

11.3 异常处理回调函数 312

第六篇 脱壳篇

第12章 专用加密软件 316

12.1 认识壳 316

12.1.1 壳的概念 316
12.1.2 压缩引擎 317

12.2 压缩壳 317

12.2.1 UPX 318
12.2.2 ASPack 318

12.3 加密壳 318

12.3.1 ASProtect 318
12.3.2 Armadillo 319
12.3.3 EXECryptor 320
12.3.4 Themida 320

12.4 虚拟机保护软件 321

12.4.1 虚拟机介绍 321
12.4.2 VMProtect简介 321

第13章 脱壳技术 324

13.1 基础知识 324

13.1.1 壳的加载过程 324
13.1.2 脱壳机 326
13.1.3 手动脱壳 326

13.2 寻找OEP 326

13.2.1 根据跨段指令寻找OEP 326
13.2.2 用内存访问断点找OEP 330
13.2.3 根据堆栈平衡原理找OEP 331
13.2.4 根据编译语言特点找OEP 332

13.3 抓取内存映像 332

13.3.1 Dump原理 332
13.3.2 反Dump技术(Anti-Dump) 334

13.4 重建输入表 336

13.4.1 输入表重建的原理 336
13.4.2 确定IAT的地址和大小 337
13.4.3 根据IAT重建输入表 338
13.4.4 ImportREC重建输入表 340
13.4.5 输入表加密概括 344

13.5 DLL文件脱壳 345

13.5.1 寻找OEP 345
13.5.2 Dump映像文件 347
13.5.3 重建DLL的输入表 348
13.5.4 构造重定位表 349

13.6 附加数据 351

13.7 PE文件的优化 353

13.8 压缩壳 356

13.8.1 UPX外壳 3565
13.8.2 ASPack外壳 359

13.9 加密壳 363

13.9.1 ASProtect 363
13.9.2 Themidia的SDK分析 367

13.10 静态脱壳 372

13.10.1 外壳Loader的分析 372
13.10.2 编写静态脱壳器 377

第七篇 保护篇

第14章 软件保护技术 380

14.1 防范算法求逆 380

14.1.1 基本概念 380
14.1.2 堡垒战术 381
14.1.3 游击战术 382

14.2 抵御静态分析 383

14.2.1 花指令 383
14.2.2 SMC技术实现 385
14.2.3 信息隐藏 390
14.2.4 简单的多态变形技术 391

14.3 文件完整性检验 392

14.3.1 磁盘文件校验实现 392
14.3.2 校验和(Checksum) 393
14.3.3 内存映像校验 393

14.4 代码与数据结合技术 395

14.4.1 准备工作 396
14.4.2 加密算法选用 397
14.4.3 手动加密代码 397
14.4.4 使.text区块可写 399

14.5 软件保护的若干忠告 399

第15章 反跟踪技术 401

15.1 由BeingDebugged引发的蝴蝶效应 401

15.1.1 BeingDebugged 401
15.1.2 NtGlobalFlag 405
15.1.3 Heap Magic 407
15.1.4 从源头消灭BeingDebugged 412

15.2 回归Native:用户态的梦魇 413

15.2.1 CheckRemoteDebuggerPresent 413
15.2.2 ProcessDebugPort 414
15.2.3 ThreadHideFromDebugger 416

15.2.4 Debug Object 419

15.2.5 SystemKernelDebuggerInformation 423
15.2.6 Native API 425
15.2.7 Hook和AntiHook 430

15.3 真正的奥秘:小技巧一览 433

15.3.1 SoftICE检测方法 433
15.3.2 OllyDbg检测方法 435
15.3.3 调试器漏洞 437
15.3.4 防止调试器附加 438
15.3.5 父进程检测 440
15.3.6 时间差 440
15.3.7 通过Trap Flag检测 441
15.3.8 双进程保护 441

第16章 外壳编写基础 442

16.1 外壳的结构 442

16.2 加壳主程序 443

16.2.1 判断文件是否为PE格式 443
16.2.2 文件基本数据读入 443
16.2.3 附加数据读取 445
16.2.4 输入表处理 445
16.2.5 重定位表处理 448
16.2.6 文件的压缩 450
16.2.7 资源数据处理 453
16.2.8 区块的融合 457

16.3 外壳部分编写 457

16.3.1 外壳的加载过程 458
16.3.2 自建输入表 458
16.3.3 外壳引导段 459
16.3.4 外壳第二段 462

16.4 将外壳部分添加至原程序 467

第17章 虚拟机的设计 471

17.1 原理 471

17.1.1 反汇编引擎 472
17.1.2 指令分类 472

17.2 启动框架和调用约定 473

17.2.1 调度器VStartVM 473
17.2.2 虚拟环境:VMContext 474
17.2.3 平衡堆栈:VBegin和VCheckEsp 474

17.3 Handler的设计 475

17.3.1 辅助Handler 475
17.3.2 普通Handler和指令拆解 476
17.3.3 标志位问题 477
17.3.4 相同作用的指令 478
17.3.5 转移指令 478
17.3.6 转移跳转指令的另一种实现 479
17.3.7 call指令 480
17.3.8 retn指令 481
17.3.9 不可模拟指令 481

17.4 托管代码的异常处理 482

17.4.1 VC++的异常处理 482
17.4.2 Delphi的异常处理 486

17.5 小结 490

第八篇 PEDIY篇

第18章 补丁技术 492

18.1 文件补丁 492

18.2 内存补丁 493

18.2.1 跨进程内存存取机制 493
18.2.2 Debug API机制 495
18.2.3 利用调试寄存器机制 498
18.2.4 DLL劫持技术 501

18.3 SMC补丁技术 505

18.3.1 单层SMC补丁技术 505
18.3.2 多层SMC补丁技术 506

18.4 补丁工具 508

第19章 代码的二次开发 510

19.1 数据对齐 510

19.2 增加空间 510

19.2.1 区块间隙 510
19.2.2 手工构造区块 511
19.2.3 工具辅助构造区块 512

19.3 获得函数的调用 512

19.3.1 增加输入函数 513
19.3.2 显式链接调用DLL 514

19.4 代码的重定位 514

19.4.1 修复重定位表 514
19.4.2 代码的自定位技术 516

19.5 增加输出函数 517

19.6 消息循环 518

19.6.1 WndProc函数 518
19.6.2 寻找消息循环 519
19.6.3 WndProc汇编形式 520

19.7 修改WndProc扩充功能 521

19.7.1 扩充WndProc 521
19.7.2 扩充Exit菜单功能 522
19.7.3 扩充Open菜单功能 522

19.8 增加接口 525

19.8.1 用DLL增加功能 525
19.8.2 扩展消息循环 526

附录A 浮点指令 531528

附录B 在Visual C++中使用内联汇编 537534