堆缓冲区溢出 - AddressSanitizer 输出 - 利用这种情况需要什么?

信息安全 开发 开发开发
2021-08-29 17:59:15

这是 AddressSanitizer 输出,对于不同的输入,我会收到 READ 和 WRITE 错误。从 Heap Buffer Overflow 的角度来看,哪个更有趣?我想执行我的shellcode。有人可以以更“人性化”的方式解释这个 AndressSanitizer 输出吗?

阅读示例:

==24222== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000010000 at pc 0x4022bd bp 0x7fff9b142e90 sp 0x7fff9b142e88
READ of size 1 at 0x602000010000 thread T0
    #0 0x4022bc (/home/user/final/apngdis-2.5.orig/apngdis+0x4022bc)
    #1 0x40619a (/home/user/final/apngdis-2.5.orig/apngdis+0x40619a)
    #2 0x4012cd (/home/user/final/apngdis-2.5.orig/apngdis+0x4012cd)
    #3 0x7f677aadfec4 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21ec4)
    #4 0x401734 (/home/user/final/apngdis-2.5.orig/apngdis+0x401734)
0x602000010000 is located 0 bytes to the right of 192-byte region [0x60200000ff40,0x602000010000)
allocated by thread T0 here:
    #0 0x7f677b0b141a (/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0+0x1541a)
    #1 0x4059bb (/home/user/final/apngdis-2.5.orig/apngdis+0x4059bb)
Shadow bytes around the buggy address:
  0x0c047fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9fe0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c047fff9ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fffa000:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==24222== ABORTING

下面是 GDB 输出

这个堆溢出可以利用吗?我应该在代码中寻找什么?你能举一些代码片段的例子吗?

Starting program: /home/user/final/apngdis-2.5.orig/apngdis crash.png

APNG Disassembler 2.5

Reading 'crash.png'...

Breakpoint 2, unpack (zstream=..., dst=dst@entry=0x6e1910 "", dst_size=dst_size@entry=192, src=src@entry=0x6e19e0 "x\332b\356\317\300", src_size=src_size@entry=14, h=2147483651, 
    rowbytes=rowbytes@entry=63, bpp=1 '\001') at apngdis.c:171
171 {
(gdb) 
(gdb) 
(gdb) l
166       row[i] += row[i-bpp];
167   }
168 }
169 
170 void unpack(z_stream zstream, unsigned char * dst, unsigned int dst_size, unsigned char * src, unsigned int src_size, unsigned int h, unsigned int rowbytes, unsigned char bpp)
171 {
172   unsigned int    j;
173   unsigned char * row = dst;
174   unsigned char * prev_row = NULL;
175 
(gdb) l
176   zstream.next_out  = dst;
177   zstream.avail_out = dst_size;
178   zstream.next_in   = src;
179   zstream.avail_in  = src_size;
180   inflate(&zstream, Z_FINISH);
181   inflateReset(&zstream);
182 
183   for (j=0; j<h; j++)
184   {
185     switch (*row++) 
(gdb) l
186     {
187       case 0: break;
188       case 1: read_sub_row(row, rowbytes, bpp); break;
189       case 2: read_up_row(row, prev_row, rowbytes, bpp); break;
190       case 3: read_average_row(row, prev_row, rowbytes, bpp); break;
191       case 4: read_paeth_row(row, prev_row, rowbytes, bpp); break;
192     }
193     prev_row = row;
194     row += rowbytes;
195   }
(gdb) cont
Continuing.

Program received signal SIGSEGV, Segmentation fault.
unpack (zstream=..., dst=dst@entry=0x6e1910 "\003\217\257\277\307\313\315\316", '\317' <repeats 17 times>, "ϗ{mfca```\200\220H$\022\t\004\002\001", dst_size=dst_size@entry=192, 
    src=src@entry=0x6e19e0 "x\332b\356\317\300", src_size=src_size@entry=14, h=2147483651, rowbytes=rowbytes@entry=63, bpp=1 '\001') at apngdis.c:185
185     switch (*row++) 
(gdb) 

这里有符号:

root@user-lap:~/final/apngdis-2.5.orig# export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.4 
root@user-lap:~/final/apngdis-2.5.orig# ASAN_OPTIONS=symbolize=1 ./apngdis crash.png 

APNG Disassembler 2.5

Reading 'crash.png'...
=================================================================
==25265== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000010000 at pc 0x41c07d bp 0x7ffc560b3f20 sp 0x7ffc560b3f18
READ of size 1 at 0x602000010000 thread T0
    #0 0x41c07c in unpack /home/user/final/apngdis-2.5.orig/apngdis.c:185
    #1 0x41ff5a in LoadAPNG /home/user/final/apngdis-2.5.orig/apngdis.c:846
    #2 0x40281d in main /home/user/final/apngdis-2.5.orig/apngdis.c:1208
    #3 0x7fb4ca7e4ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #4 0x402c84 in _start (/home/user/final/apngdis-2.5.orig/apngdis+0x402c84)
0x602000010000 is located 0 bytes to the right of 192-byte region [0x60200000ff40,0x602000010000)
allocated by thread T0 here:
    #0 0x412c0a in __interceptor_malloc (/home/user/final/apngdis-2.5.orig/apngdis+0x412c0a)
    #1 0x41f77b in LoadAPNG /home/user/final/apngdis-2.5.orig/apngdis.c:635
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/final/apngdis-2.5.orig/apngdis.c:185 unpack
Shadow bytes around the buggy address:
  0x0c047fff9fb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9fe0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c047fff9ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fffa000:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffa050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==25265== ABORTING

最后,但并非最不重要的是,一个关于 Linux 下堆缓冲区溢出的好教程的链接非常棒!

这是相关程序的完整代码:

http://pastebin.com/qu6BRtJa

更新 29.02.2016

找到了 4 个字节的写入。LoadAPNG 中似乎有一个具有用户控制值的 malloc 调用。可以使用“力量之屋”的技术吗?

==2720== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60ae0003a81c at pc 0x41ee70 bp 0x7ffc84d157d0 sp 0x7ffc84d157c8
WRITE of size 4 at 0x60ae0003a81c thread T0
    #0 0x41ee6f in compose6 /home/user/final/apngdis-2.5.orig/apngdis.c:475
    #1 0x420025 in LoadAPNG /home/user/final/apngdis-2.5.orig/apngdis.c:853
    #2 0x40281d in main /home/user/final/apngdis-2.5.orig/apngdis.c:1208
    #3 0x7f4942135ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #4 0x402c84 in _start (/home/user/final/apngdis-2.5.orig/apngdis+0x402c84)
0x60ae0003a81c is located 0 bytes to the right of 114716-byte region [0x60ae0001e800,0x60ae0003a81c)
allocated by thread T0 here:
    #0 0x412c0a in __interceptor_malloc (/home/user/final/apngdis-2.5.orig/apngdis+0x412c0a)
    #1 0x41f746 in LoadAPNG /home/user/final/apngdis-2.5.orig/apngdis.c:633
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/final/apngdis-2.5.orig/apngdis.c:474 compose6
Shadow bytes around the buggy address:
  0x0c163ffff4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c163ffff4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c163ffff4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c163ffff4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c163ffff4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c163ffff500: 00 00 00[04]fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c163ffff510: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c163ffff520: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c163ffff530: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c163ffff540: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c163ffff550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==2720== ABORTING

更新 07.02.2017

根据@grepNstepN 的要求

root@laptop:~/security/apngfuzz/apngdis-2.5.orig# gdb ./apngdis crash/crash.png
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./apngdis...done.
"/home/user/security/apngfuzz/apngdis-2.5.orig/crash/crash.png" is not a core dump: File format not recognized
(gdb) r crash/crash.png
Starting program: /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis crash/crash.png
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

APNG Disassembler 2.5

Reading 'crash/crash.png'...
=================================================================
==14864==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ef91 at pc 0x00000040b1b4 bp 0x7fffffffd9b0 sp 0x7fffffffd9a0
READ of size 1 at 0x60200000ef91 thread T0
    #0 0x40b1b3 in compose6 /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis.c:469
    #1 0x40ca5f in LoadAPNG /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis.c:850
    #2 0x4017be in main /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis.c:1202
    #3 0x7ffff68a782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #4 0x402048 in _start (/home/user/security/apngfuzz/apngdis-2.5.orig/apngdis+0x402048)

0x60200000ef91 is located 0 bytes to the right of 1-byte region [0x60200000ef90,0x60200000ef91)
allocated by thread T0 here:
    #0 0x7ffff6f02602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0x40bb97 in LoadAPNG /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis.c:632

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis.c:469 compose6
Shadow bytes around the buggy address:
  0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00 06
=>0x0c047fff9df0: fa fa[01]fa fa fa 04 fa fa fa 01 fa fa fa 01 fa
  0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==14864==ABORTING
[Inferior 1 (process 14864) exited with code 01]
(gdb) disass crash/crash.pngQuit
(gdb) dis
disable      disassemble  disconnect   display      
(gdb) disass 0x40b1b3
Dump of assembler code for function compose6:
   0x000000000040a990 <+0>: lea    -0x98(%rsp),%rsp
   0x000000000040a998 <+8>: mov    %rdx,(%rsp)
   0x000000000040a99c <+12>:    mov    %rcx,0x8(%rsp)
   0x000000000040a9a1 <+17>:    mov    %rax,0x10(%rsp)
   0x000000000040a9a6 <+22>:    mov    $0xbb3f,%rcx
   0x000000000040a9ad <+29>:    callq  0x4112e0 <__afl_maybe_log>
   0x000000000040a9b2 <+34>:    mov    0x10(%rsp),%rax
   0x000000000040a9b7 <+39>:    mov    0x8(%rsp),%rcx
   0x000000000040a9bc <+44>:    mov    (%rsp),%rdx
   0x000000000040a9c0 <+48>:    lea    0x98(%rsp),%rsp
   0x000000000040a9c8 <+56>:    push   %r15
   0x000000000040a9ca <+58>:    push   %r14
   0x000000000040a9cc <+60>:    push   %r13
   0x000000000040a9ce <+62>:    push   %r12
   0x000000000040a9d0 <+64>:    push   %rbp
   0x000000000040a9d1 <+65>:    push   %rbx
   0x000000000040a9d2 <+66>:    sub    $0x48,%rsp
   0x000000000040a9d6 <+70>:    movzbl 0x88(%rsp),%r13d
   0x000000000040a9df <+79>:    mov    %rdi,0x18(%rsp)
   0x000000000040a9e4 <+84>:    mov    %r8d,0x28(%rsp)
   0x000000000040a9e9 <+89>:    mov    %r9d,0x2c(%rsp)
   0x000000000040a9ee <+94>:    add    $0x7,%r13d
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
The program has no registers now.
(gdb) b *0x40b1b3
Breakpoint 1 at 0x40b1b3: file apngdis.c, line 469.
(gdb) r crash/crash.png
Starting program: /home/user/security/apngfuzz/apngdis-2.5.orig/apngdis crash/crash.png
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

APNG Disassembler 2.5

Reading 'crash/crash.png'...

Program received signal SIGSEGV, Segmentation fault.
0xffffffffcd4013e0 in ?? ()

(gdb) i r
rax            0x1  1
rbx            0x1  1
rcx            0x60210000efd0   105694850248656
rdx            0xc0400001df2    13211319410162
rsi            0x60200000ef92   105690555281298
rdi            0x60200000ef91   105690555281297
rbp            0x2  0x2
rsp            0x7fffffffd9b8   0x7fffffffd9b8
r8             0x0  0
r9             0x1  1
r10            0x60200000eff0   105690555281392
r11            0x60200000ef91   105690555281297
r12            0x40000000   1073741824
r13            0x1  1
r14            0x1  1
r15            0x4  4
rip            0xffffffffcd4013e0   0xffffffffcd4013e0
eflags         0x10202  [ IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
---Type <return> to continue, or q <return> to quit---
gs             0x0  0

(gdb) info registers rip
rip            0xffffffffcd4013e0   0xffffffffcd4013e0
2个回答

我了解您来自哪里,我对各种产品(chrome、flash 等)进行了模糊测试。您要做的最后一件事是放弃可能的赏金或建议(我支持前者多于后者 尤其 考虑 发生在 Aaron Schwartz 身上的事情)。

想一想:在这种情况下 apngdis 可能会在libpng中产生一个可能的解析器或文件格式漏洞,Chrome、Firefox、Webkit(iOS、OSX)等都在使用该漏洞。前面提到的都有漏洞奖励。至少,谷歌为保护开源项目提供了赏金我不知道 apngdis 是否直接用于任何产品。

考虑到上述情况,如果您需要帮助,您可以按照我过去对我发现的几个漏洞所做的操作:

  1. 向名声太大的人寻求帮助以窃取您的赏金/建议(我想到了#corelan/Peter Van Eekhoutte),但在建议中大喊大叫/感谢...好奇心/挑战/成名/利他主义很棒激励者
  2. 请某人签署 NDA 以确保不会发生盗窃。然而,作为回报,您必须提供一部分赏金/荣耀(在咨询中大喊大叫,甚至是共同作者)
  3. 查看以前的教程并利用文章,寻找相似之处
  4. 在 stackexchange 上寻求帮助,不提供任何回报,这是相当不尊重的。至少如果它是公开披露,请感谢任何提供帮助的人......这是你看不到更多人在 stackexchange 上寻求开发帮助的原因。

如果您选择 #4,我们将需要您提供以下信息:

我们需要对 [apngdis+0x4022bc] 处的读取、前一条指令和调用堆栈进行反汇编。写入也是如此(RIP 的反汇编、RIP-1 指令、调用堆栈)

考虑一下:如果没有上述内容,解释 ASan 输出不一定会帮助您提高可利用性。例如:

==24222== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000010000 at pc 0x4022bd bp 0x7fff9b142e90 sp 0x7fff9b142e88
READ of size 1 at 0x602000010000 thread T0
#0 0x4022bc (/home/user/final/apngdis-2.5.orig/apngdis+0x4022bc)
...

CVE-2017-6193已被保留用于此特定漏洞(存在于版本 2.8 中)。 您的名字已被列为发现者和共同贡献者。

明天这篇文章将在线一年,在撰写本文时已被浏览近 2000 次。因此,为了防止任何人滥用它,并且看到细节仍然是公开的,我希望你不介意我冒昧地在 afl-fuzz 集群中运行 apngdis 来重建问题以进行报告。

在重新发现这些内存损坏中,块大小描述符中也有一个,更不用说处理文件名参数时的教科书溢出了。

我调试了问题并通知了开发人员。在解释了背后发生的情况的严重性之后,他反应非常迅速,现在已经足够好心地开发 2.9 版本了。

compose_frame 函数中的内存损坏在最新版本 2.8 中仍然存在,并且很容易解释。memcpy() 在一些限制内被攻击者提供长度的一堆零调用。

首先,在确保它实际上是一个 PNG 和一个 IHDR 大小字段之后,从文件中加载该值:

    w0 = w = png_get_uint_32(chunkIHDR.p + 8);
    h0 = h = png_get_uint_32(chunkIHDR.p + 12);

然后在检查值小于const unsigned long cMaxPNGSize = 1000000UL;之后,将调用以下命令:

compose_frame(frameCur.rows, frameRaw.rows, bop, x0, y0, w0, h0);

其中包括:

void compose_frame(unsigned char ** rows_dst, unsigned char ** rows_src, unsigned char bop, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
{
  unsigned int  i, j;
  int u, v, al;

  for (j=0; j<h; j++)
  {
    unsigned char * sp = rows_src[j];
    unsigned char * dp = rows_dst[j+y] + x*4;

    if (bop == 0)
      memcpy(dp, sp, w*4);

Memcpy 被调用并愉快地开始复制几百万个零,然后运行到未映射的内存中。:

Breakpoint 1, compose_frame (rows_dst=0x7fffef54f010, rows_src=0x7ffff3150010, bop=0 '\000', x=0, y=0, w=983040, h=983040) at apngdis.cpp:77
77          if (bop == 0)
(gdb) n
78            memcpy(dp, sp, w*4);
(gdb) print dp
$1 = (unsigned char *) 0x55555576f910 ""
(gdb) print sp
$2 = (unsigned char *) 0x55555576f2a0 ""
(gdb) print w

在 Windows x86 上,它编译为以下程序集,我们可以看到从 ESI 到 EDI 的复制:

.text:011FFA90 loc_11FFA90: ; CODE XREF: .text:011FFAEBj .text:011FFA90 movdqa xmm0, oword ptr [esi] .text:011FFA94 movdqa xmm1, oword ptr [esi+10h] .text:011FFA99 movdqa xmm2, oword ptr [esi+20h] .text:011FFA9E movdqa xmm3, oword ptr [esi+30h] .text:011FFAA3 movdqa oword ptr [edi], xmm0 .text:011FFAA7 movdqa oword ptr [edi+10h], xmm1 .text:011FFAAC movdqa oword ptr [edi+20h], xmm2 .text:011FFAB1 movdqa oword ptr [edi+30h], xmm3 .text:011FFAB6 movdqa xmm4, oword ptr [esi+40h] .text:011FFABB movdqa xmm5, oword ptr [esi+50h] .text:011FFAC0 movdqa xmm6, oword ptr [esi+60h] .text:011FFAC5 movdqa xmm7, oword ptr [esi+70h] .text:011FFACA movdqa oword ptr [edi+40h], xmm4 .text:011FFACF movdqa oword ptr [edi+50h], xmm5 .text:011FFAD4 movdqa oword ptr [edi+60h], xmm6 .text:011FFAD9 movdqa oword ptr [edi+70h], xmm7 .text:011FFADE lea esi, [esi+80h] .text:011FFAE4 lea edi, [edi+80h] .text:011FFAEA dec edx .text:011FFAEB jnz short loc_11FFA90