feat(ppclock): protocol.py 协议编解码 23 测试全绿(BCD语义经JS证据校正)
This commit is contained in:
1 parent
190182fb2e
commit
6f5b0c60be
11 files changed
+32843
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,13 @@
|
||||
13187b10-eba9-a3ba-044e-83d3217d9a38 -> ['Lqbsg/top/ble/BleManagerKt;::<clinit>()V']
|
||||
4b646063-6264-f3a7-8941-e65356ea82fe -> ['Lqbsg/top/ble/BleManagerKt;::<clinit>()V']
|
||||
00001f10-0000-1000-8000-00805f9b34fb -> ['Lqbsg/top/ble/SimulatedRawGattHandle;::findFirstWritableCharacteristic()Lp6/g;', 'Lqbsg/top/ble/SimulatedRawGattHandle;::hasService(Ljava/lang/String;)Z', 'Lqbsg/top/ble/BleManagerKt;::<clinit>()V', 'Lqbsg/top/ble/SimulatedRawGattHandle;::hasCharacteristic(Ljava/lang/String; Ljava/lang/String;)Z']
|
||||
00001f1f-0000-1000-8000-00805f9b34fb -> ['Lqbsg/top/ble/SimulatedRawGattHandle;::findFirstWritableCharacteristic()Lp6/g;', 'Lqbsg/top/ble/BleManagerKt;::<clinit>()V', 'Lqbsg/top/ble/SimulatedRawGattHandle;::hasCharacteristic(Ljava/lang/String; Ljava/lang/String;)Z']
|
||||
0000fef5-0000-1000-8000-00805f9b34fb -> ['Lqbsg/top/ble/SimulatedRawGattHandle;::hasService(Ljava/lang/String;)Z', 'Lz7/b0;::i(Ljava/lang/String; Lz7/j0; Lz7/o0; I Lkotlinx/coroutines/sync/Semaphore; Lkotlin/coroutines/jvm/internal/ContinuationImpl;)Ljava/lang/Object;', 'Lqbsg/top/ble/SimulatedGattOtaChannel;::hasService(Ljava/lang/String;)Z', 'Lqbsg/top/ble/SimulatedRawGattHandle$writeCharacteristic$1;::invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;', 'La8/g;::f([B Ljava/lang/String; Lqbsg/top/ble/GattOtaChannel; Lkotlin/coroutines/jvm/internal/ContinuationImpl;)Ljava/lang/Object;', 'Lqbsg/top/ble/SimulatedRawGattHandle;::hasCharacteristic(Ljava/lang/String; Ljava/lang/String;)Z']
|
||||
00002A24-0000-1000-8000-00805f9b34fb -> ['Lqbsg/top/ble/BleManagerKt;::<clinit>()V']
|
||||
00002A26-0000-1000-8000-00805f9b34fb -> ['Lqbsg/top/ble/BleManagerKt;::<clinit>()V']
|
||||
https://qbsg.top/api/activation/activate -> ['La8/f;::l(Ljava/lang/Object;)Ljava/lang/Object;', 'La9/c2;::invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;']
|
||||
https://qbsg.top/api/activation/check -> ['La9/c2;::invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;']
|
||||
https://qbsg.top/api/check-update -> ['Lb1/m;::invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;']
|
||||
https://qbsg.top/api/firmware/catalog -> ['La0/f0;::invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;', 'Lb9/g0;::invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;']
|
||||
SPOTA_PATCH_DATA_UUID_STR -> []
|
||||
3fd29fea11187d48e527be1cb2a62d9b617d457033f076cb0b1e20bcc60f966b0ddf81dd86533d893cbc9355949b74c9a378a8ab27e2516401da22268d3a7791 -> ['Lz7/b0;::<init>(Lkotlinx/coroutines/CoroutineScope; Lqbsg/top/ble/BleManagerFacade; Lqbsg/top/ble/RawGattConnector; Ls0/u0;)V']
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Linear-sweep Thumb disassembly of DA14585 firmware.
|
||||
|
||||
Code region = file[0x40:], mapped base 0x07FC0000.
|
||||
- 16KB-aligned linear sweep; on decode failure emit .word and resync (+2).
|
||||
- Function prologue detection: PUSH {...,lr} (encoding 0xB5xx).
|
||||
Output: analysis/firmware/fw.asm (addr: bytes mnemonic [;;FUNC markers])
|
||||
"""
|
||||
from capstone import Cs, CS_ARCH_ARM, CS_MODE_THUMB, CS_MODE_LITTLE_ENDIAN
|
||||
|
||||
IMG = "app/firmware-PP_da14585_4.2_CH.img"
|
||||
OUT = "analysis/firmware/fw.asm"
|
||||
BASE = 0x07FC0000
|
||||
HDR = 0x40
|
||||
|
||||
def main():
|
||||
data = open(IMG, "rb").read()[HDR:]
|
||||
md = Cs(CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN)
|
||||
md.detail = False
|
||||
|
||||
out = open(OUT, "w")
|
||||
out.write(f"; DA14585 firmware linear sweep, base 0x{BASE:08x}, {len(data)} bytes\n")
|
||||
off = 0
|
||||
n_ins = 0
|
||||
n_bad = 0
|
||||
funcs = []
|
||||
while off < len(data):
|
||||
chunk = data[off:off+0x2000]
|
||||
addr = BASE + off
|
||||
consumed = 0
|
||||
for ins in md.disasm(chunk, addr):
|
||||
# skip if disassembler resync'd mid-chunk oddly
|
||||
if ins.address < addr + consumed:
|
||||
continue
|
||||
# fill any gap (undecodable bytes) with .word
|
||||
gap = ins.address - (addr + consumed)
|
||||
while gap > 0:
|
||||
g = addr + consumed
|
||||
raw = data[off+consumed:off+consumed+2]
|
||||
if len(raw) == 2:
|
||||
w = raw[0] | raw[1] << 8
|
||||
out.write(f"0x{g:08x}: {w:04x} .word 0x{w:04x}\n")
|
||||
else:
|
||||
out.write(f"0x{g:08x}: {raw.hex():<9s} .byte {raw.hex()}\n")
|
||||
consumed += 2
|
||||
gap -= 2
|
||||
n_bad += 1
|
||||
b = ins.bytes
|
||||
# prologue: PUSH {...,lr} => 0xB5xx ; also push {lr} alone? (B500)
|
||||
mark = ""
|
||||
if len(b) == 2 and b[1] == 0xB5:
|
||||
mark = " ;;FUNC"
|
||||
funcs.append(ins.address)
|
||||
out.write(f"0x{ins.address:08x}: {b.hex():<9s} {ins.mnemonic} {ins.op_str}{mark}\n")
|
||||
consumed = ins.address + ins.size - addr
|
||||
n_ins += 1
|
||||
off += consumed if consumed else 2
|
||||
if consumed == 0:
|
||||
n_bad += 1
|
||||
out.write(f"; instructions={n_ins} badwords={n_bad} functions={len(funcs)}\n")
|
||||
out.close()
|
||||
print(f"instructions={n_ins} badwords={n_bad} prologues={len(funcs)}")
|
||||
with open("analysis/firmware/funcs.txt", "w") as f:
|
||||
for a in funcs:
|
||||
f.write(f"0x{a:08x}\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Scan firmware for command-dispatch CMP-immediate and branch-switch patterns."""
|
||||
from capstone import Cs, CS_ARCH_ARM, CS_MODE_THUMB, CS_MODE_LITTLE_ENDIAN
|
||||
import struct, collections
|
||||
|
||||
IMG = "app/firmware-PP_da14585_4.2_CH.img"
|
||||
BASE = 0x07FC0000
|
||||
HDR = 0x40
|
||||
CODE_END = 0x119e4 # code region size
|
||||
|
||||
CMDS = {0xdd:"time", 0xe2:"commit", 0x03:"img_blk_full", 0x04:"img_blk_small",
|
||||
0x01:"refresh", 0xAA:"refresh_small", 0xEF:"activate", 0xE6:"lut_cal",
|
||||
0xFB:"sleep_time", 0xEA:"slot", 0xFA:"countdown_off", 0xE1:"mode",
|
||||
0xE3:"invert", 0xE4:"font", 0xE5:"rotate", 0x23:"bw_3color", 0x14:"12_24h",
|
||||
0x15:"clk_color", 0x99:"cal_text", 0x00:"refresh_step1", 0xE9:"carousel"}
|
||||
|
||||
def main():
|
||||
data = open(IMG, "rb").read()[HDR:HDR+CODE_END]
|
||||
md = Cs(CS_ARCH_ARM, CS_MODE_THUMB | CS_MODE_LITTLE_ENDIAN)
|
||||
# collect all instructions via same sweep
|
||||
insns = []
|
||||
off = 0
|
||||
while off < len(data):
|
||||
chunk = data[off:off+0x2000]
|
||||
addr = BASE + off
|
||||
consumed = 0
|
||||
for ins in md.disasm(chunk, addr):
|
||||
if ins.address < addr + consumed:
|
||||
continue
|
||||
gap = ins.address - (addr + consumed)
|
||||
if gap:
|
||||
consumed += (gap // 2) * 2
|
||||
insns.append(ins)
|
||||
consumed = ins.address + ins.size - addr
|
||||
off += consumed if consumed else 2
|
||||
|
||||
# CMP Rn, #imm with imm in CMDS
|
||||
hits = collections.defaultdict(list)
|
||||
for ins in insns:
|
||||
if ins.mnemonic == "cmp":
|
||||
parts = ins.op_str.split(",")
|
||||
if len(parts) == 2 and parts[1].strip().startswith("#"):
|
||||
try:
|
||||
v = int(parts[1].strip()[1:], 0)
|
||||
except ValueError:
|
||||
continue
|
||||
if v in CMDS:
|
||||
hits[v].append((ins.address, ins.op_str))
|
||||
for v in sorted(hits):
|
||||
print(f"--- CMP #0x{v:02x} ({CMDS[v]}): {len(hits[v])} hits ---")
|
||||
for a, ops in hits[v]:
|
||||
print(f" 0x{a:08x}: cmp {ops}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,273 @@
|
||||
0x07fc0574
|
||||
0x07fc05ec
|
||||
0x07fc0634
|
||||
0x07fc06ac
|
||||
0x07fc0734
|
||||
0x07fc07ea
|
||||
0x07fc081a
|
||||
0x07fc082e
|
||||
0x07fc08bc
|
||||
0x07fc0a24
|
||||
0x07fc0b18
|
||||
0x07fc0b3e
|
||||
0x07fc0c34
|
||||
0x07fc0c7a
|
||||
0x07fc0d9c
|
||||
0x07fc0dea
|
||||
0x07fc0e58
|
||||
0x07fc0f6c
|
||||
0x07fc11d8
|
||||
0x07fc1504
|
||||
0x07fc154a
|
||||
0x07fc15b8
|
||||
0x07fc16ea
|
||||
0x07fc1754
|
||||
0x07fc17e6
|
||||
0x07fc1a56
|
||||
0x07fc1ab8
|
||||
0x07fc1b0c
|
||||
0x07fc1b7c
|
||||
0x07fc1bcc
|
||||
0x07fc1c54
|
||||
0x07fc1cc6
|
||||
0x07fc1d28
|
||||
0x07fc1e8c
|
||||
0x07fc1f5c
|
||||
0x07fc204c
|
||||
0x07fc207c
|
||||
0x07fc209e
|
||||
0x07fc20c4
|
||||
0x07fc20de
|
||||
0x07fc2184
|
||||
0x07fc21ac
|
||||
0x07fc21c8
|
||||
0x07fc221c
|
||||
0x07fc238c
|
||||
0x07fc23d0
|
||||
0x07fc2574
|
||||
0x07fc2628
|
||||
0x07fc2788
|
||||
0x07fc27c4
|
||||
0x07fc2b3c
|
||||
0x07fc2c48
|
||||
0x07fc2cac
|
||||
0x07fc2da4
|
||||
0x07fc2dfc
|
||||
0x07fc3098
|
||||
0x07fc3154
|
||||
0x07fc3190
|
||||
0x07fc31b4
|
||||
0x07fc32bc
|
||||
0x07fc3344
|
||||
0x07fc336c
|
||||
0x07fc33a8
|
||||
0x07fc33d0
|
||||
0x07fc3404
|
||||
0x07fc3440
|
||||
0x07fc359c
|
||||
0x07fc3614
|
||||
0x07fc361e
|
||||
0x07fc3628
|
||||
0x07fc3632
|
||||
0x07fc363c
|
||||
0x07fc3646
|
||||
0x07fc3658
|
||||
0x07fc36c8
|
||||
0x07fc3710
|
||||
0x07fc37a8
|
||||
0x07fc3854
|
||||
0x07fc3920
|
||||
0x07fc3a38
|
||||
0x07fc3c54
|
||||
0x07fc3d20
|
||||
0x07fc3e44
|
||||
0x07fc48f4
|
||||
0x07fc4988
|
||||
0x07fc4bf8
|
||||
0x07fc4c38
|
||||
0x07fc4cdc
|
||||
0x07fc4d50
|
||||
0x07fc4e20
|
||||
0x07fc4f90
|
||||
0x07fc50c4
|
||||
0x07fc5104
|
||||
0x07fc519c
|
||||
0x07fc51d6
|
||||
0x07fc522c
|
||||
0x07fc52f4
|
||||
0x07fc5354
|
||||
0x07fc53e8
|
||||
0x07fc546c
|
||||
0x07fc54bc
|
||||
0x07fc5504
|
||||
0x07fc554c
|
||||
0x07fc5598
|
||||
0x07fc55b8
|
||||
0x07fc55e0
|
||||
0x07fc5678
|
||||
0x07fc56b0
|
||||
0x07fc570c
|
||||
0x07fc5744
|
||||
0x07fc5764
|
||||
0x07fc5798
|
||||
0x07fc57ec
|
||||
0x07fc582c
|
||||
0x07fc587c
|
||||
0x07fc58e0
|
||||
0x07fc5974
|
||||
0x07fc5a2c
|
||||
0x07fc5a6c
|
||||
0x07fc5a8c
|
||||
0x07fc5ac4
|
||||
0x07fc5adc
|
||||
0x07fc5afc
|
||||
0x07fc5b0c
|
||||
0x07fc5b7c
|
||||
0x07fc5bb0
|
||||
0x07fc5bd0
|
||||
0x07fc5c4c
|
||||
0x07fc5ca4
|
||||
0x07fc5dd4
|
||||
0x07fc5df0
|
||||
0x07fc5e0c
|
||||
0x07fc5ec0
|
||||
0x07fc5edc
|
||||
0x07fc5f5c
|
||||
0x07fc6078
|
||||
0x07fc60d8
|
||||
0x07fc6240
|
||||
0x07fc62a8
|
||||
0x07fc62f8
|
||||
0x07fc631c
|
||||
0x07fc6374
|
||||
0x07fc641c
|
||||
0x07fc6434
|
||||
0x07fc64bc
|
||||
0x07fc6540
|
||||
0x07fc6590
|
||||
0x07fc65d0
|
||||
0x07fc6634
|
||||
0x07fc6680
|
||||
0x07fc66cc
|
||||
0x07fc66f4
|
||||
0x07fc67f8
|
||||
0x07fc6814
|
||||
0x07fc683c
|
||||
0x07fc6aac
|
||||
0x07fc6b24
|
||||
0x07fc6b9c
|
||||
0x07fc6c1c
|
||||
0x07fc6c40
|
||||
0x07fc6cb8
|
||||
0x07fc6cda
|
||||
0x07fc6ce2
|
||||
0x07fc6cec
|
||||
0x07fc6e98
|
||||
0x07fc6fa0
|
||||
0x07fc6fc8
|
||||
0x07fc70a0
|
||||
0x07fc715c
|
||||
0x07fc71e0
|
||||
0x07fc7268
|
||||
0x07fc7290
|
||||
0x07fc7374
|
||||
0x07fc7430
|
||||
0x07fc7528
|
||||
0x07fc7618
|
||||
0x07fc7768
|
||||
0x07fc778c
|
||||
0x07fc78b0
|
||||
0x07fc793c
|
||||
0x07fc79d0
|
||||
0x07fc79f8
|
||||
0x07fc7a58
|
||||
0x07fc7b54
|
||||
0x07fc7b94
|
||||
0x07fc7c6c
|
||||
0x07fc7cc4
|
||||
0x07fc7d18
|
||||
0x07fc7d2c
|
||||
0x07fc7d3c
|
||||
0x07fc7e1c
|
||||
0x07fc7ee4
|
||||
0x07fc8010
|
||||
0x07fc80c0
|
||||
0x07fc826c
|
||||
0x07fc8340
|
||||
0x07fc852c
|
||||
0x07fc8598
|
||||
0x07fc85e8
|
||||
0x07fc8610
|
||||
0x07fc8648
|
||||
0x07fc9784
|
||||
0x07fc97a0
|
||||
0x07fc97cc
|
||||
0x07fc9b24
|
||||
0x07fc9ba0
|
||||
0x07fc9bc4
|
||||
0x07fc9bcc
|
||||
0x07fc9bd4
|
||||
0x07fca22c
|
||||
0x07fca2dc
|
||||
0x07fca39c
|
||||
0x07fca3cc
|
||||
0x07fca41c
|
||||
0x07fca518
|
||||
0x07fca588
|
||||
0x07fca5b4
|
||||
0x07fca5f8
|
||||
0x07fca620
|
||||
0x07fca648
|
||||
0x07fca6e4
|
||||
0x07fca718
|
||||
0x07fca814
|
||||
0x07fca880
|
||||
0x07fca974
|
||||
0x07fcaa68
|
||||
0x07fcaad8
|
||||
0x07fcaae8
|
||||
0x07fcaafc
|
||||
0x07fcab74
|
||||
0x07fcaba2
|
||||
0x07fcabb4
|
||||
0x07fcabf4
|
||||
0x07fcac54
|
||||
0x07fcac68
|
||||
0x07fcac80
|
||||
0x07fcac9c
|
||||
0x07fcacc4
|
||||
0x07fcad74
|
||||
0x07fcadac
|
||||
0x07fcae24
|
||||
0x07fcae4c
|
||||
0x07fcae8c
|
||||
0x07fcaea4
|
||||
0x07fcaeda
|
||||
0x07fcaeec
|
||||
0x07fcaf20
|
||||
0x07fcb3b8
|
||||
0x07fcb3f0
|
||||
0x07fcb6b8
|
||||
0x07fcb6f8
|
||||
0x07fcb824
|
||||
0x07fcb848
|
||||
0x07fcb86c
|
||||
0x07fcb8ec
|
||||
0x07fcb93c
|
||||
0x07fcb9bc
|
||||
0x07fcbb10
|
||||
0x07fcbc64
|
||||
0x07fcbde4
|
||||
0x07fcc1c6
|
||||
0x07fcc238
|
||||
0x07fcc660
|
||||
0x07fcc680
|
||||
0x07fcc770
|
||||
0x07fced48
|
||||
0x07fcf5f2
|
||||
0x07fd00fa
|
||||
0x07fd06ec
|
||||
0x07fd0a84
|
||||
0x07fd0f2c
|
||||
0x07fd0f46
|
||||
0x07fd0ffc
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user