608 lines
20 KiB
Python
608 lines
20 KiB
Python
import re
|
|
import os
|
|
import sys
|
|
import struct
|
|
import json
|
|
from bin.log import myprint
|
|
from bin.base import bin_path
|
|
from bin.crc import CRC32
|
|
|
|
|
|
# kunlun1,kunlun2,kunlun3的img类型
|
|
# FRW是指未压缩的fw CFRW是指压缩之后的fw
|
|
_ImgType={
|
|
0x0000:"imgROM", # Maybe,ROM doesn't need a imgType */
|
|
0xFC00:"imgSP", # sp */
|
|
0xFC01:"imgSBL", # sbl */
|
|
0xFC02:"imgFRW", # kl1: 1MB fw, uncompressed for sta, run in flash; compressed for cco, run in psram */
|
|
0xFC03:"imgCFG", # The first pib file. */
|
|
0xFC04:"imgEFUSE", # efuse */
|
|
0xFC05:"imgOEM", # oem */
|
|
0xFC06:"imgFRW2", # The second fw, maybe the backup one. not used. */
|
|
0xFC07:"imgCFG2", # The second pib file. */
|
|
0xFC08:"imgCFRW1", # kl1: 2MB fw, compressed for sta or cco, run in flash; kl2: 4M flash fw */
|
|
0xFC09:"imgCFRW2", # The second fw, maybe the backup one. not used. */
|
|
0xFC0A:"imgCFRW", # kl1: 2MB fw, compressed for sta or cco, run in psram; kl2: 4M psram fw */
|
|
0xFC0B:"imgREF", # ref */
|
|
0xFC0C:"imgCUS", # cus */
|
|
0xFC0D:"imgCFRW4F", # kl1: 4MB fw, compressed for sta or cco, run in flash */
|
|
0xFC0E:"imgCFRW4P", # kl1: 4MB fw, compressed for sta or cco, run in psram */
|
|
0xFFFF:"imgMAX", # invalid */
|
|
0x00:"imgV1ROM", # Maybe,ROM doesn't need a imgType */
|
|
0x01:"imgV1SBL", # sbl */
|
|
0x02:"imgV1FRWPLC", # FW-PLC */
|
|
0x03:"imgV1CFG", # The first pib file. */
|
|
0x05:"imgV1OEM", # oem */
|
|
0x06:"imgV1FRWCUS", # FW-CUS */
|
|
0xFF:"imgV1MAX" # invalid */
|
|
}
|
|
|
|
|
|
|
|
_DevType={
|
|
0xDC01:"devkunlun1",
|
|
0xDC02:"devkunlun2",
|
|
0xDC03:"devkunlun3",
|
|
0xFFFF:"devMax",
|
|
0x01:"devV1kunlun1",
|
|
0x02:"devV1kunlun2",
|
|
0x03:"devV1kunlun3",
|
|
0xFF:"devV1Max"
|
|
}
|
|
|
|
|
|
_PatternType={
|
|
0x00:"HTZD",
|
|
0x55:"HTZD",
|
|
0xaa:"JSMT",
|
|
0x99:"FLX",
|
|
0x66:"QJ",
|
|
0xcc:"SPE",
|
|
0x33:"GX",
|
|
0xdd:"DT",
|
|
0xa9:"YP",
|
|
0xc6:"WTZ",
|
|
0x93:"TCE"
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_layout_cfg='''
|
|
|
|
g_layout_f1_v0
|
|
part_name offset size size(kB) note
|
|
SP 0x00000000 0x00008000 32
|
|
SBL 0x00008000 0x00008000 32
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00006000 24
|
|
LOG1 0x00018000 0x00001000 4
|
|
PIB2 0x00019000 0x00006000 24
|
|
LOG2 0x0001F000 0x00001000 4
|
|
FW1 0x00020000 0x0006F000 444
|
|
CUS 0x0008F000 0x00001000 4
|
|
FW2 0x00090000 0x0006F000 444
|
|
DUMP 0x00000000 0x00000000 0 not use
|
|
CAL 0x000FF000 0x00001000 4
|
|
-
|
|
g_layout_f2_v0
|
|
part_name offset size size(kB) note
|
|
SP 0x00000000 0x00008000 32
|
|
SBL 0x00008000 0x00008000 32
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
RUN 0x00020000 0x000E0000 896 log part use the remaining space
|
|
FW1 0x00100000 0x00070000 448
|
|
FW2 0x00170000 0x00070000 448
|
|
CUS 0x001E0000 0x0001E000 120
|
|
DUMP 0x001FE000 0x00001000 4
|
|
CAL 0x001FF000 0x00001000 4
|
|
-
|
|
g_layout_f2_v1
|
|
part_name offset size size(kB) note
|
|
SBL 0x00000000 0x0000C000 48
|
|
PIB1_EXT 0X0000C000 0X00002000 8
|
|
PIB2_EXT 0X0000E000 0X00002000 8
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
RUN 0x00020000 0x000E0000 896
|
|
FW1 0x00100000 0x00070000 448
|
|
FW2 0x00170000 0x00070000 448
|
|
DUMP 0x001E0000 0x00001000 4
|
|
CUS 0x001E1000 0x0001E000 120
|
|
CALI 0x001FF000 0x00001000 4
|
|
-
|
|
g_layout_f2_v2
|
|
part_name offset size size(kb) note
|
|
SBL 0x00000000 0x0000C000 48
|
|
PIB1_EXT 0X0000C000 0X00002000 8
|
|
PIB2_EXT 0X0000E000 0X00002000 8
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
RUN_CUS 0x00020000 0x00028000 160
|
|
RUN_FW 0x00048000 0x000B8000 736
|
|
CUS1 0x00100000 0x00018000 96
|
|
FW1 0x00118000 0x00058000 352
|
|
CUS2 0x00170000 0x00018000 96
|
|
FW2 0x00188000 0x00058000 352
|
|
RESERVED 0x001E0000 0x00001000 4
|
|
CUST 0x001E1000 0x0001E000 120
|
|
CALI 0x001FF000 0x00001000 4
|
|
-
|
|
g_layout_f2_p_v0
|
|
part_name offset size size(kB) note
|
|
SP 0x00000000 0x00008000 32
|
|
SBL 0x00008000 0x00008000 32
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
FW1 0x00020000 0x000A0000 640
|
|
LOG1 0x000C0000 0x00020000 128
|
|
LOG2 0x000E0000 0x00020000 128
|
|
FW2 0x00100000 0x000A0000 640
|
|
CUS 0x001A0000 0x0005E000 376
|
|
SP_FW1 0x001F0000 0x00000000 0 not use
|
|
PARAM2 0x001F7000 0x00000000 0 not use
|
|
DUMP 0x001FE000 0x00001000 4
|
|
CAL 0x001FF000 0x00001000 4
|
|
-
|
|
g_layout_f2_p_v1
|
|
part_name offset size size(kB) note
|
|
SBL 0x00000000 0x00010000 64
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
FW1 0x00020000 0x000A0000 640
|
|
LOG1 0x000C0000 0x00020000 128
|
|
FW2 0x000E0000 0x000A0000 640
|
|
LOG2 0x00180000 0x00020000 128
|
|
DUMP 0x001A0000 0x00001000 4
|
|
CUS 0x001A1000 0x0005E000 376
|
|
CALI 0x001FF000 0x00001000 4
|
|
-
|
|
g_layout_f4_v0
|
|
part_name offset size size(kb) note
|
|
SP 0x00000000 0x00008000 32
|
|
SBL 0x00008000 0x00008000 32
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
LOG1 0x00000000 0x00000000 0 not use
|
|
PIB2 0x00019000 0x00007000 28
|
|
LOG2 0x00000000 0x00000000 0 not use
|
|
RUN 0x00020000 0x00160000 1408 log part use the remaining space
|
|
FW1 0x00180000 0x000C0000 768
|
|
FW2 0x00240000 0x000C0000 768
|
|
SP_FW1 0x00000000 0x00000000 0 not use
|
|
PARAM2 0x00000000 0x00000000 0 not use
|
|
SP_FW2 0x00000000 0x00000000 0 not use
|
|
DUMP 0x00000000 0x00000000 0 not use
|
|
CUS 0x00300000 0x000FF000 1020
|
|
CAL 0x003FF000 0x00001000 4
|
|
-
|
|
g_layout_f4_v1
|
|
part_name offset size size(kb) note
|
|
SBL 0x00000000 0x00010000 64
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
RUN 0x00020000 0x00160000 1408
|
|
FW1 0x00180000 0x000B0000 704
|
|
FW2 0x00230000 0x000B0000 704
|
|
PIB1_EXT 0x002E0000 0x0000F000 60
|
|
PIB2_EXT 0x002EF000 0x0000F000 60
|
|
DUMP 0x002FE000 0x00001000 4
|
|
RESERVED 0x002FF000 0x00001000 4
|
|
CUS 0x00300000 0x000FF000 1020
|
|
CALI 0x003FF000 0x00001000 4
|
|
-
|
|
g_layout_f4_p_v0
|
|
part_name offset size size(kb) note
|
|
SP 0x00000000 0x00008000 32
|
|
SBL 0x00008000 0x00008000 32
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
RUN 0x00020000 0x000FA000 1000
|
|
LOG1 0x0011A000 0x00066000 408
|
|
FW1 0x00180000 0x000FA000 1000
|
|
LOG2 0x0027A000 0x00066000 408
|
|
DUMP 0x002E0000 0x00001000 4
|
|
RESERVED 0x002E1000 0x00001000 4
|
|
SP_FW1 0x002E2000 0x0000F000 60
|
|
SP_FW2 0x002F1000 0x0000F000 60
|
|
CUS 0x00300000 0x000FF000 1020
|
|
CAL 0x003FF000 0x00001000 4
|
|
FW2 0x002E0000 0x00000000 0 not use
|
|
PARAM2 0x00000000 0x00000000 0 not use
|
|
-
|
|
g_layout_f4_p_v1
|
|
part_name offset size size(kb) note
|
|
SBL 0x00000000 0x00010000 64
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
FW1 0x00020000 0x000FA000 1000
|
|
LOG1 0x0011A000 0x00030000 192
|
|
LOG2 0x0014A000 0x00030000 192
|
|
RESERVED1 0x0017A000 0x00006000 24
|
|
FW2 0x00180000 0x000FA000 1000
|
|
PIB1_EXT 0x0027A000 0x0000F000 60
|
|
PIB2_EXT 0x00289000 0x0000F000 60
|
|
DUMP 0x00298000 0x00001000 4
|
|
RESERVED2 0x00299000 0x00067000 412
|
|
CUS 0x00300000 0x000FF000 1020
|
|
CALI 0x003FF000 0x00001000 4
|
|
-
|
|
g_layout_f4_p_v2
|
|
part_name offset size size(kb) note
|
|
SBL 0x00000000 0x00010000 64
|
|
PARAM 0x00010000 0x00001000 4
|
|
OEM 0x00011000 0x00001000 4
|
|
PIB1 0x00012000 0x00007000 28
|
|
PIB2 0x00019000 0x00007000 28
|
|
FW1-CUS 0x00020000 0x00080000 512
|
|
FW1-PLC 0x000A0000 0x000E0000 896
|
|
LOG1 0x00180000 0x00030000 192
|
|
LOG2 0x001B0000 0x00030000 192
|
|
FW2-CUS 0x001E0000 0x00080000 512
|
|
FW2-PLC 0x00260000 0x000E0000 896
|
|
PIB1_EXT 0x00340000 0x0000F000 60
|
|
PIB2_EXT 0x0034F000 0x0000F000 60
|
|
DUMP 0x0035E000 0x00001000 4
|
|
CUST 0x0035F000 0x000A0000 640
|
|
CALC 0x003FF000 0x00001000 4
|
|
-
|
|
'''
|
|
|
|
|
|
_layout_list=[
|
|
'g_layout_f1_v0',
|
|
'g_layout_f2_v0',
|
|
'g_layout_f2_p_v0',
|
|
'g_layout_f4_v0',
|
|
'g_layout_f4_p_v0',
|
|
'g_layout_f2_v1',
|
|
'g_layout_f2_p_v1',
|
|
'g_layout_f4_v1',
|
|
'g_layout_f4_p_v1',
|
|
'g_layout_f4_p_v2',
|
|
'g_layout_f2_v2',
|
|
]
|
|
|
|
|
|
|
|
# 根据layout index 找到 layout
|
|
def get_layout(index:int):
|
|
layout_len=len(_layout_list)
|
|
if(index>=layout_len):
|
|
return None
|
|
name=_layout_list[index]
|
|
layout=_layout_cfg.split('-')
|
|
for item in layout:
|
|
if(item.find(name)>=0):
|
|
part=item.split('\n')
|
|
break
|
|
part_dict_list:list[dict]=[]
|
|
for item in part:
|
|
sp=item.split()
|
|
if(len(sp)>=4) and sp[3].isdigit():
|
|
# myprint(f"layout {item}")
|
|
d={
|
|
'name':sp[0],
|
|
'offset':int(sp[1],base=16),
|
|
'size':int(sp[2],base=16),
|
|
}
|
|
part_dict_list.append(d)
|
|
return part_dict_list
|
|
|
|
|
|
# 校验 当前地址是不是分区地址
|
|
def check_part_addr(addr:int,part_list:list[dict]):
|
|
for item in part_list:
|
|
if(item.get('offset',None)==addr):
|
|
return item
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
_PKT_HEADER_MAGIC_NO = 0x00005566
|
|
_IMG_HEADER_MAGIC_NO = 0xa4e49a17
|
|
|
|
|
|
# 从info文件读取flash信息
|
|
def load_flash_info(file_name:str):
|
|
flash_info_list:list[dict]=[]
|
|
with open(file_name,mode='r',encoding='utf-8') as f:
|
|
lines=f.readlines()
|
|
for line in lines:
|
|
# 如果开头两个字符是数字
|
|
info = re.match(r"^\d{2}",line)
|
|
if(info):
|
|
# print(info.group(0))
|
|
sp=line.split()
|
|
flash_info={}
|
|
flash_info["DevType"]=_DevType[int(sp[1],base=16)]
|
|
flash_info["ImgType"]=_ImgType[int(sp[2],base=16)]
|
|
flash_info["Offset"]=int(sp[3],base=16)
|
|
flash_info["Size"]=int(sp[4])
|
|
flash_info_list.append(flash_info)
|
|
return flash_info_list
|
|
|
|
|
|
# 查看是不是数据头,不是返回 "",是返回解析值
|
|
def tran_pkg_header(data:bytearray):
|
|
size=len(data)
|
|
ret={}
|
|
if(size>=96):
|
|
# 大写为无符号 B 单字节 H 双字节 I 4字节 L 4字节 Q 8字节
|
|
# f 单精度浮点 d 双精度浮点 s 字符串
|
|
a=struct.unpack('>BBHIIIIIIIIIIIIIIIIIIIIIIHBB',data)
|
|
if(a[5]==_PKT_HEADER_MAGIC_NO):
|
|
ret["enctype"]=str(a[0])
|
|
ret["pattern"]=hex(a[1])
|
|
ret["dev_type"]=hex(a[2])
|
|
ret["file_crc"]=hex(a[3])
|
|
ret["file_len"]=str(a[4])
|
|
ret["magic_no"]=hex(a[5])
|
|
ret["version"]=hex(a[6])
|
|
ret["sp_start"]=hex(a[7])
|
|
ret["sp_len"]=str(a[8])
|
|
ret["sbl_start"]=hex(a[9]) # 32bytes
|
|
ret["sbl_len"]=str(a[10])
|
|
ret["oem_start"]=hex(a[11])
|
|
ret["oem_len"]=str(a[12])
|
|
ret["pib_start"]=hex(a[13])
|
|
ret["pib_len"]=str(a[14])
|
|
ret["fw_start"]=hex(a[15])
|
|
ret["fw_len"]=str(a[16])
|
|
ret["efuse_start"]=hex(a[17]) # 64bytes
|
|
ret["efuse_len"]=str(a[18])
|
|
ret["fw2_start"]=hex(a[19])
|
|
ret["fw2_len"]=str(a[20])
|
|
ret["ref_start"]=hex(a[21])
|
|
ret["ref_len"]=str(a[22])
|
|
ret["cus_start"]=hex(a[23])
|
|
ret["cus_len"]=str(a[24])
|
|
ret["vendor_id"]=hex(a[25])
|
|
ret["img_type"]=hex(a[26])
|
|
ret["img_flag"]=hex(a[27])
|
|
t=str(ret)
|
|
t=t.replace(',','\n')
|
|
# t=json.dumps(ret, sort_keys=True, indent=2, separators=(',', ': '))
|
|
return t
|
|
return ""
|
|
|
|
|
|
def tran_img_headerv0(data:bytearray):
|
|
size=len(data)
|
|
ret={}
|
|
if(size>=64):
|
|
# 大写为无符号 B 单字节 H 双字节 I 4字节 L 4字节 Q 8字节
|
|
# f 单精度浮点 d 双精度浮点 s 字符串
|
|
a=struct.unpack('>HHIHBBIIIBBBBI',data[0:32])
|
|
if(a[8]==_IMG_HEADER_MAGIC_NO):
|
|
ret["devType"]=hex(a[0])+f"({_DevType.get(a[0],'unknown')})"
|
|
ret["imgType"]=hex(a[1])+f"({_ImgType.get(a[1],'unknown')})"
|
|
ret["imgSize"]=str(a[2])
|
|
ret["imgVer"]=hex(a[3])
|
|
ret["psramSize"]=str(a[4])
|
|
ret["hdrVer"]=hex(a[5])
|
|
ret["fwSize"]=str(a[6])
|
|
ret["imgCRC"]=hex(a[7])
|
|
ret["guard"]=hex(a[8])
|
|
ret["layoutIdx"]=hex(a[9])
|
|
# reserved 3bytes
|
|
ret["fwCRC"]=hex(a[13])
|
|
ret["sha256"]=data[32:].hex()
|
|
t=str(ret)
|
|
t=t.replace(',','\n')
|
|
return t,ret
|
|
return "",{}
|
|
|
|
def tran_img_headerv1(data:bytearray):
|
|
size=len(data)
|
|
ret={}
|
|
if(size>=64):
|
|
# 大写为无符号 B 单字节 H 双字节 I 4字节 L 4字节 Q 8字节
|
|
# f 单精度浮点 d 双精度浮点 s 字符串
|
|
a=struct.unpack('>BBBBIBBBBIIIBBBBI',data[0:32])
|
|
if(a[11]==_IMG_HEADER_MAGIC_NO):
|
|
ret["devType"]=hex(a[0])+f"({_DevType.get(a[0],'unknown')})"
|
|
ret["imgType"]=hex(a[1])+f"({_ImgType.get(a[1],'unknown')})"
|
|
ret["encType"]=hex(a[2])
|
|
ret["cfg"]=hex(a[3])
|
|
ret["imgSize"]=str(a[4])
|
|
ret["zipType"]=hex(a[5])
|
|
ret["flashSize"]=str(a[6])
|
|
ret["psramSize"]=hex(a[7])
|
|
ret["hdrVer"]=hex(a[8])
|
|
ret["imgVer"]=hex(a[9])
|
|
ret["imgCRC"]=hex(a[10])
|
|
ret["guard"]=hex(a[11])
|
|
ret["layoutIdx"]=hex(a[12])
|
|
# reserved 3bytes
|
|
ret["runAddr"]=hex(a[16])
|
|
ret["sha256"]=data[32:].hex()
|
|
t=str(ret)
|
|
t=t.replace(',','\n')
|
|
return t,ret
|
|
return "",{}
|
|
|
|
|
|
# 判断是不是pkt_header
|
|
def pkt_header_check(data:bytearray):
|
|
magic=(data[12]<<24)|(data[13]<<16)|(data[14]<<8)|(data[15])
|
|
if (magic==_PKT_HEADER_MAGIC_NO):
|
|
return True
|
|
myprint(f"magic={hex(magic)}")
|
|
return False
|
|
|
|
# 判断是不是img_header
|
|
def img_header_check(data:bytearray):
|
|
if(len(data)<32):
|
|
return ''
|
|
magic=(data[20]<<24)|(data[21]<<16)|(data[22]<<8)|(data[23])
|
|
if (magic==_IMG_HEADER_MAGIC_NO):
|
|
imghdr_v=data[11]
|
|
myprint(f"magic={hex(magic)}, imghdr_v={imghdr_v}")
|
|
# 返回使用的结构体类型
|
|
if(imghdr_v==0x10):
|
|
return 'V1'
|
|
else:
|
|
return "V0"
|
|
return ""
|
|
|
|
# 判断是不是加密了
|
|
def pkt_encrypt_check(data:bytearray):
|
|
magic_data=data[12:16]
|
|
pat=magic_data[0]
|
|
for i in range(len(magic_data)):
|
|
magic_data[i]=magic_data[i]^pat
|
|
magic=(magic_data[0]<<24)|(magic_data[1]<<16)|(magic_data[2]<<8)|(magic_data[3])
|
|
if (magic==_PKT_HEADER_MAGIC_NO):
|
|
if(pat!=0):
|
|
return True
|
|
return False
|
|
|
|
|
|
# 转化为hex文本
|
|
def bin_to_hex(bin:bytearray,f,oem_file=None,layout_index=None):
|
|
all_size=len(bin)
|
|
pack_size=32
|
|
turned=0
|
|
turned_old=0
|
|
out_text=''
|
|
kunlun=''
|
|
if(layout_index is not None):
|
|
layout_list=get_layout(layout_index)
|
|
if(pkt_header_check(bin)):
|
|
out_text=tran_pkg_header(bin[0:96])+'\n'
|
|
f.write(out_text)
|
|
while turned < all_size:
|
|
if(turned+pack_size<=all_size):
|
|
data=bin[turned:turned+pack_size]
|
|
turned_old=turned
|
|
turned+=pack_size
|
|
else:
|
|
data=bin[turned:]
|
|
turned_old=turned
|
|
turned=all_size
|
|
if(all_size-turned_old>=64):
|
|
hdr_data=bin[turned_old:turned_old+64]
|
|
else:
|
|
hdr_data=bytearray()
|
|
hdr_v=img_header_check(hdr_data)
|
|
if(hdr_v=='V0'):
|
|
kunlun='kl1'
|
|
out_text,ret=tran_img_headerv0(hdr_data)
|
|
out_text+='\n'
|
|
f.write(out_text)
|
|
elif(hdr_v=='V1'):
|
|
kunlun='kl3'
|
|
out_text,ret=tran_img_headerv1(hdr_data)
|
|
out_text+='\n'
|
|
f.write(out_text)
|
|
# 截取oem部分
|
|
if(oem_file is not None):
|
|
if(_ImgType[hdr_data[1]]=="imgV1OEM"):
|
|
size=int(ret["imgSize"])
|
|
oem_bin=bin[turned_old+64:turned_old+64+size]
|
|
oem_file.write(oem_bin)
|
|
if(layout_index is not None):
|
|
layout=check_part_addr(turned_old,layout_list)
|
|
if(layout is not None):
|
|
layout['crc32']=hex(CRC32(bin[turned_old:turned_old+layout['size']]))
|
|
f.write(str(layout).replace(',',' ')+'\n')
|
|
out_text=f"[{hex(turned_old)}] {data.hex(' ')}\n"
|
|
f.write(out_text)
|
|
return kunlun
|
|
|
|
|
|
def bin_to_hex_file(bin_file_name:str,hex_file_name:str,layout_index:int):
|
|
with open(bin_file_name,mode='rb') as f:
|
|
bin=bytearray(f.read())
|
|
if(pkt_encrypt_check(bin)):
|
|
myprint("start decrypt:")
|
|
pat=(bin[12]^0x00)&0xff
|
|
myprint(f"decrypt image:{hex(pat)}({_PatternType.get(pat,'unknown')})")
|
|
for index in range(len(bin)):
|
|
bin[index]=bin[index]^pat
|
|
with open(hex_file_name,mode='w+',encoding="utf-8") as f:
|
|
# oem_bin 去除原始后缀 .bin.txt 添加新后缀 -oem.bin
|
|
oem_name=hex_file_name[0:-8]+'-oem.bin'
|
|
oem_name=os.path.normpath(oem_name)
|
|
with open(oem_name,mode='wb+') as oem_f:
|
|
kl=bin_to_hex(bin,f,oem_f,layout_index)
|
|
# 调用oem_tool 打印oem信息
|
|
oem_tool=os.path.join(bin_path(),f"{kl}_oem.exe")
|
|
if(os.path.exists(oem_tool)):
|
|
cmd_str=f"{oem_tool} --parse={oem_name}"
|
|
with os.popen(cmd_str) as f:
|
|
for line in f.readlines():
|
|
myprint(line.strip())
|
|
# os.system(cmd_str)
|
|
else:
|
|
myprint(f"oem_tool not found: {oem_tool}")
|
|
|
|
# 固件解密
|
|
def bin_file_decrypt(bin_file:str):
|
|
with open(bin_file,mode='rb') as f:
|
|
bin=bytearray(f.read())
|
|
# 自动判断是否需要解密
|
|
if (pkt_encrypt_check(bin)):
|
|
pat=(bin[12]^0x00)&0xff
|
|
myprint(f"decrypt image:{hex(pat)}({_PatternType.get(pat,'unknown')})")
|
|
for index in range(len(bin)):
|
|
bin[index]=bin[index]^pat
|
|
else:
|
|
pat=bin[1]
|
|
myprint(f"copy image:{hex(pat)}({_PatternType.get(pat,'unknown')})")
|
|
with open('tmp.bin',mode='wb+') as f:
|
|
f.write(bin)
|
|
return "tmp.bin"
|
|
|
|
|
|
|
|
# 判断一个固件是kl1还是kl3的,需要解密后的固件
|
|
def check_bin_type(file:str):
|
|
with open(file,mode='rb') as f:
|
|
bin=bytearray(f.read())
|
|
while len(bin)>32:
|
|
tmp=img_header_check(bin[:32])
|
|
if(tmp=="V1"):
|
|
return '3'
|
|
elif(tmp=="V0"):
|
|
return '1'
|
|
bin=bin[32:]
|
|
return None
|
|
|
|
|
|
def clear_tmp():
|
|
tmp_list=['tmp.bin']
|
|
for item in tmp_list:
|
|
if os.path.exists(item):
|
|
os.remove(item)
|
|
|
|
|
|
# bin_to_hex.py input_file
|
|
if __name__ == "__main__":
|
|
bin_to_hex_file(sys.argv[1],"work/"+sys.argv[1]+".txt",int(sys.argv[2]))
|
|
# get_layout(0)
|