首页 > 解决方案 > LD_PRELOAD 带有枚举和结构的函数

问题描述

我正在尝试 LD_PRELOAD 一个带有声明的函数

// header1.h
typedef enum { ... } enum1;

// header2.h
typedef enum { ... } enum2;
typedef struct { ... } Structure1;
enum1 foo(Structure1* str, enum2 val);

是否可以使用 sayunsiged int代替枚举而void*不是Structure1*.

我尝试了这样的简单代码,但似乎不起作用。会不会是因为类型不匹配?

#define _GNU_SOURCE

#include <stdio.h>
#include <stdarg.h>
#include <dlfcn.h>

typedef unsigned int (*foo_t)(void* ptr, unsigned int e2);

unsigned int foo(void* handle, unsigned int e2)
{
   printf ("foo\n");
   foo_t foo_f = (foo_t) dlsym(RTLD_NEXT, "foo");
   unsigned int result = foo_f(ptr, option);
   return result;
}

编辑 :

要了解实际用例,

我正在尝试加载

CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
    va_list param)

从这里https://github.com/curl/curl/blob/curl-7_55_1/lib/url.c

但是当我做nm时,它似乎没有找到这个功能

$ nm -D /usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0  | grep setopt
000000000002fc80 T curl_easy_setopt
0000000000037ac0 T curl_multi_setopt
000000000003ad60 T curl_share_setopt

我尝试了调用Curl_setopt的curl_easy_setopt的objdump ,但是这里没有callCurl_setopt

objdump -D -S -C  /usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0 --start-address 0x02fc80 --stop-address 0x02fd36 

/usr/lib/x86_64-linux-gnu/libcurl.so.4.4.0:     file format elf64-x86-64


Disassembly of section .text:

000000000002fc80 <curl_easy_setopt@@CURL_OPENSSL_3>:
   2fc80:   48 81 ec d8 00 00 00    sub    $0xd8,%rsp
   2fc87:   84 c0                   test   %al,%al
   2fc89:   48 89 54 24 30          mov    %rdx,0x30(%rsp)
   2fc8e:   48 89 4c 24 38          mov    %rcx,0x38(%rsp)
   2fc93:   4c 89 44 24 40          mov    %r8,0x40(%rsp)
   2fc98:   4c 89 4c 24 48          mov    %r9,0x48(%rsp)
   2fc9d:   74 37                   je     2fcd6 <curl_easy_setopt@@CURL_OPENSSL_3+0x56>
   2fc9f:   0f 29 44 24 50          movaps %xmm0,0x50(%rsp)
   2fca4:   0f 29 4c 24 60          movaps %xmm1,0x60(%rsp)
   2fca9:   0f 29 54 24 70          movaps %xmm2,0x70(%rsp)
   2fcae:   0f 29 9c 24 80 00 00    movaps %xmm3,0x80(%rsp)
   2fcb5:   00 
   2fcb6:   0f 29 a4 24 90 00 00    movaps %xmm4,0x90(%rsp)
   2fcbd:   00 
   2fcbe:   0f 29 ac 24 a0 00 00    movaps %xmm5,0xa0(%rsp)
   2fcc5:   00 
   2fcc6:   0f 29 b4 24 b0 00 00    movaps %xmm6,0xb0(%rsp)
   2fccd:   00 
   2fcce:   0f 29 bc 24 c0 00 00    movaps %xmm7,0xc0(%rsp)
   2fcd5:   00 
   2fcd6:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
   2fcdd:   00 00 
   2fcdf:   48 89 44 24 18          mov    %rax,0x18(%rsp)
   2fce4:   31 c0                   xor    %eax,%eax
   2fce6:   48 85 ff                test   %rdi,%rdi
   2fce9:   b8 2b 00 00 00          mov    $0x2b,%eax
   2fcee:   74 2e                   je     2fd1e <curl_easy_setopt@@CURL_OPENSSL_3+0x9e>
   2fcf0:   48 8d 84 24 e0 00 00    lea    0xe0(%rsp),%rax
   2fcf7:   00 
   2fcf8:   48 89 e2                mov    %rsp,%rdx
   2fcfb:   c7 04 24 10 00 00 00    movl   $0x10,(%rsp)
   2fd02:   c7 44 24 04 30 00 00    movl   $0x30,0x4(%rsp)
   2fd09:   00 
   2fd0a:   48 89 44 24 08          mov    %rax,0x8(%rsp)
   2fd0f:   48 8d 44 24 20          lea    0x20(%rsp),%rax
   2fd14:   48 89 44 24 10          mov    %rax,0x10(%rsp)
   2fd19:   e8 e2 e9 fe ff          callq  1e700 <curl_formget@@CURL_OPENSSL_3+0xf2e0>
   2fd1e:   48 8b 4c 24 18          mov    0x18(%rsp),%rcx
   2fd23:   64 48 33 0c 25 28 00    xor    %fs:0x28,%rcx
   2fd2a:   00 00 
   2fd2c:   75 08                   jne    2fd36 <curl_easy_setopt@@CURL_OPENSSL_3+0xb6>
   2fd2e:   48 81 c4 d8 00 00 00    add    $0xd8,%rsp
   2fd35:   c3                      retq   

标签: clinuxlibcurlld-preloaddlsym

解决方案


Curl_setopt()不是外部提供的符号,因此您不能 LD_PRELOAD 它。考虑替换curl_easy_setopt它,它是公共且始终可访问的符号。

作为第二个原因,函数 Curl_setopt() 甚至在最近的 libcurl 中都不存在。


推荐阅读