通过改变设备名将迈金的fit文件上传到黑鸟APP

通过改变设备名将迈金的fit文件上传到黑鸟APP

我们可以通过黑鸟网页端把来自其它码表的fit文件上传到黑鸟App.

黑鸟App的fit上传功能并不完善,来自迈金码表的fit文件在上传时会遇到导入失败的错误.

我们只要改变fit文件中的设备名和设备制造商,就可以把来自于迈金的fit文件伪装成来自佳明的fit文件, 从而骗过检测系统成功上传记录到黑鸟App.

有两种办法改变fit文件的设备名和设备制造商:

法1:

https://www.fitfiletools.com/#/top 中, 改变fit的device name. 经测试改为 edge500_china 后可以成功将迈金码表的fit文件上传到黑鸟App.

法2:

使用如下的python代码进行转换. 以下代码强制把fit文件的设备名设置成 gammin 1030.

使用时, 把如下的python代码保存成 change_name.py 放置在待转换的fit文件所在的文件夹中, 运行python chainge_name.py 即可.

import struct
import os
import fitparse
import glob

def modify_fit_to_garmin_edge500(input_file, output_file):
    """
    将 FIT 文件的 manufacturer 和 garmin_product 修改为 Garmin Edge 500 China
    """
    # 读取原始 FIT 文件
    fitfile = fitparse.FitFile(input_file)
    
    # 打开原文件读取二进制数据
    with open(input_file, 'rb') as f:
        data = bytearray(f.read())
    
    # 查找并修改 file_id 消息中的字段
    for record in fitfile.get_messages('file_id'):
        print("原始文件信息:")
        for field in record:
            print(f"  {field.name}: {field.value} (类型: {type(field.value)})")
            
            # 修改 manufacturer 字段 (1 = garmin)
            if field.name == 'manufacturer':
                old_val = get_field_numeric_value(field)
                if old_val is not None and old_val != 1:
                    print(f"修改 manufacturer: {old_val} -> 1 (garmin)")
                    modify_field_in_binary(data, old_val, 1, 2)
            
            # 修改 garmin_product 字段 (1030 = edge500_china)
            if field.name == 'garmin_product':
                old_val = get_field_numeric_value(field)
                if old_val is not None and old_val != 1030:
                    print(f"修改 garmin_product: {old_val} -> 1030 (edge500_china)")
                    modify_field_in_binary(data, old_val, 1030, 2)
    
    # 重新计算 CRC 校验和
    update_crc(data)
    
    # 写入新文件
    with open(output_file, 'wb') as f:
        f.write(data)
    
    print(f"已将 FIT 文件转换为 Garmin Edge 500 China: {output_file}")

def get_field_numeric_value(field):
    """
    获取字段的数值,处理不同数据类型
    """
    if isinstance(field.value, int):
        return field.value
    elif isinstance(field.value, str):
        # 如果是字符串,尝试从原始值获取
        if hasattr(field, 'raw_value') and isinstance(field.raw_value, int):
            return field.raw_value
    return None

def modify_field_in_binary(data, old_value, new_value, field_size):
    """
    在二进制数据中查找并替换字段值
    """
    if not isinstance(old_value, int) or not isinstance(new_value, int):
        print(f"  跳过非整数值: {old_value}")
        return
        
    if field_size == 2:
        old_bytes = struct.pack('<H', old_value)  # 小端序 2 字节
        new_bytes = struct.pack('<H', new_value)
    elif field_size == 4:
        old_bytes = struct.pack('<I', old_value)  # 小端序 4 字节
        new_bytes = struct.pack('<I', new_value)
    else:
        return
    
    # 查找并替换
    pos = data.find(old_bytes)
    if pos != -1:
        data[pos:pos+field_size] = new_bytes
        print(f"  在位置 {pos} 替换了字段值")
    else:
        print(f"  未找到要替换的字节序列")

def update_crc(data):
    """
    更新 FIT 文件的 CRC 校验和
    """
    if len(data) >= 2:
        crc = calculate_crc(data[:-2])
        data[-2:] = struct.pack('<H', crc)

def calculate_crc(data):
    """
    计算 FIT 文件的 CRC-16 校验和
    """
    crc = 0
    for byte in data:
        crc ^= byte
        for _ in range(8):
            if crc & 1:
                crc = (crc >> 1) ^ 0xA001
            else:
                crc >>= 1
    return crc & 0xFFFF

if __name__ == "__main__":

    for file in glob.glob("./*.fit"):
        print(f"Processing file: {file}")
        output_file = file.replace('.fit', '_GM.fit')
        modify_fit_to_garmin_edge500(file, output_file)

同时发布于:

https://www.codebonobo.tech/post/34#%E9%80%9A%E8%BF%87%E6%94%B9%E5%8F%98%E8%AE%BE%E5%A4%87%E5%90%8D%E5%B0%86%E8%BF%88%E9%87%91%E7%9A%84fit%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E5%88%B0%E9%BB%91%E9%B8%9FAPP

posted @ 2025-07-20 11:52  酱_油  阅读(163)  评论(0)    收藏  举报