import ctypes
import struct

k32 = ctypes.windll.kernel32
pid = 43084
h = k32.OpenProcess(0x10 | 0x400, False, pid)
br = ctypes.c_size_t()

def rpm(addr, size):
    buf = (ctypes.c_char * size)()
    if k32.ReadProcessMemory(h, ctypes.c_void_p(addr), buf, size, ctypes.byref(br)):
        return bytes(buf)
    return None

def read_str(addr, maxlen=64):
    b = rpm(addr, maxlen)
    if not b: return ""
    s = ""
    for c in b:
        if 0x20 <= c <= 0x7E: s += chr(c)
        elif c == 0: break
    return s

def read_wstr(addr, maxlen=64):
    b = rpm(addr, maxlen*2)
    if not b: return ""
    ws = ""
    for i in range(0, len(b), 2):
        wc = struct.unpack_from('<H', b, i)[0]
        if 0x20 <= wc <= 0x7E: ws += chr(wc)
        elif wc == 0: break
    return ws

for root_name, root_addr in [("UI image button", 0x02AFDF180010), ("UI basic button", 0x02AF791A0010)]:
    print(f"\n=== Root: {root_name} (0x{root_addr:X}) ===")
    data = rpm(root_addr, 0x800)
    if not data:
        print("Cannot read root")
        continue
    for off in range(0, 0x800, 8):
        q = struct.unpack_from("<Q", data, off)[0]
        if 0x10000 <= q <= 0x7FFFFFFFFFFF:
            s = read_str(q)
            ws = read_wstr(q)
            label = ""
            if len(ws) >= 3: label = f'w="{ws}"'
            elif len(s) >= 3: label = f's="{s}"'
            if label:
                print(f"  +0x{off:03X}: 0x{q:012X} -> {label}")

k32.CloseHandle(h)
