内容推荐 逆向工程是一种分析目标系统的过程,旨在于识别系统的各组件以及组件间关系,以便于通过其它形式、或在较高的抽象层次上,重建系统的表征。 本书专注于软件的逆向工程,是写给初学者的一本经典指南。全书共分为12个部分,共102章,涉及X86/X64、ARM/ARM-64、MIPS、Java/JVM等重要话题,详细解析了Oracle RDBMS、Itanium、软件狗、LD_PRELOAD、栈溢出、ELF、Win32 PE文件格式、x86-64(第、critical sections、syscalls、线程本地存储TLS、地址无关代码(PIC)、以配置文件为导向的优化、C++ STL、OpenMP、SHE等众多技术话题,堪称是逆向工程技术百科全书。除了详细讲解,本书来给出了很多习题来帮助读者巩固所学的知识,附录部分给出了习题的解答。 本书适合对逆向工程技术、操作系统底层技术、程序分析技术感兴趣的读者阅读,也适合专业的程序开发人员参考。 作者简介 Dennis Yurichev,乌克兰程序员,安全技术专家。读者可以 通过https://yurichev.com/联系他,并获取和本书相关的更多 学习资料。 目录 部分  编码模式 章  CPU简介  3 1.1  指令集的作用  3 第2章  最简函数  5 2.1  x86  5 2.2  ARM  5 2.3  MIPS  5 2.3.1  MIPS指令集与寄存器名称  6 第3章  Hello,world!  7 3.1  x86  7 3.1.1  MSVC  7 3.1.2  GCC  9 3.1.3  GCC:AT&T语体  9 3.2  x86-64  11 3.2.1  MSVC-x86-64  11 3.2.2  GCC-x86-64  12 3.3  GCC的其他特性  12 3.4  ARM  13 3.4.1  Keil 6/2013——未启用优化功能的ARM模式  14 3.4.2  Thumb模式下、未开启优化选项的Keil  15 3.4.3  ARM模式下、开启优化选项的Xcode  15 3.4.4  Thumb-2模式下、开启优化选项的Xcode(LLVM)  16 3.4.5  ARM64  18 3.5  MIPS  19 3.5.1  全局指针Global pointer  19 3.5.2  Optimizing GCC  19 3.5.3  Non-optimizing GCC  21 3.5.4  栈帧  23 3.5.5  Optimizing GCC: GDB的分析方法  23 3.6  总结  24 3.7  练习  24 3.7.1  题目1  24 3.7.2  题目2  24 第4章  函数序言和函数尾声  25 4.1  递归调用  25 第5章  栈  26 5.1  为什么栈会逆增长?  26 5.2  栈的用途  27 5.2.1  保存函数结束时的返回地址  27 5.2.2  参数传递  28 5.2.3  存储局部变量  29 5.2.4  x86:alloca()函数  29 5.2.5  (Windows)SEH结构化 异常处理  31 5.2.6  缓冲区溢出保护  31 5.3  典型的栈的内存存储格式  31 5.4  栈的噪音  31 5.5  练习题  34 5.5.1  题目1  34 5.5.2  题目2  34 第6章  printf()函数与参数调用  36 6.1  x86  36 6.1.1  x86:传递3个参数  36 6.1.2  x64:传递9个参数  41 6.2  ARM  44 6.2.1  ARM模式下传递3个参数  44 6.2.2  ARM模式下传递8个参数  46 6.3  MIPS  50 6.3.1  传递3个参数  50 6.3.2  传递9个参数  52 6.4  总结  56 6.5  其他  57 第7章  scanf()  58 7.1  演示案例  58 7.1.1  指针简介  58 7.1.2  x86  58 7.1.3  MSVC+OllyDbg  60 7.1.4  x64  62 7.1.5  ARM  63 7.1.6  MIPS  64 7.2  全局变量  65 7.2.1  MSVC:x86  66 7.2.2  MSVC:x86+OllyDbg  67 7.2.3  GCC:x86  68 7.2.4  MSVC:x64  68 7.2.5  ARM: Optimizing Keil 6/2013 (Thumb模式)  69 7.2.6  ARM64  70 7.2.7  MIPS  70 7.3  scanf()函数的状态监测  74 7.3.1  MSVC:x86  74 7.3.2  MSVC:x86:IDA  75 7.3.3  MSVC:x86+OllyDbg  77 7.3.4  MSVC:x86+Hiew  78 7.3.5  MSVC:x64  79 7.3.6  ARM  80 7.3.7  MIPS  81 7.3.8  练习题  82 第8章  参数获取  83 8.1  x86  83 8.1.1  MSVC  83 8.1.2  MSVC+OllyDbg  84 8.1.3  GCC  84 8.2  x64  85 8.2.1  MSVC  85 8.2.2  GCC  86 8.2.3  GCC: uint64_t型参数  87 8.3  ARM  88 8.3.1  Non-optimizing Keil 6/2013 (ARM  mode)  88 8.3.2  Optimizing Keil 6/2013 (ARM  mode)  89 8.3.3  Optimizing Keil 6/2013 (Thumb  mode)  89 8.3.4  ARM64  89 8.4  MIPS  91 第9章  返回值  93 9.1  void型函数的返回值  93 9.2  函数返回值不被调用的情况  94 9.3  返回值为结构体型数据  94 0章  指针  96 10.1  全局变量  96 10.2  局部变量  98 10.3  总结  100 1章  GOTO语句  101 11.1  无用代码Dead Code  102 11.2  练习题  102 2章  条件转移指令  103 12.1  数值比较  103 12.1.1  x86  103 12.1.2  ARM  109 12.1.3  MIPS  112 12.2  计算绝对值  115 12.2.1  Optimizing MSVC  115 12.2.2  Optimizing Keil 6/2013: Thumb   mode  116 12.2.3  Optimizing Keil 6/2013: ARM   mode  116 12.2.4  Non-optimizng GCC 4.9   (ARM64)  116 12.2.5  MIPS  117 12.2.6  不使用转移指令  117 12.3  条件运算符  117 12.3.1  x86  117 12.3.2  ARM  118 12.3.3  ARM64  119 12.3.4  MIPS  119 12.3.5  使用if/else替代条件运算符  120 12.3.6  总结  120 12.3.7  练习题  120 12.4  比较优选值和最小值  120 12.4.1  32位  120 12.4.2  64位  123 12.4.3  MIPS  125 12.5  总结  125 12.5.1  x86  125 12.5.2  ARM  125 12.5.3  MIPS  126 12.5.4  不使用转移指令  126 3章  switch()/case/default  128 13.1  case陈述式较少的情况  128 13.1.1  x86  128 13.1.2  ARM: Optimizing Keil 6/2013   (ARM mode)  133 13.1.3  ARM: Optimizing Keil 6/2013   (Thumb mode)  133 13.1.4  ARM64: Non-optimizing GCC   (Linaro) 4.9  134 13.1.5  ARM64: Optimizing GCC   (Linaro) 4.9  134 13.1.6  MIPS  135 13.1.7  总结  136 13.2  多个case从句  136 13.2.1  x86  136 13.2.2  ARM: Optimizing Keil 6/2013   (ARM mode)  140 13.2.3  ARM: Optimizing Keil 6/2013   (Thumb mode)  141 13.2.4  MIPS  143 13.2.5  总结  144 13.3  case从句多对一的情况  145 13.3.1  MSVC  145 13.3.2  GCC  147 13.3.3  ARM64: Optimizing   GCC 4.9.1  147 13.4  Fall-through  149 13.4.1  MSVC x86  149 13.4.2  ARM64  150 13.5  练习题  151 13.5.1  题目1  151 4章  循环  152 14.1  举例说明  152 14.1.1  x86  152 14.1.2  x86:OllyDbg  155 14.1.3  x86:跟踪调试工具tracer  156 14.1.4  ARM  157 14.1.5  MIPS  160 14.1.6  其他  161 14.2  内存块复制  161 14.2.1  编译结果  161 14.2.2  编译为ARM模式的   程序  162 14.2.3  MIPS  163 14.2.4  矢量化技术  164 14.3  总结  164 14.4  练习题  165 14.4.1  题目1  165 14.4.2  题目2  165 14.4.3  题目3  166 14.4.4  题目4  167 5章  C语言字符串的函数  170 15.1  strlen()  170 15.1.1  x86  170 15.1.2  ARM  174 15.1.3  MIPS  177 15.2  练习题  178 15.2.1  练习题1  178 6章  数学计算指令的替换  181 16.1  乘法  181 16.1.1  替换为加法运算  181 16.1.2  替换为位移运算  181 16.1.3  替换为位移、加减法的   混合运算  182 16.2  除法运算  186 16.2.1  替换为位移运算  186 16.3  练习题  186 16.3.1  题目2  186 7章  FPU  188 17.1  IEEE 754  188 17.2  x86  188 17.3  ARM、MIPD、x86/x64 SIMD  188 17.4  C/C++  188 17.5  举例说明  189 17.5.1  x86  189 17.5.2  ARM: Optimizing Xcode   4.6.3 (LLVM) (ARM mode)  193 17.5.3  ARM: Optimizing Keil 6/2013   (Thumb mode)  193 17.5.4  ARM64: Optimizing GCC   (Linaro) 4.9  194 17.5.5  ARM64: Non-optimizing GCC   (Linaro) 4.9  195 17.5.6  MIPS  195 17.6  利用参数传递浮点型数据  196 17.6.1  x86  196 17.6.2  ARM + Non-optimizing   Xcode 4.6.3 (LLVM)   (Thumb-2 mode)  197 17.6.3  ARM + Non-optimizing Keil   6/2013 (ARM mode)  198 17.6.4  ARM64 + Optimizing GCC   (Linaro) 4.9  198 17.6.5  MIPS  199 17.7  比较说明  200 17.7.1  x86  200 17.7.2  ARM  216 17.7.3  ARM64  219 Optimizing  GCC (Linaro) 4.9—float  220 17.7.4  MIPS  220 17.8  栈、计算器及逆波兰表示法  221 17.9  x64  221 17.10  练习题  221 17.10.1  题目1  221 17.10.2  题目2  221 8章  数组  223 18.1  简介  223 18.1.1  x86  223 18.1.2  ARM  225 18.1.3  MIPS  228 18.2  缓冲区溢出  229 18.2.1  读取数组边界以外的内容  229 18.2.2  向数组边界之外的地址赋值  231 18.3  缓冲区溢出的保护方法  234 18.3.1  Optimizing Xcode 4.6.3 (LLVM)   (Thumb-2 mode)  236 18.4  其他  238 18.5  字符串指针  238 18.5.1  x64  239 18.5.2  32位ARM  240 18.5.3  ARM64  241 18.5.4  MIPS  242 18.5.5  数组溢出  242 18.6  多维数组  245 18.6.1  二维数组举例  246 18.6.2  以一维数组的方式访问   二维数组  247 18.6.3  三维数组  248 18.6.4  更多案例  251 18.7  二维字符串数组的封装格式  251 18.7.1  32位ARM  253 18.7.2  ARM64  254 18.7.3  MIPS  254 18.7.4  总结  255 18.8  本章小结  255 18.9  练习题  255 18.9.1  题目1  255 18.9.2  题目2  258 18.9.3  题目3  263 18.9.4  题目4  264 18.9.5  题目5  265 9章  位操作  270 19.1  特定位  270 19.1.1  x86  270 19.1.2  ARM  272 19.2  设置/清除特定位  274 19.2.1  x86  274 19.2.2  ARM + Optimizing Keil 6/2013   (ARM mode)  277 19.2.3  ARM + Optimizing Keil 6/2013   (Thumb mode)  278 19.2.4  ARM + Optimizing Xcode (LLVM)   + ARM mode  278 19.2.5  ARM:BIC指令详解  278 19.2.6  ARM64: Optimizing GCC(Linaro)   4.9  278 19.2.7  ARM64: Non-optimizing GCC (Linaro) 4.9  279 19.2.8  MIPS  279 19.3  位移  279 19.4  在FPU上设置特定位  279 19.4.1  XOR操作详解  280 19.4.2  x86  280 19.4.3  MIPS  282 19.4.4  ARM  282 19.5  位校验  284 19.5.1  x86  286 19.5.2  x64  289 19.5.3  ARM + Optimizing Xcode 4.6.3   (LLVM) + ARM mode  291 19.5.4  ARM + Optimizing Xcode 4.6.3 (LLVM)+  Thumb-2 mode  292 19.5.5  ARM64 + Optimizing GCC 4.9  292 19.5.6  ARM64 + Non-optimizing   GCC 4.9  292 19.5.7  MIPS  293 19.6  本章小结  295 19.6.1  检测特定位(编译阶段)  295 19.6.2  检测特定位(runtime阶段)  295 19.6.3  设置特定位(编译阶段)  296 19.6.4  设置特定位(runtime阶段)  296 19.6.5  清除特定位(编译阶段)  296 19.6.6  清除特定位(runtime阶段)  297 19.7  练习题  297 19.7.1  题目1  297 19.7.2  题目2  298 19.7.3  题目3  301 19.7.4  题目4  301 第20章  线性同馀法与伪随机函数  304 20.1  x86  304 20.2  x64  305 20.3  32位ARM  306 20.4  MIPS  306 20.4.1  MIPS的重新定位  307 20.5  本例的线程安全改进版  309 第21章  结 构 体  310 21.1  MSVC: systemtime  310 21.1.1  OllyDbg  311 21.1.2  以数组替代结构体  312 21.2  用malloc()分配结构体的空间  313 21.3  UNIX: struct tm  315 21.3.1  Linux  315 21.3.2  ARM  317 21.3.3  MIPS  319 21.3.4  数组替代法  320 21.3.5  替换为32位words  322 21.3.6  替换为字节型数组  323 21.4  结构体的字段封装  325 21.4.1  x86  325 21.4.2  ARM  329 21.4.3  MIPS  330 21.4.4  其他  331 21.5  结构体的嵌套  331 21.5.1  OllyDbg  332 21.6  结构体中的位操作  333 21.6.1  CPUID  333 21.6.2  用结构体构建浮点数  337 21.7  练习题  339 21.7.1  题目1  339 21.7.2  题目2  340 第22章  共用体(union)类型  345 22.1  伪随机数生成程序  345 22.1.1  x86  346 22.1.2  MIPS  347 22.1.3  ARM (ARM mode)  348 22.2  计算机器精度  349 22.2.1  x86  350 22.2.2  ARM64  350 22.2.3  MIPS  351 22.2.4  本章小结  351 第二部分  硬件基础 第23章  函数指针  352 23.1  MSVC  353 23.1.1  MSVC+OllyDbg  354 23.1.2  MSVC+tracer  355 23.1.3  MSVC + tracer (code coverage)  356 23.2  GCC  357 23.2.1  GCC + GDB (有源代码的情况)  358 23.2.2  GCC+GDB (没有源代码的情况)  359 第24章  32位系统处理64位数据  362 24.1  64位返回值  362 24.1.1  x86  362 24.1.2  ARM  362 24.1.3  MIPS  362 24.2  参数传递及加减运算  363 24.2.1  x86  363 24.2.2  ARM  365 24.2.3  MIPS  365 24.3  乘法和除法运算  366 24.3.1  x86  367 24.3.2  ARM  368 24.3.3  MIPS  369 24.4  右移  370 24.4.1  x86  370 24.4.2  ARM  371 24.4.3  MIPS  371 24.5  32位数据转换为64位数据  371 24.5.1  x86  372 24.5.2  ARM  372 24.5.3  MIPS  372 第25章  SIMD  373 25.1  并行矢量化  373 25.1.1  用于加法计算  374 25.1.2  用于内存复制  379 25.2  SIMD实现strlen()  383 第26章  64位平台  387 26.1  x86-64  387 26.2  ARM  394 26.3  浮点数  394 第27章  SIMD与浮点数的并行运算  395 27.1  样板程序  395 27.1.1  x64  395 27.1.2  x86  396 27.2  传递浮点型参数  399 27.3  浮点数之间的比较  400 27.3.1  x64  400 27.3.2  x86  401 27.4  计算机器精确度  402 27.5  伪随机数生成程序(续)  402 27.6  总结  403 第28章  ARM指令详解  404 28.1  立即数标识(#)  404 28.2  变址寻址  404 28.3  常量赋值  405 28.3.1  32位ARM  405 28.3.2  ARM64  405 28.4  重定位  406 第29章  MIPS的特点  409 29.1  加载常量  409 29.2  阅读推荐  409 第30章  有符号数的表示方法  413 第31章  字节序  414 31.1  大端字节序  414 31.2  小端字节序  414 31.3  举例说明  414 31.4  双模二元数据格式  415 31.5  转换字节序  415 第32章  内存布局  416 第33章  CPU  417 33.1  分支预测  417 33.2  数据相关性  417 第34章  哈希函数  418 34.1  单向函数与不可逆算法  418 第三部分  一些不错的例子 第35章  温度转换  421 35.1  整数值  421 35.1.1  x86构架下MSVC  2012   优化  421 35.1.2  x64构架下的MSVC  2012   优化  423 35.2  浮点数运算  423 第36章  Fibonacci数列 (斐波拉契数列)  426 36.1  例子1  426 36.2  例子2  428 36.3  总结  431 第37章  CRC32计算的例子  432 第38章  网络地址计算实例  435 38.1  计算网络地址函数 calc_network_address()  436 38.2  函数form_IP()  437 38.3  函数print_as_IP()  438 38.4  form_netmask()函数和set_bit()   函数  440 38.5  总结  440 第39章  循环:几个迭代  441 39.1  三个迭代  441 39.2  两个迭代  442 39.3  Intel C++ 2011实例  443 第40章  Duff的装置  446 第41章  除以9  449 41.1  x86  449 41.2  ARM  450 41.2.1  ARM模式下,采用Xcode 4.6.3 (LLVM)优化  450 41.2.2  Thumb-2模式下的Xcode 4.6.3   优化(LLVM)  451 41.2.3  非优化的Xcode 4.6.3(LLVM)   以及Keil 6/2013  451 41.3  MIPS  451 41.4  它是如何工作的  452 41.4.1  更多的理论  453 41.5  除法运算  453 41.5.1  变量#1  453 41.5.2  变量#2  454 41.6  练习题  455 第42章  字符串转换成数字, 函数atoi()  456 42.1  一个简单的例子  456 42.1.1  64位下的MSVC 2013优化  456 42.1.2  64位下的GCC 4.9.1优化  457 42.1.3  ARM模式下Keil 6/2013优化  457 42.1.4  Thumb模式下Keil 6/2013   优化  458 42.1.5  ARM64下的GCC 4.9.1优化  458 42.2  一个略微不错的例子  459 42.2.1  64位下的GCC 4.9.1优化  460
 
 
 
 
 
 
 
 
  42.2.2  ARM模式下的Keil6/2013   优化  461 42.3  练习  462 第43章  Inline函数(联机函数)  463 43.1  字符串和内存操作函数  464 43.1.1  字符串比较函数strcmp()  464 43.1.2  字符串长度函数strlen()  466 43.1.3  字符串复制函数strcpy()  466 43.1.4  内存设置函数memset()  467 43.1.5  内存复制函数memcpy()  468 43.1.6  内存对比函数 memcmp()  470 43.1.7  IDA脚本  471 第44章  C99限制  472 第45章  无分支函数abs()  475 45.1  x64下的GCC 4.9.1优化  475 45.2  ARM64下的GCC 4.9优化  475 第46章  参数个数可变函数  477 46.1  计算算术平均值  477 46.1.1  cdecl调用规范  477 46.1.2  基于寄存器的调用规范  478 46.2  vprintf()函数例子  480 目  录 第47章  字符串剪切  482 47.1  x64下的MSVC 2013优化  483 47.2  x64下采用编辑器GCC 4.9.1进行   非优化操作  484 47.3  x64下的GCC 4.9.1优化  485 47.4  ARM64:非优化的   GCC(Linaro)4.9  486 47.5  ARM64:优化GCC(Linaro)4.9  487 47.6  ARM: Keil 6/2013优化   (ARM模式)  488 47.7  ARM:Keil 6/2013   (Thumb模式)优化  489 47.8  MIPS  489 第48章  toupper()函数  491 48.1  x64  491 48.1.1  两个比较操作  491 48.1.2  一个比较操作  492 48.2  ARM  493 48.2.1  ARM64下的GCC  493 48.3  总结  494 第49章  不正确的反汇编代码  495 49.1  x86环境下的,从一开始错误的   反汇编  495 49.2  一些随机数,怎么看起来像   反汇编指令?  496 第50章  混淆  501 50.1  字符串  501 50.2  可执行代码  501 50.2.1  插入垃圾代码  501 50.2.2  用多个指令组合代替原来的   一个指令  502 50.2.3  始终执行或者从来不会执行的   代码  502 50.2.4  把指令序列搞乱  502 50.2.5  使用间接指针  503 50.3  虚拟机以及伪代码  503 50.4  一些其他的事情  503 50.5  练习  503 50.5.1  练习1  503 第51章  C++  504 51.1  类  504 51.1.1  一个简单的例子  504 51.1.2  类继承  510 51.1.3  封装  513 51.1.4  多重继承  515 51.1.5  虚拟方法  518 51.2  ostream流  521 51.3  引用  522 51.4  STL(standard language file system)标准   语言文件系统  522 51.4.1  std::string(字符串)  523 51.4.2  std::list函数  529 51.4.3  std::vector标准向量  539 51.4.4  std::map()和std::set()  547 第52章  数组的负数偏移  558 第53章  16位的Windows程序  561 53.1  例子#1  561 53.2  例子#2  561 53.3  例子#3  562 53.4  例子#4  563 53.5  例子#5  566 53.6  例子#6  569 53.6.1  全局变量  571 第四部分  Java 第54章  JAVA  575 54.1  简介  575 54.2  返回一个值  575 54.3  简单的计算函数  579 54.4  JVM的内存模型  582 54.5  简单的函数调用  582 54.6  调用函数beep()(蜂鸣器)  584 54.7  线性同余随机数产生器(PRNG)  584 54.8  条件跳转  586 54.9  传递参数  588 54.10  位操作  589 54.11  循环  590 54.12  开关函数switch()  592 54.13  数组  593 54.13.1  简单的例子  593 54.13.2  数组元素求和  594 54.13.3  单一变量的主函数main()依然 是一个数组  595 54.13.4  预设初始值的的数组  596 54.13.5  可变参数函数  597 54.13.6  二维数组  599 54.13.7  三维数组  600 54.13.8  小结  601 54.14  字符串  601 54.14.1  个例子  601 54.14.2  第二个例子  602 54.15  例外  603 54.16  类  606 54.17  简单的补丁  608 54.17.1  个例子  608 54.17.2  第二个例子  610 54.18  总结  612 第五部分  在代码中发现重要而有趣的内容 第55章  可执行文件的识别  615 55.1  Microsoft Visual C++  615 55.1.1  命名规则  615 55.2  GCC编译器  615 55.2.1  命名规则  615 55.2.2  Cygwin  615 55.2.3  MinGW  615 55.3  Intel FORTRAN  615 55.4  Watcom以及OpenWatcom  616 55.4.1  命名规则  616 55.5  Borland编译器  616 55.5.1  Dephi编程语言  616 55.6  其他的已知DLL文件  617 第56章  Win32环境下与外部通信  618 56.1  在Windows API中最经常使用的函数  618 56.2  tracer:解析指定模块的所有函数  618 第57章  字符串  620 57.1  字符串  620 57.1.1  C/C++中的字符串  620 57.1.2  Borland Delphi  620 57.1.3  Unicode编码  620 57.1.4  Base64  623 57.2  错误/调试信息  623 57.3  可疑的魔数字符串  623 第58章  调用宏assert() (中文称为断言)  624 第59章  常数  625 59.1  魔数  625 59.1.1  动态主机配置协议(Dynamic Host Configuration Protocol,   DHCP)  626 59.2  寻找常数  626 第60章  发现正确的指令  627 第61章  可疑的代码模型  629 61.1  XOR异或指令  629 61.2  手写汇编代码  629 第62章  在跟踪程序的过程中使用魔数  631 第63章  其他的事情  632 63.1  一般的观点  632 63.2  C++  632 63.3  一些二进制文件模型  632 63.4  内存“快照”对比  633 63.4.1  Windows注册表  633 63.4.2  瞬变比较器Blink-comparator  633 第六部分  操作系统相关 第64章  参数的传递方法(调用规范)  637 64.1  cdecl [C Declaration的缩写]  637 64.2  stdcall [Standard Call的缩写]  637 64.2.1  有可变参数个数的函数  638 64.3  fastcall  638 64.3.1  GCC regparm  639 64.3.2  Watcom/OpenWatcom  639 64.4  thiscall  639 64.5  64位下的x86  639 64.5.1  Windows x64  639 64.5.2  64位下的Linux  642 64.6  浮点数float和双精度数double两种 类型的返回值  642 64.7  修改参数  643 64.8  将指针作为一个函数的参数  643 第65章  线程本地存储TLS  646 65.1  重新审视线性同余发生器  646 65.1.1  Win32系统  646 65.1.2  Linux系统  650 第66章  系统调用(syscall-s)  652 66.1  Linux  652 66.2  Windows  653 第67章  Linux  654 67.1  与位置无关的代码  654 67.1.1  Windows  656 67.2  在Linux下的LD_PRELOAD  656 第68章  Windows NT  660 68.1  CRT (Win32)  660 68.2  Win32 PE文件  663 68.2.1  术语  664 68.2.2  基地址  664 68.2.3  子系统  664 68.2.4  操作系统版本  665 68.2.5  段  665 68.2.6  再分配Relocations(relocs)  666 68.2.7  输出和输入  666 68.2.8  资源  669 68.2.9  .NET  669 68.2.10  线程本地存储(Thread Local   Storage,TLS)  669 68.2.11  工具  669 68.2.12  更进一步  669 68.3  Windows SEH  669 68.3.1  让我们暂时把MSVC   放在一边  669 68.3.2  让我们重新回到MSVC  674 68.3.3  Windows x64  687 68.3.4  关于SEH的更多信息  691 68.4  Windows NT:关键段  691 第七部分  常用工具 第69章  反汇编工具  697 69.1  IDA  697 第70章  调试工具  698 70.1  tracer  698 70.2  OllyDbg  698 70.3  GDB  698 第71章  系统调用的跟踪工具  699 71.1  strace/dtruss  699 第72章  反编译工具  700 第73章  其他工具  701 第八部分  更多范例 第74章  修改任务管理器(Vista)  705 74.1  使用LEA指令赋值  707 第75章  修改彩球游戏  709 第76章  扫雷(Windows XP)  711 76.1  练习题  715 第77章  人工反编译与Z3 SMT   求解法  716 77.1  人工反编译  716 77.2  Z3 SMT求解法  719 第78章  加密狗  724 78.1  例1:PowerPC平台的MacOS Classic   程序  724 78.2  例2: SCO OpenServer  731 78.2.1  解密错误信息  739 78.3  例3: MS-DOS  741 第79章  “QR9”:魔方态加密模型  747 第80章  SAP  776 80.1  关闭客户端的网络数据包压缩功能  776 80.2  SAP 6.0的密码验证函数  787 第81章  Oracle RDBMS  791 81.1  V$VERSION表  791 81.2  X$KSMLRU表  799 81.3  V$TIMER表  800 第82章  汇编指令与屏显字符  805 82.1  EICAR  805 第83章  实例演示  807 83.110  PRINT CHR$(205.5+RND(1));: GOTO  10  807 83.1.1  Trixter的42字节程序  807 83.1.2  笔者对Trixter算法的改进: 27字节  808 83.1.3  从随机地址读取随机数  808 83.1.4  其他  809 83.2  曼德博集合  809 83.2.1  理论  810 83.2.2  demo程序  814 83.2.3  笔者的改进版  816 第九部分  文件分析 第84章  基于XOR的文件加密  821 84.1  Norton Guide:单字节XOR 加密实例  821 84.1.1  信息熵  822 84.2  4字节XOR加密实例  822 84.2.1  练习题  824 第85章  Millenium游戏的存档文件  825 第86章  Oracle的.SYM文件  829 第87章  Oracle的.MSDB文件  836 87.1  本章总结  839 第十部分  其他 第88章  npad  843 第89章  修改可执行文件  845 89.1  文本字符串  845 89.2  x86指令  845 第90章  编译器内部函数  846 第91章  编译器的智能短板  847 第92章  OpenMP  848 92.1  MSVC  850 92.2  GCC  852 第93章  安腾指令  854 第94章  8086的寻址方式  857 第95章  基本块重排  858 95.1  PGO的优化方式  858 第十一部分  推荐阅读 第96章  参考书籍  863 96.1  Windows  863 96.2  C/C++  863 96.3  x86/x86-64  863 96.4  ARM  863 96.5  加密学  863 第97章  博客  864 97.1  Windows平台  864 第98章  其他内容  865 第十二部分  练习题 第99章  初等难度练习  869 99.1  练习题1.4  869 00章  中等难度练习  870 100.1  练习题2.1  870 100.1.1  Optimizing MSVC 2010 x86  870 100.1.2  Optimizing MSVC 2012 x64  871 100.2  练习题2.4  871 100.2.1  Optimizing MSVC 2010  871 100.2.2  GCC 4.4.1  872 100.2.3  Optimizing Keil   (ARM mode)  873 100.2.4  Optimizing Keil   (Thumb mode)  874 100.2.5  Optimizing GCC 4.9.1   (ARM64)  874 100.2.6  Optimizing GCC 4.4.5   (MIPS)  875 100.3  练习题2.6  876 100.3.1  Optimizing MSVC 2010  876 100.3.2  Optimizing Keil   (ARM mode)  877 100.3.3  Optimizing Keil   (Thumb mode)  878 100.3.4  Optimizing GCC 4.9.1   (ARM64)  878 100.3.5  Optimizing GCC 4.4.5 (MIPS)  879 100.4  练习题2.13  879 100.4.1  Optimizing MSVC 2012  880 100.4.2  Keil(ARM mode)  880 100.4.3  Keil(Thumb mode)  880 100.4.4  Optimizing GCC 4.9.1   (ARM64)  880 100.4.5  Optimizing GCC 4.4.5   (MIPS)  881 100.5  练习题2.14  881 100.5.1  MSVC 2012  881 100.5.2  Keil(ARM mode)  882 100.5.3  GCC 4.6.3 for Raspberry Pi   (ARM mode)  882 100.5.4  Optimizing GCC 4.9.1   (ARM64)  883 100.5.5  Optimizing GCC 4.4.5   (MIPS)  884 100.6  练习题2.15  885 100.6.1  Optimizing MSVC 2012 x64  886 100.6.2  Optimizing GCC 4.4.6 x64  888 100.6.3  Optimizing GCC 4.8.1 x86  889 100.6.4  Keil(ARM模式):面向   Cortex-R4F CPU的代码  890 100.6.5  Optimizing GCC 4.9.1   (ARM64)  891 100.6.6  Optimizing GCC 4.4.5   (MIPS)  892 100.7  练习题2.16  893 100.7.1  Optimizing MSVC 2012 x64  893 100.7.2  Optimizing Keil   (ARM mode)  893 100.7.3  Optimizing Keil   (Thumb mode)  894 100.7.4  Non-optimizing GCC 4.9.1   (ARM64)  894 100.7.5  Optimizing GCC 4.9.1   (ARM64)  895 100.7.6  Non-optimizing GCC   4.4.5(MIPS)  898 100.8  练习题2.17  899 100.9  练习题2.18  899 100.10  练习题2.19  899 100.11  练习题2.20  899 01章  高难度练习  900 101.1  练习题3.2  900 101.2  练习题3.3  900 101.3  练习题3.4  900 101.4  练习题3.5  900 101.5  练习题3.6  901 101.6  练习题3.8  901 02章  Crackme/Keygenme  902 附录A  x86  903 A.1  数据类型  903 A.2  通用寄存器  903 A.2.1  RAX/EAX/AX/AL  903 A.2.2  RBX/EBX/BX/BL  904 A.2.3  RCX/ECX/CX/CL  904 A.2.4  RDX/EDX/DX/DL  904 A.2.5  RSI/ESI/SI/SIL  904 A.2.6  RDI/EDI/DI/DIL  904 A.2.7  R8/R8D/R8W/R8L  905 A.2.8  R9/R9D/R9W/R9L  905 A.2.9  R10/R10D/R10W/R10L  905 A.2.10  R11/R11D/R11W/R11L  905 A.2.11  R12/R12D/R12W/R12L  905 A.2.12  R13/R13D/R13W/R13L  905 A.2.13  R14/R14D/R14W/R14L  906 A.2.14  R15/R15D/R15W/R15L  906 A.2.15  RSP/ESP/SP/SPL  906 A.2.16  RBP/EBP/BP/BPL  906 A.2.17  RIP/EIP/IP  906 A.2.18  段地址寄存器   CS/DS/ES/SS/FS/GS  907 A.2.19  标识寄存器  907 A.3  FPU寄存器  907 A.3.1  控制字寄存器(16位)  908 A.3.2  状态字寄存器(16位)  908 A.3.3  标记字寄存器(16位)  909 A.4  SIMD寄存器  909 A.4.1  MMX寄存器  909 A.4.2  SSE与AVX寄存器  909 A.5  FPU调试寄存器  909 A.5.1  DR6规格  910 A.5.2  DR7规格  910 A.6  指令  911 A.6.1  指令前缀  911 A.6.2  常见指令  911 A.6.3  不常用的汇编指令  916 A.6.4  FPU指令  921 A.6.5  可屏显的汇编指令(32位)  922 附录B  ARM  925 B.1  术语  925 B.2  版本差异  925 B.3  32位ARM(AArch32)  925 B.3.1  通用寄存器  925 B.3.2  程序状态寄存器/CPSR  925 B.3.3  VFP(浮点)和NEON寄存器  926 B.4  64位ARM(AArch64)  926 B.4.1  通用寄存器  926 B.5  指令  927 B.5.1  Conditional codes速查表  927 附录C  MIPS  928 C.1  寄存器  928 C.1.1  通用寄存器GPR  928 C.1.2  浮点寄存器FPR  928 C.2  指令  928 C.2.1  转移指令  929 附录D  部分GCC库函数  930 附录E  部分MSVC库函数  931 附录E  部分MSVC库函数  931 附录G  练习题答案  935 G.1  各章练习  935
 
  G.1.1  “栈”  935 G.1.2  “switch()/case/default”语句  935 G.1.3  练习题#1  935 G.1.4  “Loop”语句  935 G.1.5  练习题#3  935 G.1.6  练习题#4  935 G.1.7  C语言字符串处理练习题  936 G.1.8  算术指令替代  936 G.1.9  FPU练习题  936 G.1.10  数组练习题  936 G.1.11  位操作练习题  937 G.1.12  结构体练习题  939 G.1.13  混淆技术练习题  940 G.1.14  除9练习题  940 G.2  初级练习题  940 G.2.1  练习题1.1  940 G.2.2  练习题1.4  940 G.3  中级练习题  941 G.3.1  练习题2.1  941 G.3.2  练习题2.4  941 G.3.3  练习题2.6  942 G.3.4  练习题2.13  942 G.3.5  练习题2.14  943 G.3.6  练习题2.15  943 G.3.7  练习题2.16  943 G.3.8  练习题2.17  943 G.3.9  练习题2.18  943 G.3.10  练习题2.19  943 G.3.11  练习题2.20  943 G.4  高难度练习题  943 G.4.1  练习题3.2  943 G.4.2  练习题3.3  943 G.4.3  练习题3.4  944 G.4.4  练习题3.5  944 G.4.5  练习题3.6  944 G.4.6  练习题3.8  944 G.5  其他练习题  944 G.5.1  “扫雷(Windows XP)”  944 参考文献  947  |