问题描述
关于以前的
我已成功插入 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
, butcalloc
seems to be more problematic.That is with certain hosts,
calloc
gets stuck in an infinite loop with a possible internalcalloc
call insidedlsym
. 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.EDITNote that the following host program works correctly -
init()
is only called once, andcalloc
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 yourmalloc()
andcalloc()
implementations are first called. Pick one.With regard to the
calloc()
interposer crashing your application: Some of the functions you're using, includingdlsym()
andfprintf()
, may themselves be attempting to allocate memory, calling your interposer functions. Consider the consequences, and act accordingly.这篇关于某些可执行文件的LD_PRELOAD和calloc()插入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!