|
8 | 8 |
|
9 | 9 | from qiling.core import Qiling |
10 | 10 | from qiling.const import QL_ARCH, QL_OS, QL_VERBOSE |
11 | | -from qiling.os.const import STRING |
| 11 | +from qiling.os.const import STRING, SIZE_T, POINTER |
12 | 12 |
|
13 | 13 |
|
14 | | -def get_kaimendaji_password(): |
15 | | - def my_getenv(ql: Qiling): |
16 | | - env = { |
17 | | - "ID" : b"000000000000000", |
18 | | - "ethaddr" : b"11:22:33:44:55:66" |
19 | | - } |
| 14 | +def my_getenv(ql: Qiling): |
| 15 | + env = { |
| 16 | + "ID" : b"000000000000000", |
| 17 | + "ethaddr" : b"11:22:33:44:55:66" |
| 18 | + } |
20 | 19 |
|
21 | | - params = ql.os.resolve_fcall_params({'key': STRING}) |
22 | | - value = env.get(params["key"], b"") |
| 20 | + params = ql.os.resolve_fcall_params({'key': STRING}) |
| 21 | + value = env.get(params["key"], b"") |
23 | 22 |
|
24 | | - value_addr = ql.os.heap.alloc(len(value)) |
25 | | - ql.mem.write(value_addr, value) |
| 23 | + value_addr = ql.os.heap.alloc(len(value)) |
| 24 | + ql.mem.write(value_addr, value) |
26 | 25 |
|
27 | | - ql.arch.regs.r0 = value_addr |
28 | | - ql.arch.regs.arch_pc = ql.arch.regs.lr |
| 26 | + ql.arch.regs.r0 = value_addr |
| 27 | + ql.arch.regs.arch_pc = ql.arch.regs.lr |
29 | 28 |
|
30 | | - def get_password(ql: Qiling): |
31 | | - password_raw = ql.mem.read(ql.arch.regs.r0, ql.arch.regs.r2) |
32 | 29 |
|
33 | | - password = '' |
34 | | - for item in password_raw: |
35 | | - if 0 <= item <= 9: |
36 | | - password += chr(item + 48) |
37 | | - else: |
38 | | - password += chr(item + 87) |
| 30 | +def get_password(ql: Qiling): |
| 31 | + # we land on a memcmp call, where the real password is being compared to |
| 32 | + # the one provided by the user. we can follow the arguments to read the |
| 33 | + # real password |
39 | 34 |
|
40 | | - print("The password is: %s" % password) |
| 35 | + params = ql.os.resolve_fcall_params({ |
| 36 | + 'ptr1': POINTER, # points to real password |
| 37 | + 'ptr2': POINTER, # points to user provided password |
| 38 | + 'size': SIZE_T # comparison length |
| 39 | + }) |
41 | 40 |
|
42 | | - def partial_run_init(ql: Qiling): |
43 | | - # argv prepare |
44 | | - ql.arch.regs.arch_sp -= 0x30 |
45 | | - arg0_ptr = ql.arch.regs.arch_sp |
46 | | - ql.mem.write(arg0_ptr, b"kaimendaji") |
| 41 | + ptr1 = params['ptr1'] |
| 42 | + size = params['size'] |
47 | 43 |
|
48 | | - ql.arch.regs.arch_sp -= 0x10 |
49 | | - arg1_ptr = ql.arch.regs.arch_sp |
50 | | - ql.mem.write(arg1_ptr, b"000000") # arbitrary password |
| 44 | + password_raw = ql.mem.read(ptr1, size) |
51 | 45 |
|
52 | | - ql.arch.regs.arch_sp -= 0x20 |
53 | | - argv_ptr = ql.arch.regs.arch_sp |
54 | | - ql.mem.write_ptr(argv_ptr, arg0_ptr) |
55 | | - ql.mem.write_ptr(argv_ptr + ql.arch.pointersize, arg1_ptr) |
| 46 | + def __hex_digit(ch: int) -> str: |
| 47 | + off = ord('0') if ch in range(10) else ord('a') - 10 |
56 | 48 |
|
57 | | - ql.arch.regs.r2 = 2 |
58 | | - ql.arch.regs.r3 = argv_ptr |
| 49 | + return chr(ch + off) |
59 | 50 |
|
60 | | - with open("../examples/rootfs/blob/u-boot.bin.img", "rb") as f: |
61 | | - uboot_code = f.read() |
| 51 | + # should be: "013f1f" |
| 52 | + password = "".join(__hex_digit(ch) for ch in password_raw) |
62 | 53 |
|
63 | | - ql = Qiling(code=uboot_code[0x40:], archtype=QL_ARCH.ARM, ostype=QL_OS.BLOB, profile="uboot_bin.ql", verbose=QL_VERBOSE.OFF) |
| 54 | + print(f'The password is: {password}') |
64 | 55 |
|
65 | | - image_base_addr = ql.loader.load_address |
66 | | - ql.hook_address(my_getenv, image_base_addr + 0x13AC0) |
67 | | - ql.hook_address(get_password, image_base_addr + 0x48634) |
68 | 56 |
|
69 | | - partial_run_init(ql) |
| 57 | +def partial_run_init(ql: Qiling): |
| 58 | + # argv prepare |
| 59 | + ql.arch.regs.arch_sp -= 0x30 |
| 60 | + arg0_ptr = ql.arch.regs.arch_sp |
| 61 | + ql.mem.write(arg0_ptr, b"kaimendaji") |
| 62 | + |
| 63 | + ql.arch.regs.arch_sp -= 0x10 |
| 64 | + arg1_ptr = ql.arch.regs.arch_sp |
| 65 | + ql.mem.write(arg1_ptr, b"000000") # arbitrary password |
70 | 66 |
|
71 | | - ql.run(image_base_addr + 0x486B4, image_base_addr + 0x48718) |
| 67 | + ql.arch.regs.arch_sp -= 0x20 |
| 68 | + argv_ptr = ql.arch.regs.arch_sp |
| 69 | + ql.mem.write_ptr(argv_ptr, arg0_ptr) |
| 70 | + ql.mem.write_ptr(argv_ptr + ql.arch.pointersize, arg1_ptr) |
| 71 | + |
| 72 | + ql.arch.regs.r2 = 2 |
| 73 | + ql.arch.regs.r3 = argv_ptr |
72 | 74 |
|
73 | 75 |
|
74 | 76 | if __name__ == "__main__": |
75 | | - get_kaimendaji_password() |
| 77 | + with open("../examples/rootfs/blob/u-boot.bin.img", "rb") as f: |
| 78 | + uboot_code = f.read() |
| 79 | + |
| 80 | + ql = Qiling(code=uboot_code[0x40:], archtype=QL_ARCH.ARM, ostype=QL_OS.BLOB, profile="uboot_bin.ql", verbose=QL_VERBOSE.DEBUG) |
| 81 | + |
| 82 | + imgbase = ql.loader.images[0].base |
| 83 | + |
| 84 | + ql.hook_address(my_getenv, imgbase + 0x13AC0) |
| 85 | + ql.hook_address(get_password, imgbase + 0x48634) |
| 86 | + |
| 87 | + partial_run_init(ql) |
| 88 | + |
| 89 | + ql.run(imgbase + 0x486B4, imgbase + 0x48718) |
0 commit comments