{"id":13740985,"url":"https://github.com/atlas0fd00m/CanCat","last_synced_at":"2025-05-08T20:33:02.799Z","repository":{"id":30075264,"uuid":"33624794","full_name":"atlas0fd00m/CanCat","owner":"atlas0fd00m","description":"swiss army knife of Controller Area Networks (CAN) often used in cars and building automation, etc...","archived":false,"fork":false,"pushed_at":"2023-04-07T17:39:32.000Z","size":11817,"stargazers_count":196,"open_issues_count":6,"forks_count":33,"subscribers_count":22,"default_branch":"master","last_synced_at":"2024-11-15T10:44:11.060Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atlas0fd00m.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2015-04-08T18:32:01.000Z","updated_at":"2024-11-03T07:28:49.000Z","dependencies_parsed_at":"2024-01-03T03:56:23.722Z","dependency_job_id":"393b49ff-8188-472b-bdba-10079128f541","html_url":"https://github.com/atlas0fd00m/CanCat","commit_stats":{"total_commits":320,"total_committers":13,"mean_commits":"24.615384615384617","dds":0.5875,"last_synced_commit":"f75caa741143e57a8ce664bdca291cfc1f7cd274"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atlas0fd00m%2FCanCat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atlas0fd00m%2FCanCat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atlas0fd00m%2FCanCat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atlas0fd00m%2FCanCat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atlas0fd00m","download_url":"https://codeload.github.com/atlas0fd00m/CanCat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253145149,"owners_count":21861195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T04:00:54.220Z","updated_at":"2025-05-08T20:32:57.793Z","avatar_url":"https://github.com/atlas0fd00m.png","language":"Python","funding_links":[],"categories":["Libraries and Tools","Utils"],"sub_categories":["C++","Python Tools"],"readme":"# CanCat\nCanCat is an open source multi-purpose tool for interacting and experimenting with Controller Area Networks (CAN), such as those that are often used in cars, building automation, etc.\n\n## Description\nCanCat has two main parts:\n1) Firmware for compatible CAN-transceivers,\n2) Python client to talk to CanCat,\n\nThe CAN-transceiver combinations that are currently supported by CanCat are:\n* Arduino with SeeedStudio's CANBUS Shield\n* Arduino DUE with Togglebit.net's CAN shield\n* [Macchina M2 (Under-the-Hood)](https://www.macchina.cc/catalog)\n* [Macchina M2 (Under-the-Dash)](https://www.macchina.cc/catalog)\n\nThe goals of CanCat are to provide:\n* a way to capture and transmit messages on an arbitrary CAN bus (whatever the speed, as supported by hardware)\n* an architecture for analyzing and identifying messages on a CAN bus\n* a manner for data to be shared (Ford sends different messages from GM, Saab, Toyota, Honda, Hyundai, Kia, etc.) (either in the form of lookup tables or in the form of accessor codes.)\n\n\n\n## Software\n### Required:\n* Python 3.6+\n\n\n### Recommended:\n* CANBUS_Shield from SeeedStudio (for Firmware compilation)\n    https://github.com/Seeed-Studio/CAN_BUS_Shield\n\n* vstructs From the Vivisect framework in the Python Path:\n    (required for J1939 module)\n    https://github.com/vivisect/vivisect\n\n* ipython\n\n\n\n## Installation\n1) Install pyserial:\n```\n$ pip install --user pyserial\n```\n\n2) (OPTIONAL) Install ipython if you want to use CanCat interactively.\n```\n$ pip install --user ipython\n```\n\n3) Install the [Arduino IDE](https://www.arduino.cc/en/main/software).\n\n4) (OPTIONAL) If you are using a [Macchina M2](https://www.macchina.cc/) follow\nthe [getting started\nguide](http://docs.macchina.cc/m2/getting-started/arduino.html) for the M2 to\ninstall the M2 hardware definitions in the Arduino tool.\n\n5) (OPTIONAL) If you are on a Linux system, you may choose to install the\n[arduino-cli](https://github.com/arduino/arduino-cli) for your platform. The\narduino-cli tool can be used to compile and flash your CAN device without\nopening the Arudino IDE.\n\n6) Clone CanCat and build the desired firmware. If you are not using the\narduino-cli tool, use the Arduino IDE as normal to build and flash the sketch\nonto your target device. If you have installed the arguing-cli tool you can\ncompile and flash the CanCat firmware with the following steps:\n\n```\n$ git clone https://github.com/atlas0fd00m/CanCat\n$ arduino-cli config init\n$ arduino-cli config add board_manager.additional_urls https://macchina.cc/package_macchina_index.json\n$ arduino-cli lib update-index\n$ arduino-cli lib install due_can\n$ arduino-cli core update-index\n$ arduino-cli core install arduino:sam\n$ arduino-cli core install macchina:sam\n$ cd CanCat/sketches\n$ make m2\n```\n\n7) Ensure that your CAN-transceiver is not in bootloader mode by unplugging its\nUSB connector and then plugging it back in again.\n\n8) Connect to your CAN-transceiver with CanCat\n\n9) Use CanCat.\n\n\n\n## Connecting to your CAN-transceiver with CanCat\nOnce you have the required software installed and your device is flashed, you can use CanCat with your CAN-transceiver.\n\n### Connect to the CAN-transceiver with CanCat [Linux]:\n```bash\n$ ./CanCat.py -p /dev/ttyACM0  # if CanCat device is /dev/ttyACM0\n```\n\n```\n'CanCat, the greatest thing since J2534!'\n\nResearch Mode: enjoy the raw power of CanCat\n\ncurrently your environment has an object called \"c\" for CanCat.  this is how\nyou interact with the CanCat tool:\n    \u003e\u003e\u003e c.ping()\n    \u003e\u003e\u003e c.placeBookmark('')\n    \u003e\u003e\u003e c.snapshotCanMsgs()\n    \u003e\u003e\u003e c.printSessionStats()\n    \u003e\u003e\u003e c.printCanMsgs()\n    \u003e\u003e\u003e c.printCanSessions()\n    \u003e\u003e\u003e c.CANxmit('message', )\n    \u003e\u003e\u003e c.CANreplay()\n    \u003e\u003e\u003e c.saveSessionToFile('file_to_save_session_to')\n    \u003e\u003e\u003e help(c)\n```\n\n### Connect to the CAN-transceiver with CanCat [Linux and other systems]:\n```python\n\u003e\u003e\u003e import cancatlib\n\n\u003e\u003e\u003e CANalysis = cancat.CanInterface('/dev/ttyACM0', 115200) # your device may vary\n\n\u003e\u003e\u003e CANalysis.ping()\n```\n\n`\u003e\u003e\u003e` and `In [#]:` are used interchangeably in this instruction guide.\n\n`\u003e\u003e\u003e` is the default interactive python prompt, and commands using this prompt will use the `CANalysis` object.\n\n`In [#]:` is the ipython prompt, and commands using this prompt will begin with the `c` object.\n\nOther than the different in prompt type, the commands for CanCat will look the same.\n\n\n\n## Getting Started\n### Pinging your CAN-transceiver\nTo see if CanCat is communicating correctly with your computer and the connected CAN-transceiver, use the `ping()` command.\n\n```python\nIn [1]: c.ping()\n```\n\n\n### Setting the Baud Rate\nOnce you connect to your CAN-transceiver, you will want to use CanCat to set the CAN bus interface baud rate on the device. *(Note: 500kbps is the most likely baud rate for devices that you will interact with.)*\n\n```python\n\u003e\u003e\u003e CANalysis.setCanBaud(cancat.CAN_125KBPS)\n```\n\nAfter you have set the baud rate on your CAN-transceiver, CanCat will automatically capture any messages it sees on the CAN bus it is attached to. CanCat will store these messages in the current session for analysis. *Note: Unless you save the CanCat capture, the messages you have captured will no longer be stored once you end your CanCat session.*\n\n### Saving CanCat captures\nCanCat will only save what it has captured when you tell it to save, so make sure to save your capture session / analysis periodically.\n\n```python\n\u003e\u003e\u003e CANalysis.saveSessionToFile('filename_for_this_session')\n```\n\nOnce you save for the first time, the file name will be cached so you can simply save your capture to the same file again by typing:\n\n```python\n\u003e\u003e\u003e CANalysis.saveSessionToFile()\n```\n\n### CanCat help and tips\nTo access the help function in CanCat:\n```python\n\u003e\u003e\u003e help(cancat)\n```\n\nIf help doesn't provide you with what you are looking for, you can do a tab-complete search to bring up each of the possible CanCat commands.\n```python\nIn [6]: c.\u003cPRESS_TAB_KEY\u003e\nc.CANrecv\nc.genCanMsgs\nc.ping\nc.recv\nc.saveSessionToFile\nc.CANreplay\nc.getArbitrationIds\nc.placeCanBookmark\nc.recvall\nc.setCanBaud\nc.CANsniff\nc.getBookmarkFromMsgIndex\nc.port\nc.register_handler\nc.setCanBookmarkComment\nc.CANxmit\nc.getCanMsgCount\nc.printAsciiStrings\nc.remove_handler\nc.setCanBookmarkCommentByMsgIndex\nc.bookmark_info\nc.getMsgIndexFromBookmark\nc.printBookmarks\nc.reprBookmark\nc.setCanBookmarkName\nc.bookmarks\nc.getSessionStats\nc.printCanMsgs\nc.reprBookmarks\nc.setCanBookmarkNameByMsgIndex\nc.clearCanMsgs\nc.getSessionStatsByBookmark\nc.printCanMsgsByBookmark\nc.reprCanMsgs\nc.snapshotCanMessages\nc.comments\nc.loadFromFile\nc.printCanSessions\nc.reprCanMsgsByBookmark\nc.verbose\nc.filterCanMsgs\nc.log\nc.printSessionStats\nc.restoreSession\nc.filterCanMsgsByBookmark\nc.name\nc.printSessionStatsByBookmark\nc.saveSession\n```\n\n## UDS Module\nCanCat has a UDS module for doing UDS diagnostics. Basic usage is as follows:\n\n```python\nIn [1]: import uds\n\nIn [2]: u = uds.UDS(c, 0x760, 0x768) # 11-bit IDs\n\nIn [3]: u = uds.UDS(c, 0x18da98f1, 0x18daf198, extflag=1) # 29-bit IDs\n```\n\nWhen initializing the module, pass in the CanCat object you are using (c, in\nour case), then the arbitration IDs that you will be transmitting and receiving\non. Also set extflag to 1 if using 29-bit identifiers.\n\nNow that our UDS module is initialized, we can use it to perform UDS diagnostics\non a vehicle. Let's start with something simple:\n\n```python\nIn [4]: u.ReadDID(0xF190)\n```\n\nThis will read Data Identifier (DID) 0xF190, which should contain the VIN for the\nvehicle. If the read succeeds then the requested data is returned by the ReadDID\nfunction. If the read fails, then a NegativeResponseException will be thrown, which\nwill print out the UDS error message that was received.\n\nSince CanCat can be scripted easily, scanning for UDS servers on CAN is easily\naccomplished. The following loop will send a ReadDID request to every\narbitration ID from 0x700 to 0x7F7 and print out which servers respond, and which\ntime out.\n\n```python\nfor i in range(0x700, 0x7f8):\n    u = uds.UDS(c, i, i+8)\n    print(\"Trying \", hex(i))\n    try:\n        u.ReadDID(0xf190)\n    except:\n        print(\"Error reading DID 0xF190, server exists at this address\")\n```\n\nIf a timeout is received then no UDS server responded on the address.\nIf a positive response or negative respons is received, then you have\ndiscovered a UDS server. Other functionality can be scripted as well,\nsuch as scanning DIDs to see which are implemented. This code will\nscan all the DIDs in the range from 0xF180 to 0xF19F, which contains\nuseful information such as hardware and software part numbers, VINs, and\nother identifying information for this UDS server.\n\n```python\nfor i in range(0xf180, 0xf1a0):\n    try:\n        print(u.ReadDID(i))\n    except:\n        print(hex(i), \" Returned error\")\n```\n\nOther UDS functionality includes:\n\n* xmit\\_recv - Transmit and receive any data\n* SendTesterPresent - Sends the tester present message one time\n* StartTesterPresent - Starts sending the tester present message periodically\n* StopTesterPresent - Stop sending the tester present message periodically\n* DiagnosticSessionControl - Change the diagnostic session\n* ReadMemoryByAddress - Read a memory address\n* ReadDID - Read a DID\n* WriteDID - Write a DID\n* RequestDownload - Start a data download\n* writeMemoryByAddress - Write a memory address\n* RequestUpload - Start a data upload\n* EcuReset - Reset an ECU\n* ScanDIDs - A built-in function for scannin DIDs\n* SecurityAccess - Starts a security access request\n* \\_key\\_from\\_seed - This method can be overloaded to provide the algorithm for turning a seed into a key. Unimplemented by default.\n\nAn additional function provided is `printUDSSession`, which takes a CanCat\nvariable, and the RX and TX arbitration IDs and parses UDS traffic from the\nCAN traffic captured by CanCat.\n\n## CCP Module\nCanCat has a CCP (CAN Calibration Protocol) module. CCP is a predecessor to XCP and is used for calibration and data acquisition.\n\nCCP allows a single master device (called \"leaders\" in this implementation) connect to multiple slave devices (called \"followers\" in this implementation).\n\nBasic usage is as follows:\n\n```python\nIn [1]: import ccp\n\nIn [2]: cl = ccp.CCPLeader(c) # if you are acting as a leader device, communicating with a follower device\n\nIn [3]: cf = ccp.CCPFollower(c) # if you are acting as a follower device, communicating with a leader device\n```\n\nCanCat's CCP module implements \"parse\" and \"generate\" functions for each of the CCP commands defined in the CCP specification (https://automotivetechis.files.wordpress.com/2012/06/ccp211.pdf) unless otherwise noted:\n* Leader-side parsing of received event messages (errors) and data acquisition CRMs have not been implemented at this time.\n* Data Acquisition (DAQ) functions have been added to the follower according to the spec but have not been tested.\n\nIn addition to the \"parse\" and \"generate\" functions, CCP sequences are defined at the end of `ccp_leader.py`.\n\nCCP’s endianness is implementation-specific (aside from CONNECT, DISCONNECT, and TEST messages), so you may need to make modifications to this code. Other implementation-specific settings are noted in the documentation above each function.\n\nBefore calibration or data acquisition (\"DAQ\") can happen, a logical point-to-point connection needs to be established between the leader and follower devices using a CONNECT message.\n\nIn CCP, all messages (and data responses) are packed into \"message objects\" with up to 8 bytes of data. The available message types are as follows:\n\n  CRO (Command Receive Object): message sent from the leader device to the\n      follower device(s).\n  CRM (Command Return Message): one type of message sent from the follower device\n      to the leader device containing command / error code and command counter.\n  DTO (Data Transmission Object): message sent from the follower device to the\n      leader device (Command Return Message or Event Message or Data Acquisition Message).\n\n\n## Other CanCat Uses\n### Using CanCat to Analyze Previous Captures\nIf all you want to do is analyze a previous CanCat capture you can skip the hardware set up steps mentioned in the Installation section, clone the CanCat repository, add the file you wish to analyze to the CanCat folder, and run the command:\n\n```bash\n$ ./CanCat.py -f filename_of_previous_capture  # no CanCat device required\n```\n\n\n### CAN-in-the-Middle\nCAN-in-the-Middle is another way to utilize your CanCat. It requires two CAN shields\non one arduino. One of the CAN shields needs to be modified so that the CS pin of the\nMCP2515 CAN controller is on D10, rather than D9. This is accomplished by cutting a\ntrace on the CAN shield PCB and bridging (solder bridge or 0-ohm resistor) the pads\nfor CS and D10. Instructions are also on the seeedstudio Wiki, although their board\ndiffered slightly from mine, mostly in that the pads are on the bottom of the board\non mine and on the top of the board in their example.\n\nOnce you have a properly modified CAN Bus shield, you'll be able to isolate components\nconnected to the CAN bus to see which messages a specific device is sending, without\nchanging the conditions by fully removing it from the CAN Bus. This can be very helpful for\ncertain reverse engineering tasks.\n\nFlash the CAN_in_the_middle firmware to the Arduino. Hook the CAN wires up so that the\ndevice you are trying to isolate is connected to the modified CAN shield that uses D10\nfor CS, and the vehicle CAN bus (with the rest of the devices) is connected to the\nunmodified CAN shield. These are referred to as the Isolation network (ISO)\nand the Vehicle network (VEH) respectively.\n\nStart CAN_in_the_middle with the following command:\n\n`./CanCat.py -I CanInTheMiddle -p /dev/tty.usbmodem1411 -S 500K`\n\n( where the -p option is your port and -S is the CAN Baud rate.)\n\nMost of the commands for Can-in-the-Middle are the same as the normal CanCat interface.\nFunctions that report only what has been received on the Isolation side have Iso appended\nto the end of the function name. For example:\n\n```sh\n$ citm.getCanMsgCount() # The number of CAN packets seen in aggregate\n\n$ citm.getCanMsgCountIso() # The number of CAN packets received on the Isolation network\n\n$ citm.printCanMsgs() # Prints all CAN messages\n\n$ citm.printCanMsgsIso() # prints all CAN messages received on the Isolation network\n```\n\nPlacing a bookmark places a bookmark simultaneously on both the Isolation information (Iso interface messages) and the aggregate information (standard CAN interface messages).\n\n##  canmap\n\nCanmap is a tool built on CanCat to scan a CAN bus for various UDS capabilities.\nCanmap is built on top of the `cancat.uds.UDS` class.  Canmap has many different\noptions to control what type of scans are performed, and how the scans are\nperformed, but the basic information required is the type of scan to run, the\nport the CanCat device is present on, and the bus speed:\n\nThe most basic scan is an ECU scan to identify what ECUs are on the bus\n\n```bash\n$ ./canmap -p /dev/ttyACM0 -b 500K -sE\n```\n\nAdditional scan modes are:\n- DIDs\n- Sessions\n\nAll items can be scanned with this command:\n\n```bash\n$ ./canmap -p /dev/ttyACM0 -b 500K -sEDS\n```\n\n### Saving canmap scan output\n\nThe results of a canmap scan can be saved as a configuration yaml file with the\n`-o` (`--output-file`) option. This yaml file can be used as an input to future\nscans with the `-i` (`--input-file`) option. If an input config file is provided\ninformation that is already in the config will not be scanned again unless the\n`-r` (`--rescan`) option is provided. For example an aborted DID scan can later\nbe resumed and any ECUs that DIDs were found for will not be searched for again:\n\n```bash\n$ ./canmap -p /dev/ttyACM0 -b 500K -sEDS -o scan_results.yml\n\u003coutput\u003e\n^C\n$ ./canmap -p /dev/ttyACM0 -b 500K -sEDS -i scan_results.yml -o scan_results.yml\n```\n\nThe configuration file saves some additional scan parameters such as the baud\nrate, and timeout parameters. These parameters are re-used when the config file\nis provided as an input config.\n\nThe config file contain a `notes` field that indicates the command(s) used to\ncreate that config file.\n\nThe raw can messages can also be saved as a CanCat session with the `-c`\n(`--can-sesison-file`) option. This can be useful to diagnose strange responses\nfound during the scanning:\n\n```bash\n$ ./canmap -p /dev/ttyACM0 -b 500K -sEDS -c scan_with_weird_errors.sess\n```\n\nThe session can then be opened with the normal CanCat options:\n\n```bash\n$ ./CanCat.py -f scan_with_weird_errors.sess\n```\n\n### ECU Scanning\n\nThe Range of ECUs to scan can be specified with the `-E` option, the default\nrange is `00-FF` for both standard (11-bit) and extended (29-bit) CAN\naddressing. The bus mode can be set with the `-m` (`-bus-mode`) option.\n\nTo scan only a subset of the ECU range in 11-bit mode the command would be:\n\n```bash\n$ ./canmap -p /dev/ttyACM0 -b 500K -sE -E 60-A0 -m std\n```\n\nECU scanning works by sending a read DID request (`cancat.uds.UDS.ReadDID`) or\na session control request (`cancat.uds.UDS.DiagnosticSessionControl`) and\nwaiting for a timeout, a negative response or a positive response.  The default\nmethod is to attempt to read the VIN from each UDS address\n(`cancat.uds.UDS.ReadDID(0xF190)`). Different methods are available because\ndifferent methods have different degrees of success on different vehicles.\n\nThe other factor that can affect the success rate is how quickly ECUs respond.\nThe UDS standard timeout is 3 seconds, scanning both bus modes with 3 second\ntimeouts could take up to 25 minutes. Instead the default timeout for ECU\nscanning is 0.2 seconds, if fewer ECUs than expected are identified it may be\nworth re-trying the scan with an increased timeout by setting the `-T`\n(--timeout`) option.\n\n### DID Scanning\n\nDID scanning can take a while depending on the behavior of the ECUs. By default\nonly the UDS standard identification DIDs (`F180-F18E,F190-F1FF`) are searched\nfor.  Testing has shown that searching a range of `F000-FFFF` can take around\n2 minutes for cooperative ECUs, but much much longer for ECUs which allow\nrequests to timeout rather than sending negative responses. A larger range can\nbe specified with the `-D` option:\n\n```bash\n$ ./canmap -p /dev/ttyACM0 -b 500K -sD -D F000-FFFF -i known_ecus.yml\n```\n\nDIDs are only scanned on ECUs that have already been identified. If a DID scan\nis run and there are no known ECUs then no messages will be sent.\n\n### Session Scanning\n\nIt is assumed that the default session for each ECU is session 1.  DIDs\nidentified through scanning are associated with session 1. By default the full\nrange of diagnostic sessions is searched (`02-7F`). I have found on some ECUs\nthat sessions can only be entered after already being in another prerequesite\nsession. Searching for these recursive diagnostic sessions is enabled by default\nbut can be disabled with the `-n` (`--no-recursive-session-scanning`) option.\n\nDepending on the ECU behavior, session scanning can take a varying amount of\ntime and/or produce strange error conditions.\n\n## Unit Tests\nUnit tests can be run with:\n```\npython -m unittest discover -v\n```\n\n## Acknowledgments\nThis project is made possible through collaboration with researchers at GRIMM (SMFS, Inc.), most notably Matt Carpenter and Tim Brom.\n\n## Happy Hacking!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatlas0fd00m%2FCanCat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatlas0fd00m%2FCanCat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatlas0fd00m%2FCanCat/lists"}