# VBForums CodeBank > CodeBank - C++ >  [Linux] Redirecting parent functions from shared object

## RudiVisser

*Hi deLusion`*

Okay so an implementation of the following would be if you need to redirect a library to another one.

For example, application aaa.x86 loads bbb.so, and you would like to load your own shared library (via LD_PRELOAD), which would in turn stop xxx.x86 loading bbb.so, and make it load ccc.so.

elf.cpp


```
#include "elf.h"

bool HookGlobalFunc(const char *SymbolName, void *HookFunc) {
	int fileDescriptor = open("/proc/self/exe", O_RDONLY); // We'll only need to hook Global funcs from et.x86
	elf_version(EV_CURRENT);
	Elf *elf = elf_begin(fileDescriptor, ELF_C_READ, NULL);
	Elf32_Ehdr *header = 0; // ELF Header
	Elf_Scn *section = 0; // ELF Section
	Elf_Data *sectionData = 0; // ELF Section Data
	Elf32_Shdr *sectionHeader = 0; // ELF Section Header
	int symbolNumber = -1;
	if(!elf) { goto end; /* close(fileDescriptor); return false;*/ }
	unsigned short ndx;
	if((header = elf32_getehdr(elf)) == 0) {
		goto error;
		//elf_end(elf);
		//close(fileDescriptor);
		//return false;
	}
	ndx = header->e_shstrndx;
	// Go through the sections
	// .dynsym = Dynamic Symbol Location (linked with .hash and .dynstr)
		while((section = elf_nextscn(elf, section)) != 0) {
			char *name = 0;
			if((sectionHeader = elf32_getshdr(section)) != 0) {
				name = elf_strptr(elf, ndx, (size_t)sectionHeader->sh_name);
				if(!strcmp(name, ".dynsym")) {
					Elf32_Shdr *strtabhdr;
					Elf32_Sym *symbol, *symbolp; // ELF Symbol Pointers
					char *string;
					strtabhdr = &sectionHeader[sectionHeader->sh_link];
					string = (char *)malloc(strtabhdr->sh_size);
					if(string == NULL) goto error;
					if((size_t)lseek(fileDescriptor, strtabhdr->sh_offset, SEEK_SET) != strtabhdr->sh_offset) goto error;
					if((size_t)read(fileDescriptor, string, strtabhdr->sh_size) != strtabhdr->sh_size) goto error;
					symbol = (Elf32_Sym *)malloc(sectionHeader->sh_size);
					if(symbol == NULL) goto error;
					if((size_t)lseek(fileDescriptor, sectionHeader->sh_offset, SEEK_SET) != sectionHeader->sh_offset) goto error;
					if((size_t)read(fileDescriptor, symbol, sectionHeader->sh_size) != sectionHeader->sh_size) goto error;
					symbolp = symbol;
					for(int i = 0; (size_t)i < sectionHeader->sh_size; i += sizeof(Elf32_Sym)) {
						if(!strcmp(elf_strptr(elf, sectionHeader->sh_link, symbolp->st_name), SymbolName)) {
							symbolNumber = symbolp - symbol;
							break;
						}
						++symbolp;
					}
					free(string);
				} else continue;
			} else continue;
		}
	// .rel.plt = Relocation Procedure Linkage Table (Actual GOT)
		if(symbolNumber == -1) goto error;
		// Lookup the Hash from .dynsym in .rel.plt
		section = 0; sectionHeader = 0;
		while((section = elf_nextscn(elf, section)) != 0) {
			char *name = 0;
			if((sectionHeader = elf32_getshdr(section)) != 0) {
				name = elf_strptr(elf, ndx, (size_t)sectionHeader->sh_name);
				if(!strcmp(name, ".rel.plt")) {
					sectionData = elf_getdata(section, NULL);
					if(!sectionData) goto error;
					for(int i = 0; (size_t)i < (sectionHeader->sh_size / sectionHeader->sh_entsize); i++) {
						GElf_Rel relocation;
						gelf_getrel(sectionData, i, &relocation);
						if(ELF64_R_SYM(relocation.r_info) == (size_t)symbolNumber) {
							if(HookFunc == NULL) {
								// Debug
								printf("Symbol '%s' found at 0x%x\n", SymbolName, (unsigned int)relocation.r_offset);
							} else {
								#ifdef DEBUG
								// Only on absolute debug build in muppetTools/
								printf("Found symbol (%i) at %x redirecting to %x\n", symbolNumber, relocation.r_offset, &HookFunc);
								#endif
								*(void **)(unsigned int)relocation.r_offset = HookFunc;
							}
						}
					}
				} else continue;
			} else continue;
		}
	end:
	close(fileDescriptor);
	elf_end(elf);
	return true;
	error:
	close(fileDescriptor);
	elf_end(elf);
	return false;
}
```

elf.h


```
#pragma once

#include <libelf.h>
#include <gelf.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

bool HookGlobalFunc(const char *SymbolName, void *HookFunc);
```

Implementation example (.cpp for compilation into a shared object):


```
void *_dlopen(const char *fileName, int flags) {
	if(strstr(fileName, "bbb.so"))
		return dlopen("ccc.so", flags);
	else
		return dlopen(fileName, flags);
}
void __atrribute__ ((constructor)) MyMain(void) {
	HookGlobalFunc("dlopen", (void *)&_dlopen);
}
```

----------


## deepu8

That is interesting one thanks for sharing it..

----------

