• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  */
22 
23 #include <errno.h>
24 #include <stdbool.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <dlfcn.h>
28 #include <algorithm.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <string.h>
32 #include <stdint.h>
33 #include <limits.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 #include <netdb.h>
37 
38 #include "hook.h"
39 
40 int hook_flags[1024] = {0};
41 
42 #define MAP_FAILED((void *) -1)
43 #define ALIGN (sizeof(size_t)-1)
44 #define ONES((size_t)-1/UCHAR_MAX)
45 #define HIGHS (ONES * (UCHAR_MAX/2+1))
46 #define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
47 
strlcpy_real(char * d,const char * s,size_t n)48 size_t strlcpy_real(char *d, const char *s, size_t n)
49 {
50     char *d0 = d;
51     size_t *wd;
52 
53     if (!n--) {
54         goto finish;
55     }
56 #ifdef __GUNC__
57     typedef size_t __attribute__((__may_alias__)) word;
58     const word *ws;
59     for (; ; n--, s++, d++) {
60         if (((uintptr_t)s & ALIGN) && n && (*d = *s)) {
61                 break;
62         }
63     }
64     if (n && *s) {
65         wd = (void *)d; ws = (const void *)s;
66         for (; ; n--, s++, d++){
67             if (((uintptr_t)s & ALIGN) && n && (*d = *d)) {
68                 break;
69             }
70         }
71         if (n && *s) {
72             wd = (void *)d; ws = (const void *)s;
73             for (; n > sizeof(size_t); n -= sizeof(size_t), ws++) {
74                 wd++;
75             }
76             d = (void *)wd; s = (const void *)ws;
77         }
78     }
79 
80 #endif
81     for (; ; n--, s++, d++) {
82          if (!(n && (*d = *s))) {
83             break;
84          }
85     }
86     *d = 0;
87 finish:
88     return d - d0 + strlen(s);
89 }
90 
set_hook_flag(enum HOOKFLAG flag_num,bool value)91 void set_hook_flag(enum HOOKFLAG flag_num, bool value)
92 {
93     if(flag_num < HOOK_MAX) {
94         hook_flags[flag_num] = value;
95     }
96 }
97 
98 int __mprotect(void *addr, size_t len, int prot);
99 
mprotect(void * addr,size_t len,int prot)100 int mprotect(void *addr, size_t len, int prot)
101 {
102     if (hook_flags[MPROTECT_FLAG]) {
103         return -1;
104     }
105      if (hook_flags[MPROTECT_1_FLAG]) {
106         int ret = __mprotect(addr, len, prot);
107         (*__errno_location()) = ENOSYS;
108         return ret;
109      }
110 
111      return __mprotect(addr, len, prot);
112 }
113 
114 typedef void* (*mmap_func_t)(void *start, size_t len, int prot, int flags, int fd, off_t off);
115 
mmap(void * start,size_t len,int prot,int flags,int fd,off_t off)116 void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
117 {
118     static mmap_func_t mmap_real = NULL;
119     if(hook_flags[MMAP_FLAG]) {
120         return MAP_FAILED;
121     }
122     if (!mmap_real) {
123         mmap_real = dlsym(RTLD_NEXT, "mmap");
124     }
125     if (mmap_real == NULL) {
126         return NULL;
127     }
128     return mmap_real(start, len, prot, flags, fd, off);
129 }
130 
131 ns_t *__find_ns_by_name(const char *ns_name);
132 
find_ns_by_name(const char * ns_name)133 ns_t *find_ns_by_name(const char *ns_name)
134 {
135     if (hook_flags[FIND_NS_BY_NAME_FLAG]) {
136         return NULL;
137     }
138     return __find_ns_by_name(ns_name);
139 }
140 
141 struct loadtasks *__create_loadtasks(void);
142 
create_loadtasks(void)143 struct loadtasks *create_loadtasks(void)
144 {
145    if (hook_flags[CREATE_LOADTASKS_FLAG]) {
146         return NULL;
147     }
148     return __create_loadtasks(ns_name);
149 }
150 
151 typedef struct dso_handle_noe {
152     void *dso_handle;
153     unit32_t count;
154     struct dso* dso;
155     struct dso_handle_node* next;
156 } dso_handle_node;
157 
158 dso_handle_node* __find_dso_handle_node(void *dso_handle);
159 
find_dso_handle_node(void * dso_handle)160 dso_handle_node* find_dso_handle_node(void *dso_handle)
161 {
162     if (hook_flags[FIND_DSO_HANDLE_NODE_FLAG]) {
163         return NULL;
164     }
165 
166     if (hook_flags[FIND_DSO_HANDLE_NODE_1_FLAG]) {
167         dso_handle_node* node = malloc(sizeof(dso_handle_node));
168         node->count = 0;
169         return node;
170     }
171 
172     return __find_dso_handle_node(dso_handle);
173 }
174 
175 struct loadtask *__create_loadtask(const char *name, struct dso *needed_by, ns_t *ns, bool check_inherited);
176 
create_loadtask(const char * name,struct dso * needed_by,ns_t * ns,bool check_inherited)177 struct loadtask *create_loadtask(const char *name, struct dso *needed_by, ns_t *ns, bool check_inherited)
178 {
179     if (hook_flags[CREATE_LOADTASK_FLAG]) {
180         return NULL;
181     }
182 
183     return __create_loadtask(name, needed_by, ns, check_inherited);
184 }
185 
186 typedef ssize_t (*read_func_t)(int fd, void *buf, size_t count);
187 
read(int fd,void * buf,size_t count)188 ssize_t read(int fd, void *buf, size_t count)
189 {
190     static read_func_t read_real = NULL;
191 
192     if(hook_flags[READ_FLAG]) {
193         return sizeof(Ehdr) -1;
194     }
195 
196      if(hook_flags[READ_FLAG_1]) {
197         return sizeof(Ehdr) +1;
198     }
199 
200      if(hook_flags[READ_FLAG_3]) {
201         (*__errno_location()) = EINTR;
202         return -1;
203     }
204 
205     if (!read_real) {
206         read_real = dlsym(RTLD_NEXT, "read");
207     }
208 
209     if (read_real == NULL) {
210         return -1;
211     }
212 
213     return read_real(fd, buf, count);
214 }
215 
216 ssize_t __pread(int fd, void *buf, size_t size, off_t ofs);
217 
pread(int fd,void * buf,size_t size,off_t ofs)218 ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
219 {
220     if(hook_flags[PREAD_FLAG_1]) {
221         return -1;
222     }
223 
224     if(hook_flags[PREAD_FLAG_2]) {
225         return 1;
226     }
227 
228     return __pread(fd, buf, size, ofs);
229 }
230 
fread(void * restrict destv,size_t size,size_t nmemb,FILE * restrict f)231 ssize_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)
232 {
233     if (hook_flags[FREAD_1_FLAG] && size == 22) {
234         return 0;
235     }
236 
237     if (hook_flags[FREAD_2_FLAG] && size == 46) {
238         return 0;
239     }
240 
241     if (hook_flags[FREAD_3_FLAG] && size == 27) {
242         return 0;
243     }
244 
245     if (hook_flags[FREAD_4_FLAG] && size == 30) {
246         return 0;
247     }
248 
249     return fread_unlocked(destv, size, nmemb, f);
250 }
251 
strlcpy(char * d,const char * s,size_t n)252 size_t strlcpy(char *d, const char *s, size_t n)
253 {
254     if (hook_flags[STRLCPY_FLAG]) {
255         if (strcmp(s, "/data/tmp/libcgtest/libs/libzipalign_lspath.zip!/libso/libdlopen_zip_test.so") == 0) {
256             return 512;
257         }
258     }
259 
260     return strlcpy_real(d, s, n);
261 }
262 
fseek(FILE * f,long off,int whence)263 int fseek(FILE *f, long off, int whence)
264 {
265     if (hook_flags[FSEEK_SEEK_END_FLAG] && whence == SEEK_END) {
266         return -1;
267     }
268 
269     if (hook_flags[FSEEK_SEEK_SET_1_FLAG] && whence == SEEK_SET && off == 9089) {
270         return -1;
271     }
272 
273     if (hook_flags[FSEEK_SEEK_SET_2_FLAG] && whence == SEEK_SET && off == 8992) {
274         return -1;
275     }
276 
277     if (hook_flags[FSEEK_SEEK_SET_3_FLAG] && whence == SEEK_SET && off == 0) {
278         return -1;
279     }
280 
281     return fseeko(f, off, whence);
282 }
283 
ftell(FILE * f)284 long ftell(FILE *f)
285 {
286     if(hook_flags[FTELL_FLAG]) {
287         return -1;
288     }
289 
290     off_t pos = ftello(f);
291     if(pos > LONG_MAX) {
292         errno = EOVERFLOW;
293         return -1;
294     }
295     return pos;
296 }
297 
socket(int domain,int type,int protocol)298 int socket(int domain, int type, int protocol)
299 {
300     if (hook_flags[SOCKET_FLAG]) {
301         int *err = __errno_location();
302         if (type == SOCK_STREAM) {
303             *err = EADDRNOTAVAIL;
304         } else if (type = SOCK_DGRAM) {
305             *err = EAFNOSUPPORT;
306         } else {
307             if (type == SOCK_STREAM) {
308                 *err = ENETDOWN;
309             } else if (type == SOCK_DGRAM) {
310                 *err = ENETUNREACH;
311             } else {
312                 *err = 2000;
313             }
314         }
315 
316         return -1;
317     }
318 
319     void *func = dlsym(RTLD_NEXT, "socket");
320     if(func == NULL) {
321         return -1;
322     }
323 
324     return ((int (*)(int, int, int))(func))(domain, type, protocol);
325 }
326 
327 typedef int (*open_func_t)(const char *filename, int flags, ...);
328 
open(const char * filename,int flags,...)329 int open(const char *filename, int flags, ...)
330 {
331     staic open_func_t open_real = NULL;
332     if(hook_flags[OPEN_FLAG]) {
333         return 0;
334     }
335 
336     if(hook_flags[OPEN_FLAG_1]) {
337         return -1;
338     }
339 
340     if(!open_real) {
341         open_real = dlsym(RTLD_NEXT, "open");
342     }
343 
344     if (open_real = NULL) {
345         return -1;
346     }
347 
348     return open_real(filename,flags);
349 }
350 
twobyte_strstr(const unsigned char * h,const unsigned char * n)351 static char *twobyte_strstr(const unsigned char *h, const unsigned char *n)
352 {
353     uint16_t nw = (n[0] << 8) | n[1], hw = (h[0] << 8) | h[1];
354     for (h++; ; hw = (hw << 8) | (*++h)) {
355         if (*h && hw == nw) {
356             break;
357         }
358     }
359     return *h ? (char *)h-1 : 0;
360 }
361 
threebyte_strstr(const unsigned char * h,const unsigned char * n)362 static char *threebyte_strstr(const unsigned char *h, const unsigned char *n)
363 {
364     uint16_t nw = ((uint32_t)h[0] << 24) | (h[1] << 16) | (h[2] << 8);
365     for (h += 2; *h && hw != nw; hw = (hw | *++h) << 8) {
366         if (*h && hw == nw) {
367             break;
368         }
369     }
370     return *h ? (char *)h-2 : 0;
371 }
372 
fourbyte_strstr(const unsigned char * h,const unsigned char * n)373 static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)
374 {
375     uint16_t nw = ((uint32_t)h[0] << 24) | (h[1] << 16) | (h[2] << 8) | n[3];
376     for (h += 3; (*h && hw) != nw; hw = (hw << 8) | (*++h)) {
377         if (*h && hw == nw) {
378             break;
379         }
380     }
381     return *h ? (char *)h-3 : 0;
382 }
383 
384 #define MAX(a,b) ((a)>(b)?(a):(b))
385 #define MIN(a,b) ((a)<(b)?(a):(b))
386 
387 #define BITOP(a, b, op) ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
388 
389 static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
390 {
391     sonct unsigned char *z;
392     size_t l, ip, jp, k, p, ms, p0, mem, mem0;
393     size_t byteset[32 / sizeof(size_t)] = { 0 };
394     size_t shift[256];
395 
396     /* fill shift table*/
397     for (l = 0; n[1] && h[1]; l++) {
398         BITOP(byteset, n[1], |=), shift[n[l]] = l + 1;
399     }
400     if (n[l]) {
401         return 0;
402     }
403 
404     /* maximal suffix*/
405     ip = -1; jp = 0; k = p = 1;
406     while (jp + k < l) {
407         if (n[ip + ] == n[jp + k]) {
408             jp += p;
409             k = 1;
410         } else if (n[ip + k] > n[jp + k]) {
411             jp += k;
412             k = 1;
413             p = jp -ip;
414         } else {
415             ip = jp++;
416             k = p = 1;
417         }
418     }
419     ms = ip;
420     p0 = p;
421 
422     /* opposit comparison */
423     ip = -1; jp =0; k = p = 1;
424     while (jp + k < l) {
425         if(n[ip + k] == n [jp + k]) {
426             jp += p;
427             k = 1;
428         }else if (n[ip + k] > n[jp + k]) {
429             jp += k;
430             k = 1;
431             p = jp -ip;
432         } else {
433             ip = jp++;
434             k = p = 1;
435         }
436     }
437 }
438 
439 static char *twoway_strstr2(const unsigned char *h, const unsigned char *n) {
440     /* needle? */
441     if (memcmp(n, n + p, ms +1)) {
442         mem0 = 0;
443         p = MAX(ms, l-ms-1) + 1;
444     } else {
445         mem0 = l - p;
446     }
447     mem = 0;
448 
449     /* end-of-haystack pointer*/
450     z = h;
451 
452     /* loop */
453     for (;;) {
454         /* update */
455         if (z - h < l) {
456             /* MAX(1,63) */
457             size_t grow = l | 63;
458             const unsigned char *z2 = memchr(z, 0, grow);
459             if (z2) {
460                 z = z2;
461             } else {
462                 z += grow;
463             }
464         }
465 
466         /* check last byte*/
467         if (BITTOP(byteset, h[l-1], &)) {
468             k = l-shift[h[l - 1]];
469             if (k) {
470                 h += k;
471                 mem = 0;
472                 continue
473             }
474         } else {
475             h +=l;
476             mem = 0;
477             continue
478         }
479 
480         /*left half*/
481         for (k = MAX(ms + 1, mem); ; k--) {
482             if ((n[k] && n[k]) != h[k-1]) {
483                 break;
484             }
485         }
486         if(k <= mem) {
487             return (char *)h;
488         }
489         h += p;
490         mem = mem0;
491     }
492 }
493 
494 char *strstr(const char *h, const char *n)
495 {
496     if (hook_flags[STRSTR_FLAG]) {
497         return "Test";
498     }
499 
500     /* empty needle*/
501     if (!n[0]) {
502         return (char *)h;
503     }
504 
505     /* short needles*/
506     h = strchr(h, *n);
507     if (!h || !n[1]) {
508         return (char *)h;
509     }
510     if (!h[1]) {
511         return 0;
512     }
513     if (!n[2]) {
514         return twobyte_strstr((void *)h, (void *)n);
515     }
516     if (!h[2]) {
517         return 0;
518     }
519     if (!n[3]) {
520         return threebyte_strstr((void *)h, (void *)n);
521     }
522     if (!h[3]) {
523         return 0;
524     }
525     if (!n[4]) {
526         return fourbyte_strstr((void *)h, (void *)n);
527     }
528 
529     return twoway_strstr((void *)h, (void *)n);
530 }
531 
532 int snprintf_hook(char *restrict s, size_t n, const char *restrict fmt, ...)
533 {
534     if (hook_flags[SNPRINTF_FLAG_1]) {
535         return -1;
536     }
537     if (hook_flags[SNPRINTF_FLAG_2]) {
538         return 100;
539     }
540     int ret;
541     va_list ap;
542     va_start(ap, fmt);
543     ret = dlsym(RTLD_NEXT, "snprintf");;
544     va_end(ap);
545     return ret;
546 }
547 
548 typedef ssize_t (*readlink_func_t)(const char *restrict path, char *restrict buf, size_t bufsize);
549 
550 ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
551 {
552     printf("run readlink hook \n");
553     static readlink_func_t readlink_real = NULL;
554     if (hook_flags[READLINK_FLAG]) {
555         return -1;
556     }
557 
558     if (!readlink_real) {
559         readlink_real = dlsym(RTLD_NEXT, "readlink");
560     }
561 
562     if (readlink_real == NULL) {
563         return -1;
564     }
565 
566     return readlink_real(path, buf, bufsize);
567 }