-
Notifications
You must be signed in to change notification settings - Fork 20
Blob Reversing
The USB Armory is intended to be a fully open platform. While this is mostly true already (uBoot, Linux, and userland are open source) our trust is rooted in some magic hidden inside the i.MX53 ROM and its proprietary High Assurance Boot system.
There is a boot ROM dumper which will allow us to inspect the ROM inside the i.MX53. Converting the ROM dump to ELF, will make disassembly and analysis easier.
# imx53_bootrom-dump 0 16 > bootrom-0-16k.bin
# imx53_bootrom-dump 0x404000 48 > bootrom-1-48k.bin
Consult §7.4.1 of IMX53RM (i.MX53 Multimedia Applications Processor Reference Manual); figure 7-2 illustrates the memory mapping.
Additionally, §7.10 describes some functions of the HAB library:
The RVT table contains the pointers to the HAB API functions and is located at 0x00000094
The HAB ... includes a software implementation of SHA-256 for cases where a hardware accelerator cannot be used. The core RSA signature verification operations are performed by a software implementation contained in the HAB library. The main features supported by HAB are X.509 Public key certificate ... [and] CMS signature format support
Also of interest is §7.4.5 which says:
The exception vectors located at the start of iROM are used to map all the ARM exceptions (except the reset exception) to a duplicate exception vector table in internal RAM. During the boot phase, the iRAM vectors point to the serial downloader in iROM.
Hopper is awesome for this. If you want to play along, I wrote some scripts to import and export annotations, and some of the observations can be seen here
Eventually the firmware of the SD cards should also be analyzed. Once we get HAB to work, a hostile SD card should be less of a concern. Bunnie did some interesting work that may be useful: [1] [2] [3] [4] [5]
- X.509 certificate parser will be found
- RSA signature verification will be found
- i.MX53 has a USB downloader: find instructions relating to USB
- SAHARAv4 may be used: find instructions that call it
- When secure boot is active, the processor will probably reset if signature checks fail. Look for resets...
- get friendly with the datasheet and register maps. there's a really good chance that every time you see
53fd4000something nearby is messing with the clock control module. take a few passes through the assembly listing and annotate potential register accesses. Boundarydevices did a really great i.MX53 Register Map, which I should try use to generate automatic annotations. - As you reverse things, name your subroutines descriptively until you understand their true names eg.
sub_218_wait_for_pll_ready - Look for patterns - lots of 0x53f____ or 0x63f____, those are probably register accesses; lots of 0x0040____ might be pointers to other code or data
- now that the ELF converter creates memory segments for all the registers, individual addresses can be named and crossreferenced
- sometimes the call graph makes more sense, other times the pseudocode is easier. switch back and forth, name memory locations, annotate function names until it all makes sense
- watch out for disassembly that doesn't make sense. the example below is probably interpreting a lot of zeroes as code.
... 0040ebd4 movs r0, r0 0040ebd6 movs r0, r0 0040ebd8 movs r0, r0 0040ebda movs r0, r0 0040ebdc movs r0, r0 0040ebde movs r0, r0 ...
###Functions
-
0x000574enable clock gates for peripheral (NOTE: 0-20 are valid, still a few cases to identify)- case 1: eSDHC1
- case 2: eSDHC2
- case 3: eSDHC3
- case 4: eSDHC4
- case 5: I2C1
- case 6: I2C2
- case 7: I2C3
- case 8: ECSPI1
- case 9: ECSPI2
- case 10: CSPI
- case 15: UART1
- case 16: UART2
- case 17: UART3
- case 18: UART4
- case 19: UART5
-
0x001be0main() -
0x001d86setup exception vectors, copy rodata, do secure init, jump to main() -
0x404000read GPIO pad status -
0x404010write GPIO data -
0x40407ewrite IOMUXC control register -
0x404090refresh watchdog timeout counter -
0x40409esetup watchdog -
0x4040f2disable watchdog power down counter -
0x404924enter USB/UART polling loop, if activity is detected, run serial downloader -
0x405b9c__aeabi_memcpy() -
0x405c44wait for n general purpose timer ticks to elapse -
0x405c72set general purpose timer OF1 trigger value -
0x405c92get general purpose timer OF1 value -
0x405ca0disable general purpose timer -
0x407a86memcpy() -
0x407a9aappears to extract 1/2/4-byte integers from a buffer (ASN.1 parser?) -
0x407ab6copies 1/2/4 byte from one pointer to another -
0x40a00astart of SHA256-related functions -
0x40bff8appears to extract integers and change their endianness (ASN.1 parser?) -
0x40e2bcdecode SIGFPE reason to string -
0x40e364possibly a puts() implementation -
0x40e508return from exception -
0x40e510disable interrupts for entering deep sleep mode -
0x40e55cexception vector(s) target -
0x40e568reset vector target; init registers, disable interrupts, setup stack -
0x40e5b0write L1 TTEs -
0x40e624zero target memory region in 32 bit chunks, like bzero() -
0x40e674copy 32 bit aligned words (part of __aeabi_memcpy family) -
0x40e6c8disable data and instruction caches -
0x40e76cinvalidate data cache -
0x40e884shutdown MMU -
0x40e8f4wait for interrupt -
0x40e8fcdisable VFP (CP11 and CP10 access)
###rodata contents
- SHA256 initial registers are at
0x40f094 - SHA256 round constants are at
0x40f0b4 - USB descriptor structs are at
0x40fa36 - 0x40fb9a - USB identification strings are at
0x40fad4
- http://www.rockbox.org/wiki/ObjdumpGuide
- http://chdk.wikia.com/wiki/GPL_Disassembling
- https://www.blackhat.com/presentations/bh-europe-04/bh-eu-04-dehaas/bh-eu-04-dehaas.pdf
- http://beginners.re/Reverse_Engineering_for_Beginners-en.pdf
- http://www.mathyvanhoef.com/2013/12/reversing-and-exploiting-arm-binaries.html
- http://hexblog.com/files/recon%202010%20Skochinsky.pdf
- http://doar-e.github.io/blog/2014/04/30/corrupting-arm-evt/
- https://sites.google.com/site/shihsung/rc32xxx-soc/analyze-firmware
- http://bhduan.blogspot.com/2007/11/arm-coprocessor-cp15-summary.html