Browse code

Initial commit

Dario Rodriguez authored on 01/11/2025 11:49:23
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,93 @@
1
+/*
2
+ * libyesterday.c
3
+ *
4
+ * Captures gettimeofday(), time() and clock_gettime() to simulate yesterday's date
5
+ *
6
+ * History:
7
+ *      01/11/2025 Creation.
8
+ *
9
+ * Documentation:
10
+ *      https://rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
11
+ *
12
+ * Usage examples:
13
+ *      # load date program with day set to yesterday
14
+ *      LD_PRELOAD=/path/to/libyesterday.so /bin/date
15
+ *      # load date program with day set to a week ago
16
+ *      LIBYESTERDAY=$((3600*24*7)) LD_PRELOAD=/path/to/libyesterday.so /bin/date
17
+ *
18
+ * Author: Dario Rodriguez antartica@whereismybit.com
19
+ * This program is licensed under the terms of the MIT/X license.
20
+ */
21
+
22
+#define _GNU_SOURCE
23
+#include <dlfcn.h>
24
+#include <time.h>
25
+#include <sys/time.h>
26
+#include <stdlib.h>
27
+
28
+typedef time_t (*time_fn_type)(time_t *tloc);
29
+typedef int (*gettimeofday_fn_type)(struct timeval *restrict tv, void *restrict tz);
30
+typedef int (*clock_gettime_fn_type)(clockid_t clockid, struct timespec *tp);
31
+
32
+static int
33
+libyesterdaydata(time_fn_type *paramtime_fn, gettimeofday_fn_type *paramgettimeofday_fn, clock_gettime_fn_type *paramclock_gettime_fn)
34
+{
35
+        static int init=0;
36
+        static int seconds=3600*24;
37
+        static time_fn_type realtimefn=(time_fn_type)NULL;
38
+        static gettimeofday_fn_type realgettimeofdayfn=(gettimeofday_fn_type)NULL;
39
+        static clock_gettime_fn_type realclock_gettimefn=(clock_gettime_fn_type)NULL;
40
+        if(init==0) {
41
+                char *ptr;
42
+                realtimefn = (time_fn_type)dlsym(RTLD_NEXT,"time");
43
+                realgettimeofdayfn = (gettimeofday_fn_type)dlsym(RTLD_NEXT,"gettimeofday");
44
+                realclock_gettimefn = (clock_gettime_fn_type)dlsym(RTLD_NEXT,"clock_gettime");
45
+                if((ptr=getenv("LIBYESTERDAY"))!=NULL)
46
+                        seconds=atoi(ptr);
47
+                init=1;
48
+        }
49
+        if(paramtime_fn!=NULL)
50
+                *paramtime_fn=realtimefn;
51
+        if(paramgettimeofday_fn!=NULL)
52
+                *paramgettimeofday_fn=realgettimeofdayfn;
53
+        if(paramclock_gettime_fn!=NULL)
54
+                *paramclock_gettime_fn=realclock_gettimefn;
55
+        return(seconds);
56
+}
57
+
58
+extern time_t time(time_t *tloc)
59
+{
60
+        time_fn_type realtimefn=(time_fn_type)NULL;
61
+        int seconds;
62
+        int res;
63
+        seconds=libyesterdaydata(&realtimefn,NULL,NULL);
64
+        res=realtimefn(NULL);
65
+        res-=seconds;
66
+        if(tloc!=NULL)
67
+                *tloc=res;
68
+        return(res);
69
+}
70
+
71
+extern int gettimeofday(struct timeval *restrict tv, void *restrict tz)
72
+{
73
+        static gettimeofday_fn_type realgettimeofdayfn=(gettimeofday_fn_type)NULL;
74
+        int seconds;
75
+        int res;
76
+        seconds=libyesterdaydata(NULL,&realgettimeofdayfn,NULL);
77
+        res=realgettimeofdayfn(tv,tz);
78
+        tv->tv_sec-=seconds;
79
+        return(res);
80
+}
81
+
82
+extern int clock_gettime(clockid_t clockid, struct timespec *tp)
83
+{
84
+        static clock_gettime_fn_type realclock_gettimefn=(clock_gettime_fn_type)NULL;
85
+        int seconds;
86
+        int res;
87
+        seconds=libyesterdaydata(NULL,NULL,&realclock_gettimefn);
88
+        res=realclock_gettimefn(clockid,tp);
89
+        tp->tv_sec-=seconds;
90
+        return(res);
91
+}
92
+
93
+