Initial commit
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.idea/
|
||||
bin/
|
||||
*.so
|
||||
*.o
|
||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
Bachelor's Thesis
|
||||
=================
|
||||
|
||||
See [doc/](doc) for more details.
|
||||
59
doc/README.md
Normal file
59
doc/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
Intercepting Function/System Calls in Linux
|
||||
===========================================
|
||||
|
||||
Option 1: `LD_PRELOAD`
|
||||
----------------------
|
||||
|
||||
* No need to re-link
|
||||
* Works for *all* functions
|
||||
* Works only on dynamically linked executables
|
||||
|
||||
Example:
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
|
||||
void *malloc(size_t size) {
|
||||
// before call to malloc
|
||||
void *(* _malloc)(size_t);
|
||||
if ((_malloc = dlsym(RTLD_NEXT, "malloc")) == NULL) {
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
void *ret = _malloc(size);
|
||||
// after call to malloc
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Option 2: `gcc --wrap`
|
||||
----------------------
|
||||
|
||||
* Need to re-link
|
||||
* 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
|
||||
|
||||
Example:
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
|
||||
void *__wrap_malloc(size_t size) {
|
||||
// before call to malloc
|
||||
void *ret = __real_malloc(size);
|
||||
// after call to malloc
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Option 3: Linux kernel
|
||||
----------------------
|
||||
|
||||
* Only works with Linux system calls
|
||||
* Also works with statically linked executables
|
||||
1
proj/test1/.gitignore
vendored
Normal file
1
proj/test1/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/main
|
||||
17
proj/test1/Makefile
Normal file
17
proj/test1/Makefile
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
CC=gcc
|
||||
CFLAGS=-std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809L -g
|
||||
LDFLAGS=-lc
|
||||
|
||||
.PHONY: all clean
|
||||
all: default
|
||||
default: main test.so
|
||||
|
||||
test.so: src
|
||||
$(CC) -shared -fPIC -o $@ $< $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
main: src
|
||||
$(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf main test.so
|
||||
39
proj/test1/src/main.c
Normal file
39
proj/test1/src/main.c
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
static void usage(const char *prog_name) {
|
||||
fprintf(stderr, "usage: %s [-a]\n", prog_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void do_something(void) {
|
||||
printf("Hello World!\n");
|
||||
void *mem = malloc(123);
|
||||
if (mem == NULL) {
|
||||
fprintf(stderr, "Unable to malloc: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
printf("%p\n", mem);
|
||||
free(mem);
|
||||
}
|
||||
|
||||
int main(const int argc, char *const argv[]) {
|
||||
for (int ch; (ch = getopt(argc, argv, "a")) != -1;) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
if (optind != argc)
|
||||
usage(argv[0]);
|
||||
|
||||
do_something();
|
||||
do_something();
|
||||
do_something();
|
||||
}
|
||||
105
proj/test1/src/test.c
Normal file
105
proj/test1/src/test.c
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void *malloc(size_t size) {
|
||||
fprintf(stderr, PREFIX "malloc(%li)\n", size);
|
||||
void *(* _malloc)(size_t);
|
||||
if ((_malloc = dlsym(RTLD_NEXT, "malloc")) == NULL) {
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
void *ret = _malloc(size);
|
||||
fprintf(stderr, PREFIX "-> %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *calloc(size_t nmemb, size_t size) {
|
||||
fprintf(stderr, PREFIX "calloc(%li, %li)\n", nmemb, size);
|
||||
void *(* _calloc)(size_t, size_t);
|
||||
if ((_calloc = dlsym(RTLD_NEXT, "calloc")) == NULL) {
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
void *ret = _calloc(nmemb, size);
|
||||
fprintf(stderr, PREFIX "-> %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
fprintf(stderr, PREFIX "realloc(%p, %li)\n", ptr, size);
|
||||
void *(* _realloc)(void *, size_t);
|
||||
if ((_realloc = dlsym(RTLD_NEXT, "realloc")) == NULL) {
|
||||
errno = ENOSYS;
|
||||
return NULL;
|
||||
}
|
||||
void *ret = _realloc(ptr, size);
|
||||
fprintf(stderr, PREFIX "-> %p\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
fprintf(stderr, PREFIX "free(%p)\n", ptr);
|
||||
void (* _free)(void *);
|
||||
if ((_free = dlsym(RTLD_NEXT, "free")) == NULL) {
|
||||
errno = ENOSYS;
|
||||
return;
|
||||
}
|
||||
_free(ptr);
|
||||
fprintf(stderr, PREFIX "-> void\n");
|
||||
}
|
||||
|
||||
int 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 (* _getopt)(int, char *const[], const char *);
|
||||
if ((_getopt = dlsym(RTLD_NEXT, "getopt")) == NULL) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
int ret = _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;
|
||||
}
|
||||
0
thesis/thesis.tex
Normal file
0
thesis/thesis.tex
Normal file
Reference in New Issue
Block a user