Originally Posted by
MutantJohn
Edit edit: Ha ha ha, I figured it out. First, I think all I have to really type is LD_PRELOAD=libhoard.so
If you have the library in one of the system library directories, then the library name is enough. Otherwise you have to type the full path.
Here is an example "do-nothing" malloc-interposing library, libmymalloc.c:
Code:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
static void *(*original_malloc)(size_t size) = NULL;
static int notified = 0;
void *malloc(size_t size)
{
if (!notified) {
notified = 1;
fflush(stdout);
fprintf(stderr, "Using custom malloc().\n");
fflush(stderr);
}
if (!original_malloc)
*((void **)&original_malloc) = dlsym(RTLD_NEXT, "malloc");
return original_malloc(size);
}
static void libmymalloc_init(void) __attribute__((constructor));
static void libmymalloc_init(void)
{
fflush(stdout);
fprintf(stderr, "libmymalloc loaded.\n");
fflush(stderr);
}
It just prints "libmymalloc loaded." before a program starts main(), and "Using custom malloc()" when malloc() is called for the first time.
To compile libmymalloc.c into a libmymalloc.so library, use
Code:
gcc -W -Wall -O3 -shared -Wl,-soname,libmymalloc.so libmymalloc.o -ldl -o libmymalloc.so
gcc -W -Wall -O3 -fpic -fPIC -c libmymalloc.c
If you compare this and the hoard library, you see that hoard does not interpose malloc(), it just hooks into the malloc() internals.
Here is another helper program that you might find useful. It is very simple: give it one or more symbol names as command-line parameters, and it tells you where they are from, if they are available in the loaded libraries. I call this symbol.c:
Code:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
int main(int argc, char *argv[])
{
Dl_info info;
void *sym;
int arg;
if (argc < 2 || !strcmp("-h", argv[1]) || !strcmp("--help", argv[1])) {
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
fprintf(stderr, " %s SYMBOL-NAME ...\n", argv[0]);
fprintf(stderr, "\n");
return 1;
}
for (arg = 1; arg < argc; arg++) {
sym = dlsym(RTLD_DEFAULT, argv[arg]);
if (sym) {
printf("%s: Found (%p)\n", argv[arg], sym);
dladdr(sym, &info);
if (info.dli_sname && info.dli_fname)
printf("\t%s from %s\n", info.dli_sname, info.dli_fname);
} else
printf("%s: Not found.\n", argv[arg]);
}
return 0;
}
Compile it using e.g.
Code:
gcc -W -Wall -O3 symbol.c -ldl -o symbol
Now, if you have all binaries in the same directory, then you should get something like
Code:
./symbol malloc
malloc: Found (0x7fcbe88cdf50)
__libc_malloc from /lib/x86_64-linux-gnu/libc.so.6
env LD_PRELOAD=./libhoard.so ./symbol malloc
malloc: Found (0x7fcbe88cdf50)
__libc_malloc from /lib/x86_64-linux-gnu/libc.so.6
env LD_PRELOAD=./libmymalloc.so ./symbol malloc
malloc: Found (0x7f8517267740)
malloc from ./libmymalloc.so
Finally, for detecting Hoard, you can use the following simple program. It does not need any special libraries (no need to use -ldl, for example, when linking).
Code:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int using_hoard_malloc(void)
{
char buffer[1024], *line;
FILE *maps;
/* Hoard uses malloc hooks. */
if (!__malloc_initialize_hook)
return 0;
/* Read memory maps to see if libhoard.so is loaded. */
maps = fopen("/proc/self/maps", "rb");
if (!maps)
return 0;
/* If we see /libhoard.so, it's likely enough it is loaded. */
while ((line = fgets(buffer, sizeof buffer, maps)))
if (strstr(line, "/libhoard.so")) {
fclose(maps);
return 1;
}
/* Nope. */
fclose(maps);
return 0;
}
int main(void)
{
if (using_hoard_malloc())
printf("This program is using libhoard malloc().\n");
else
printf("This program is not using libhoard malloc().\n");
return 0;
}
Instead of using the dynamic linker, this one checks if malloc() is hooked. If not, hoard is not in use because it always hooks malloc().
If malloc() is hooked, this uses the Linux /proc/self/maps pseudofile, which contains the memory maps the current process is using. It includes libraries, too. If the listing includes the string /libhoard.so (the paths are absolute in the pseudofile), then the function is satisfied that Hoard is in use. It's not perfect, but it should be robust enough for casual use.