【发布时间】:2013-11-16 02:16:46
【问题描述】:
我有一个小型测试应用程序(我们称之为test.c)和一个小型共享库代码(我们称之为plugin.c)。
测试应用使用$(CC) -o $@ $^ -g -Wall -std=gnu99 -ldl -lcrypto -Wl,--export-dynamic编译,而共享库代码使用$(CC) -c $< -o $@ -pedantic -g -Wall -std=gnu99 -fpic -I.编译。
测试代码dlopens 共享库,然后调用void plugin_test(<ptr_to_function> f) 函数。函数plugin_test 接收一个指向函数(称为f)的指针,该函数将malloc 几个字节然后返回为unsigned char *。
所以,一般来说,它看起来是这样的:
- 运行
test -
test加载plugin。 -
test运行plugin_test函数。 -
plugin_test函数运行f内部test -
fmalloc 几个字节并返回它们。 -
plugin_test保存f在unsigned char *中返回的内容
我的问题是:如果我从 plugin_test 内部调用它,free(returned_pointer_from_f_function) 应该可以工作吗?
由于该指令,我遇到了崩溃(段错误)。 我注意到(来自 gdb bt full)似乎存在某种指针不匹配。
这是回溯:
*** Error in `./test': free(): invalid pointer: 0x0000000000d10066 ***
======= Backtrace: =========
/usr/lib/libc.so.6(+0x72e5f)[0x7f2637464e5f]
/usr/lib/libc.so.6(+0x7862e)[0x7f263746a62e]
/usr/lib/libc.so.6(+0x79307)[0x7f263746b307]
./plugins/tt.so(match+0x275)[0x7f2636fdac6d]
./test(main+0x515)[0x401b2c]
/usr/lib/libc.so.6(__libc_start_main+0xf5)[0x7f2637413bc5]
./test[0x4012c9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:11 24641553 /home/alexandernst/Proyectos/mem_dumper/test
00602000-00603000 rw-p 00002000 08:11 24641553 /home/alexandernst/Proyectos/mem_dumper/test
00d10000-01539000 rw-p 00000000 00:00 0 [heap]
7f2636dc4000-7f2636dd9000 r-xp 00000000 08:02 1489785 /usr/lib/libgcc_s.so.1
7f2636dd9000-7f2636fd9000 ---p 00015000 08:02 1489785 /usr/lib/libgcc_s.so.1
7f2636fd9000-7f2636fda000 rw-p 00015000 08:02 1489785 /usr/lib/libgcc_s.so.1
7f2636fda000-7f2636fdb000 r-xp 00000000 08:11 24641572 /home/alexandernst/Proyectos/mem_dumper/plugins/tt.so
7f2636fdb000-7f26371db000 ---p 00001000 08:11 24641572 /home/alexandernst/Proyectos/mem_dumper/plugins/tt.so
7f26371db000-7f26371dc000 rw-p 00001000 08:11 24641572 /home/alexandernst/Proyectos/mem_dumper/plugins/tt.so
7f26371dc000-7f26371f1000 r-xp 00000000 08:02 1448187 /usr/lib/libz.so.1.2.8
7f26371f1000-7f26373f0000 ---p 00015000 08:02 1448187 /usr/lib/libz.so.1.2.8
7f26373f0000-7f26373f1000 r--p 00014000 08:02 1448187 /usr/lib/libz.so.1.2.8
7f26373f1000-7f26373f2000 rw-p 00015000 08:02 1448187 /usr/lib/libz.so.1.2.8
7f26373f2000-7f2637594000 r-xp 00000000 08:02 1445202 /usr/lib/libc-2.18.so
7f2637594000-7f2637793000 ---p 001a2000 08:02 1445202 /usr/lib/libc-2.18.so
7f2637793000-7f2637797000 r--p 001a1000 08:02 1445202 /usr/lib/libc-2.18.so
7f2637797000-7f2637799000 rw-p 001a5000 08:02 1445202 /usr/lib/libc-2.18.so
7f2637799000-7f263779d000 rw-p 00000000 00:00 0
7f263779d000-7f263797c000 r-xp 00000000 08:02 1453900 /usr/lib/libcrypto.so.1.0.0
7f263797c000-7f2637b7b000 ---p 001df000 08:02 1453900 /usr/lib/libcrypto.so.1.0.0
7f2637b7b000-7f2637b96000 r--p 001de000 08:02 1453900 /usr/lib/libcrypto.so.1.0.0
7f2637b96000-7f2637ba1000 rw-p 001f9000 08:02 1453900 /usr/lib/libcrypto.so.1.0.0
7f2637ba1000-7f2637ba5000 rw-p 00000000 00:00 0
7f2637ba5000-7f2637ba8000 r-xp 00000000 08:02 1445237 /usr/lib/libdl-2.18.so
7f2637ba8000-7f2637da7000 ---p 00003000 08:02 1445237 /usr/lib/libdl-2.18.so
7f2637da7000-7f2637da8000 r--p 00002000 08:02 1445237 /usr/lib/libdl-2.18.so
7f2637da8000-7f2637da9000 rw-p 00003000 08:02 1445237 /usr/lib/libdl-2.18.so
7f2637da9000-7f2637dc9000 r-xp 00000000 08:02 1445178 /usr/lib/ld-2.18.so
7f2637f8a000-7f2637f8f000 rw-p 00000000 00:00 0
7f2637fc5000-7f2637fc8000 rw-p 00000000 00:00 0
7f2637fc8000-7f2637fc9000 r--p 0001f000 08:02 1445178 /usr/lib/ld-2.18.so
7f2637fc9000-7f2637fca000 rw-p 00020000 08:02 1445178 /usr/lib/ld-2.18.so
7f2637fca000-7f2637fcb000 rw-p 00000000 00:00 0
7fffd30f9000-7fffd311a000 rw-p 00000000 00:00 0 [stack]
7fffd31fe000-7fffd3200000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted (core dumped)
[alexandernst@stupidbox mem_dumper]# gdb ./test core.30740
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 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-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/alexandernst/Proyectos/mem_dumper/test...(no debugging symbols found)...done.
[New LWP 30740]
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7fffd31fe000
Core was generated by `./test 29882'.
Program terminated with signal 6, Aborted.
#0 0x00007f26374273d9 in raise () from /usr/lib/libc.so.6
(gdb) bt full
#0 0x00007f26374273d9 in raise () from /usr/lib/libc.so.6
No symbol table info available.
#1 0x00007f26374287d8 in abort () from /usr/lib/libc.so.6
No symbol table info available.
#2 0x00007f2637464e64 in __libc_message () from /usr/lib/libc.so.6
No symbol table info available.
#3 0x00007f263746a62e in malloc_printerr () from /usr/lib/libc.so.6
No symbol table info available.
#4 0x00007f263746b307 in _int_free () from /usr/lib/libc.so.6
No symbol table info available.
#5 0x00007f2636fdac6d in match (mem_buf=0xd186f0 "@\020\206\377M\177", mem_size=1048576) at plugins/tt.c:82
hash = 0xd10280 "/usr/lib/libgcc_s.so.1"
str_hash = 0xd10066 ""
fname = "./dumps/94a92daf9555939d14300d68e1f69392-1384545306-936816-4"
i = 936816
size = 0xd10280 "/usr/lib/libgcc_s.so.1"
fcontent = 0xd102a0 "P", <incomplete sequence \321>
fsize = 48
#6 0x0000000000401b2c in main ()
No symbol table info available.
注意第 1 行的方向和第 81 行的方向。
编辑:这是我的代码:
内部test
unsigned char *hash_to_str(unsigned char *mem_hash){
int i;
unsigned char *hash;
hash = malloc(MD5_DIGEST_LENGTH * 2);
for(i = 0; i < MD5_DIGEST_LENGTH; i++)
sprintf(&hash[i*2], "%02x", mem_hash[i]);
return hash;
}
现场plugin
unsigned char *str_hash = _->hash_to_str(hash);
printf("%s\n", str_hash);
free(str_hash);
编辑:
按照建议修复 snprintf 的+1 字节后,bt 已满:
(gdb) bt full
#0 0x00007fe04b266024 in free () from /usr/lib/libc.so.6
No symbol table info available.
#1 0x00007fe04add2c6d in match (mem_buf=0x7fe04a2f1010 "", mem_size=11403264) at plugins/tt.c:82
hash = 0x25ca280 ""
str_hash = 0x6677732e31 <Address 0x6677732e31 out of bounds>
fname = "./dumps/ee0c6f3d65d31c4af6db76a47e28aff2-1384569665-9257680-"
i = 9257680
size = 0x25ca280 ""
fcontent = 0x25d26f0 "FWS", <incomplete sequence \353\234>
fsize = 40171
#2 0x0000000000401b2c in main ()
编辑:我不知道这是否有关系,但我正在运行 test 和 sudo,因为我需要 ptrace(PTRACE_ATTACH...)。
【问题讨论】:
-
在 tt.c 第 82 行从 match() 内部传递给 free 的 ptr 可能不是来自 malloc。是否在“插件”中进行了 malloc 处理并不重要。
-
指针
0x0000000000d10066的值表明(至少对我而言)它是一个自动变量地址(或根本不是地址)。要么,要么你有我见过的最奇怪的动态内存管理器,因为它显然不是一个对齐的值(只有底部是清晰的) -
你能检查我的编辑吗?
-
你在这上面运行过 valgrind 吗?
-
@CharlieBurns 不,还没有。我应该寻找什么?内存泄漏?