-
Notifications
You must be signed in to change notification settings - Fork 0
/
ld_preload_stdinout.c
100 lines (79 loc) · 2.35 KB
/
ld_preload_stdinout.c
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// gcc -shared -fPIC -o ld_preload_stdinout.so ld_preload_stdinout.c -ldl
#define _GNU_SOURCE
#include <dlfcn.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static ssize_t (*real_write)(int fd, const void *buf, size_t count) = NULL;
static ssize_t (*real_read)(int fd, void *buf, size_t count) = NULL;
static int (*real_printf)(const char *format, ...) = NULL;
static int (*real_puts)(const char *s) = NULL;
static int (*real_fprintf)(FILE *stream, const char *format, ...) = NULL;
static int log_fd = -1;
__attribute__((constructor)) void my_init(void) {
real_write = dlsym(RTLD_NEXT, "write");
real_read = dlsym(RTLD_NEXT, "read");
real_printf = dlsym(RTLD_NEXT, "printf");
real_puts = dlsym(RTLD_NEXT, "puts");
real_fprintf = dlsym(RTLD_NEXT, "fprintf");
log_fd = open("/tmp/file.log", O_WRONLY | O_CREAT | O_APPEND, 0666);
if (log_fd == -1) {
perror("Failed to open log file");
exit(1);
}
setbuf(stdout, NULL);
setbuf(stderr, NULL);
}
__attribute__((destructor)) void my_fini(void) {
if (log_fd != -1) {
close(log_fd);
}
}
ssize_t write(int fd, const void *buf, size_t count) {
ssize_t result = real_write(fd, buf, count);
if ((fd == STDOUT_FILENO || fd == STDERR_FILENO) && fd != log_fd) {
real_write(log_fd, buf, count);
}
return result;
}
ssize_t read(int fd, void *buf, size_t count) {
ssize_t result = real_read(fd, buf, count);
if (fd == STDIN_FILENO && fd != log_fd) {
real_write(log_fd, buf, result);
}
return result;
}
int printf(const char *format, ...) {
va_list args;
va_start(args, format);
int result = vfprintf(stdout, format, args);
va_end(args);
va_start(args, format);
real_fprintf(log_fd != -1 ? fdopen(log_fd, "w") : stderr, format, args);
va_end(args);
return result;
}
int puts(const char *s) {
int result = real_puts(s);
if (log_fd != -1) {
real_write(log_fd, s, strlen(s));
real_write(log_fd, "\n", 1);
}
return result;
}
int fprintf(FILE *stream, const char *format, ...) {
va_list args;
va_start(args, format);
int result = real_fprintf(stream, format, args);
va_end(args);
if (stream == stdout || stream == stderr) {
va_start(args, format);
real_fprintf(log_fd != -1 ? fdopen(log_fd, "w") : stream, format, args);
va_end(args);
}
return result;
}