(input_data_buffer: bytes)
| 39 | print(f"Unmapped Memory R/W, trying to access {size:d} bytes at {addr:#010x} from {ql.arch.regs.pc:#010x}") |
| 40 | |
| 41 | def emulate_checksum_function(input_data_buffer: bytes) -> None: |
| 42 | print(f"\n--- Testing with input: {input_data_buffer.hex()} ---") |
| 43 | |
| 44 | test_file = "rootfs/blob/example_raw.bin" |
| 45 | |
| 46 | with open(test_file, "rb") as f: |
| 47 | raw_code: bytes = f.read() |
| 48 | |
| 49 | ql: Qiling = Qiling( |
| 50 | code=raw_code, |
| 51 | archtype=QL_ARCH.ARM, |
| 52 | ostype=QL_OS.BLOB, |
| 53 | profile="blob_raw.ql", |
| 54 | verbose=QL_VERBOSE.DEBUG, |
| 55 | thumb=True |
| 56 | ) |
| 57 | |
| 58 | ''' monkeypatch - Correcting the loader image name, used for coverage collection |
| 59 | removing all images with name 'blob_code' that were created by the blob loader. |
| 60 | This is necessary because some code coverage visualization tools require the |
| 61 | module name to match that of the input file ''' |
| 62 | ql.loader.images = [img for img in ql.loader.images if img.path != 'blob_code'] |
| 63 | ql.loader.images.append(Image(ql.loader.load_address, ql.loader.load_address + ql.os.code_ram_size, os.path.basename(test_file))) |
| 64 | |
| 65 | input_data_len: int = len(input_data_buffer) |
| 66 | |
| 67 | # Map memory for the data and stack |
| 68 | ql.mem.map(STACK_ADDR, 0x2000) |
| 69 | ql.mem.map(DATA_ADDR, ql.mem.align_up(input_data_len + 0x100)) # Map enough space for data |
| 70 | |
| 71 | # Write input data |
| 72 | ql.mem.write(DATA_ADDR, input_data_buffer) |
| 73 | |
| 74 | # Set up the stack pointer |
| 75 | ql.arch.regs.sp = STACK_ADDR + 0x2000 - 4 |
| 76 | # Set up argument registers |
| 77 | ql.arch.regs.r0 = DATA_ADDR |
| 78 | ql.arch.regs.r1 = input_data_len |
| 79 | |
| 80 | # Set the program counter to the function's entry point |
| 81 | ql.arch.regs.pc = CHECKSUM_FUNC_ADDR |
| 82 | |
| 83 | # Set the return address (LR) to a dummy address. |
| 84 | ql.arch.regs.lr = 0xbebebebe |
| 85 | |
| 86 | ql.hook_mem_unmapped(unmapped_handler) |
| 87 | #ql.debugger="gdb:127.0.0.1:9999" |
| 88 | |
| 89 | # Start emulation |
| 90 | print(f"Starting emulation at PC: {hex(ql.arch.regs.pc)}") |
| 91 | try: |
| 92 | with cov_utils.collect_coverage(ql, 'drcov', 'output.cov'): |
| 93 | ql.run(begin=CHECKSUM_FUNC_ADDR, end=END_ADDRESS) |
| 94 | except Exception as e: |
| 95 | print(f"Emulation error: {e}") |
| 96 | |
| 97 | print(f"Emulated checksum: {hex(ql.arch.regs.r0)}") |
| 98 |
no test coverage detected