Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C LD_PRELOAD如何在我的代码中工作_C_Ld_Glibc - Fatal编程技术网

C LD_PRELOAD如何在我的代码中工作

C LD_PRELOAD如何在我的代码中工作,c,ld,glibc,C,Ld,Glibc,LD_PRELOAD可以用来在一个共享对象之前链接另一个共享对象,所以我尝试在glibc中重写memcpy 我定义了memcpy,它将反转src的字节顺序,并返回NULL以区别于glibc的memcpy mymem.c #include <string.h> void *memcpy(void *dest, const void *src, size_t n) { char *dest_c = dest; const char *src_c = src; s

LD_PRELOAD可以用来在一个共享对象之前链接另一个共享对象,所以我尝试在glibc中重写memcpy

我定义了memcpy,它将反转src的字节顺序,并返回NULL以区别于glibc的memcpy

mymem.c

#include <string.h>

void *memcpy(void *dest, const void *src, size_t n) {
    char *dest_c = dest;
    const char *src_c = src;
    size_t i = 0;

    //reverse the byte order in src
    for(i = 0; i < n; i++)
        dest_c[i] = src_c[n-i-1];

    return NULL;
}
结果是:

str2: 0x7fff0297e710
hello 0x400470 0x7fff0297e710
lehlo 0x400470 (nil)
 0x400470 (nil)
当第三个参数等于char数组的大小(在本例中,sizeof str为6)时,输出不是我所期望的

在第一个memcpy之后,我认为str2[0]应该是'\0',因此str2是一个空字符串,但输出是“hello”。memcpy的返回值应该为NULL,但输出是str2的地址。看起来glic的memcpy可以工作(我不确定)

另外两个memcpy的工作方式与我预期的一样

我已经在Debian8和Ubuntu14.04中进行了测试


有人能解释一下吗?

这是因为出于某种原因,GCC决定在第一次调用
memcpy
时使用
memcpy
的内联版本。为了避免这种情况,您可以使用
-fno-builtin
选项


还要注意,如果出于某种原因,
memcpy
静态链接到可执行文件中,则可能导致该
memcpy
被静态解析。由于
memcpy
是一个低级函数,CRT启动代码(静态链接)提供实现并非不可能。

只需在二进制文件上执行
objdump-DS
(正如qarma已经建议的),您就可以看到您的第一个
memcpy
不会生成函数调用。这是它在我的机器上的外观:

//print str2, address of memcpy, return value of memcpy                         
ret = memcpy(str2, str, 6);                                                     
40066e:       8b 85 70 ff ff ff       mov    -0x90(%rbp),%eax                     
400674:       89 45 80                mov    %eax,-0x80(%rbp)                     
400677:       0f b7 85 74 ff ff ff    movzwl -0x8c(%rbp),%eax                     
40067e:       66 89 45 84             mov    %ax,-0x7c(%rbp)                      
400682:       48 8d 45 80             lea    -0x80(%rbp),%rax                     
400686:       48 89 85 68 ff ff ff    mov    %rax,-0x98(%rbp) 
尝试使用
-fno内置memcpy编译-它应该可以解决以下问题:

ret = memcpy(str2, str, 6);
40066e:       48 8d 8d 70 ff ff ff    lea    -0x90(%rbp),%rcx
400675:       48 8d 45 80             lea    -0x80(%rbp),%rax
400679:       ba 06 00 00 00          mov    $0x6,%edx
40067e:       48 89 ce                mov    %rcx,%rsi
400681:       48 89 c7                mov    %rax,%rdi
400684:       e8 87 fe ff ff          callq  400510 <memcpy@plt>
400689:       48 89 85 68 ff ff ff    mov    %rax,-0x98(%rbp)
ret=memcpy(str2,str,6);
40066e:48 8d 8d 70 ff ff ff lea-0x90(%rbp),%rcx
400675:48 8d 45 80 lea-0x80(%rbp),%rax
400679:ba 06 00 mov$0x6,%edx
40067e:48 89 ce mov%rcx%rsi
400681:48 89 c7 mov%rax,%rdi
400684:e8 87 fe ff ff callq 400510
400689:48 89 85 68 ff ff移动百分比rax,-0x98(%rbp)

memcpy
可以通过“内在”进行内联或实现--请运行
nm-D您的\u二进制文件
进行验证。此外,
printf
可能在内部使用
memcpy
,这使年轻人的测试变得非常复杂:)请重载一些罕见的函数,或者重载外部副作用(与可逆数据损坏相反)
//print str2, address of memcpy, return value of memcpy                         
ret = memcpy(str2, str, 6);                                                     
40066e:       8b 85 70 ff ff ff       mov    -0x90(%rbp),%eax                     
400674:       89 45 80                mov    %eax,-0x80(%rbp)                     
400677:       0f b7 85 74 ff ff ff    movzwl -0x8c(%rbp),%eax                     
40067e:       66 89 45 84             mov    %ax,-0x7c(%rbp)                      
400682:       48 8d 45 80             lea    -0x80(%rbp),%rax                     
400686:       48 89 85 68 ff ff ff    mov    %rax,-0x98(%rbp) 
ret = memcpy(str2, str, 6);
40066e:       48 8d 8d 70 ff ff ff    lea    -0x90(%rbp),%rcx
400675:       48 8d 45 80             lea    -0x80(%rbp),%rax
400679:       ba 06 00 00 00          mov    $0x6,%edx
40067e:       48 89 ce                mov    %rcx,%rsi
400681:       48 89 c7                mov    %rax,%rdi
400684:       e8 87 fe ff ff          callq  400510 <memcpy@plt>
400689:       48 89 85 68 ff ff ff    mov    %rax,-0x98(%rbp)