예제 #1
0
 def test_service_discovery(self):
     # Service discovery arguments
     range_start = 0x09
     range_end = 0x13
     print_results = False
     # Perform service discovery
     result = uds.service_discovery(arb_id_request=self.ARB_ID_REQUEST,
                                    arb_id_response=self.ARB_ID_RESPONSE,
                                    timeout=self.BRUTEFORCE_TIMEOUT,
                                    min_id=range_start,
                                    max_id=range_end,
                                    print_results=print_results)
     # Supported services within specified range
     expected_result = [ServiceID.DIAGNOSTIC_SESSION_CONTROL, ServiceID.ECU_RESET]
     self.assertListEqual(result, expected_result, "UDS service discovery gave '{0}', expected '{1}'".format(
         result, expected_result))
예제 #2
0
 def test_service_discovery_empty_range(self):
     # Service discovery arguments
     range_start = 0x00
     range_end = 0x05
     print_results = False
     # Perform service discovery
     result = uds.service_discovery(arb_id_request=self.ARB_ID_REQUEST,
                                    arb_id_response=self.ARB_ID_RESPONSE,
                                    timeout=self.BRUTEFORCE_TIMEOUT,
                                    min_id=range_start,
                                    max_id=range_end,
                                    print_results=print_results)
     # No services should be found within range
     expected_result = []
     self.assertListEqual(result, expected_result, "UDS service discovery gave '{0}', expected no hits".format(
         result))
예제 #3
0
def read_ecm(args):
    """
    Read ECM ROM.

    :param args: A namespace containing output filename, start address and size
    """
    filename = args.filename
    addr = args.addr
    size = args.size

    # Use hardcodded 0x7e0 ECM Arb ID
    send_arb_id = 0x7e0

    #
    # 1. Ping ECM by discovering response Arb ID
    #
    print("Probe ECM by ID 0x{0:03x}:".format(send_arb_id))
    arb_id_pairs = uds.uds_discovery(send_arb_id, send_arb_id,
                                     print_results=False)
    if len(arb_id_pairs) != 1:
        print("  ECM is not found")
        return
    (a, rcv_arb_id) = arb_id_pairs[0]
    print("  ECM is detected... response ID 0x{0:03x}".format(rcv_arb_id))

    #
    # 2. Scan for needed services availability
    #
    print("Probe ECM services:")
    needed_services = [
        0x1a, # GMLAN_READ_DIAGNOSTIC_ID
        ServiceID.READ_MEMORY_BY_ADDRESS,
        ServiceID.SECURITY_ACCESS,
        ServiceID.TESTER_PRESENT
    ]
    found_services = uds.service_discovery(send_arb_id, rcv_arb_id,
                                           min_id=min(needed_services),
                                           max_id=max(needed_services),
                                           print_results=False)
    found_services = found_services and needed_services
    missing_services = set(needed_services) - set(found_services)
    if len(missing_services) != 0:
        print("  Missing services: ", end="")
        print(", ".join('{}'.format(uds.UDS_SERVICE_NAMES[s]) for s in missing_services))
        return
    print("  All needed services are present")

    #
    # 3. Read ECM info
    #
    print("Read ECM info:")
    vin_did = uds.service_1a(send_arb_id, rcv_arb_id, 0x90, 0x90)
    if len(vin_did) == 1:
        vin = int_list_to_ascii(vin_did[0x90])
    else:
        vin = "<not found>"
    print("  VIN: {}".format(vin))

    os_did = uds.service_1a(send_arb_id, rcv_arb_id, 0xc1, 0xc1)
    if len(os_did) != 1:
        print("  OS ID: <not found>")
        return
    else:
        osid = int_from_byte_list(os_did[0xc1])
    print("  OS ID: {}".format(osid))

    ecm_type = OSID_TO_ECM.get(osid)
    if not ecm_type:
        print("Not supported OS ID!")
        return
    print("  ECM type: {}".format(ecm_type))
    ecm_spec = ECM_SPECS[ecm_type]

    #
    # 4. Input addr/size sanity check
    #
    ecm_mem_addr = ecm_spec['mem_addr']
    ecm_mem_size = ecm_spec['mem_size']
    if not addr:
        addr = ecm_mem_addr
    if not size:
        size = ecm_mem_size - addr
    if addr < ecm_mem_addr or addr >= ecm_mem_addr + ecm_mem_size:
        print("Incorrect 'addr' for the ECM, valid range: [0x{0:x};0x{1:x})".format(ecm_mem_addr, ecm_mem_addr + ecm_mem_size))
        return
    if size <= 0 or size + addr > ecm_mem_addr + ecm_mem_size:
        print("Incorrect 'addr+size' address out of ECM memory, valid range: [0x{0:x};0x{1:x})".format(ecm_mem_addr, ecm_mem_addr + ecm_mem_size))
        return

    #
    # 5. Unlock the ECM
    #
    print("Unlock ECM:")
    (seed, err) = uds.service_27(send_arb_id, rcv_arb_id, None)
    if err:
        print("  Unable to get seed: {}".format(err))
        return
    print("  Got seed: 0x{0:04x}".format(seed))

    key = ecm_spec['key_algo'](seed)
    print("  Use key:  0x{0:04x}".format(key))
    (_, err) = uds.service_27(send_arb_id, rcv_arb_id, key)
    if err:
        print("  Error: {}".format(err))
        return
    print("  Unlocked!")

    #
    # 6. Read memory
    #
    print("Read ECU memory:")
    ret = uds.read_memory(send_arb_id, rcv_arb_id, filename, addr, size,
                          ecm_spec['mem_addr_bytes'], tester_present=True)
    if ret:
        print(" "*40 + "\r  Completed!")