def test_uds_discovery(self):
     # Discovery arguments
     start_arb_id = self.ARB_ID_REQUEST - 5
     end_arb_id = self.ARB_ID_REQUEST + 5
     blacklist = []
     auto_blacklist_duration = 0
     timeout = self.BRUTEFORCE_TIMEOUT
     print_results = False
     # Perform UDS discovery
     result = uds.uds_discovery(start_arb_id, end_arb_id, blacklist, auto_blacklist_duration, timeout, print_results)
     expected_result = [(self.ARB_ID_REQUEST, self.ARB_ID_RESPONSE)]
     self.assertListEqual(result, expected_result, "UDS discovery gave '{0}', expected '{1}'".format(
         result, expected_result))
 def test_uds_discovery_blacklist(self):
     # Discovery arguments
     start_arb_id = self.ARB_ID_REQUEST - 5
     end_arb_id = self.ARB_ID_REQUEST + 5
     # Blacklist the arbitration ID used for response
     blacklist = [self.ARB_ID_RESPONSE]
     auto_blacklist_duration = 0
     timeout = self.BRUTEFORCE_TIMEOUT
     print_results = False
     # Perform UDS discovery
     result = uds.uds_discovery(start_arb_id, end_arb_id, blacklist, auto_blacklist_duration, timeout, print_results)
     # No results expected due to blacklist
     expected_result = []
     self.assertListEqual(result, expected_result, "UDS discovery gave '{0}', expected '{1}'".format(
         result, expected_result))
Exemple #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!")