某些可执行文件的LD_PRELOAD和calloc()插入问题 [英] Problems with LD_PRELOAD and calloc() interposition for certain executables

查看:234
本文介绍了某些可执行文件的LD_PRELOAD和calloc()插入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于以前的我的问题

我已成功插入 malloc ,但 calloc 更有问题。



这是与某些主机, calloc 陷入无限循环, code> calloc 调用 dlsym 。但是,基本测试主机不会显示此行为,但是我的系统的ls命令。



这是我的代码:

  // build with:g ++ -O2 -Wall -fPIC -ldl -o libnano.so -shared Main.cc 
#include< stdio.h>
#include< dlfcn.h>

bool gNanoUp = false; // global

//函数类型
typedef void *(* MallocFn)(size_t size);
typedef void *(* CallocFn)(size_t elements,size_t size);

struct MemoryFunctions {
MallocFn mMalloc;
CallocFn mCalloc;
};

MemoryFunctions orgMemFuncs;

//保存原始方法。
void __attribute __((constructor))__nano_init(void){
fprintf(stderr,NANO:init()\\\
);

//获取原始函数的地址
orgMemFuncs.mMalloc =(MallocFn)dlsym(RTLD_NEXT,malloc);
orgMemFuncs.mCalloc =(CallocFn)dlsym(RTLD_NEXT,calloc);

fprintf(stderr,NANO:malloc()found @%p\\\
,orgMemFuncs.mMalloc);
fprintf(stderr,NANO:calloc()found @%p \\\
,orgMemFuncs.mCalloc);

gNanoUp = true;
}

//替换函数
externC{
void * malloc(size_t size){
if(!gNanoUp)__nano_init ;
return orgMemFuncs.mMalloc(size);
}

void * calloc(size_t elements,size_t size){
if(!gNanoUp)__nano_init();
return orgMemFuncs.mCalloc(elements,size);
}
}

现在,当我执行以下操作时,无限循环后跟一个seg错误,例如:

 %setenv LD_PRELOAD./libnano.so
%ls
...
NANO:init()
NANO:init()
NANO:init()
分段故障(内核转储)
<然而,如果我注释掉 calloc 插件,它几乎

似乎

 %setenv LD_PRELOAD./libnano.so
%ls
NANO:init()
NANO:init()
NANO:malloc()找到@ 0x3b36274dc0
NANO:calloc()found @ 0x3b362749e0
@ 0x3b36274dc0
NANO:calloc()found @ 0x3b362749e0
< directory content>
...

所以有些ls表示 init()被调用两次。



EDIT
请注意,以下主机程序可正常工作 - init()并且 calloc 已成功插入,如您从输出中可以看到的。

  // build with:g ++ test.cc -o test 
#include< stdio.h&
#include< stdlib.h>

int main(int argc,char * argv []){

void * p = malloc(123);
printf(HOST p =%p\\\
,p);
free(p);

char * c = new char;
printf(HOST c =%p \\\
,c);
delete c;

void * ca = calloc(10,10);
printf(HOST ca =%p\\\
,ca);
free(ca);
}

%setenv LD_PRELOAD./libnano.so
%./test
NANO:init()
NANO:malloc @ 0x3b36274dc0
NANO:calloc()found @ 0x3b362749e0
HOST p = 0x601010
HOST c = 0x601010
HOST ca = 0x601030


解决方案

关于 __ nano_init()你已经将函数声明为一个构造函数,因此在库加载时被调用,当你的 malloc() calloc()实现首先被调用。选择一个。



关于 calloc() Interposer会崩溃您的应用程序:使用 dlsym() fprintf()可能正在尝试分配内存,调用插件函数。考虑后果,并据此采取行动。


Relating to a previous question of mine

I've successfully interposed malloc, but calloc seems to be more problematic.

That is with certain hosts, calloc gets stuck in an infinite loop with a possible internal calloc call inside dlsym. However, a basic test host does not exhibit this behaviour, but my system's "ls" command does.

Here's my code:

// build with: g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared Main.cc
#include <stdio.h>
#include <dlfcn.h>

bool gNanoUp = false;// global

// Function types
typedef void* (*MallocFn)(size_t size);
typedef void* (*CallocFn)(size_t elements, size_t size);

struct MemoryFunctions {
    MallocFn   mMalloc;
    CallocFn   mCalloc;
};

MemoryFunctions orgMemFuncs;

// Save original methods.
void __attribute__((constructor)) __nano_init(void) {
    fprintf(stderr, "NANO: init()\n");

    // Get address of original functions
    orgMemFuncs.mMalloc = (MallocFn)dlsym(RTLD_NEXT, "malloc");
    orgMemFuncs.mCalloc = (CallocFn)dlsym(RTLD_NEXT, "calloc");

    fprintf(stderr, "NANO: malloc() found @%p\n", orgMemFuncs.mMalloc);
    fprintf(stderr, "NANO: calloc() found @%p\n", orgMemFuncs.mCalloc);

    gNanoUp = true;
}

// replacement functions
extern "C" {
    void *malloc(size_t size) {
        if (!gNanoUp) __nano_init();
        return orgMemFuncs.mMalloc(size);
    }

    void* calloc(size_t elements, size_t size) {
        if (!gNanoUp) __nano_init();
        return orgMemFuncs.mCalloc(elements, size);
    }
}

Now, When I do the following, I get an infinite loop followed by a seg fault, eg:

% setenv LD_PRELOAD "./libnano.so"
% ls
...
NANO: init()
NANO: init()
NANO: init()
Segmentation fault (core dumped)

However if I comment out the calloc interposer, it almost seems to work:

% setenv LD_PRELOAD "./libnano.so"
% ls
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
<directory contents>
...

So somethings up with "ls" that means init() gets called twice.

EDIT Note that the following host program works correctly - init() is only called once, and calloc is successfully interposed, as you can see from the output.

// build with: g++ test.cc -o test
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {

    void* p = malloc(123);
    printf("HOST p=%p\n", p);
    free(p);

    char* c = new char;
    printf("HOST c=%p\n", c);
    delete c;

    void* ca = calloc(10,10);
    printf("HOST ca=%p\n", ca);
    free(ca);
}

% setenv LD_PRELOAD "./libnano.so"
% ./test 
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
HOST p=0x601010
HOST c=0x601010
HOST ca=0x601030

解决方案

With regard to __nano_init() being called twice: You've declared the function as a constructor, so it's called when the library is loaded, and it's called a second time explicitly when your malloc() and calloc() implementations are first called. Pick one.

With regard to the calloc() interposer crashing your application: Some of the functions you're using, including dlsym() and fprintf(), may themselves be attempting to allocate memory, calling your interposer functions. Consider the consequences, and act accordingly.

这篇关于某些可执行文件的LD_PRELOAD和calloc()插入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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