cdc711dc |
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 |