(self, elffile: ELFFile, stack_addr: int, loadbase: int = 0)
| 594 | return rev_reloc_symbols |
| 595 | |
| 596 | def load_driver(self, elffile: ELFFile, stack_addr: int, loadbase: int = 0) -> None: |
| 597 | elfdata_mapping = self.get_elfdata_mapping(elffile) |
| 598 | |
| 599 | mem_start = self.ql.mem.align(loadbase) |
| 600 | mem_end = self.ql.mem.align_up(loadbase + len(elfdata_mapping)) |
| 601 | |
| 602 | # map some memory to intercept external functions of Linux kernel |
| 603 | self.ql.mem.map(API_HOOK_MEM, API_HOOK_SIZE, info="[api_mem]") |
| 604 | |
| 605 | self.ql.log.debug(f'mem_start : {mem_start:#x}') |
| 606 | self.ql.log.debug(f'mem_end : {mem_end:#x}') |
| 607 | |
| 608 | self.ql.mem.map(mem_start, mem_end - mem_start, info=os.path.basename(self.ql.path)) |
| 609 | self.ql.mem.write(loadbase, elfdata_mapping) |
| 610 | |
| 611 | self.images.append(Image(mem_start, mem_end, os.path.abspath(self.path))) |
| 612 | |
| 613 | init_module = loadbase + self.lkm_get_init(elffile) |
| 614 | self.ql.log.debug(f'init_module : {init_module:#x}') |
| 615 | |
| 616 | self.brk_address = mem_end |
| 617 | |
| 618 | # Set MMAP addr |
| 619 | mmap_address = self.profile.getint('mmap_address') |
| 620 | self.ql.log.debug(f'mmap_address is : {mmap_address:#x}') |
| 621 | |
| 622 | # there is no interperter so emulation entry point is also elf entry |
| 623 | self.elf_entry = self.entry_point = init_module |
| 624 | self.ql.os.entry_point = self.entry_point |
| 625 | |
| 626 | self.stack_address = self.ql.mem.align(stack_addr, self.ql.arch.pointersize) |
| 627 | self.load_address = loadbase |
| 628 | |
| 629 | # setup syscall table |
| 630 | self.ql.mem.map(SYSCALL_MEM, SYSCALL_SIZE, info="[syscall_mem]") |
| 631 | self.ql.mem.write(SYSCALL_MEM, b'\x00' * SYSCALL_SIZE) |
| 632 | |
| 633 | rev_reloc_symbols = self.lkm_dynlinker(elffile, loadbase) |
| 634 | |
| 635 | # iterate over relocatable symbols, but pick only those who start with 'sys_' |
| 636 | for sc, addr in rev_reloc_symbols.items(): |
| 637 | if sc.startswith('sys_') and sc != 'sys_call_table': |
| 638 | tmp_sc = sc[4:] |
| 639 | |
| 640 | if hasattr(SYSCALL_NR, tmp_sc): |
| 641 | syscall_id = getattr(SYSCALL_NR, tmp_sc).value |
| 642 | dest = SYSCALL_MEM + syscall_id * self.ql.arch.pointersize |
| 643 | |
| 644 | self.ql.log.debug(f'Writing syscall {tmp_sc} to {dest:#x}') |
| 645 | self.ql.mem.write_ptr(dest, addr) |
| 646 | |
| 647 | # write syscall addresses into syscall table |
| 648 | self.ql.mem.write_ptr(SYSCALL_MEM + 0 * self.ql.arch.pointersize, self.ql.os.hook_addr + 0 * self.ql.arch.pointersize) |
| 649 | self.ql.mem.write_ptr(SYSCALL_MEM + 1 * self.ql.arch.pointersize, self.ql.os.hook_addr + 1 * self.ql.arch.pointersize) |
| 650 | self.ql.mem.write_ptr(SYSCALL_MEM + 2 * self.ql.arch.pointersize, self.ql.os.hook_addr + 2 * self.ql.arch.pointersize) |
| 651 | |
| 652 | # setup hooks for read/write/open syscalls |
| 653 | self.import_symbols[self.ql.os.hook_addr + 0 * self.ql.arch.pointersize] = hook_sys_read |
no test coverage detected