Add test_wrap.c
This commit is contained in:
5
Makefile
Normal file
5
Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
.PHONY: all clean
|
||||
all:
|
||||
$(MAKE) -C proj/test1/
|
||||
clean:
|
||||
$(MAKE) -C proj/test1/
|
||||
@@ -3,3 +3,5 @@ Bachelor's Thesis
|
||||
=================
|
||||
|
||||
See [doc/](doc) for more details.
|
||||
|
||||
[LaTeX template](https://www.overleaf.com/latex/templates/thesis-template-tu-wien-faculty-of-informatics-vutinfth/ygcskyrqcrff).
|
||||
|
||||
@@ -8,8 +8,9 @@ Option 1: `LD_PRELOAD`
|
||||
* No need to re-link
|
||||
* Works for *all* functions
|
||||
* Works only on dynamically linked executables
|
||||
* Intercepts all calls (including stack allocations etc.)
|
||||
|
||||
Example:
|
||||
Example (`preload.c`):
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
@@ -28,21 +29,30 @@ void *malloc(size_t size) {
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
# ./main is already compiled and ready
|
||||
gcc -shared -fPIC -o preload.so preload.c
|
||||
LD_PRELOAD="$(pwd)/preload.so" ./main
|
||||
```
|
||||
|
||||
|
||||
Option 2: `gcc --wrap`
|
||||
----------------------
|
||||
|
||||
* Need to re-link
|
||||
* Need to re-link(/-comiple)
|
||||
* Relatively simple code:
|
||||
* Function name: `__wrap_<symbol>`
|
||||
* Call to real function inside wrapper: `__real_<symbol>`
|
||||
* Works for *all* functions
|
||||
* Works only on dynamically linked executables
|
||||
* Intercepts only calls inside the given source file
|
||||
|
||||
Example:
|
||||
Example (`wrap.c`):
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
|
||||
extern void *__real_malloc(size_t size);
|
||||
|
||||
void *__wrap_malloc(size_t size) {
|
||||
// before call to malloc
|
||||
void *ret = __real_malloc(size);
|
||||
@@ -51,6 +61,11 @@ void *__wrap_malloc(size_t size) {
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
gcc -o main_wrapped main.c wrap.c -Wl,--wrap=malloc
|
||||
./main_wrapped
|
||||
```
|
||||
|
||||
|
||||
Option 3: Linux kernel
|
||||
----------------------
|
||||
|
||||
1
proj/test1/.gitignore
vendored
1
proj/test1/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
/main
|
||||
/main_wrapped
|
||||
|
||||
@@ -5,13 +5,16 @@ LDFLAGS=-lc
|
||||
|
||||
.PHONY: all clean
|
||||
all: default
|
||||
default: main test.so
|
||||
default: main main_wrapped test_preload.so
|
||||
|
||||
test.so: src
|
||||
$(CC) -shared -fPIC -o $@ $< $(CFLAGS) $(LDFLAGS)
|
||||
test_preload.so: src/test_preload.c
|
||||
$(CC) -shared -fPIC -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
main: src
|
||||
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
|
||||
main: src/main.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
main_wrapped: src/main.c src/test_wrap.c
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) -Wl,--wrap=malloc -Wl,--wrap=free -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=getopt
|
||||
|
||||
clean:
|
||||
rm -rf main test.so
|
||||
rm -rf main test_preload.so main_wrapped
|
||||
|
||||
90
proj/test1/src/test_wrap.c
Normal file
90
proj/test1/src/test_wrap.c
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define PREFIX "---====[ "
|
||||
|
||||
static void log_str(FILE *out, const char *str) {
|
||||
fprintf(out, "%p:\"", str);
|
||||
for (char ch; (ch = *str) != 0; str++) {
|
||||
if (ch == '\\' || ch == '"') {
|
||||
fputc('\\', out);
|
||||
fputc(ch, out);
|
||||
} else if (ch == '\t') {
|
||||
fputs("\\t", out);
|
||||
} else if (ch == '\n') {
|
||||
fputs("\\n", out);
|
||||
} else if (ch == '\r') {
|
||||
fputs("\\r", out);
|
||||
} else if ((ch >= 0 && ch < 0x20) || ch == 0x7F) {
|
||||
fprintf(out, "\\x%02x", ch);
|
||||
} else {
|
||||
fputc(ch, out);
|
||||
}
|
||||
}
|
||||
fputc('"', out);
|
||||
}
|
||||
|
||||
static void log_array_str(FILE *out, char *const array[], int n) {
|
||||
fprintf(out, "%p:[", (void *)array);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) fputs(", ", stderr);
|
||||
log_str(stderr, array[i]);
|
||||
}
|
||||
fputc(']', out);
|
||||
}
|
||||
|
||||
extern void *__real_malloc(size_t size);
|
||||
|
||||
void *__wrap_malloc(size_t size) {
|
||||
fprintf(stderr, PREFIX "malloc(%li)\n", size);
|
||||
void *ret = __real_malloc(size);
|
||||
fprintf(stderr, PREFIX "-> %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern void *__real_calloc(size_t nmemb, size_t size);
|
||||
|
||||
void *__wrap_calloc(size_t nmemb, size_t size) {
|
||||
fprintf(stderr, PREFIX "calloc(%li, %li)\n", nmemb, size);
|
||||
void *ret = __real_calloc(nmemb, size);
|
||||
fprintf(stderr, PREFIX "-> %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern void *__real_realloc(void *ptr, size_t size);
|
||||
|
||||
void *__wrap_realloc(void *ptr, size_t size) {
|
||||
fprintf(stderr, PREFIX "realloc(%p, %li)\n", ptr, size);
|
||||
void *ret = __real_realloc(ptr, size);
|
||||
fprintf(stderr, PREFIX "-> %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern void __real_free(void *ptr);
|
||||
|
||||
void __wrap_free(void *ptr) {
|
||||
fprintf(stderr, PREFIX "free(%p)\n", ptr);
|
||||
__real_free(ptr);
|
||||
fprintf(stderr, PREFIX "-> void\n");
|
||||
}
|
||||
|
||||
extern int __real_getopt(int argc, char *const argv[], const char *shortopts);
|
||||
|
||||
int __wrap_getopt(const int argc, char *const argv[], const char *shortopts) {
|
||||
fprintf(stderr, PREFIX "getopt(%i, ", argc);
|
||||
log_array_str(stderr, argv, argc);
|
||||
fputs(", ", stderr);
|
||||
log_str(stderr, shortopts);
|
||||
fputs(")\n", stderr);
|
||||
|
||||
int ret = __real_getopt(argc, argv, shortopts);
|
||||
fprintf(stderr, PREFIX "-> %i", ret);
|
||||
if (ret >= 0x20 && ret < 0x7F) {
|
||||
fprintf(stderr, " ('%c')\n", ret);
|
||||
} else {
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user