Encryption for Dashcams Research Seminar in Cryptography Karl Tarbe May 29, 2015 1 Introduction Increasing number of drivers use dashcams to record their everyday driving, just to have extra evidence when a traffic accident happens. Common dashcams just record video / audio and some even have built-in GPS to also store location. However all of that information is stored unencrypted, which means that a car thief can learn a lot about the owners daily routine by just looking at recordings stored in the dashcam. The goal of this project was to add encryption to Prestigio RoadRunner 530. 1.1 Contributions The author of this report contributed by analysing the existing information and wrote a tool to generate ROM image from a directory. Arbitrary code execution was achieved, but actual encryption was not. 2 Monopol Many consumer cameras available in the market actually use system on a chip (SoC) produced by the same company called Ambarella[2]. The firmware is also quite similar because Ambarella has a software development kit, which helps camera developers to work with Ambarella’s SoCs. Ambarella’s main focus seems to be on designing chips that do video compression. The camera used for testing was Prestigio RoadRunner 530[1]. The camera is based on Amabrella A5S30 SoC. See Figure 1 for a block diagram of the A5S SoC. 3 State of Ambarella firmware hacking It turns out that different people have messed around with Ambarella firmwares for quite some time now. Firmware on the devices can be updated by writing a firmware file to the SD memory card and the system will update it’s firmware itself. There have been people who have managed to change parts of the firmware image. One such project can be found in [3]. Another one is called the Ambarella Firmware Toolbox (AFT) and it even has a graphical user interface [4]. The author of AFT had access to some version of Ambarella SDK. AFT also 1 Figure 1: Block diagram of A5S SoC. has an editor for the bitrate table, and it has been used to improve the video quality. However AFT is distributed as an obfuscated Java archive, so it does not offer much help. However on [3], the sources are available, and there is a reference to [8], which from the code structure seems to be written by a more experienced coder, and therefore seems to be the most trustworthy piece of information about firmware file format. Some devices also have a UART serial interface. This can be accessed by soldering wires to the circuit board. However on the Prestigio RoadRunner 530 no UART signal was found on the circuit board. On the UART interface is a shell for the bootloader[10]. After the bootloader another shell is present, it is called ambsh and it is a unix like shell[9]. One of the most important programs runnable from ambsh is t, because it can be used to control the behaviour of the camera. The shell also has facilities for firmware updating, memory dumping and raw memory access. On some devices the firmware automatically executes the commands from a script called autoexec.ash, when it is placed on the SD memory card. One collector of such scripts is Konrad Iturbe [5]. The script is a easy way to alter the behaviour of the camera without bricking it, because you can make the changes non-persistent. The most impressive work so far is a tetris game on a camera[6]. The author of this hack manually searched for common functions inside the firmware image. He wrote his code in C, but a used a custom linker script to place his code on a specific memory address, that was free. The linker script was also responsible for storing the addresses of the common functions that were used from the main firmware. 4 Firmware According to various sources the firmware consists of multiple parts. The most readable description can be found on [4]. In detail, the firmware sections for Prestigio RoadRunner 530 are 1. First stage bootloader. 2 2. Second stage bootloader - this even has a shell on the UART interface. 3. Hardware Abstraction Layer - device specific code. 4. Primary firmware - RTOS with all things included. 5. Read Only file system - some static files as sounds and logos. 6. Microcode for Digital Signal Processor. Primary firmware consist of real time operating system called PrKERNELv4. File format of firmware is best described in [7]. 4.1 Read only file system (ROM) This is a very simple file system. Basically after header it just contains the files padded with 0xff bytes to align each file to the start of a 2048 byte block. All the words in the file are 4 bytes wide and stored in little-endian. The first word of the file contains the number of files stored. The next word is a magic word, which contains the value: 0x66fc328a. Magic in here means a file signature to identify the file type. After that follows padding (0xff) to offset 0x800. On that offset is the list of file descriptions. All file descriptions are just concatenated together. A file description starts with 116 bytes, which are allocated for storing the file name as a zero terminated C-string. Next there is one word to mark the offset of the file, one word for the length of file and an another magic word, which in this case is 0x2387ab76. After the list of file descriptions is once again padding of 0xff till the start of next 2048 byte block. Then comes the contents of the first file. Every file is padded to the start of a 0x800 byte block. Even the last file is padded so that the overall ROM file size is a multiple of 0x800. For simple overview see Figure 2. For an concrete example see Table 1. RFS uint32 t number of files; uint32 t magic; header file 1 file 2 .. . char name[0x73]; uint32 t offset; uint32 t file size; uint32 t magic; file n Figure 2: Rough overview of the ROM file format. 3 Offset 0x000000 . . . 0x000800 . . . 0x000870 0x000880 . . . 0x0008f0 . . . 0x001000 . . . 0x001800 . . . 0x001ff0 Data 0200 0000 8a32 fc66 ffff ffff ffff ffff Padding (ff) 6279 652e 7478 7400 0000 0000 0000 0000 Unused space for file name (00) 0000 0000 0010 0000 0400 0000 76ab 8723 6865 6c6c 6f2e 7478 7400 0000 0000 0000 Unused space for file name (00) 0000 0000 0018 0000 0600 0000 76ab 8723 Padding (ff) 6279 65ff ffff ffff ffff ffff ffff ffff Padding (ff) 6865 6c6c 6fff ffff ffff ffff ffff ffff Padding (ff) ffff ffff ffff ffff ffff ffff ffff ffff Table 1: Example of a Read only file system containing two simple text files: bye.txt with contents ‘bye‘ and hello.txt with contents ‘hello‘. 4.2 Format of the firmware file The firmware file starts with a header which describes the sections in it. The first 128 bytes are used for an array of 4 byte words, which describe the start offset of a section. At offset 0x80, there is an array of words, which describe the end offset of the sections. From the size it appears that there might be a total of 32 sections in the firmware file. However on Prestigio RoadRunner 530 there are only six sections and for the unused sections the start offset and the end offset fields are set to zero. At offset 0x100 until 0x210 are some data, which is currently unknown to the author. The header is padded with zeros until the offset 0x800, which is the start address of the first section. Every section begins with a section header. Section header consists of several words. • CRC32 checksum of the section contents. • Section version. • Build date. The first byte is the build day, the next byte is the build month and the last two bytes (little-endian) are the build year. • Actual length of the section contents. • Location in memory, where the section should be loaded to. • Some flags, usually zero. • Magic word, which is 0xa324eb90. • And the next word seems to be the same as the flags word. 4 The rest of the header is padded with zeros. The actual section contents begins at section start offset + 0x100. The sections are aligned at 0x800 byte block boundaries, and zeros are used for padding. For an overview see Figure 3. firmware.bin header uint32 t section start[32]; uint32 t section end[32]; section header 1 section contents 1 .. . section header n section contents n uint32 t crc32; uint32 t version; uint8 t build day; uint8 t build month; uint16 t build year; uint32 t length; uint32 t load address; uint32 t flags; uint32 t magic; uint32 t flags2; Figure 3: Overview of the firmware file format. 5 Contents of the ROM Inside the ROM there are many files. One of these is a file called strings.bin. It contains the strings used in the camera user interface. There are many languages, because the user interface supports many languages. More info about it is available on [4]. There are also a lot of .jpg files, and sounds. Some Windows executables are also stored in ROM, the camera copies these files to the SD memory card so that the user can view recordings on a Windows OS. There are also some other binary files, the purpose of which remains a mystery. It turns out that the logos displayed when powering on the device and powering it off, are also stored in the ROM. So to change them, you need to generate a new ROM, which contains the JPG images you like, with the same names. The names used are pre on h.jpg and pre off.jpg. 6 Code execution The primary firmware image is just a huge binary blob. Disassembling showed that code and data is mixed. However some things are identifiable. For an example at the very start of the primary firmware image is the interrupt vector table, which contains references to the interrupt handling functions. The most common way of analysing a binary is by searching for strings. And there are 22160 static strings inside the firmware. Some of these are error messages, which give a hint at what function failed, or at which subprocess they are from. However when you know the location of a string, finding the 5 code, which uses it, is not trivial. In the firmware it is common, that a string address is loaded into a register by a instruction like “add r0, pc, 0x44;”. This is translated as: take the program counter(pc), add 0x44 to that, and store it in register 0 (r0). Now r0 contains the address of the string. However addressing like that means, that just searching for the absolute address of the string in question, will not give you results. However disassemblers usually can find some of those references. The easiest function to discover by strings is the printf function, because of the specific format strings, which go hand in hand with printf. In the Prestigio RoadRunner 530 firmware version PE3K7HGC.130523, the printf function is located at address 0xc714. Looking at format strings, function arguments and error messages, a few common function can be identified. Note that to determine function arguments from assembly code, one needs to know the calling convention used on ARM. Function name printf sprintf fopen fwrite address 0xc714 0xe9104 0x36b68 0x36eac At the end of the firmware file there were some zeros, which seem to be unused. That area can be used to write your own assembly without overwriting anything else. However something needs to be changed to make sure that code is executed. A printf call inside a function responsible for opening the GPS data file was changed to a call to inserted assembly. Having the call in there meant that the firmware functions normally until recording is started. This avoids bricking the device. For payload, a simple function was made. The goal of this function was to create a new file on the SD memory card and then write “tere” to it. The code was definitely executed, because when the code contained a bug, the UI thread/process on the camera crashed. When the bug was fixed, the process worked like nothing had happened. However no file was created on the memory card. There could be several reasons why it did not work. It might be that the systems only supports a handful of open file descriptors. Or it could be that for the actual writing to take place one needs to call fflush and fclose on the file stream. 7 Future work More time needs to be spent on disassembling the firmware to find the actual data path for the video data. Maybe it goes through the ARM CPU, and encryption can be implemented. The SoC even has some hardware crypto primitives. However it might be the case that, data is written to the SD memory card directly by the DSP used for video encoding. If this is the case, there still might be ways to encrypt the video on the CPU. 6 8 Conclusion Device manufactures have not included encryption to their cameras. However need for privacy is increasing in the age of information society. Fortunately the community is working on taking matters to their own hands. Thanks to reverse engineering, community has created firmwares that improve the cameras. When there is greater demand for privacy the device manufactures or the community will add encryption. 9 Acknowledgements The author would like to thank Lauri Mihkels, for his help in trying to find UART signal on the circuit board. While writing this report, the author received scholarship from IT Academy. References [1] Prestigio RoadRunner 530 http://www.prestigio.com/catalogue/DVRs/Roadrunner_530GPS# /product-specs?article=PCDVRR530A5GPS [2] Ambarella fact sheet http://www.ambarella.com/uploads/docs/company-fact-sheet.pdf [3] Evilwombat’s github repository https://github.com/evilwombat/gopro-fw-tools/ [4] Dashcam Hacking http://dc.p-mc.eu/ [5] Konrad’s github repository https://github.com/konradit/autoexechack [6] Hacking the Kodak Zx3 http://spritesmods.com/?art=zx3hack [7] DashCamTalk forum post https://forum.dashcamtalk.com/threads/r-d-a7-r-d-thread.5119/ [8] Extractor for GoPro camera firmware https://gist.github.com/nezza/2394361 [9] CHDK forum thread about GoPro HD HERO firmware http://chdk.setepontos.com/index.php?topic=5890.0 [10] Forum post about the discovery of amboot http://goprouser.freeforums.org/stickie-hero2-firmware-studies-t4961-30. html 7
© Copyright 2026 Paperzz