Jump to: navigation, search

What is mbmloader

Strictly speaking, mbmloader (There's a (c) 2006 Motorola notice in it, since it reuses code from the older versions of mbmloader used in previous Motorola phones. This works to our advantage because some of those earlier versions have been reverse engineered in the past by yakk in his MotoMagX hack.) is one of the first components in the boot chain. It verifies and then loads the mbm component. It checks mbmbackup for newer versions of mbm, so that mbm cannot be downgraded (this can be easily bypassed once running as root, since both mbm and mbmbackup could be downgraded at the same time).

More generally speaking, we sometimes say "mbmloader" to refer to the whole bootstrap system, which is composed by:

The mtd-hack module by janneg allows us to dump mtd00 which includes all of these, and we usually call this the "mbmloader dump" or "mbmloader CG".

mbmloader protections

Mbmloader has public certificates in it (see the ISW section). These certificates parsed on Cryptography page. We also know that both the Milestone and the Droid run in HS mode, which requires this format.

According to the CSST's use of openssl, the openssl "commands" used to generate the certificates may somehow be intercepted. Moreover, analyzing the csstcli(command line tool) and it's parameters may identify what and how the certificates are signing upon.

Loading mbmloader from SD card

mbmloader can be loaded from SD card after software reset. It may be useful to check new version of mbmloader without reflashing phone. Details: How to load mbmloader from SD card

How mbmloader verify mbm?


yakk has contributed his effort to map many high level functions name for the mbmloader image. This allows easier inspection of how the verification of mbm is performed. Perhaps he has already reviewed the related portion of codes for potential vulnerability, trying to document the findings that allows continuation could be a possible way to figure out a way.

Work flow

mbm is read into address 0x8f310000.

Search for the end of signature mark(the data length suggests a sha1sum):

6B D3 98 E2 D6 F0 F8 CF FC D4 96 72 5E B3 A8 B3 6B F9 B1 16

Milestone mbmloader

now we only known only two versions of mbmloader for milestone:

Both versions have same code (and even version number - 05.0A!), but some data and keys differ.


Accredited by yakk, idb of mbmloader with high level function names are available. Further exploration is in the progress to map more information from kernel source and technical reference manual.

Kernel source


  1. #define REGISTER_ADDRESS_DIE_ID  0x4830A218
  2. #define REGISTER_ADDRESS_MSV 0x480023B4

Searching b4 23 00 48 in mbmloader give:

  1. ROM:87004954 EF BE AD DE dword_87004954  DCD 0xDEADBEEF          ; DATA XREF: get_fuse+4
  2. ROM:87004954                                                     ; sub_87004798+A
  3. ROM:87004958 B4 23 00 48 MSV             DCD 0x480023B4          ; DATA XREF: get_fuse:loc_87004786
  4. ROM:8700495C 18 A2 30 48 DIE_ID          DCD 0x4830A218          ; DATA XREF: sub_87004832+18


  1. #define L4_34XX_BASE            0x48000000
  2. #define L4_WK_34XX_BASE         0x48300000
  3. #define L4_PER_34XX_BASE        0x49000000
  4. #define L4_EMU_34XX_BASE        0x54000000
  5. #define L3_34XX_BASE            0x68000000
  6. #define OMAP3430_32KSYNCT_BASE  0x48320000
  7. #define OMAP3430_CM_BASE        0x48004800
  8. #define OMAP3430_PRM_BASE       0x48306800
  9. #define OMAP343X_SMS_BASE       0x6C000000
  10. #define OMAP343X_SDRC_BASE      0x6D000000
  11. #define OMAP34XX_GPMC_BASE      0x6E000000
  12. #define OMAP343X_SCM_BASE       0x48002000
  13. #define OMAP34XX_IC_BASE        0x48200000
  14. #define OMAP34XX_IVA_INTC_BASE  0x40000000
  15. #define OMAP34XX_SR1_BASE       0x480C9000
  16. #define OMAP34XX_SR2_BASE       0x480CB000
  17. #define OMAP34XX_DSP_BASE       0x58000000

Technical Reference Manual

Abbreviation Meaning Reference
MSV Model Specific Value spruf98 p. 981, Control Module, Registers, GENERAL registers description), Table 6-496. CONTROL_MSV_0

4.14.1 CM Module Registers, Table 4-90. CM Instance Summary (spruf98 p.440)

Module Name Base Address (hex) Size
IVA2_CM 0x4800 4000 8192 bytes
OCP_System_Registers_CM 0x4800 4800 8192 bytes
MPU_CM 0x4800 4900 8192 bytes
CORE_CM 0x4800 4A00 8192 bytes
SGX_CM 0x4800 4B00 8192 bytes
WKUP_CM 0x4800 4C00 8192 bytes
Clock_Control_Registers_CM 0x4800 4D00 8192 bytes
DSS_CM 0x4800 4E00 8192 bytes
CAM_CM 0x4800 4F00 8192 bytes
PER_CM 0x4800 5000 8192 bytes
EMU_CM 0x4800 5100 8192 bytes
Global_Registers_CM 0x4800 5200 8192 bytes
NEON_CM 0x4800 5300 8192 bytes
USBHOST_CM 0x4800 5400 8192 bytes

6.6 System Control Module Registers Table 6-80. Instance Summary

Name Address Instance length
INTERFACE 0x4800 2000 36 bytes
PADCONFS 0x4800 2030 564 bytes
GENERAL 0x4800 2270 767 bytes
MEM_WKUP 0x4800 2600 1K byte
PADCONFS_WKUP 0x4800 2A00 80 bytes
GENERAL_WKUP 0x4800 2A60 31 bytes

18.8 McSPI Registers, Table 18-22. Instance Summary

Module Name Base Address Size
MCSPI1 0x4809 8000 4Kbytes
MCSPI2 0x4809 A000 4Kbytes
MCSPI3 0x480B 8000 4Kbytes
MCSPI4 0x480B A000 4Kbytes

Address extracted from mbmloader

Prefixed by 0x4800:

0x48002000 Control Revision
0x48002180 CONTROL_PADCONF_UART1_CTS - Configuration register for pads uart1_cts(clear to send), uart1_rx. ((spruf98 p. 870, CONTROL_PADCONF_UART1_CTS))
0x480021C8 CONTROL_PADCONF_MCSPI1_CLK - Configuration register for pads mcspi1_clk, mcspi1_simo
0x480022F0 Control status - SYS_BOOT and DEVICETYPE
0x480023B4 MSV - Model Specific Value, 4 bytes
0x48004000 Clock manager, Module region A, 8KB ((spruf98 p.203, Table 2-3. L4-Core Memory Space Mapping))
0x48004904 CM_CLKEN_PLL_MPU, This register allows controlling the DPLL1 modes. ((spruf98 p.454))
0x48004A00 Table 4-143. CM_FCLKEN1_CORE, Controls the module functional clock activity.
0x48004A10 Table 4-147. CM_ICLKEN1_CORE, Controls the modules interface clock activity.
0x48004A20 Table 4-153. CM_IDLEST1_CORE, CORE modules access availability monitoring. This register is read only and automatically updated.
0x48004B40 Table 4-177. CM_CLKSEL_SGX, SGX clock selection.
0x48004C00 CM_FCLKEN_WKUP, Table 4-185. CM_FCLKEN_WKUP, Controls the modules functional clock activity.
0x48004D00 Table 4-195. CM_CLKEN_PLL, This register allows controlling the DPLL3 and DPLL4 modes.
0x48004E40 Table 4-227. CM_CLKSEL_DSS, Modules clock selection.
0x48005000 Table 4-251. CM_FCLKEN_PER, Controls the modules functional clock activity. RW, WDTIMER can be enabled/disabled here.
0x48005140 Table 4-267. CM_CLKSEL1_EMU, Modules clock selection.

Prefixed by 0x4830:

0x48306000 Table 4-297. PRM Instance Summary, IVA2_PRM
0x48306D40 Table 4-387. PRM_CLKSEL, This register controls the selection of the system clock frequency. This register is reset on power-up only. RW
0x48307000 Table 4-297. PRM Instance Summary, PER_PRM
0x48307250 Table 4-456. PRM_RSTCTRL, Global software and DPLL3 reset control. This register is auto-cleared. Only write 1 is possible. A read returns 0 only. Perhaps it be used to issue a software reset? (( Global Warm Reset Sequence))
0x48307270 Table 4-466. PRM_CLKSRC_CTRL, This register provides control over the device source clock.
0x4830A218 DIE ID, 16 bytes

Other 32-bit dword:

0x40208800 SRAM 
0x4020C800 SRAM
0x4806A000 UART1 DLL_REG, 16.6 UART/IrDA/CIR Registers
0x48098000 18.8 McSPI Registers, McSPI1(Multichannel Serial Port Interface)
0x48314000 WDTIMER2, Table 15-66. WDT2 Register Summary
0x48318000 GPTIMER1, 15.3 General-Purpose (GP) Timer Registers
0x49020000 UART3 (infrared), L4-Peripheral Memory Space Mapping, Table 2-5. L4-Peripheral Memory Space Mapping
0x5A827999 SHA1 c1
0x6E000000 Table 10-27. Instance Summary, GPMC.
0x6E00007C GPMC_NAND_COMMAND_i, This register is not a true register, just an address location.
0x6E000084 GPMC_NAND_DATA_i, This register is not a true register, just an address location.
0x6E0000A8 GPMC_CONFIG7_i, i = 1
0x6E0001F4 GPMC_ECC_CONFIG, ECC configuration, RW, able to control hardware ECC.
0x6E0001F8 GPMC_ECC_CONTROL, ECC control, RW, able to control hardware ECC.
0x6ED9EBA1 SHA1 c2
0x8F1BBCDC SHA1 c3
0x8F310000 mbm load address
0x8F311000 mbm offset 0x1000
0xB17219E9 special value in mbm
0xCA62C1D6 SHA1 c4
0xDEADBEEF dummy value mark dead beef

Mbmloader replacement Attack

By having probed the hardware, with this simple code:

#include <mach/cpu.h>
main () 
   printk(KERN_INFO "omap type: %d\n", omap_type());
we know the OMAP processor works in High Security mode upon booting (as opposed to General Purpose mode). We know the Droid is working in HS mode too. 

In HS mode the mbmloader's cryptographic signature can be checked before booting, and since the signatures are being checked in later stages of the boot process, we guess both mbmloader and mbm are probably signed and verified too. Static code analysis seem to confirm the signatures are in place. Mbmloader itself apparently checks for mbm's signature before passing control to it. The idea of this attack is simply to replace mbmloader with another version that does not check for mbm's signature. We would then be free to replace mbm with a patched version that allowed us to run modified kernels and boot images.


We can find some mbmloader that is signed with the same key as the Milestone's but that does not enforce the signature chain on mbm. We are also able to write to the NAND area where mbmloader is stored, so as to replace it.

How can we write to the NAND area where mbmloader is stored

Janneg's test has sadly demonstrated that we're currently unable to write meaningful data on those sectors of the NAND Flash. The Hardware ECC mechanism should be used somehow.

How to know in advance whether a given mbmloader can work on the Milestone

When janneg's phone was unfortunately bricked, it ended up with a corrupted mbmloader and trying to boot from USB (expecting a signed image in some unknown format). In this mode, the phone's boot ROM sends the ASIC ID to the USB host. In janneg's case, the ASIC ID was:

05010501 34300757 13020100 12150136 
66e176b7 00efa289 0d53bd71 93627710
b01bbe14 15011d3f b662794d 8c70fb57
b4cb492e 27f66f15 2e4f1509 01f7488f
28a027e5 b3

This has been decomposed into the following information by user [mbm], based on table 1-8 in the section of the sprufd6.pdf TRM document:

  ASIC ID Item    Size [bytes]    Description
  Items                      1    Number of subblocks
  ID sub block               7    Device identification information
  Secure mode subblock       4    Secure identification data
  Public ID subblock        23    Public identification data generated by secure ROM
  Root key hash subblock    23    Root key hash generated by a secure ROM service
  Checksum Subblock         11    4 bytes: CRC of public ROM. 4 bytes: CRC of secure ROM
  ITEMS: 05
    ID[01] 05 [01][34 30 07 57]
  SECURE[13] 02 [01][00]
  PUBLIC[12] 15 [01][36 66 e1 76 b7 00 ef a2 89 0d 53 bd 71 93 62 77 10 b0 1b be]
    ROOT[14] 15 [01][1d 3f b6 62 79 4d 8c 70 fb 57 b4 cb 49 2e 27 f6 6f 15 2e 4f]
    CRCS[15] 09 [01][f7 48 8f 28][a0 27 e5 b3]

It is possible to get the device into USB peripheral boot mode by changing "software booting configuration" (see How to load mbmloader from SD card).

It seems user kokone has been able to guess how the key verification process works. Using his tool for exporting mbmloader keys into .PEM format, he realized that the SHA1 verification hash of the "Public Key in LBL Format including the 0x14 bytes status info in front" results in value 1d3fb662794d8c70fb57b4cb492e27f66f152e4f, which is precisely the same value as the ROOT[14] field decoded from the ASIC ID. It is verified that kokone calculated the sha1 hash based on this formula:

root_pk_hash = sha1_hash(20_bytes_key_info + modulus)

Modulus's length is specified in the key info. For instance, a 1024-bits modulus would require only 1024-bits to be hashed due to the least significant byte order of modulus.

The content can be extracted by mbmloader using this command:

dd if=mtd_00_mbmloader.img skip=1076 bs=1 count=276 of=pk.bin
sha1sum pk.bin
1d3fb662794d8c70fb57b4cb492e27f66f152e4f *pk.bin  

A sample file can be downloaded ->

It has also been found that droid001's returns this same value (reversed order is normal due to different presentation method of sha1sum and pkhash) in its CONTROL_RPUB_KEY_H[4:0] field.

Running droid001's pkhash in Latam Milestone phones shows that those phones have the same hardware key as the European Milestone.

Sadly, the Droid hash stored in hardware is different from the Milestone's: it is 75ed7020641333dd7bc3aecb9857683c2422efe1(see [1].). Thus, we won't be able to use Droid's mbmloader on the Milestone. It's strange that the root pk hash is different from the value calculated by hand according to the method above.((http://milestone.denhaas.info/date/10-03-2010/ 17:42:38 nothize))

XVilka's developer phone, mbmloader version 90.80 (which has a CertPK that matches the CSST 2.6's multiroot key; see [2].), does NOT run in HS mode. It does have a hash key stored in hardware (different from the one in the normal Milestone, see [3].), but it is not used in GP mode.

So, all in all, we do not have any mbmloader suitable for installation on the Milestone that will break Motorola's chain of trust. If you know of any other mbmloader version, let us know.


mbm's entry point

The Droid's mbm might have a different entry point than the one in the Milestone's mbm. Thus the Droid's mbmloader would not be able to pass control to the Milestone's mbm. The obvious workaround would be to replace mbm too. There might be other offsets to take care of, besides mbm's entry point.

mbm's hardware initialization process

The Droid's hardware might be a bit different from the Milestone's. This is supported by an official Motorola reply to a direct question by vekexasia. If that's the case, the Droid's mbm would fail to initialize the Milestone's hardware, thereby bricking the phone. The workaround would be to use the Milestone's mbm, but patching it so that the Droid's mbmloader is able to use it (e.g., moving mbm code around, inserting jumps, etc.). There would be no problem with patching Milestone's mbm in this case, since the Droid's mbmloader would not check on mbm's signature (but this is an ad-hoc hypothesis, because we don't know it for sure!).

cdt format

The CDT table's format seems to differ between the Droid and the Milestone, so if we were to use the Droid mbmloader this should be handled somehow.


In the event of a mistake in the process, or if our hypothesis is wrong, the device would be bricked beyond repair (at least with the resources we have, namely RSD Lite). The person trying this attack should be aware of this risk, and would probably be willing to try it on a device which could be sent to Motorola for repair without much hassle or cost (e.g., a Milestone that has some obvious warranty-covered issue such as a defective keyboard, etc). A German Motorola service agent is said to have quoted 89 euros for repairing firmware tampering.

Attack process

Here's a donation link that some people have set up to buy a Milestone for testing this attack.

 Note: this test procedure is under review, so please ask before following it!
  1. If possible, record the whole process with a video camera), so it can later be analyzed. You should also log in to the IRC channel for assistance during this attack.
  2. Get the 6mb droid dump and gunzip the file((Since the CH header differs between the Droid and the Milestone, the Droid CH table may not work with a Milestone. The risk is low, though, because the difference is small. Although we cannot be sure about it, it is [mbm]'s opinion that it could work. In case you want to keep the Milestone CH table, you can use this other patched Droid dump instead, but keep in mind that the Release Notes for CSST v2.4 suggest the CH header can be signed too (and if it is, this patched Droid dump could brick your phone permanently). Nonetheless, as far as we know the CH table doesn't seem to be signed in the Milestone nor in the Droid, so this patched Droid dump should probably work fine. Finally, a whole dump of a Droid NAND flash can be used too; just remember that it should contain at least CH+MBMLOADER+MBM+MBMBACKUP+CDT.).
  3. Obtain and transfer a modified, write-enabled mtd-hack-based harakiri.ko module to the phone (untested source code by [mbm here that compiles with warnings](it's a quick and dirty version; it takes mtd->erase and points it at new erase function which is just a cut and paste of the old one with the panic commented out), precompiled binary here with those warnings solved).
  4. Set USB Debugging in the Milestone's Settings/Applications/Development configuration menu.
  5. Boot the Milestone in Recovery mode with ADBrecovery, so it's running on RAM.
  6. Follow this procedure to change mbmloader:
    1. su to root
    2. Execute a command to write the Droid image into the h_harakiri mtd. The correct command is yet to be determined((There are two known teardowns of the Droid, and none of the Milestone. There's the phoneWreck teardown and the iSuppli cost analysis. The 512 MB total NAND flash is split in 256 MB PoP and 256 MB standalone. The PoP chip is a Toshiba YBC0A111100L8, although there is no information about this chip ID on the web; iSupply but doesn't mention any chip ID. The standalone chip seen in the phoneWreck teardown is Toshiba TY9000A000GLLF, and the one seen in the iSuppli pictures is a Numonyx (SGS-Thomson, STMicroelectronics) NANDA9R4N4CZBA5. As seen on the Linux syslog, the Droid's memory detection message is "NAND device: Manufacturer ID 0x20, Chip ID: 0xbc (ST Micro NAND 512MiB 1,8V 16-bit)". In contrast, the Milestone's memory detection message is "NAND device: Manufacturer ID: 0x98, Chip ID: 0xbc (Toshiba NAND 512MiB 1,8V 16-bit)".)).
  • Note 1: do NOT use dd at this point, because it seems to corrupt the hardware-ECC-corrected part of the NAND flash((see the patches introduced to the OMAPZoom project on 2010-01-07 here. They may point the way to fix this problem, although those sources seem to apply to a Samsung K9F1G08R0A chip. User kokone proposes that "The ROM loader reads mbmloader using low level access to the Flash ... Perhaps the hardware ECC is not yet enabled and the used software ECC not compatible with hardware ECC?". But user sgx says "I can confirm that hardware ecc is required to properly flash an omap initial bootloader".)). User janneg created a Milestone dump, flashed it using dd but saw md5 difference with his previous dump; he then tried flash_image and the phone rebooted automatically due to panic in old mtd-hack. The reboot went fine (even though there were bit errors) and the system ran fine, even booting Android. (Here's the corrupted code diff, so we can inspect whether that was ECC or not).
  • Note 2: do NOT use "flash_image h_harakiri droid.flash" at this point, because it may not be writing to the correct NAND flash location (or otherwise does in a way that is not bootable). User janneg tried this command after his abovementioned test; he also added mtd-hack with panic workaround, flashed the Milestone dump again using flash_image and md5 hash of boot area was correct again. But then he rebooted and the phone was bricked. We still do not know what went wrong with this test. His phone was left with the boot ROM receiving USB commands((see the abovementioned sprufd6.pdf TRM. User playya has put together [some untested code] for talking to the boot ROM in this state.)).
  • Note 3: An alternative method has been proposed by Skrilax_CZ based on how other Motorola phones have their mbmloader updated: by creating an SBF file containing mbm (CG30), mbmloader (CG31), bploader (CG32) and a modded ramdld. The ramdld can be modded because the address table inside the ramdld located between addresses 0x0F8 and 0x260 (offsets of the smg) is not signed. But applying this SBF file blindly is likely to brick your phone, because:
          - we do not know whether the Milestone mbm is able to write to the hardware-based ECC protection of the first sectors of the NAND flash.
          - the included mbmloader version is 90.72 which is the oldest Milestone version. If you have a later mbm version, the mbmloader will refuse to boot in order to prevent the mbm downgrade; thus, the phone would be bricked.
          - the included bploader is set at 128KB long. This has been extracted from a live phone. The length is guessed (there are only 0xff after this part, and the Sholes Table bploader is also 128KB long).
  1. Execute "sync" as root.
  2. Execute "dmesg" and see the latest info, to check if there were any errors during the flashing.
  3. Dump the flash contents in the SD card. For example, try something like "dd if=/dev/mtd11 of=/sdcard/afterflash.img" if mtd11 is h_harakiri
  4. Take the battery out.
  5. Put the battery back.
  6. Connect the Milestone via USB to a Linux host.
  7. Press the D-Pad UP key, and hold it. Press the Power button for a while, then let go of both keys.
  8. Report what happens at this point.
  9. Does it turn the screen on? (check it out in a dark room).
  10. run "lsusb -vd 22b8:41db" on the Linux host (you may need to wait a bit before you get any results with this).
  11. If mbm shows up on the display and says "OK to program", then we're in. We just need to prepare a custom SBF with the correct baseband, etc., and then load it with RSD Lite under Windows XP (MUST be XP for meaningful results).