|
18 | 18 | #include <sys/stat.h> |
19 | 19 | #include <unistd.h> |
20 | 20 |
|
21 | | -#ifdef __FreeBSD__ |
| 21 | +#if defined(__FreeBSD__) || defined(__NetBSD__) |
22 | 22 | #define PROCFS_MAP "/proc/self/map" |
23 | 23 | #else |
24 | 24 | #define PROCFS_MAP "/proc/self/maps" |
@@ -120,7 +120,7 @@ void ____asm_impl(void) { |
120 | 120 | "adrp x6, :got:syscall_table \n\t" |
121 | 121 | "ldr x6, [x6, #:got_lo12:syscall_table] \n\t" |
122 | 122 | "ldr x6, [x6] \n\t" |
123 | | - "add x6, x6, xzr, lsl #3 \n\t" |
| 123 | + "add x6, x6, x8, lsl #3 \n\t" |
124 | 124 | "br x6 \n\t"); |
125 | 125 |
|
126 | 126 | /* |
@@ -189,7 +189,9 @@ void ____asm_impl(void) { |
189 | 189 |
|
190 | 190 | /* arguments for syscall_hook */ |
191 | 191 | "mov x7, x14 \n\t" /* return address */ |
| 192 | +#if !defined(__NetBSD__) |
192 | 193 | "mov x6, x8 \n\t" /* syscall NR */ |
| 194 | +#endif /* !defined(__NetBSD__) */ |
193 | 195 |
|
194 | 196 | "bl syscall_hook \n\t" |
195 | 197 |
|
@@ -508,7 +510,7 @@ static void scan_exec_code(char *code, size_t code_size, int mem_prot, |
508 | 510 | close(fd); |
509 | 511 | } |
510 | 512 |
|
511 | | -#ifdef __FreeBSD__ |
| 513 | +#if defined(__FreeBSD__) |
512 | 514 | /* entry point for binary scanning on FreeBSD */ |
513 | 515 | static void scan_code(void) { |
514 | 516 | LIST_INIT(&head); |
@@ -559,6 +561,57 @@ static void scan_code(void) { |
559 | 561 | } |
560 | 562 | fclose(fp); |
561 | 563 | } |
| 564 | +#elif defined(__NetBSD__) |
| 565 | +/* entry point for binary scanning on NetBSD */ |
| 566 | +static void scan_code(void) { |
| 567 | + LIST_INIT(&head); |
| 568 | + |
| 569 | + FILE *fp = NULL; |
| 570 | + /* get memory mapping information from procfs */ |
| 571 | + assert((fp = fopen(PROCFS_MAP, "r")) != NULL); |
| 572 | + char buf[4096]; |
| 573 | + while (fgets(buf, sizeof(buf), fp) != NULL) { |
| 574 | + /* we do not touch stack memory */ |
| 575 | + if (strstr(buf, "[stack]") != NULL) { |
| 576 | + continue; |
| 577 | + } |
| 578 | + int mem_prot = 0; |
| 579 | + int i = 0; |
| 580 | + char from_addr[65] = {0}; |
| 581 | + char to_addr[65] = {0}; |
| 582 | + char *c = strtok(buf, " "); |
| 583 | + while (c != NULL) { |
| 584 | + switch (i) { |
| 585 | + case 0: |
| 586 | + strncpy(from_addr, c, sizeof(from_addr) - 1); |
| 587 | + break; |
| 588 | + case 1: |
| 589 | + strncpy(to_addr, c, sizeof(to_addr) - 1); |
| 590 | + break; |
| 591 | + case 2: |
| 592 | + for (size_t j = 0; j < strlen(c); j++) { |
| 593 | + if (c[j] == 'r') mem_prot |= PROT_READ; |
| 594 | + if (c[j] == 'w') mem_prot |= PROT_WRITE; |
| 595 | + if (c[j] == 'x') mem_prot |= PROT_EXEC; |
| 596 | + } |
| 597 | + break; |
| 598 | + case 4: |
| 599 | + if (strncmp(c, "COW", 3) == 0) { |
| 600 | + int64_t from = strtol(&from_addr[0], NULL, 16); |
| 601 | + int64_t to = strtol(&to_addr[0], NULL, 16); |
| 602 | + if (mem_prot & PROT_EXEC) { |
| 603 | + scan_exec_code((char *)from, (size_t)to - from, mem_prot, NULL); |
| 604 | + } |
| 605 | + } |
| 606 | + break; |
| 607 | + } |
| 608 | + if (i == 4) break; |
| 609 | + c = strtok(NULL, " "); |
| 610 | + i++; |
| 611 | + } |
| 612 | + } |
| 613 | + fclose(fp); |
| 614 | +} |
562 | 615 | #else |
563 | 616 | /* entry point for binary scanning on Linux */ |
564 | 617 | static void scan_code(void) { |
|
0 commit comments