Hi! We're discussing a clarification of the content license; please look over to Current events if you're interested in editing.
How to Extract an OS Image
From Htc-linux
This is a tutorial on how to extract files from a NBH image. A full NBH image usually contains at least three things:
- Radio image (00_Unknown.nb)
- SPL image (01_SPL.nb)
- OS image (03_OS.nb)
Note: above filenames are just examples; they were generated by NBHextract for the sample image that was used.
With the Radio and SPL image there's not much you can do except feed them to a disassembler. The OS image can be extracted so you end up with all the files that are inside.
For this tutorial, we'll dissect a HTC Diamond firmware. Remember that extracting firmwares for other flavors might need a bit of tweaking (especially the NBSplit part). See the help text for the tool, and try tweaking the params.
Contents |
[edit] Step 0: Tools of the Trade
You'll need NBHextract and ImgfsTools to extract the files. These are Windows tools, but you can run them under wine (as in following example).
You'll also need cabextract or something similar to extract the NBH file from the firmware package (which is a self-extracting CAB). This is available as a package for most Linux distros.
user@local:~/dev$ ls tools/ cecompr_nt.dll ImgfsFromNb.exe ImgfsToDump.exe NBHextract.exe NBInfo.exe NBSplit.exe
[edit] Step 1: Get the NBH image
user@local:~/dev$ ls -l images/*
-rwxr-xr-x 1 user user 103022024 2009-08-31 04:49 images/RUU_Diamond_bla.exe
user@local:~/dev$ cabextract -l images/RUU_Diamond_bla.exe
images/RUU_Diamond_bla.exe: library not compiled to support large files.
images/RUU_Diamond_bla.exe: library not compiled to support large files.
Viewing cabinet: images/RUU_Diamond_bla.exe
File size | Date Time | Name
-----------+---------------------+-------------
1478656 | 14.12.2007 13:46:40 | ROMUpdateUtility.exe
6648 | 29.11.2006 13:36:02 | EnterBootloader.exe
11256 | 27.07.2007 22:20:10 | RUUGetInfo.exe
172032 | 19.10.2007 16:09:52 | rapitool.exe
1445888 | 23.07.2007 19:46:02 | RUUResource.dll
26354654 | 26.04.2008 20:44:54 | README.doc
154585186 | 25.07.2008 18:56:32 | RUU_signed.nbh
213862 | 26.04.2008 16:14:12 | ModelID.fig
141368 | 22.04.2008 15:20:42 | ErrorUSB.fig
143300 | 22.04.2008 15:21:56 | ErrorBattery.fig
13 | 03.07.2007 15:28:30 | ROMUpdateUtility.cfg
All done, no errors.
user@local:~/dev$ cabextract -F RUU_signed.nbh images/RUU_Diamond_bla.exe
images/RUU_Diamond_bla.exe: library not compiled to support large files.
images/RUU_Diamond_bla.exe: library not compiled to support large files.
Extracting cabinet: images/RUU_Diamond_bla.exe
extracting RUU_signed.nbh
All done, no errors.
user@local:~/dev$ ls -l RUU_signed.nbh
-rw-r--r-- 1 user user 154585186 2008-07-25 18:56 RUU_signed.nbh
[edit] Step 2: Extract the NBH
user@local:~/dev$ wine tools/NBHextract.exe RUU_signed.nbh === NBHextract v1.0 === Extract contents from HTC NBH files === (c)2007 xda-developers.com === by: pof & TheBlasphemer based on itsme perl scripts Device: DIAM10000 CID: HTC__032 Version: 1.93.479.3 Language: USA Extracting: 00_Unknown.nb Extracting: 01_SPL.nb Extracting: 02_MainSplash.nb Encoding: 02_MainSplash.bmp Extracting: 03_OS.nb user@local:~/dev$ ls -l *.nb *.bmp -rw-r--r-- 1 user user 20840448 2009-08-31 04:53 00_Unknown.nb -rw-r--r-- 1 user user 524288 2009-08-31 04:53 01_SPL.nb -rw-r--r-- 1 user user 230454 2009-08-31 04:53 02_MainSplash.bmp -rw-r--r-- 1 user user 655360 2009-08-31 04:53 02_MainSplash.nb -rw-r--r-- 1 user user 132241920 2009-08-31 04:53 03_OS.nb
[edit] Step 3: Split the OS.nb
user@local:~/dev$ wine tools/NBSplit.exe -kaiser 03_OS.nb NBSplit 2.1rc2 Using data chunk size = 0x800 and extra chunk size = 0x8 on file 03_OS.nb Done. user@local:~/dev$ ls -l 03_OS.nb.* -rw-r--r-- 1 user user 514560 2009-08-31 05:01 03_OS.nb.extra -rw-r--r-- 1 user user 131727360 2009-08-31 05:01 03_OS.nb.payload user@local:~/dev$ wine tools/NBInfo.exe 03_OS.nb.payload NBInfo 2.1rc2 '03_OS.nb.payload' has valid boot sector Partition table: Partition 0 ----------- File System: 0x20 (boot) Start Sector: 0x00000002 Total Sectors: 0x0000063e Boot indicator: 0x00 First Head: 0x02 First Sector: 0x01 First Track: 0x00 Last Head: 0x3f Last Sector: 0x01 Last Track: 0x18 Partition 1 ----------- File System: 0x23 (XIP RAM) Start Sector: 0x00000640 Total Sectors: 0x00000900 Boot indicator: 0x00 First Head: 0x00 First Sector: 0x01 First Track: 0x19 Last Head: 0x3f Last Sector: 0x01 Last Track: 0x3c Partition 2 ----------- File System: 0x25 (imgfs) Start Sector: 0x00000f40 Total Sectors: 0x0000ec00 Boot indicator: 0x00 First Head: 0x00 First Sector: 0x01 First Track: 0x3d Last Head: 0x3f Last Sector: 0x01 Last Track: 0x3ec Partition 3 ----------- File System: 0x04 (FAT) Start Sector: 0x0000fb40 Total Sectors: 0x0000b480 Boot indicator: 0x00 First Head: 0x00 First Sector: 0x01 First Track: 0x3ed Last Head: 0x3f Last Sector: 0x01 Last Track: 0x2be Geometry: flash has 64 virtual heads MSFLSH50 header found at offset 0x800 (0 Reserved Entries, 3 Flash Region Entries) Flash Region Entry 0: --------------------- Region type: XIP Start phys. block: 0x00000000 Size in phys. blocks: 0x00000000 Size in log. blocks: 0x0000003d -> Size in sectors: 0x00000f40 Sectors per block: 0x00000040 Bytes per block: 0x00020000 Compact blocks: 0x00000000 -> Bytes per sector: 0x00000800 Flash Region Entry 1: --------------------- Region type: READONLY_FILESYS Start phys. block: 0x00000000 Size in phys. blocks: 0x00000000 Size in log. blocks: 0x000003b0 -> Size in sectors: 0x0000ec00 Sectors per block: 0x00000040 Bytes per block: 0x00020000 Compact blocks: 0x00000002 -> Bytes per sector: 0x00000800 Flash Region Entry 2: --------------------- Region type: FILESYS Start phys. block: 0x00000000 Size in phys. blocks: 0x00000000 Size in log. blocks: 0xffffffff -> Size in sectors: 0xffffffc0 Sectors per block: 0x00000040 Bytes per block: 0x00020000 Compact blocks: 0x00000002 -> Bytes per sector: 0x00000800 Searching for IMGFS signature... Found IMGFS at byte 0x007e0000 (sector 0x00000fc0). dwFSVersion: 00000001 dwSectorsPerHeaderBlock: 00000001 dwRunsPerFileHeader: 00000001 dwBytesPerHeader: 00000034 dwChunksPerSector: 00000020 dwFirstHeaderBlockOffset: 00000800 dwDataBlockSize: 00001000 szCompressionType: XPR dwFreeSectorCount: 0000DAC0 dwHiddenSectorCount: 00000040 dwUpdateModeFlag: 00000000 ---
Note: Running NBInfo is optional, but it's good to run it so you can check if you got the splitting right. NBInfo will tell you if the .nb.payload file has a valid boot sector, although this does not guarantee NBSplit got everything right.
[edit] Step 4: Convert OS.nb.payload to Imgfs
user@local:~/dev$ wine tools/ImgfsFromNb.exe 03_OS.nb.payload imgfs.bin ImgfsFromNb 2.1rc2 Sector size is 0x800 bytes ImgFs partition starts at 0x007a0000 and ends at 0x07da0000 Dumping IMGFS at offset 0x007e0000 (size 0x075c0000) Done! user@local:~/dev$ ls -l imgfs.bin -rw-r--r-- 1 user user 123469824 2009-08-31 05:03 imgfs.bin
[edit] Step 5: Dump the Imgfs
user@local:~/dev$ wine tools/ImgfsToDump.exe imgfs.bin ImgfsToDump 2.1rc2 IMGFS guidBootSignature: F8 AC 2C 9D E3 D4 2B 4D BD 30 91 6E D8 4F 31 DC dwFSVersion: 00000001 dwSectorsPerHeaderBlock: 00000001 dwRunsPerFileHeader: 00000001 dwBytesPerHeader: 00000034 dwChunksPerSector: 00000020 dwFirstHeaderBlockOffset: 00000800 dwDataBlockSize: 00001000 szCompressionType: XPR dwFreeSectorCount: 0000DAC0 dwHiddenSectorCount: 00000040 dwUpdateModeFlag: 00000000 Address: 00000800, dwBlockSignature: 2F5314CE dwNextHeaderBlock: 0001C000 (size: 0001B800) ... [lots of output] ... user@local:~/dev$ ls dump/ | wc -l 4179 user@local:~/dev$ ls -l dump_MemoryMap.txt -rw-r--r-- 1 user user 27459 2009-08-31 05:06 dump_MemoryMap.txt user@local:~/dev$
You're done. Besides the actual files, which will be in a 'dump' directory, you'll see a 'dump_MemoryMap.txt' which contains the offsets of each file inside the image.
