1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#define _GNU_SOURCE 1
#include <dlfcn.h>
#include <errno.h>
#include <paths.h>
#include <stdarg.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
// #define DEBUG 1
static int (*libc_open)(const char *pathname, int flags, ...);
static int (*libc_close)(int fd);
static char logs_path[128];
static int logs_fd = -1;
static void __init__() __attribute__((constructor));
static void __fini__() __attribute__((destructor));
void __init__() {
libc_close = dlsym(RTLD_NEXT, "close");
libc_open = dlsym(RTLD_NEXT, "open");
#if DEBUG
fprintf(stderr, "found real close %p and open %p\n", libc_close, libc_open);
#endif
}
void __fini__ () {
if (logs_fd != -1) {
fprintf(stderr, "closing %d\n", logs_fd);
libc_close(logs_fd);
}
}
int close(int fd) {
if (fd != logs_fd)
return libc_close(fd);
return 0;
}
int open(const char *pathname, int flags, ...) {
int mode = -1;
va_list ap;
if (flags & O_CREAT) {
va_start(ap, flags);
mode = va_arg(ap, int);
va_end(ap);
}
#if DEBUG
fprintf(stderr, "caught %s\n", pathname);
#endif
// 25341 openat(AT_FDCWD, "/home/asmadeus/.wine/dosdevices/z:/EverQuest/Logs/eqlog_Asmadeus_antonius.txt", O_WRONLY|O_CREAT|O_NONBLOCK, 0666) = 160
if (strstr(pathname, "Logs/eqlog_")) {
#if DEBUG
fprintf(stderr, "found Logs/eqlog_\n");
#endif
if (strncmp(pathname, logs_path, sizeof(logs_path)-1) == 0)
return logs_fd;
else if (logs_fd != -1)
libc_close(logs_fd);
strncpy(logs_path, pathname, sizeof(logs_path));
logs_fd = libc_open(pathname, flags, mode);
fprintf(stderr, "new path %s, opened %d, flags %x\n", pathname, logs_fd, flags);
return logs_fd;
}
if (mode >= 0)
return libc_open(pathname, flags, mode);
else
return libc_open(pathname, flags);
}
|