堆栈粉碎和sscanf

时间:2011-09-15 19:10:46

标签: c scanf stack-smash

replyS|[2 3 4 5 6 7 8 9]|[2 3 4 5 6 7 8 9]

char com[10], f[100], s[100];
sscanf(reply, "%[^!]|%[^!]|%[^!]", com, f, s);

它导致堆栈粉碎。我知道sscanf通常是不安全的,但我想知道为什么它在这里失败 - 输入字符串很好。

这是输出:

  

*检测到堆栈粉碎* :./ testClient已终止   ======= Backtrace:=========   /lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x50)[0x1f5df0]   /lib/i386-linux-gnu/libc.so.6(+0xe5d9a)[0x1f5d9a]   ./testClient[0x804b336]   /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x126e37]   ./testClient[0x804add1]

     

=======记忆地图:======== 00110000-0026a000 r-xp 00000000 08:01   523281 /lib/i386-linux-gnu/libc-2.13.so 0026a000-0026b000 --- p   0015a000 08:01 523281 /lib/i386-linux-gnu/libc-2.13.so   0026b000-0026d000 r - p 0015a000 08:01 523281
  /lib/i386-linux-gnu/libc-2.13.so 0026d000-0026e000 rw-p 0015c000 08:01   523281 /lib/i386-linux-gnu/libc-2.13.so 0026e000-00271000 rw-p   00000000 00:00 0 00271000-00286000 r-xp 00000000 08:01 523299
  /lib/i386-linux-gnu/libpthread-2.13.so 00286000-00287000 r - p 00015000   08:01 523299 /lib/i386-linux-gnu/libpthread-2.13.so   00287000-00288000 rw-p 00016000 08:01 523299
  /lib/i386-linux-gnu/libpthread-2.13.so 00288000-0028a000 rw-p 00000000   00:00 0 003e8000-00404000 r-xp 00000000 08:01 523304
  /lib/i386-linux-gnu/ld-2.13.so 00404000-00405000 r - p 0001b000 08:01   523304 /lib/i386-linux-gnu/ld-2.13.so 00405000-00406000 rw-p   0001c000 08:01 523304 /lib/i386-linux-gnu/ld-2.13.so   004c9000-004d0000 r-xp 00000000 08:01 523283
  /lib/i386-linux-gnu/librt-2.13.so 004d0000-004d1000 r - p 00006000   08:01 523283 /lib/i386-linux-gnu/librt-2.13.so 004d1000-004d2000   rw-p 00007000 08:01 523283 /lib/i386-linux-gnu/librt-2.13.so   0053f000-00540000 r-xp 00000000 00:00 0 [vdso]   007c9000-007ed000 r-xp 00000000 08:01 523303
  /lib/i386-linux-gnu/libm-2.13.so 007ed000-007ee000 r - p 00023000 08:01   523303 /lib/i386-linux-gnu/libm-2.13.so 007ee000-007ef000 rw-p   00024000 08:01 523303 /lib/i386-linux-gnu/libm-2.13.so   00cee000-00dcd000 r-xp 00000000 08:01 1051412
  /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14 00dcd000-00dd1000 r - p   000de000 08:01 1051412 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14   00dd1000-00dd2000 rw-p 000e2000 08:01 1051412
  /usr/lib/i386-linux-gnu/libstdc++.so.6.0.14 00dd2000-00dd9000 rw-p   00000000 00:00 0 00e51000-00e53000 r-xp 00000000 08:01 1070941
  /usr/lib/libboost_system.so.1.46.1 00e53000-00e54000 r - p 00002000   08:01 1070941 /usr/lib/libboost_system.so.1.46.1 00e54000-00e55000   rw-p 00003000 08:01 1070941 /usr/lib/libboost_system.so.1.46.1   00e9c000-00eb6000 r-xp 00000000 08:01 523308
  /lib/i386-linux-gnu/libgcc_s.so.1 00eb6000-00eb7000 r - p 00019000   08:01 523308 /lib/i386-linux-gnu/libgcc_s.so.1 00eb7000-00eb8000   rw-p 0001a000 08:01 523308 /lib/i386-linux-gnu/libgcc_s.so.1   08048000-08067000 r-xp 00000000 08:01 1591111
  / home / alex / pj / cpp / testClient / bin / Debug / testClient 08067000-08068000   r - p 0001e000 08:01 1591111
  / home / alex / pj / cpp / testClient / bin / Debug / testClient 08068000-08069000   rw-p 0001f000 08:01 1591111
  / home / alex / pj / cpp / testClient / bin / Debug / testClient 09050000-09071000   rw-p 00000000 00:00 0 [堆] b78d9000-b78dd000 rw-p 00000000   00:00 0 b78ef000-b78f2000 rw-p 00000000 00:00 0 bfba9000-bfbca000   rw-p 00000000 00:00 0 [stack]

1 个答案:

答案 0 :(得分:3)

一个问题是,您的数据中的字符串分隔了|个字符,但sscanf()格式会查找字符类[^!](除感叹号外的所有字符串)。您还应该为字符类指定缓冲区的大小,并检查返回值:

char com[10], f[100], s[100];
if (sscanf(reply, "%9[^|]|%99[^|]|%99[^|]", com, f, s) != 3)
    ...format error...

注意使用9和99;您必须为终端指定留出空间的大小。