Ansi C补丁使用dlsym编译确定下linux但失败在Mac Os X [英] Ansi C patch using dlsym compiles OK under linux but fails on Mac Os X

查看:200
本文介绍了Ansi C补丁使用dlsym编译确定下linux但失败在Mac Os X的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经构建一个补丁附加到某个应用程序,并跟踪一些函数的调用。其中,malloc()和open()。我使用dlsym存储指向原始符号的指针,并用我自己的函数名称替换。它编译和工作 - 完全在linux下。以下是代码:

I have build a little patch to append to a certain application and trace the invocations of some functions. Among them, malloc() and open(). I am using dlsym to store the pointer to the original symbol and replace the function name with my own. It compiles -and works- perfectly under linux. Here's the code:

#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <dlfcn.h>

/**
 * Interponemos nuestra funcion open
 * 
 * @param   char*    filename
 * @param   int      flags
 **/

int open(char * filename, int flags)
{
    static int (*real_open)(char*, int) = NULL;
    if (!real_open)
        real_open = dlsym(RTLD_NEXT, "open");

    // Entero
    int p = real_open(filename, flags);
    fprintf(stderr, "Abrimos %s) = %i\n", filename, flags);

    // Devolvemos
    return p;
}

//--------------------------------------------------------

/**
 * Interponemos nuestra funcion malloc
 * 
 * @param   size_t    size
 */

void* malloc(size_t size)
{
    static void* (*real_malloc)(size_t) = NULL;
    if (!real_malloc)
        real_malloc = dlsym(RTLD_NEXT, "malloc");

    void *p = real_malloc(size);

    // Memoria reservada
    fprintf(stderr, "Reserva de memoria (%d) = %p\n", size, p);

    // Devolvemos
    return p;
}

然后,我用下面的指令编译它,创建一个pi.so。

Then, I compile it with the following instruction, creating a pi.so.

gcc -Wall -O2 -fPIC -shared -ldl -o pi.so pi.c 

然后,我使用LD_PRELOAD指令将它注入任何应用程序。

And then, I use the LD_PRELOAD directive to inject it into any app.

LD_PRELOAD=/home/.../injection/pi.so <binary>

而且它在Linux下的奇妙!但是当我回到家并尝试使用GCC在Mac下编译它,它无法编译,LD_PRELOAd指令不工作。我应该改变什么?非常感谢。

And it worjks marvellous under Linux! But when I get back home and try to compile it using GCC under Mac, it fails to compile and the LD_PRELOAd directive does not work. What should I change? Thank you very much.

推荐答案

在mach上,您必须使用 DYLD_INSERT_LIBRARIES 宏而不是 LD_PRELOAD 来指定要预加载的共享库列表(1 ... *)。

On mach, you have to use DYLD_INSERT_LIBRARIES macro instead of LD_PRELOAD to specify a list of shared libraries to pre-load (1...*).

默认情况下,标准函数不会被来自共享对象的函数替换,因为它们具有相同的名称。您必须明确说明什么函数使用 DYLD_INTERPOSE 宏。它允许您使用任何名称声明替换函数(例如,使用 my_open 覆盖 open ),调用原始函数,你是凌驾。除此之外,您不必手动解析真实函数的地址。

By default, standard functions are not getting replaced with functions from the shared objects just because they have the same names. You have to explicitly state what function overrides what using DYLD_INTERPOSE macro. It allows you to declare a replacement function with any name (for example, override open with my_open) and be able to call original function you are overriding. In addition to that, you don't have to resolve addresses of real functions manually.

或者,要实现类似Linux的行为,您必须定义 DYLD_FORCE_FLAT_NAMESPACE 宏。

Alternatively, to achieve Linux-like behavior you have to define DYLD_FORCE_FLAT_NAMESPACE macro.

还有很多事情,请参阅

There is a lot more going on, see dyld manual for details.

所以你的代码应该看起来像这样:

So your code should look something like this:

#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <dlfcn.h>
#include <mach-o/dyld-interposing.h>

/**
 * Interponemos nuestra funcion open
 * 
 * @param   char*    filename
 * @param   int      flags
 **/

int my_open(char * filename, int flags)
{
    // Entero
    int p = open(filename, flags);
    fprintf(stderr, "Abrimos %s) = %i\n", filename, flags);

    // Devolvemos
    return p;
}
DYLD_INTERPOSE(my_open, open)

//--------------------------------------------------------

/**
 * Interponemos nuestra funcion malloc
 * 
 * @param   size_t    size
 */

void* my_malloc(size_t size)
{
    void *p = malloc(size);

    // Memoria reservada
    fprintf(stderr, "Reserva de memoria (%d) = %p\n", size, p);

    // Devolvemos
    return p;
}
DYLD_INTERPOSE(my_malloc, malloc)

这篇关于Ansi C补丁使用dlsym编译确定下linux但失败在Mac Os X的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆