第一篇 基础篇 2
第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
第二篇 调试篇 16
第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
第三篇 解密篇 102
第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
第四篇 语言和平台篇 194
第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
第五篇 系统篇 262
第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、CONTEXT 313
11.3 异常处理回调函数 312
第六篇 脱壳篇 316
第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外壳 356
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
第七篇 保护篇 380
第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篇 492
第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 浮点指令 528
附录B 在Visual C++中使用内联汇编 534
术语表 542
参考文献 544