]>
Commit | Line | Data |
---|---|---|
1 | #if defined(__GNUC__) && !defined(__STRICT_ANSI__) | |
2 | ||
3 | #define _GNU_SOURCE 1 | |
4 | ||
5 | #if defined(RTLD_NEXT) | |
6 | #define REAL_LIBC RTLD_NEXT | |
7 | #else | |
8 | #define REAL_LIBC ((void *) -1L) | |
9 | #endif | |
10 | ||
11 | #include <dlfcn.h> | |
12 | #include <stdarg.h> | |
13 | #include <stdlib.h> | |
14 | #include <string.h> | |
15 | #include <unistd.h> | |
16 | #include <fcntl.h> | |
17 | #include <sys/types.h> | |
18 | #include <sys/stat.h> | |
19 | #include <sys/time.h> | |
20 | #include <stdio.h> | |
21 | ||
22 | #define SNIFFLEN 4096 | |
23 | ||
24 | void hexdump(unsigned char *buf, int len); | |
25 | ||
26 | struct header_struct { | |
27 | unsigned long dwHeader; | |
28 | void* data; | |
29 | unsigned long dwSize; | |
30 | }; | |
31 | ||
32 | struct version_struct { | |
33 | unsigned long versionul; | |
34 | char version[128]; | |
35 | }; | |
36 | ||
37 | struct license_struct { | |
38 | char cLicense[128]; // Buffer with license string to put. | |
39 | // If empty string then get current license setting | |
40 | // into dwLicense. | |
41 | unsigned long dwLicense; // Returns license settings: LICENSE_DEMO, LICENSE_WD | |
42 | // etc..., or 0 for invalid license. | |
43 | unsigned long dwLicense2; // Returns additional license settings, if dwLicense | |
44 | // could not hold all the information. | |
45 | // Then dwLicense will return 0. | |
46 | }; | |
47 | ||
48 | #define WD_IOCTL_HEADER_CODE 0xa410b413UL | |
49 | ||
50 | void parse_wdioctlreq(unsigned char *wdioctl, unsigned int request) { | |
51 | struct header_struct* wdheader = (struct header_struct*)wdioctl; | |
52 | ||
53 | if (wdheader->dwHeader != WD_IOCTL_HEADER_CODE) { | |
54 | fprintf(stderr,"!!!ERROR: Header does not match!!!\n"); | |
55 | return; | |
56 | } | |
57 | ||
58 | fprintf(stderr, "Request: "); | |
59 | switch(request) { | |
60 | case 0x910: | |
61 | fprintf(stderr,"IOCTL_WD_VERSION"); | |
62 | //fprintf(stderr," %s(%d)", ((struct version_struct*)(wdheader->data))->version, ((struct version_struct*)(wdheader->data))->versionul); | |
63 | break; | |
64 | case 0x952: | |
65 | fprintf(stderr,"IOCTL_WD_LICENSE"); | |
66 | break; | |
67 | case 0x98c: | |
68 | fprintf(stderr,"IOCTL_WD_TRANSFER"); | |
69 | break; | |
70 | case 0x983: | |
71 | fprintf(stderr,"IOCTL_WDU_TRANSFER"); | |
72 | break; | |
73 | case 0x987: | |
74 | fprintf(stderr,"IOCTL_WD_EVENT_UNREGISTER"); | |
75 | break; | |
76 | case 0x91f: | |
77 | fprintf(stderr,"IOCTL_WD_INT_DISABLE"); | |
78 | break; | |
79 | case 0x94b: | |
80 | fprintf(stderr,"IOCTL_WD_INT_WAIT"); | |
81 | break; | |
82 | case 0x92b: | |
83 | fprintf(stderr,"IOCTL_WD_CARD_UNREGISTER"); | |
84 | break; | |
85 | case 0x9a7: | |
86 | fprintf(stderr,"IOCTL_WDU_GET_DEVICE_DATA"); | |
87 | break; | |
88 | case 0x98e: | |
89 | fprintf(stderr,"IOCTL_WD_INT_ENABLE"); | |
90 | break; | |
91 | case 0x988: | |
92 | fprintf(stderr,"IOCTL_WD_EVENT_PULL"); | |
93 | break; | |
94 | case 0x981: | |
95 | fprintf(stderr,"IOCTL_WDU_SET_INTERFACE"); | |
96 | break; | |
97 | default: | |
98 | fprintf(stderr,"Unknown(%x)",request); | |
99 | } | |
100 | ||
101 | fprintf(stderr, ", size: %d\n", wdheader->dwSize); | |
102 | } | |
103 | ||
104 | void parse_wdioctlans(unsigned char *wdioctl, unsigned int request, int result) { | |
105 | struct header_struct* wdheader = (struct header_struct*)wdioctl; | |
106 | ||
107 | if (wdheader->dwHeader != WD_IOCTL_HEADER_CODE) { | |
108 | fprintf(stderr,"!!!ERROR: Header does not match!!!\n"); | |
109 | return; | |
110 | } | |
111 | ||
112 | fprintf(stderr, "Answer: %d ", result); | |
113 | switch(request) { | |
114 | case 0x910: | |
115 | fprintf(stderr,"\"%s\" (%d)", ((struct version_struct*)(wdheader->data))->version, ((struct version_struct*)(wdheader->data))->versionul); | |
116 | break; | |
117 | case 0x952: | |
118 | fprintf(stderr,"\"%s\" (XX,XX)", ((struct license_struct*)(wdheader->data))->cLicense); | |
119 | break; | |
120 | default: | |
121 | break; | |
122 | } | |
123 | fprintf(stderr, "\n"); | |
124 | } | |
125 | ||
126 | ||
127 | typedef int (*open_funcptr_t) (const char *, int, mode_t); | |
128 | ||
129 | static windrvrfd = 0; | |
130 | static void* mmapped = NULL; | |
131 | static size_t mmapplen = 0; | |
132 | ||
133 | int open (const char *pathname, int flags, ...) | |
134 | { | |
135 | static open_funcptr_t func = NULL; | |
136 | mode_t mode = 0; | |
137 | va_list args; | |
138 | int fd; | |
139 | ||
140 | if (!func) | |
141 | func = (open_funcptr_t) dlsym (REAL_LIBC, "open"); | |
142 | ||
143 | if (flags & O_CREAT) { | |
144 | va_start(args, flags); | |
145 | mode = va_arg(args, mode_t); | |
146 | va_end(args); | |
147 | } | |
148 | ||
149 | fd = (*func) (pathname, flags, mode); | |
150 | ||
151 | if (!strcmp (pathname, "/dev/windrvr6")) { | |
152 | fprintf(stderr,"opening windrvr6\n"); | |
153 | windrvrfd = fd; | |
154 | } | |
155 | ||
156 | return fd; | |
157 | } | |
158 | ||
159 | void diff(unsigned char *buf1, unsigned char *buf2, int len) { | |
160 | int i; | |
161 | ||
162 | for(i=0; i<len; i++) { | |
163 | if (buf1[i] != buf2[i]) { | |
164 | fprintf(stderr,"Diff at %d: %02x(%c)->%02x(%c)\n", i, buf1[i], ((buf1[i] >= 31 && buf1[i] <= 126)?buf1[i]:'.'), buf2[i], ((buf2[i] >= 31 && buf2[i] <= 126)?buf2[i]:'.')); | |
165 | } | |
166 | } | |
167 | } | |
168 | ||
169 | void hexdump(unsigned char *buf, int len) { | |
170 | int i; | |
171 | ||
172 | for(i=0; i<len; i++) { | |
173 | fprintf(stderr,"%02x ", buf[i]); | |
174 | if ((i % 16) == 15) | |
175 | fprintf(stderr,"\n"); | |
176 | } | |
177 | } | |
178 | ||
179 | int ioctl(int fd, int request, ...) | |
180 | { | |
181 | static int (*func) (int, int, void *) = NULL; | |
182 | va_list args; | |
183 | void *argp; | |
184 | unsigned char prebuf[SNIFFLEN]; | |
185 | int ret; | |
186 | ||
187 | if (!func) | |
188 | func = (int (*) (int, int, void *)) dlsym (REAL_LIBC, "ioctl"); | |
189 | ||
190 | va_start (args, request); | |
191 | argp = va_arg (args, void *); | |
192 | va_end (args); | |
193 | ||
194 | if (fd == windrvrfd) { | |
195 | memcpy(prebuf, argp, SNIFFLEN); | |
196 | parse_wdioctlreq(argp, request); | |
197 | } | |
198 | ||
199 | ret = (*func) (fd, request, argp); | |
200 | ||
201 | if (fd == windrvrfd) { | |
202 | parse_wdioctlans(argp, request, ret); | |
203 | } | |
204 | return ret; | |
205 | } | |
206 | ||
207 | void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) | |
208 | { | |
209 | static void* (*func) (void *, size_t, int, int, int, off_t) = NULL; | |
210 | void *ret; | |
211 | ||
212 | if (!func) | |
213 | func = (void* (*) (void *, size_t, int, int, int, off_t)) dlsym (REAL_LIBC, "mmap"); | |
214 | ||
215 | ret = (*func) (start, length, prot, flags, fd, offset); | |
216 | fprintf(stderr,"MMAP: %x, %d, %d, %d, %d, %d -> %x\n", (unsigned int)start, length, prot, flags, fd, offset, (unsigned int)ret); | |
217 | mmapped = ret; | |
218 | mmapplen = length; | |
219 | ||
220 | return ret; | |
221 | } | |
222 | ||
223 | void *mmap64(void *start, size_t length, int prot, int flags, int fd, off64_t offset) | |
224 | { | |
225 | static void* (*func) (void *, size_t, int, int, int, off64_t) = NULL; | |
226 | void *ret; | |
227 | ||
228 | if (!func) | |
229 | func = (void* (*) (void *, size_t, int, int, int, off64_t)) dlsym (REAL_LIBC, "mmap64"); | |
230 | ||
231 | ret = (*func) (start, length, prot, flags, fd, offset); | |
232 | fprintf(stderr,"MMAP64: %x, %d, %d, %d, %d, %lld -> %x\n", (unsigned int)start, length, prot, flags, fd, offset, (unsigned int)ret); | |
233 | mmapped = ret; | |
234 | mmapplen = length; | |
235 | ||
236 | return ret; | |
237 | } | |
238 | ||
239 | void *mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset) | |
240 | { | |
241 | static void* (*func) (void *, size_t, int, int, int, off_t) = NULL; | |
242 | void *ret; | |
243 | ||
244 | if (!func) | |
245 | func = (void* (*) (void *, size_t, int, int, int, off_t)) dlsym (REAL_LIBC, "mmap2"); | |
246 | ||
247 | ret = (*func) (start, length, prot, flags, fd, pgoffset); | |
248 | fprintf(stderr,"MMAP2: %x, %d, %d, %d, %d, %d -> %x\n", (unsigned int)start, length, prot, flags, fd, pgoffset, (unsigned int)ret); | |
249 | mmapped = ret; | |
250 | mmapplen = length; | |
251 | ||
252 | return ret; | |
253 | } | |
254 | ||
255 | void *malloc(size_t size) | |
256 | { | |
257 | static void* (*func) (size_t) = NULL; | |
258 | void *ret; | |
259 | ||
260 | if (!func) | |
261 | func = (void* (*) (size_t)) dlsym(REAL_LIBC, "malloc"); | |
262 | ||
263 | ret = (*func) (size); | |
264 | ||
265 | //fprintf(stderr,"MALLOC: %d -> %x\n", size, (unsigned int) ret); | |
266 | ||
267 | return ret; | |
268 | } | |
269 | ||
270 | ||
271 | #endif |