一、概述
1.背景
本文章主要是记录用Python基于周立功ZCANPRO开发VIN和SN码刷写工具。
2.环境搭建
Python3.8.10 32位(必须)
周立功上位机:ZCANPRO
周立功CAN盒:USBCANFD-200U
二、刷写脚本
from ctypes import *import os, timeimport zcanpro"""使用方法:1.VIN填写需要刷写的VIN码,如:VIN="12345678901234567"2.SNN填写需要刷写的VIN码,如:SN="12345678901234567890123456"3.ZCANPRO工具扩展脚本功能执行本脚本"""VIN = ""# 填写VIN码SN = ""# 填写SN码stopTask = Falsedef z_notify(type, obj):zcanpro.write_log("Notify " + str(type) + " " + str(obj))if type == "stop":zcanpro.write_log("Stop...")global stopTaskstopTask = Truedef 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 responsedef uds_Serve(sid, data):"""data组装"""uds = {"src_addr": 0x113, "dst_addr": 0x11b, "suppress_response": 0, "sid": 0x10, "data": []}uds["sid"] = siduds["data"] = datareturn udsdef 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 = 0x00for 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 Trueelse:zcanpro.write_log('27解锁失败')return Falsereturn Falseif VIN != "":if len(VIN.strip()) == 17:"""刷写VIN码"""if unlock_27():VIN_16hex = [ord(i) for i in VIN]data = [0xF1, 0x90] + VIN_16hexuds_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_16hexCR = 0for 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()
三、刷写VIN与SN
1.打开上位机ZCANPRO-高级功能-扩展脚本
2.执行章节二的刷写脚本