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