1.背景
本文章主要是記錄用Python基於周立功ZCANPRO開發VIN和SN碼刷寫工具。
2.環境搭建
Python3.8.10 32位元(必須)
周立功上位機:ZCANPRO
周立功CAN盒:USBCANFD-200U
from ctypes import * import os, time import zcanpro """ 使用方法: 1.VIN填寫需要刷寫的VIN碼,如:VIN="12345678901234567" 2.SNN填寫需要刷寫的VIN碼,如:SN="12345678901234567890123456" 3.ZCANPRO工具擴充套件指令碼功能執行本指令碼 """ VIN = "" # 填寫VIN碼 SN = "" # 填寫SN碼 stopTask = False def z_notify(type, obj): zcanpro.write_log("Notify " + str(type) + " " + str(obj)) if type == "stop": zcanpro.write_log("Stop...") global stopTask stopTask = True def uds_req(buses, req): """診斷服務命令封裝""" zcanpro.write_log("[UDS Tx] " + ("%02X " % req["sid"]) + " ".join('{:02X}'.format(a) for a in req["data"])) response = zcanpro.uds_request(buses[0]["busID"], req) if not response["result"]: zcanpro.write_log("Request error! " + response["result_msg"]) else: zcanpro.write_log("[UDS Rx] " + " ".join('{:02X}'.format(a) for a in response["data"])) return response def uds_Serve(sid, data): """data組裝""" uds = {"src_addr": 0x113, "dst_addr": 0x11b, "suppress_response": 0, "sid": 0x10, "data": []} uds["sid"] = sid uds["data"] = data return uds def z_main(): udsCfg = { "response_timeout_ms": 3000, "use_canfd": 1, "canfd_brs": 1, "trans_ver": 0, "fill_byte": 0x00, "frame_type": 0, "trans_stmin_valid": 0, "trans_stmin": 0, "enhanced_timeout_ms": 5000 } lib = cdll.LoadLibrary(os.path.join(os.path.dirname(__file__), 'DLL檔案')) # 呼叫DLL解密檔案 buses = zcanpro.get_buses() zcanpro.uds_init(udsCfg) def unlock_27(): """處理27服務解鎖DLL方法""" uds_req(buses, uds_Serve(0x10, [0x03])) response1 = uds_req(buses, uds_Serve(0x27, [0x01])) if response1["data"][0] == 0x67: m = 0x00 for i in range(2, len(response1["data"])): m = m | response1["data"][i] << 24 - 8 * (i - 2) lib.keyFromSeedLevel1.restype = c_ulong # 定義DLL返回型別 keys = lib.keyFromSeedLevel1(m) data_27 = [0x02] n1 = divmod(keys, 0x1000000)[0] n2 = divmod(divmod(keys, 0x10000)[0], 0x100)[1] n3 = divmod(divmod(keys, 0x10000)[1], 0x100)[0] n4 = divmod(keys, 0x100)[1] data_27.append(n1) data_27.append(n2) data_27.append(n3) data_27.append(n4) response2 = uds_req(buses, uds_Serve(0x27, data_27)) if response2["data"][0] == 0x67: return True else: zcanpro.write_log('27解鎖失敗') return False return False if VIN != "": if len(VIN.strip()) == 17: """刷寫VIN碼""" if unlock_27(): VIN_16hex = [ord(i) for i in VIN] data = [0xF1, 0x90] + VIN_16hex uds_req(buses, uds_Serve(0x2E, data)) response3 = uds_req(buses, uds_Serve(0x22, [0xF1, 0x90])) if response3["data"][3:] == VIN_16hex: zcanpro.write_log("VIN刷寫成功") else: zcanpro.write_log("VIN刷寫失敗") else: zcanpro.write_log("27解鎖失敗") else: zcanpro.write_log("VIN碼長度不是17位") if SN != "": if len(SN.strip()) == 26: """刷寫SN碼""" if unlock_27(): SN_16hex = [ord(i) for i in SN] write_31 = [0x01, 0xFF, 0xAA, 0x03, 0x04, 0x1A, 0x00] + SN_16hex CR = 0 for i in range(3, len(write_31)): CR = CR ^ write_31[i] write_31.append(CR) uds_req(buses, uds_Serve(0x31, write_31)) response = uds_req(buses, uds_Serve(0x22, [0xF1, 0x8C])) if response['data'][3:] == SN_16hex: zcanpro.write_log("SN刷寫成功") else: zcanpro.write_log("SN刷寫失敗") else: zcanpro.write_log("SN碼長度不是26位") time.sleep(1) zcanpro.uds_deinit()
1.開啟上位機ZCANPRO-高階功能-擴充套件指令碼
2.執行章節二的刷寫指令碼