某些可执行文件的LD_PRELOAD和calloc()插入问题 [英] Problems with LD_PRELOAD and calloc() interposition for certain executables
问题描述
关于以前的我的问题
我已成功插入 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屋!