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
I know I am a bit late (6 years). But I wanted to override calloc() today and faced a problem because dlsym() internally uses calloc(). I solved it using a simple technique and thought of sharing it here:
static unsigned char buffer[8192];
void *calloc(size_t nmemb, size_t size)
{
if (calloc_ptr == NULL) // obtained from dlsym
return buffer;
init(); // uses dlsym() to find address of the real calloc()
return calloc_ptr(len);
}
void free(void *in)
{
if (in == buffer)
return;
free_ptr(in);
}
buffer satisfies the need of dlsym() till the real calloc() has been located and my calloc_ptr function pointer initialized.
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.
Using dlsym based hooking can result in crashes, as dlsym calls back into the memory allocator. Instead use malloc hooks, as I suggested in your prior question; these can be installed without actually invoking dlsym at all.
You can get away with a preliminary poor calloc that simply returns NULL. This actually works on Linux, YMMV.
static void* poor_calloc(size_t nmemb, size_t size)
{
// So dlsym uses calloc internally, which will lead to infinite recursion, since our calloc calls dlsym.
// Apparently dlsym can cope with slightly wrong calloc, see for further explanation:
// http://blog.bigpixel.ro/2010/09/interposing-calloc-on-linux
return NULL; // This is a poor implementation of calloc!
}
You can also use sbrk to allocate the memory for "poor calloc".
Related
I have previously, here, been shown that C++ functions aren't easily represented in assembly. Now I am interested in reading them one way or another because Callgrind, part of Valgrind, show them demangled while in assembly they are shown mangled.
So I would like to either mangle the Valgrind function output or demangle the assembly names of functions. Anyone ever tried something like that? I was looking at a website and found out the following:
Code to implement demangling is part of the GNU Binutils package;
see libiberty/cplus-dem.c and include/demangle.h.
Has anyone ever tried something like that? I want to demangle/mangle in C.
My compiler is gcc 4.x.
Use the c++filt command line tool to demangle the name.
Here is my C++11 implementation, derived from the following page:
http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
#include <cxxabi.h> // needed for abi::__cxa_demangle
std::shared_ptr<char> cppDemangle(const char *abiName)
{
int status;
char *ret = abi::__cxa_demangle(abiName, 0, 0, &status);
/* NOTE: must free() the returned char when done with it! */
std::shared_ptr<char> retval;
retval.reset( (char *)ret, [](char *mem) { if (mem) free((void*)mem); } );
return retval;
}
To make the memory management easy on the returned (char *), I'm using a std::shared_ptr with a custom lambda 'deleter' function that calls free() on the returned memory. Because of this, I don't ever have to worry about deleting the memory on my own, I just use it as needed, and when the shared_ptr goes out of scope, the memory will be free'd.
Here's the macro I use to access the demangled type name as a (const char *). Note that you must have RTTI turned on to have access to 'typeid'
#define CLASS_NAME(somePointer) ((const char *) cppDemangle(typeid(*somePointer).name()).get() )
So, from within a C++ class I can say:
printf("I am inside of a %s\n",CLASS_NAME(this));
This is a slight variation on Dave's version above. This is a unique_ptr version with a little bit of checking on the return type, though it looks like you could just ignore that, but somehow that just seems unclean.
auto cppDemangle (const char *abiName)
{
//
// This function allocates and returns storage in ret
//
int status;
char *ret = abi::__cxa_demangle(abiName, 0 /* output buffer */, 0 /* length */, &status);
auto deallocator = ( [](char *mem) { if (mem) free((void*)mem); } );
if (status) {
// 0: The demangling operation succeeded.
// -1: A memory allocation failure occurred.
// -2: mangled_name is not a valid name under the C++ ABI mangling rules.
// -3: One of the arguments is invalid.
std::unique_ptr<char, decltype(deallocator) > retval(nullptr, deallocator);
return retval;
}
//
// Create a unique pointer to take ownership of the returned string so it
// is freed when that pointers goes out of scope
//
std::unique_ptr<char, decltype(deallocator) > retval(ret, deallocator);
return retval;
}
I am using LD_PRELOAD to log malloc calls from an application and map out the virtual address space however malloc is used internally by fopen/printf. Is there a way I can fix this issue?
I know about glibc's hooks but I want to avoid changing the source code of the application.
My issue was caused by the fact that malloc is used internally by glibc so when I use LD_PRELOAD to override malloc any attempt to log caused malloc to be called resulting in a recursive call to malloc itself
Solution:
call original malloc whenever the TLS needs memory allocation
providing code:
static __thread int no_hook;
static void *(*real_malloc)(size_t) = NULL;
static void __attribute__((constructor))init(void) {
real_malloc = (void * (*)(size_t))dlsym(RTLD_NEXT, "malloc");
}
void * malloc(size_t len) {
void* ret;
void* caller;
if (no_hook) {
return (*real_malloc)(len);
}
no_hook = 1;
caller = (void*)(long) __builtin_return_address(0);
printf("malloc call %zu from %lu\n", len, (long)caller);
ret = (*real_malloc)(len);
// fprintf(logfp, ") -> %pn", ret);
no_hook = 0;
return ret;
}
I want to override new/delete and malloc/free. I have tcmalloc library linked in my application. My aim is to add stats.
From new I am calling malloc. Below is an example it's global.
void* my_malloc(size_t size, const char *file, int line, const char *func)
{
void *p = malloc(size);
....
....
....
return p;
}
#define malloc(X) my_malloc(X, __FILE__, __LINE__, __FUNCTION__)
void *
operator new(size_t size)
{
auto new_addr = malloc(size);
....
...
return new_addr;
}
New/delete override is working fine.
My question is what happen to other file where I have use malloc directly for example
first.cpp
malloc(sizeof(..))
second.cpp
malloc(sizeof(..))
How this malloc call get's interpret as my macro is not in header file.
tcmalloc provides new/delete hooks that can be used to implement any kind of tracking/accounting of memory usage. See e.g. AddNewHook in https://github.com/gperftools/gperftools/blob/master/src/gperftools/malloc_hook.h
I want the program to jump to a specific address in memory and continue execution from that address. I thought about using goto but I don't have a label rather just an address in memory.
There is no need to worry about return back from the jump address.
edit: using GCC compiler
Inline assembly might be the easiest and most "elegant" solution, although doing this is highly unusual, unless you are writing a debugger or some specialized introspective system.
Another option might be to declare a pointer to a void function (void (*foo)(void)), then set the pointer to contain your address, and then invoke it:
void (*foo)(void) = (void (*)())0x12345678;
foo();
There will be things pushed on the stack since the compiler thinks you are doing a subroutine call, but since you don't care about returning, this might work.
gcc has an extension that allows jumping to an arbitrary address:
void *ptr = (void *)0x1234567; // a random memory address
goto *ptr; // jump there -- probably crash
This is pretty much the same as using a function pointer that you set to a fixed value, but it will actually use a jump instruction rather than a call instruction (so the stack won't be modified)
#include <stdio.h>
#include <stdlib.h>
void go(unsigned int addr) {
(&addr)[-1] = addr;
}
int sub() {
static int i;
if(i++ < 10) printf("Hello %d\n", i);
else exit(0);
go((unsigned int)sub);
}
int main() {
sub();
}
Of course, this invokes undefined behavior, is platform-dependent, assumes that code addresses are the same size as int, etc, etc.
It should look something like this:
unsigned long address=0x80;
void (*func_ptr)(void) = (void (*)(void))address;
func_ptr();
However, it is not a very safe operation, jumping to some unknown address will probably result in a crash!
Since the question has a C++ tag, here's an example of a C++ call to a function with a signature like main()--int main(int argc, char* argv[]):
int main(int argc, char* argv[])
{
auto funcAddr = 0x12345678; //or use &main...
auto result = reinterpret_cast<int (*)(int, char**)>(funcAddr)(argc, argv);
}
Do you have control of the code at the address that you intend to jump to? Is this C or C++?
I hesitantly suggest setjmp() / longjmp() if you're using C and can run setjmp() where you need to jump back to. That being said, you've got to be VERY careful with these.
As for C++, see the following discussion about longjmp() shortcutting exception handling and destructors destructors. This would make me even more hesitant to suggest it's use in C++.
C++: Safe to use longjmp and setjmp?
This is what I am using for my bootstrap loader(MSP430AFE253,Compiler = gcc,CodeCompeserStudio);
#define API_RESET_VECT 0xFBFE
#define JUMP_TO_APP() {((void (*)()) (*(uint16_t*)API_RESET_VECT)) ();}
I Propos this code:
asm(
"LDR R0,=0x0a0000\n\t" /* Or 0x0a0000 for the base Addr. */
"LDR R0, [R0, #4]\n\t" /* Vector+4 for PC */
"BX R0"
);
I have previously, here, been shown that C++ functions aren't easily represented in assembly. Now I am interested in reading them one way or another because Callgrind, part of Valgrind, show them demangled while in assembly they are shown mangled.
So I would like to either mangle the Valgrind function output or demangle the assembly names of functions. Anyone ever tried something like that? I was looking at a website and found out the following:
Code to implement demangling is part of the GNU Binutils package;
see libiberty/cplus-dem.c and include/demangle.h.
Has anyone ever tried something like that? I want to demangle/mangle in C.
My compiler is gcc 4.x.
Use the c++filt command line tool to demangle the name.
Here is my C++11 implementation, derived from the following page:
http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
#include <cxxabi.h> // needed for abi::__cxa_demangle
std::shared_ptr<char> cppDemangle(const char *abiName)
{
int status;
char *ret = abi::__cxa_demangle(abiName, 0, 0, &status);
/* NOTE: must free() the returned char when done with it! */
std::shared_ptr<char> retval;
retval.reset( (char *)ret, [](char *mem) { if (mem) free((void*)mem); } );
return retval;
}
To make the memory management easy on the returned (char *), I'm using a std::shared_ptr with a custom lambda 'deleter' function that calls free() on the returned memory. Because of this, I don't ever have to worry about deleting the memory on my own, I just use it as needed, and when the shared_ptr goes out of scope, the memory will be free'd.
Here's the macro I use to access the demangled type name as a (const char *). Note that you must have RTTI turned on to have access to 'typeid'
#define CLASS_NAME(somePointer) ((const char *) cppDemangle(typeid(*somePointer).name()).get() )
So, from within a C++ class I can say:
printf("I am inside of a %s\n",CLASS_NAME(this));
This is a slight variation on Dave's version above. This is a unique_ptr version with a little bit of checking on the return type, though it looks like you could just ignore that, but somehow that just seems unclean.
auto cppDemangle (const char *abiName)
{
//
// This function allocates and returns storage in ret
//
int status;
char *ret = abi::__cxa_demangle(abiName, 0 /* output buffer */, 0 /* length */, &status);
auto deallocator = ( [](char *mem) { if (mem) free((void*)mem); } );
if (status) {
// 0: The demangling operation succeeded.
// -1: A memory allocation failure occurred.
// -2: mangled_name is not a valid name under the C++ ABI mangling rules.
// -3: One of the arguments is invalid.
std::unique_ptr<char, decltype(deallocator) > retval(nullptr, deallocator);
return retval;
}
//
// Create a unique pointer to take ownership of the returned string so it
// is freed when that pointers goes out of scope
//
std::unique_ptr<char, decltype(deallocator) > retval(ret, deallocator);
return retval;
}