|
18 | 18 | #include <sys/stat.h> |
19 | 19 | #include <unistd.h> |
20 | 20 |
|
21 | | -#ifdef SUPPLEMENTAL__SYSCALL_RECORD |
| 21 | +#ifdef __FreeBSD__ |
| 22 | +#define PROCFS_MAP "/proc/self/map" |
| 23 | +#else |
| 24 | +#define PROCFS_MAP "/proc/self/maps" |
| 25 | +#endif |
| 26 | + |
| 27 | +#ifndef SUPPLEMENTAL__SYSCALL_RECORD |
| 28 | +#define SUPPLEMENTAL__SYSCALL_RECORD 0 |
| 29 | +#endif |
| 30 | + |
| 31 | +#if SUPPLEMENTAL__SYSCALL_RECORD |
22 | 32 | /* |
23 | 33 | * SUPPLEMENTAL: syscall record without syscalls |
24 | 34 | */ |
@@ -203,7 +213,7 @@ static long (*hook_fn)(int64_t a1, int64_t a2, int64_t a3, int64_t a4, |
203 | 213 | long syscall_hook(int64_t x0, int64_t x1, int64_t x2, int64_t x3, int64_t x4, |
204 | 214 | int64_t x5, int64_t x8, /* syscall NR */ |
205 | 215 | int64_t retptr) { |
206 | | -#ifdef SUPPLEMENTAL__SYSCALL_RECORD |
| 216 | +#if SUPPLEMENTAL__SYSCALL_RECORD |
207 | 217 | bm_increment(x8); |
208 | 218 | #endif /* SUPPLEMENTAL__SYSCALL_RECORD */ |
209 | 219 | return hook_fn(x0, x1, x2, x3, x4, x5, x8, retptr); |
@@ -498,72 +508,121 @@ static void scan_exec_code(char *code, size_t code_size, int mem_prot, |
498 | 508 | close(fd); |
499 | 509 | } |
500 | 510 |
|
501 | | -/* entry point for binary scanning */ |
| 511 | +#ifdef __FreeBSD__ |
| 512 | +/* entry point for binary scanning on FreeBSD */ |
502 | 513 | static void scan_code(void) { |
503 | 514 | LIST_INIT(&head); |
504 | 515 |
|
505 | 516 | FILE *fp = NULL; |
506 | 517 | /* get memory mapping information from procfs */ |
507 | | - assert((fp = fopen("/proc/self/maps", "r")) != NULL); |
508 | | - { |
509 | | - char buf[4096]; |
510 | | - while (fgets(buf, sizeof(buf), fp) != NULL) { |
511 | | - /* we do not touch stack memory */ |
512 | | - if (strstr(buf, "[stack]") != NULL) { |
513 | | - continue; |
514 | | - } |
515 | | - int i = 0; |
516 | | - char addr[65] = {0}; |
517 | | - int64_t addr_start = 0; |
518 | | - int64_t addr_end = 0; |
519 | | - int mem_prot = 0; |
520 | | - char *c = strtok(buf, " "); |
521 | | - while (c != NULL) { |
522 | | - switch (i) { |
523 | | - case 0: |
524 | | - strncpy(addr, c, sizeof(addr) - 1); |
525 | | - break; |
526 | | - case 1: { |
527 | | - for (size_t j = 0; j < strlen(c); j++) { |
528 | | - if (c[j] == 'r') mem_prot |= PROT_READ; |
529 | | - if (c[j] == 'w') mem_prot |= PROT_WRITE; |
530 | | - if (c[j] == 'x') mem_prot |= PROT_EXEC; |
531 | | - } |
532 | | - size_t k = 0; |
533 | | - for (k = 0; k < strlen(addr); k++) { |
534 | | - if (addr[k] == '-') { |
535 | | - addr[k] = '\0'; |
536 | | - break; |
537 | | - } |
538 | | - } |
539 | | - addr_start = strtol(&addr[0], NULL, 16); |
540 | | - addr_end = strtol(&addr[k + 1], NULL, 16); |
541 | | - } break; |
542 | | - case 5: { |
543 | | - char *path = NULL; |
544 | | - size_t path_len = 0; |
545 | | - /* get the path of the code */ |
546 | | - if (c[0] == '/') { |
547 | | - path = strndup(c, sizeof(buf) - 1); |
548 | | - path_len = strnlen(path, sizeof(buf) - 1); |
549 | | - path[path_len - 1] = '\0'; |
550 | | - } |
551 | | - /* scan code if the memory is executable */ |
| 518 | + assert((fp = fopen(PROCFS_MAP, "r")) != NULL); |
| 519 | + char buf[4096]; |
| 520 | + while (fgets(buf, sizeof(buf), fp) != NULL) { |
| 521 | + /* we do not touch stack memory */ |
| 522 | + if (strstr(buf, "[stack]") != NULL) { |
| 523 | + continue; |
| 524 | + } |
| 525 | + int mem_prot = 0; |
| 526 | + int i = 0; |
| 527 | + char from_addr[65] = {0}; |
| 528 | + char to_addr[65] = {0}; |
| 529 | + char *c = strtok(buf, " "); |
| 530 | + while (c != NULL) { |
| 531 | + switch (i) { |
| 532 | + case 0: |
| 533 | + strncpy(from_addr, c, sizeof(from_addr) - 1); |
| 534 | + break; |
| 535 | + case 1: |
| 536 | + strncpy(to_addr, c, sizeof(to_addr) - 1); |
| 537 | + break; |
| 538 | + case 5: |
| 539 | + for (size_t j = 0; j < strlen(c); j++) { |
| 540 | + if (c[j] == 'r') mem_prot |= PROT_READ; |
| 541 | + if (c[j] == 'w') mem_prot |= PROT_WRITE; |
| 542 | + if (c[j] == 'x') mem_prot |= PROT_EXEC; |
| 543 | + } |
| 544 | + break; |
| 545 | + case 9: |
| 546 | + if (strncmp(c, "COW", 3) == 0) { |
| 547 | + int64_t from = strtol(&from_addr[0], NULL, 16); |
| 548 | + int64_t to = strtol(&to_addr[0], NULL, 16); |
552 | 549 | if (mem_prot & PROT_EXEC) { |
553 | | - scan_exec_code((char *)addr_start, (size_t)addr_end - addr_start, |
554 | | - mem_prot, path); |
| 550 | + scan_exec_code((char *)from, (size_t)to - from, mem_prot, NULL); |
| 551 | + } |
| 552 | + } |
| 553 | + break; |
| 554 | + } |
| 555 | + if (i == 9) break; |
| 556 | + c = strtok(NULL, " "); |
| 557 | + i++; |
| 558 | + } |
| 559 | + } |
| 560 | + fclose(fp); |
| 561 | +} |
| 562 | +#else |
| 563 | +/* entry point for binary scanning on Linux */ |
| 564 | +static void scan_code(void) { |
| 565 | + LIST_INIT(&head); |
| 566 | + |
| 567 | + FILE *fp = NULL; |
| 568 | + /* get memory mapping information from procfs */ |
| 569 | + assert((fp = fopen(PROCFS_MAP, "r")) != NULL); |
| 570 | + char buf[4096]; |
| 571 | + while (fgets(buf, sizeof(buf), fp) != NULL) { |
| 572 | + /* we do not touch stack memory */ |
| 573 | + if (strstr(buf, "[stack]") != NULL) { |
| 574 | + continue; |
| 575 | + } |
| 576 | + int mem_prot = 0; |
| 577 | + int i = 0; |
| 578 | + char addr[65] = {0}; |
| 579 | + int64_t addr_start = 0; |
| 580 | + int64_t addr_end = 0; |
| 581 | + char *c = strtok(buf, " "); |
| 582 | + while (c != NULL) { |
| 583 | + switch (i) { |
| 584 | + case 0: |
| 585 | + strncpy(addr, c, sizeof(addr) - 1); |
| 586 | + break; |
| 587 | + case 1: |
| 588 | + for (size_t j = 0; j < strlen(c); j++) { |
| 589 | + if (c[j] == 'r') mem_prot |= PROT_READ; |
| 590 | + if (c[j] == 'w') mem_prot |= PROT_WRITE; |
| 591 | + if (c[j] == 'x') mem_prot |= PROT_EXEC; |
| 592 | + } |
| 593 | + size_t k = 0; |
| 594 | + for (k = 0; k < strlen(addr); k++) { |
| 595 | + if (addr[k] == '-') { |
| 596 | + addr[k] = '\0'; |
| 597 | + break; |
555 | 598 | } |
556 | | - break; |
557 | 599 | } |
| 600 | + addr_start = strtol(&addr[0], NULL, 16); |
| 601 | + addr_end = strtol(&addr[k + 1], NULL, 16); |
| 602 | + break; |
| 603 | + case 5: { |
| 604 | + char *path = NULL; |
| 605 | + size_t path_len = 0; |
| 606 | + if (c[0] == '/') { |
| 607 | + path = strndup(c, sizeof(buf) - 1); |
| 608 | + path_len = strnlen(path, sizeof(buf) - 1); |
| 609 | + path[path_len - 1] = '\0'; |
| 610 | + } |
| 611 | + if (mem_prot & PROT_EXEC) { |
| 612 | + scan_exec_code((char *)addr_start, (size_t)addr_end - addr_start, |
| 613 | + mem_prot, path); |
| 614 | + } |
| 615 | + break; |
558 | 616 | } |
559 | | - if (i == 5) break; |
560 | | - c = strtok(NULL, " "); |
561 | | - i++; |
562 | 617 | } |
| 618 | + if (i == 5) break; |
| 619 | + c = strtok(NULL, " "); |
| 620 | + i++; |
563 | 621 | } |
564 | 622 | } |
565 | 623 | fclose(fp); |
566 | 624 | } |
| 625 | +#endif |
567 | 626 |
|
568 | 627 | /* entry point for binary rewriting */ |
569 | 628 | static void rewrite_code(void) { |
@@ -817,7 +876,7 @@ static void load_hook_lib(void) { |
817 | 876 | } |
818 | 877 |
|
819 | 878 | __attribute__((constructor(0xffff))) static void __svc_hook_init(void) { |
820 | | -#ifdef SUPPLEMENTAL__SYSCALL_RECORD |
| 879 | +#if SUPPLEMENTAL__SYSCALL_RECORD |
821 | 880 | bm_init(); |
822 | 881 | #endif /* SUPPLEMENTAL__SYSCALL_RECORD */ |
823 | 882 | scan_code(); |
|
0 commit comments