• 全新单提交:清除含敏感信息的旧历史(sudo 口令、内网 IP、SSH 密钥路径、热点 SSID、设备 MAC) • 本地开发文档/测试记录/构建脚本全部移入 gitignored 的 devdocs/ 与 scripts/build/(不入库) • 保留:MeowOS 源码(launcher/watchdog/bootmenu/meow_svcd/SDK)、项目规范文档、mips-repo 增补组件:SDK 统一日志+通知 API、meow_svcd 服务管理器、mips-repo 软件仓库
82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Find string xrefs in hiby_player (lui/addiu address-load pattern).
|
|
|
|
Usage: python3 rev_xref.py <string> [string ...]
|
|
Prints the string's rodata vaddr and every code location that loads it via
|
|
the lui rt,hi16; addiu rt,rt,lo16 idiom.
|
|
"""
|
|
import sys, struct, subprocess
|
|
from capstone import Cs, CS_ARCH_MIPS, CS_MODE_MIPS32, CS_MODE_LITTLE_ENDIAN
|
|
|
|
BIN = "patch_demo/hiby_player_stock"
|
|
data = open(BIN, "rb").read()
|
|
|
|
|
|
def segs():
|
|
out = subprocess.run(["readelf", "-lW", BIN], capture_output=True, text=True).stdout
|
|
res = []
|
|
for line in out.splitlines():
|
|
p = line.split()
|
|
if len(p) >= 9 and p[0] == "LOAD":
|
|
off, vaddr = int(p[1], 16), int(p[2], 16)
|
|
filesz = int(p[4], 16)
|
|
flags = "".join(p[6:8])
|
|
res.append((vaddr, filesz, off, flags))
|
|
return res
|
|
|
|
|
|
SEGS = segs()
|
|
|
|
|
|
def v2off(v):
|
|
for vaddr, sz, off, fl in SEGS:
|
|
if vaddr <= v < vaddr + sz:
|
|
return off + (v - vaddr)
|
|
return None
|
|
|
|
|
|
def find_string(s):
|
|
b = s.encode() + b"\x00"
|
|
idx = data.find(b)
|
|
if idx < 0:
|
|
return None
|
|
for vaddr, sz, off, fl in SEGS:
|
|
if off <= idx < off + sz:
|
|
return vaddr + (idx - off)
|
|
return None
|
|
|
|
|
|
def find_load_addr(addr):
|
|
# .text range
|
|
out = subprocess.run(["readelf", "-SW", BIN], capture_output=True, text=True).stdout
|
|
tv = ts = None
|
|
for line in out.splitlines():
|
|
p = line.split()
|
|
if len(p) >= 7 and p[1] == ".text":
|
|
tv, ts = int(p[3], 16), int(p[5], 16)
|
|
blob = data[v2off(tv):v2off(tv) + ts]
|
|
ins = []
|
|
for i in range(0, len(blob) - 8, 4):
|
|
w1 = struct.unpack_from("<I", blob, i)[0]
|
|
w2 = struct.unpack_from("<I", blob, i + 4)[0]
|
|
if (w1 >> 26) == 0x0F and (w2 >> 26) == 0x09 and ((w1 >> 16) & 0x1F) == ((w2 >> 21) & 0x1F):
|
|
rt = (w1 >> 16) & 0x1F
|
|
lo = w2 & 0xFFFF
|
|
if lo & 0x8000:
|
|
lo -= 0x10000
|
|
val = ((w1 & 0xFFFF) << 16) + lo
|
|
if val == addr:
|
|
ins.append((tv + i, rt))
|
|
return ins
|
|
|
|
|
|
if __name__ == "__main__":
|
|
for s in sys.argv[1:]:
|
|
addr = find_string(s)
|
|
if addr is None:
|
|
print(f"{s!r}: NOT FOUND")
|
|
continue
|
|
print(f"{s!r}: rodata vaddr {addr:#x}")
|
|
for a, rt in find_load_addr(addr):
|
|
print(f" lui/addiu at {a:#x} -> reg ${rt}")
|