释放由另一个二进制文件分配的内存

时间:2013-11-16 02:16:46

标签: c pointers malloc free

我有一个小型测试应用程序(我们称之为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.进行编译。

测试代码dlopen是共享库,然后调用void plugin_test(<ptr_to_function> f)函数。函数plugin_test接收一个指向函数(称为f)的指针,该函数将malloc几个字节,然后返回unsigned char *

所以,一般来说,它看起来就是这样:

  1. 运行test
  2. test加载plugin
  3. test运行plugin_test功能。
  4. plugin_test函数在f
  5. 内运行test
  6. f mallocs几个字节并返回它们。
  7. plugin_test保存f
  8. 中返回的unsigned char *

    我的问题是:如果我从free(returned_pointer_from_f_function)内部调用它,plugin_test是否可以正常工作?

    因为该指令我遇到了崩溃(段错误)。 我注意到(从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字节后,

    完全填写:

    (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 ()
    

    编辑:我不知道这是否有事可做,但我正在testsudo一起运行ptrace(PTRACE_ATTACH...)

2 个答案:

答案 0 :(得分:2)

  

我的问题是:假设它是免费的(returned_pointer_from_f_function)   如果我从plugin_test内部调用它?

是的。你在某种程度上是免费的()'没有从malloc返回的指针。

答案 1 :(得分:1)

这是错误的:

hash = malloc(MD5_DIGEST_LENGTH * 2);

你没有为你的终结角色分配空间,所以最后sprintf()将离开你的分配结束,写入不属于你的记忆,并正式欢迎你张开双臂进入你的土地未定义的行为。在这个过程中,您可能会踩踏自由列表或其他堆管理结构。

将其更改为:

hash = malloc(MD5_DIGEST_LENGTH * 2 + 1);

再试一次。