Skip to content

Commit

Permalink
automotive/uds: special case to allow sending malformed 7f request (#…
Browse files Browse the repository at this point in the history
…4347)

Similar to the motivation in #3947 (comment) :
I would like to scan all the possible services including a
nonsense/malformed/invalid request to a 7f service.

v2: adding unit test for range(256) of UDS Scanner and trying to avoid
expensive checks in .hashret() (@polybassa)
v3: flake8 formatting fixes
  • Loading branch information
BenGardiner committed Apr 23, 2024
1 parent cd2fed9 commit e7ae05a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
3 changes: 2 additions & 1 deletion scapy/contrib/automotive/uds.py
Expand Up @@ -124,7 +124,8 @@ def answers(self, other):

def hashret(self):
# type: () -> bytes
if self.service == 0x7f:
if self.service == 0x7f and len(self) >= 2 and \
(bytes(self.payload) != b'\x00' and bytes(self.payload) != b'\x00\x00'):
return struct.pack('B', self.requestServiceId & ~0x40)
return struct.pack('B', self.service & ~0x40)

Expand Down
45 changes: 45 additions & 0 deletions test/contrib/automotive/scanner/uds_scanner.uts
Expand Up @@ -1097,6 +1097,51 @@ tc.show()

assert len(tc.results_with_negative_response) == 4

= UDS_ServiceEnumerator, all range

def req_handler(resp, req):
if req.service != 0x22:
return False
if len(req) == 1:
resp.negativeResponseCode="generalReject"
return True
if len(req) == 2:
resp.negativeResponseCode="incorrectMessageLengthOrInvalidFormat"
return True
if len(req) == 3:
resp.negativeResponseCode="requestOutOfRange"
return True
return False

resps = [EcuResponse(None, [UDS()/UDS_NR(negativeResponseCode="subFunctionNotSupported", requestServiceId="ReadDataByIdentifier")], req_handler)]

es = [UDS_ServiceEnumerator]

debug_dissector_backup = conf.debug_dissector

# This Enumerator is sending corrupted Packets, therefore we need to disable the debug_dissector
conf.debug_dissector = False
scanner = executeScannerInVirtualEnvironment(
resps, es, UDS_ServiceEnumerator_kwargs={"request_length": 3, "scan_range": range(256)}, unstable_socket=False)
conf.debug_dissector = debug_dissector_backup

assert scanner.scan_completed
assert scanner.progress() > 0.95
tc = scanner.configuration.test_cases[0]

assert len(tc.results_without_response) < 10
if tc.results_without_response:
tc.show()

tc.show()

assert len(tc.scanned_states) == 1

result = tc.show(dump=True)

assert "incorrectMessageLengthOrInvalidFormat" in result
assert "requestOutOfRange" in result

+ Cleanup

= Delete testsockets
Expand Down
5 changes: 5 additions & 0 deletions test/contrib/automotive/uds.uts
Expand Up @@ -1412,6 +1412,11 @@ rftpr_build = UDS()/UDS_RFTPR(modeOfOperation=0x1,
compressionMethod=1, encryptingMethod=1)
assert bytes(rftpr_build) == bytes(rftpr)

= Check (invalid) UDS_NRC, no reply-to service

nrc = UDS(b'\x7f')
assert nrc.service == 0x7f

= Check UDS_NRC

nrc = UDS(b'\x7f\x22\x33')
Expand Down

0 comments on commit e7ae05a

Please sign in to comment.