1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| from dataclasses import dataclass import struct from PIL import Image
TARGET_NAME = b"lglogo_image" REPLACE_WITH = "nl.png" ORIG_FILE = "raw_resources_a.bin" OUT_FILE = "edited.bin"
HEAD_FMT = struct.Struct("<16s2L16sL") IMINFO_FMT = struct.Struct("<40s6L") IMG_LIST_ADDR = 0x1000
@dataclass class RLE_IMG_INFO: name:bytes offset:int size:int width:int height:int offsetX:int offsetY:int
@dataclass class RLE_IMG: info:RLE_IMG_INFO data:bytes
LAST_OFF = 0x2000 def calc_off(size): global LAST_OFF ret = LAST_OFF LAST_OFF = (LAST_OFF+size&0xfffffff000)+0x1000 return ret
def to_rle(source) -> RLE_IMG: img = Image.open(source).convert("RGB")
counter = -1 prev = (-1,-1,-1) result_bytes = b""
for p in img.getdata(): if p != prev or counter >= 0xff: if counter != -1: result_bytes += bytes([counter,prev[2],prev[1],prev[0]]) prev = p counter = 1 else: counter += 1 result_bytes += bytes([counter,prev[2],prev[1],prev[0]]) return RLE_IMG(RLE_IMG_INFO( b'',0,len(result_bytes),img.width,img.height,0,0 ),result_bytes)
image_list:list[tuple[int,RLE_IMG]] = []
raw_res = open(ORIG_FILE,"rb")
magic, count, version, dev, dataend = HEAD_FMT.unpack(raw_res.read(HEAD_FMT.size))
if magic != b'BOOT_IMAGE_RLE\x00\x00': print('bad magic!') exit(1) print("magic:{}\nimage_count:{}\nversion:{}\ntarget_dev:{}\ndata_end:{}\n".format(magic, count, version, dev, dataend))
raw_res.seek(dataend,0) sign_orig = raw_res.read(0x100)
for i in range(count): raw_res.seek(IMG_LIST_ADDR+i*IMINFO_FMT.size,0) r_info = RLE_IMG_INFO(*IMINFO_FMT.unpack(raw_res.read(IMINFO_FMT.size))) raw_res.seek(r_info.offset,0) img_data = raw_res.read(r_info.size) if len(img_data) != r_info.size: print("读取到的字节不够") exit(1) image_list.append((i,RLE_IMG(r_info,img_data)))
for i,img in image_list: if not img.info.name.startswith(TARGET_NAME): continue print("found target_image:",img.info) r_rle = to_rle(REPLACE_WITH) r_rle.info.name = img.info.name r_rle.info.offsetX = img.info.offsetX r_rle.info.offsetY = img.info.offsetY image_list[i] = (i,r_rle)
out_file = open(OUT_FILE,"wb") for i,img in image_list: out_file.seek(IMG_LIST_ADDR+i*IMINFO_FMT.size,0) print("rearange image:",img.info.name.decode('ansi')) img.info.offset = calc_off(img.info.size) print(" size={},new_offset={}".format(hex(img.info.size),hex(img.info.offset))) out_file.write(IMINFO_FMT.pack(*tuple(img.info.__dict__.values()))) out_file.seek(img.info.offset,0) out_file.write(img.data) new_dataending = out_file.tell() out_file.write(sign_orig) out_file.seek(0,0) out_file.write(HEAD_FMT.pack( magic, count, version, dev, new_dataending )) print("new_dataending =",hex(new_dataending)) out_file.seek(0x7fffff) out_file.write(b'\x00')
|