Shim layer C++
2 min readJun 26, 2021
shim layer for library
Simple replacement layer that replace gnu library
Application
// test.cpp
#include <stdio.h>
#include <stdlib.h>int main(int argc, char** argv) {
for (int i=0; i<5; i++) {
printf("%d: %d\n", i, rand());
}
return 0;
}
Shim layer for rand()
// shim.cpp
extern "C" {
int rand();
}int rand() {
return 888;
}
Makefile
CC=g++
CFLAGS=-Wall -g
BINS=test.elf shim.soall: $(BINS)%.so: %.cpp
$(CC) $(CFLAGS) -fPIC -shared -o $@ $^%.elf: %.cpp
$(CC) $(CFLAGS) -o $@ $^clean:
rm $(BINS)
rm -r *.so
Run
$ make
g++ -Wall -g -o test.elf test.cpp
g++ -Wall -g -fPIC -shared -o shim.so shim.cpp$ LD_PRELOAD=./shim.so ./test.elf
0: 888
1: 888
2: 888
3: 888
4: 888
Shim layer that adds more to gnu rand()
Application
#include <stdio.h>
#include <stdlib.h>int main(int argc, char** argv) {
for (int i=0; i<5; i++) {
printf("%d: %d\n", i, rand());
}
return 0;
}
Shim layer
#define _GNU_SOURCE#include <unistd.h>
#include <dlfcn.h>extern "C" {
int rand(); // this is needed for C++ shared library because C++ complier mangles function name
}int rand() {
typedef int (*func)(void);
func f;
f = (func)dlsym(RTLD_NEXT, "rand");
return f() % 1000;
}
Makefile
CC=g++
CFLAGS=-Wall -g
BINS=test.elf shim.soall: $(BINS)%.so: %.cpp
$(CC) $(CFLAGS) -fPIC -shared -Wl,--no-as-needed -ldl -o $@ $^%.elf: %.cpp
$(CC) $(CFLAGS) -o $@ $^clean:
rm $(BINS)
rm -r *.so
Execution
$ make
g++ -Wall -g -fPIC -shared -Wl,--no-as-needed -ldl -o shim.so shim.cpp
shim.cpp:1:0: warning: "_GNU_SOURCE" redefined
#define _GNU_SOURCE
<command-line>:0:0: note: this is the location of the previous definition$ LD_PRELOAD=./shim.so ./test.elf
0: 383
1: 886
2: 777
3: 915
4: 793