我在动态库中重新定义了标准C库函数,但我无法使用它

时间:2016-03-20 12:58:25

标签: c gcc shared-libraries solaris ld

有一个简单的例子来描述我的问题:

我有3个文件,主要 level1.so level2.so 。 (我的操作系统是solaris11.3,gcc版本是3.4.3)

主要中,它会从 level1.so 调用execute()execute()来自 level2.so run()来电run()fcloseall()调用fcloseall(),在 level2.so 中重新定义。

execute()被重新定义为什么都不做(它将关闭所有打开的fds包括stdout,stdin和stderr)。

现在我希望在main execute()周围打印一些内容,但只打印#include <stdio.h> int run() { fcloseall(); return 0; } 之前的消息。

代码如下所示:

level2.so 是从 level2.c level2depend.c 编译的。

level2.c:

#include <stdio.h>
int fcloseall() //redefine the std c function fcloseall
{
    printf("in redefined fcloseall\n");
    return 0;
}

level2depend.c:

#include <dlfcn.h>
int execute()
{

        int (*sofunc)(void);
        void * lib_handle = NULL;   
        char *errorInfo;    
        lib_handle = dlopen("./liblevel2.so",RTLD_LAZY);
        if(!lib_handle)
        {
            return 0;
        }
        sofunc = (int(*)(void))dlsym(lib_handle,"run");
        errorInfo = dlerror();
        if (errorInfo != NULL){
            dlclose(lib_handle);
            return 0;
        }
        int ret = sofunc();
        dlclose(lib_handle);
        return 0;
}

level1.so 是从 level1.c 编译的。

level1.c

#include <dlfcn.h>
#include <stdio.h>
int main()
{

        int (*sofunc)(void);
        void * lib_handle = NULL;   
        char *errorInfo;    
        lib_handle = dlopen("./liblevel1.so",RTLD_LAZY);
        if(!lib_handle)
        {
            return 0;
        }
        sofunc = (int(*)(void))dlsym(lib_handle,"execute");
        errorInfo = dlerror();
        if (errorInfo != NULL){
            dlclose(lib_handle);
            return 0;
        }
        printf("before\n");
        int ret = sofunc();
        printf("after\n");
        dlclose(lib_handle);
        return 0;
}

main 是从 main.c 编译的。

的main.c

all:
    gcc level2depend.c -o level2depend.o -c -g -fPIC
    gcc level2.c -o level2.o -c -g -fPIC
    gcc -shared -g level2.o level2depend.o -o liblevel2.so -fPIC
    gcc level1.c -o level1.o -c -g -fPIC
    gcc level1.o -o liblevel1.so -shared -fPIC
    gcc main.c -o main -g -ldl
clean:
    rm level2depend.o level1.o liblevel1.so level2.o liblevel2.so main

makefile 是:

root@solaris#./main
before

我执行main,结果是:

gcc main.c -o main -g -ldl -llevel2

如果我将makefile更改为root@solaris#./main before in redefined fcloseall after ,结果为:

$msg= "";
if(openssl_private_decrypt(base64_decode($_POST['data']),$msg,openssl_get_privatekey('file://keys/private.pem'))){
     echo $msg;
}
else{
     echo openssl_error_string();
}

这就是我想要的。

我想知道为什么会这样。谢谢!

1 个答案:

答案 0 :(得分:0)

您可以使用ld。

提供的wrap功能
gcc -Wl,-wrap,fcloseall ....

并在您的源代码中

int __wrap_fcloseall(void)
{...}