自iPhone 6s 之後iphone就開始使用NVME SSD
但是若透過iPhone 主控來處理,受到限制會很多. 這篇文章為逆向iPhone 6S NVME SSD方法
轉自http://ramtin-amin.fr/#nvmepcie
OSSLab翻譯與編修
NVMexpress是嵌入式設備中使用的下一代存儲技術。主要想法是直接在PCIexpress級別安裝儲存控制器,避免了大量協議轉換。
該技術基於PCIe。我們可以在最近的Macbook 12 retina上看到它在控制面板上的詳細信息:
最近,Macrumers在這個屏幕截圖上展示了這個特點:
所以這實際上是非常有趣的去看看它,
關於Macbook用的NVME控制器可以參考OSSLab文
解焊Nand
這裡有幾個視頻,顯示了Nand Flash是如何被移除或替換的。
物理接口
網路上有流出的iPhone 6S 電路圖, 這顆Flash芯片的引腳如圖。
我們可以看到它需要3個主電壓:0.9v,1.8v和3.0v。我們有一個帶有TX [0..1] +/-和RX [0..1] +/-以及CLK +/-引腳的2個PCIe接口。請注意那些是差分對。我認為他們是用90R阻抗路由的。最重要的是,我們可以找到一些PCIe控制引腳,例如CLKREQ,NRST。還有其他一些配置引腳,如低功耗模式,固件綁定和SWD jtag。另一個有趣的部分是Clkc頻率直接由SoC PLL本身控制。為了讓芯片在其他地方工作,人們需要知道頻率。用範圍很容易做到的事情:
所以需要24Mhz 1.8v。
自己做的Apple iOhone NVMe讀取器
為了讀取NVMe,我為此開發了帶有零插入力讀卡器的PCIe卡。我將JTAG部分引入20pin頭部。
這裡的難點在於差分對的信號完整性。為了做到這一點,我不得不使用多層PCB,並且通過了解疊層,用於prepeg的材料等來進行阻抗匹配。
由於我不打算自己出售這些設備,所以我想要感謝同意進行一小部分製作的Itead Studio。吟遊詩人目前正在預購。請注意,為這個項目製作的套接字不是通用的,而是為LGA70定制的,這解釋了這個價格。 https://www.itead.cc/nvme-reader.html
NVMe枚舉
# lspci -d 106b:2002 -vvv
09:00.0 Mass storage controller: Apple Inc. Device 2002 (rev 11) (prog-if 02)
Subsystem: Apple Inc. Device 2002
Physical Slot: 1-2
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 19
Region 0: Memory at a0800000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [50] MSI: Enable- Count=1/8 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [70] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <4us, L1 <32us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset-
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x2, ASPM L0s L1, Exit Latency L0s <1us, L1 <8us
ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x2, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Not Supported, TimeoutDis+, LTR+, OBFF Not Supported
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-, EqualizationPhase1-
EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
Capabilities: [148 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
Status: NegoPending- InProgress-
Capabilities: [168 v1] #19
Capabilities: [178 v1] Latency Tolerance Reporting
Max snoop latency: 0ns
Max no snoop latency: 0ns
Capabilities: [180 v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
PortCommonModeRestoreTime=25us PortTPowerOnTime=10us
正如我們所看到的,該設備使用Apple的VID:0x106b,PID是0x2002。請記住,mac book air中的版本是0x2001!在具有NVMe驅動程序的Mac書中使用此卡時,我無法使其工作。它看起來像驅動程序不工作。
驅動逆向工程
為了讓它工作,我必須設法讓驅動工作。NVMe是在Linux中實現的,Matthew Wilcox(給了我很大的支持)做了一件非常棒的Linux的NVMe驅動程序開發。其他一些人已經做了porting轉移,以便讓Driver 為MacbookAir工作。所以在將PID添加到驅動程序並重新編譯後,發現還是無法正常工作。它看起來像減少所需的大小,NVMe核心使用主機DDR為了工作。因此,蘋果並不嚴格遵循有關初始化的規範。臨時區域從一開始就被保留,它的地址和長度都在設備樹中。為了設置這些值,NVMe有一些從地址BAR0 + 0x1800開始的特殊寄存器。例如,寄存器偏移量0x1910 0x1914 0x1918 0x191c接縫包含有關錯誤代碼的信息,當NVMe在其STATUS(CSTS)寄存器中設置錯誤位時。當處於BFH模式時,一些其他有趣的寄存器位於0x1b00附近。我們將在稍後回复。
# nvme list
Node SN Model Version NS Usage Format FW Rev
---------------- -------------------- -------------------- -------- -- -------------------------- ---------------- ---------
/dev/nvme0n1 01061019E5C211EB0 APPLE SSD AP0016K 1.0 1 16,00 GB / 16,00 GB 4 KiB + 0 B 11.90.01
/dev/nvme0n2 01061019E5C211EB0 APPLE SSD AP0016K 1.0 2 8,39 MB / 8,39 MB 4 KiB + 0 B 11.90.01
/dev/nvme0n3 01061019E5C211EB0 APPLE SSD AP0016K 1.0 3 131,07 kB / 131,07 kB 4 KiB + 0 B 11.90.01
/dev/nvme0n4 01061019E5C211EB0 APPLE SSD AP0016K 1.0 4 8,19 kB / 8,19 kB 4 KiB + 0 B 11.90.01
/dev/nvme0n5 01061019E5C211EB0 APPLE SSD AP0016K 1.0 5 8,19 kB / 8,19 kB 4 KiB + 0 B 11.90.01
/dev/nvme0n6 01061019E5C211EB0 APPLE SSD AP0016K 1.0 6 4,10 kB / 4,10 kB 4 KiB + 0 B 11.90.01
/dev/nvme0n7 01061019E5C211EB0 APPLE SSD AP0016K 1.0 7 1,05 MB / 1,05 MB 4 KiB + 0 B 11.90.01
如你所見,nand包含7個分區。他們通常是第一個帶有系統的HFS,第二個是llb + iboot(當然GID加密)。第三個是syscfg …等等。
名字空間的解析。
NS1
NS1用於’fsys’,並包含一個LwVM格式的分區,其中包含三個卷 – 系統(/),數據(/ private / var)和Baseband。這些對iOS都是可見的,分別為/dev/disk0s1s1..s3 (注意 這邊會有HFS +加密)
00000000 6a 90 88 cf 8a fd 63 0a e3 51 e2 48 87 e0 b9 8b |j.....c..Q.H....|
00000010 a3 a2 64 6b a1 b1 41 9b 89 49 95 75 61 74 53 31 |..dk..A..I.uatS1|
00000020 00 80 b2 e6 0e 00 00 00 03 00 00 00 1d 4f 5c b9 |.............O\.|
00000030 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200 48 46 53 00 00 00 11 aa aa 11 00 30 65 43 ec ac |HFS........0eC..|
00000210 a9 49 c9 cf 91 41 43 bc bc c3 2a 80 c9 71 e1 79 |.I...AC...*..q.y|
00000220 00 60 00 00 00 00 00 00 00 f0 16 da 00 00 00 00 |.`..............|
00000230 00 00 00 00 00 00 00 00 53 00 79 00 73 00 74 00 |........S.y.s.t.|
00000240 65 00 6d 00 00 00 00 00 00 00 00 00 00 00 00 00 |e.m.............|
00000250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000280 48 46 53 00 00 00 11 aa aa 11 00 30 65 43 ec ac |HFS........0eC..|
00000290 6b a9 57 fb 7e 21 46 78 96 16 b5 15 4f df 4d 3e |k.W.~!Fx....O.M>|
000002a0 00 f0 16 da 00 00 00 00 00 10 61 c3 0e 00 00 00 |..........a.....|
000002b0 00 00 00 00 00 00 03 00 44 00 61 00 74 00 61 00 |........D.a.t.a.|
000002c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000300 48 46 53 00 00 00 11 aa aa 11 00 30 65 43 ec ac |HFS........0eC..|
00000310 7a 69 fe f8 7f 82 45 23 b0 75 e8 1a 43 36 90 b2 |zi....E#.u..C6..|
00000320 00 10 61 c3 0e 00 00 00 00 60 00 c4 0e 00 00 00 |..a......`......|
00000330 00 00 00 00 00 00 00 00 42 00 61 00 73 00 65 00 |........B.a.s.e.|
00000340 62 00 61 00 6e 00 64 00 20 00 44 00 61 00 74 00 |b.a.n.d. .D.a.t.|
00000350 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |a...............|
00000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
NS2
第二個NameSpace包含illb和iBoot。從我們在這個十六進制轉儲中可以看到的。它使用GID密鑰加密
00000000 30 83 03 96 1e 16 04 49 4d 47 34 30 83 03 80 99 |0......IMG40....|
00000010 16 04 49 4d 34 50 16 04 69 6c 6c 62 16 10 69 42 |..IM4P..illb..iB|
00000020 6f 6f 74 2d 32 38 31 37 2e 32 30 2e 32 36 04 83 |oot-2817.20.26..|
00000030 03 80 00 9f 1c 04 9b 76 e3 d6 d3 70 15 99 89 b7 |.......v...p....|
00000040 8a 73 4e dd f8 00 d8 e7 5c 5a b4 55 85 2a 03 e1 |.sN.....\Z.U.*..|
00000050 6b 4a 38 0a 59 6e 28 9d f1 be c5 41 1b 17 bd dd |kJ8.Yn(....A....|
00000060 89 0c 69 63 54 ed bd 72 a1 3d 4f 97 04 de 28 fc |..icT..r.=O...(.|
00000070 94 58 29 b4 45 67 23 ae cc d7 be 59 bc 07 3f fc |.X).Eg#....Y..?.|
00000080 ba 55 03 71 a4 a2 86 dd 23 8f 5a ce 67 18 6e 1e |.U.q....#.Z.g.n.|
00000090 8a 6a ec 83 f8 d6 8c 32 ca 24 36 50 77 76 1e bd |.j.....2.$6Pwv..|
000000a0 4f a9 ac d3 5e 15 70 4e 32 58 a8 34 16 22 0c d3 |O...^.pN2X.4."..|
...
NS3
第三個NS是SysCFG分區。SysCFG通過AppleDiagnosticDataAccessReadOnly IOregistry節點的AppleDiagnosticDataSysCfg屬性在IORegistry中可見。(由com.apple.driver.AppleDiagnosticDataAccessReadOnly kext提供)。(如Jonathan Levin的* OS Internals Volumes III和II中所討論的)
00000000 67 66 43 53 04 05 00 00 00 00 02 00 02 00 02 00 |gfCS............|
00000010 00 00 00 00 3f 00 00 00 42 54 4e 43 23 42 4c 4d |....?...BTNC#BLM|
00000020 11 00 00 00 ec ff 01 00 ff ff ff ff 23 47 46 43 |............#GFC|
00000030 2f 2f 2f 2f 2a 2f 2a 00 00 00 00 00 00 00 00 00 |////*/*.........|
00000040 63 61 4d 57 38 71 de 30 82 ff 00 00 00 00 00 00 |caMW8q.0........|
00000050 00 00 00 00 63 61 4d 42 38 71 de 30 83 00 00 00 |....caMB8q.0....|
00000060 00 00 00 00 00 00 00 00 42 54 4e 43 56 43 41 50 |........BTNCVCAP|
00000070 29 00 00 00 c0 ff 01 00 ff ff ff ff 42 54 4e 43 |)...........BTNC|
00000080 54 41 42 43 31 00 00 00 8c ff 01 00 ff ff ff ff |TABC1...........|
00000090 54 53 42 56 09 00 00 00 00 00 00 00 00 00 00 00 |TSBV............|
000000a0 00 00 00 00 52 42 50 56 0b 00 00 00 00 00 00 00 |....RBPV........|
000000b0 00 00 00 00 00 00 00 00 42 54 4e 43 41 43 42 56 |........BTNCACBV|
000000c0 14 00 00 00 78 ff 01 00 ff ff ff ff 42 54 4e 43 |....x.......BTNC|
000000d0 4c 41 43 57 ac 02 00 00 cc fc 01 00 ff ff ff ff |LACW............|
NS4
第四個NameSpace包含WiFi信息。實際上,即使在未解鎖的情況下,它也允許電話訪問密碼以激活網絡
00000000 69 50 43 42 00 01 00 00 01 00 00 00 80 00 00 00 |iPCB............|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000002e0 fc ff ef ff af ec 22 08 57 69 50 41 53 58 4e 65 |......".WiPASXNe|
000002f0 78 74 20 31 38 41 41 64 4d 32 00 00 00 00 00 00 |xt 18AAdM2......|
00000300 fc ff ef ff 97 76 22 08 57 69 50 41 53 20 31 43 |.....v".WiPAS 1C|
00000310 4d 50 32 37 00 00 00 00 00 00 00 00 00 00 00 00 |MP27............|
00000320 fc ff ef ff 79 79 22 08 57 69 50 41 53 20 31 43 |....yy".WiPAS 1C|
00000330 4d 50 32 37 00 00 00 00 00 00 00 00 00 00 00 00 |MP27............|
NS5
第五個分區是NVRAM,可通過相應的Kext作為邏輯鍵/值訪問
00000000 5a 82 02 00 6e 76 72 61 6d 00 00 00 00 00 00 00 |Z...nvram.......|
00000010 fd 20 e6 d3 58 01 00 00 00 00 00 00 00 00 00 00 |. ..X...........|
00000020 70 7c 80 00 63 6f 6d 6d 6f 6e 00 00 00 00 00 00 |p|..common......|
00000030 61 75 74 6f 2d 62 6f 6f 74 3d 74 72 75 65 00 62 |auto-boot=true.b|
00000040 61 63 6b 6c 69 67 68 74 2d 6c 65 76 65 6c 3d 31 |acklight-level=1|
00000050 34 39 37 00 62 6f 6f 74 2d 61 72 67 73 3d 00 00 |497.boot-args=..|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000820 a1 15 81 00 41 50 4c 2c 4f 53 58 50 61 6e 69 63 |....APL,OSXPanic|
00000830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001030 7f 17 fd 00 77 77 77 77 77 77 77 77 77 77 77 77 |....wwwwwwwwwwww|
00001040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002000
NS6
第六個分區是PLOG。kbag信息存儲在哪裡。當您使用加密引擎解鎖手機時會使用該功能。此外,超過10次錯誤的密碼,這會得到擦除。
00000000 4e 0b 2a 02 c5 30 09 f8 ae 0e ca 8d 8f c1 88 8c |N.*..0..........|
00000010 2b 68 4b 44 c4 30 09 f8 af 0e ca 8d 8f c1 88 8c |+hKD.0..........|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 1b 00 00 00 0c 97 b4 a8 |................|
00000040 6b 4c 50 00 4d 56 77 4c 2b a0 ab f1 3e 62 df a6 |kLP.MVwL+...>b..|
00000050 66 93 52 4e 2a da 12 f9 17 ba 37 ea 08 f2 cd 62 |f.RN*.....7....b|
00000060 d8 02 71 b3 a7 a9 38 b8 a1 db 0e 47 29 50 e9 41 |..q...8....G)P.A|
00000070 eb 57 88 e9 76 7a f7 c3 8f 77 bd c8 08 0f 83 3c |.W..vz...w.....<|
00000080 b7 96 20 46 71 a7 ad 59 e1 e3 b4 cc 1b cf 83 83 |.. Fq..Y........|
00000090 5e 60 c8 be f3 20 8c f5 6b 4c 34 00 31 47 41 42 |^`... ..kL4.1GAB|
000000a0 31 47 41 42 18 1b 7c 83 11 63 64 95 96 0d 0e fc |1GAB..|..cd.....|
000000b0 09 30 c0 3e c5 f6 48 70 a8 f4 86 f8 52 77 49 20 |.0.>..Hp....RwI |
000000c0 57 ad 7e 21 23 38 b0 dd 4a aa 21 05 6e 20 0a 8e |W.~!#8..J.!.n ..|
000000d0 76 24 55 fc 6b 4c 28 00 79 65 6b c4 6a dc ee 85 |v$U.kL(.yek.j...|
000000e0 f3 1e d2 0f 66 f8 25 e1 97 bd ef 61 7e 9a 7b 18 |....f.%....a~.{.|
000000f0 d3 60 89 d8 57 43 3c d8 44 30 e3 1a e6 eb 0c 3e |.`..WC<.D0.....>|
00000100 9b 65 f4 69 6b 4c 00 00 45 4e 4f 44 00 00 00 00 |.e.ikL..ENOD....|
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
....
NS7
第七個分區目前看起來是空的
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00100000
導航到nand
Jonathan Levin的HFSleuth可以讀取原始設備文件並檢查其中的HFS +文件系統。 http://NewOSXBook.com/tools/hfsleuth.html(謝來@Morpheus_____)
重用NAND
如果你有一個適當的JIG使用彈簧針來接觸墊,那麼該NAND可以在iphone中重新使用。當想要例如從外部修改NAND然後開始測試,它非常方便。
JTAG / SWD
如前所述,NVMe芯片具有JTAG / SWD接口。將OpenOCD放在它上面看看發生了什麼是很有趣的。
使用帶有OpenOCD的KT-Link接口,我們可以有一個TAP枚舉。
Open On-Chip Debugger 0.10.0-dev-00212-g50d4f76 (2016-02-15-18:11)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
debug_level: 2
Info : FTDI SWD mode enabled
adapter speed: 10000 kHz
Info : clock speed 10000 kHz
Info : SWD IDCODE 0x5ba02477
Info : SWD IDCODE 0x5ba02477
Info : SWD IDCODE 0x5ba02477
Info : SWD IDCODE 0x5ba02477
Info : mynvme.cpu: hardware has 3 breakpoints, 2 watchpoints
Info : mynvme.cpu rev 1, partnum c05, arch f, variant 0, implementor 41
Info : mynvme.cpu cluster 0 core 0 multi core
看了一會兒之後,它首先看到0x5ba02477是一個Cortex M,但實際上它是一個皮層A.
> dap info
AP ID register 0x44770002
Type is MEM-AP APB
MEM-AP BASE 0x80000000
ROM table in legacy format
MEMTYPE system memory not present: dedicated debug bus
ROMTABLE[0x0] = 0x40000002
Component not present
ROMTABLE[0x4] = 0x74300003
Component base address 0xf4300000, start address 0xf4300000
Component class is 0x1, ROM table
Peripheral ID[4..0] = hex 00 00 0c 85 33
Unrecognized (Part 0x533, designer 0xc8)
[L01] ROM table in legacy format
[L01] MEMTYPE system memory not present: dedicated debug bus
[L01] ROMTABLE[0x0] = 0x1003
Component base address 0xf4301000, start address 0xf4301000
Component class is 0xf, PrimeCell or System component
Peripheral ID[4..0] = hex 00 00 4c 80 00
Unrecognized (Part 0x0, designer 0xc8)
[L01] ROMTABLE[0x4] = 0x10003
Component base address 0xf4310000, start address 0xf4310000
Component class is 0x9, CoreSight component
Type is 0x15, Debug Logic, Processor
Peripheral ID[4..0] = hex 04 00 1b bc 05
Part is Cortex-A5 Debug (Debug Unit)
[L01] ROMTABLE[0x8] = 0x11002
Component not present
[L01] ROMTABLE[0xc] = 0x12003
Component base address 0xf4312000, start address 0xf4312000
Component class is 0x9, CoreSight component
Type is 0x13, Trace Source, Processor
Peripheral ID[4..0] = hex 04 00 2b b9 55
Part is Cortex-A5 ETM (Embedded Trace)
[L01] ROMTABLE[0x10] = 0x13003
Component base address 0xf4313000, start address 0xf4313000
Component class is 0x9, CoreSight component
Type is 0x21, Trace Sink, Buffer
Peripheral ID[4..0] = hex 04 00 3b b9 07
Part is CoreSight ETB (Trace Buffer)
[L01] ROMTABLE[0x14] = 0x14003
Component base address 0xf4314000, start address 0xf4314000
Component class is 0x9, CoreSight component
Type is 0x14, Debug Control, Trigger Matrix
Peripheral ID[4..0] = hex 04 00 4b b9 06
Part is CoreSight CTI (Cross Trigger)
[L01] ROMTABLE[0x18] = 0x15003
Component base address 0xf4315000, start address 0xf4315000
Component class is 0x9, CoreSight component
Type is 0x14, Debug Control, Trigger Matrix
Peripheral ID[4..0] = hex 04 00 4b b9 06
Part is CoreSight CTI (Cross Trigger)
[L01] ROMTABLE[0x1c] = 0x20003
Component base address 0xf4320000, start address 0xf4320000
Component class is 0x9, CoreSight component
Type is 0x15, Debug Logic, Processor
Peripheral ID[4..0] = hex 04 00 4b bc 15
Part is Cortex-R5 Debug (Debug Unit)
[L01] ROMTABLE[0x20] = 0x21002
Component not present
[L01] ROMTABLE[0x24] = 0x22003
Component base address 0xf4322000, start address 0xf4322000
Component class is 0x9, CoreSight component
Type is 0x13, Trace Source, Processor
Peripheral ID[4..0] = hex 04 00 0b b9 31
Part is Cortex-R5 ETM (Embedded Trace)
[L01] ROMTABLE[0x28] = 0x23003
Component base address 0xf4323000, start address 0xf4323000
Component class is 0x9, CoreSight component
Type is 0x21, Trace Sink, Buffer
Peripheral ID[4..0] = hex 04 00 3b b9 07
Part is CoreSight ETB (Trace Buffer)
[L01] ROMTABLE[0x2c] = 0x24003
Component base address 0xf4324000, start address 0xf4324000
Component class is 0x9, CoreSight component
Type is 0x14, Debug Control, Trigger Matrix
Peripheral ID[4..0] = hex 04 00 4b b9 06
Part is CoreSight CTI (Cross Trigger)
[L01] ROMTABLE[0x30] = 0x25003
Component base address 0xf4325000, start address 0xf4325000
Component class is 0x9, CoreSight component
Type is 0x14, Debug Control, Trigger Matrix
Peripheral ID[4..0] = hex 04 00 4b b9 06
Part is CoreSight CTI (Cross Trigger)
[L01] ROMTABLE[0x34] = 0x26003
Component base address 0xf4326000, start address 0xf4326000
Component class is 0x9, CoreSight component
Type is 0x12, Trace Link, Funnel, router
Peripheral ID[4..0] = hex 04 00 2b b9 08
Part is CoreSight CSTF (Trace Funnel)
[L01] ROMTABLE[0x38] = 0xffe00002
Component not present
[L01] ROMTABLE[0x3c] = 0x0
[L01] End of ROM table
ROMTABLE[0x8] = 0x0
End of ROM table
在這個階段,為了找到芯片的工作方式,轉儲他們的bootrom非常有趣。
從現在開始,可以使用IDA將其附加到它上面,就好像它是3333端口上的GDB一樣。
固件分析
有趣的是,蘋果在ramrod OTA更新中有固件升級工具。為拿到它,為實現它:
# wget http://appldnld.apple.com/iOS9.3/031-28353-20160321-9904D9BA-EA47-11E5-9069-7170BD379832/com_apple_MobileAsset_SoftwareUpdate/352b7321dda0925f84c7beb6128a3dbdb71476fe.zip
# unzip 352b7321dda0925f84c7beb6128a3dbdb71476fe.zip AssetData/payload/replace/usr/standalone/update/ramdisk/H8SURamDisk.dmg
# dd if=AssetData/payload/replace/usr/standalone/update/ramdisk/H8SURamDisk.dmg of=update.dmg bs=27 skip=1
# file update.dmg
update.dmg: Macintosh HFS Extended version 4 data last mounted by: '10.0', created: Fri Mar 15 00:27:05 2148, last modified: Fri Mar 15 09:31:59 2148, block size: 4096, number of blocks: 17228, free blocks: 1
# mkdir d
# mount -o loop,ro update.dmg d
。
├──./ BFH│├──./
BFH/ s3e
- bfh
- loader.bin│└──./ BFH/ version.plist├──./ Hynix - mlc - 1y - bdie -
2p│├── ./Hynix-mlc-1y-bdie-2p/FWUpdate-Hynix-mlc-1y-bdie-2p-1dpc-2ch-NonCES.pak
│├── ./Hynix-mlc-1y-bdie-2p/FWUpdate-Hynix -mlc-1Y-bdie-2P-2dpc-2 CH-NonCES.pak - > fwupdate子-力士-MLC-1Y-bdie-2P-1dpc-2 CH-NonCES.pak
│├── ./Hynix-mlc-1y-bdie -2p / FWUpdate-Hynix-mlc-1y-bdie-2p-4dpc-2ch-NonCES.pak → FWUpdate-Hynix-mlc-1y-bdie-2p-1dpc-2ch-NonCES.pak│├──.
/ Hynix -mlc-1y-bdie-2p / FWUpdate-Hynix-mlc-1y-bdie-2p.pak - >fwupdate子-力士-MLC-1Y-bdie-2P-1dpc-2 CH-NonCES.pak
│└── ./Hynix-mlc-1y-bdie-2p/version.plist
├── ./Hynix-mlc-1y-cdie -2p│├──./
Hynix -
mlc- 1y- cdie - 2p/ FWUpdate- Hynix - mlc- 1y- cdie - 2p- 1dpc- 2ch - NonCES.pak│├──./ Hynix- mlc - 1y- cdie -2p / FWUpdate-Hynix-mlc-1y-cdie-2p-2dpc-2ch-NonCES.pak - > FWUpdate-Hynix-mlc-1y-cdie-2p-1dpc-2ch-NonCES.pak│├──.
/ Hynix -mlc-1Y-cdie-2P / fwupdate子-力士-MLC-1Y-cdie-2P-4dpc-2 CH-NonCES.pak - > fwupdate子-力士-MLC-1Y-cdie-2P-1dpc-2 CH-NonCES.pak
│ ├── ./Hynix-mlc-1y-cdie-2p/FWUpdate-Hynix-mlc-1y-cdie-2p.pak - > fwupdate子-力士-MLC-1Y-cdie-2P-1dpc-2 CH-NonCES.pak
│ └──./Hynix-mlc-1y-cdie-2p/version.plist
├── ./Hynix-tlc-1y-2p
│├── ./Hynix-tlc-1y-2p/FWUpdate-Hynix-tlc-1y-2p -1dpc-2 CH-NonCES.pak
│├── ./Hynix-tlc-1y-2p/FWUpdate-Hynix-tlc-1y-2p-2dpc-2ch-NonCES.pak - > fwupdate子-力士型TLC-1Y-2P -1dpc-2 CH-NonCES.pak
│├── ./Hynix-tlc-1y-2p/FWUpdate-Hynix-tlc-1y-2p-4dpc-2ch-NonCES.pak - > fwupdate子-力士型TLC-1Y-2P -1dpc-2 CH-NonCES.pak
│├── ./Hynix-tlc-1y-2p/FWUpdate-Hynix-tlc-1y-2p.pak - > fwupdate子-力士型TLC-1Y-2P-1dpc-2 CH-隨機數.pak
│└── ./Hynix-tlc-1y-2p/version.plist
├── ./Sandisk-mlc-1y-2p
│├──./Sandisk-mlc-1y-2p/FWUpdate-Sandisk-mlc-1y-2p-1dpc-2ch-NonCES.pak
│├── ./Sandisk-mlc-1y-2p/FWUpdate-Sandisk-mlc-1y-2p -2dpc-2 CH-NonCES.pak - > fwupdate子-的Sandisk-MLC-1Y-2P-1dpc-2 CH-NonCES.pak
│├── ./Sandisk-mlc-1y-2p/FWUpdate-Sandisk-mlc-1y-2p -4dpc-2 CH-NonCES.pak - > fwupdate子-的Sandisk-MLC-1Y-2P-1dpc-2 CH-NonCES.pak
│├── ./Sandisk-mlc-1y-2p/FWUpdate-Sandisk-mlc-1y-2p .pak - > fwupdate子-的Sandisk-MLC-1Y-2P-1dpc-2 CH-NonCES.pak
│└── ./Sandisk-mlc-1y-2p/version.plist
├── ./Sandisk-tlc-1y-2p
│├──./ Sandisk-
tlc-1y- 2p/ FWUpdate- Sandisk- tlc- 1y- 2p- 1dpc- 2ch- NonCES.pak│├──./Sandisk-tlc-1y-2p/FWUpdate-Sandisk-tlc-1y-2p-2dpc-2ch-NonCES.pak - > FWUpdate-Sandisk -tlc-1y-2p-1dpc-2ch-
NonCES.pak│├── ./Sandisk-tlc-1y-2p/FWUpdate-Sandisk-tlc-1y-2p-4dpc-2ch-NonCES.pak - > FWUpdate-Sandisk -tlc-1y-2p-1dpc-2ch-
NonCES.pak│├── ./Sandisk-tlc-1y-2p/FWUpdate-Sandisk-tlc-1y-2p.pak - > fwupdate子-晟碟型TLC-1Y-2P-1dpc-2 CH-NonCES.pak
│└── ./Sandisk-tlc- 1y-2p / version.plist├──./
Sandisk - tlc - 1z - 2p│├── ./ Sandisk - tlc - 1z -2p/ FWUpdate - Sandisk - tlc - 1z -2p- 1dpc - 2ch
- NonCES.pak
│├──./ Sandisk - tlc- 1z - 2p/ FWUpdate - Sandisk- tlc - 1z - 2p- 2dpc - 2ch- NonCES.pak - >fwupdate子-晟碟型TLC-1Z-2P-1dpc-2 CH-NonCES.pak
│├── ./Sandisk-tlc-1z-2p/FWUpdate-Sandisk-tlc-1z-2p-4dpc-2ch-NonCES.pak - > fwupdate子-晟碟型TLC-1Z-2P-1dpc-2 CH-NonCES.pak
│├── ./Sandisk-tlc-1z-2p/FWUpdate-Sandisk-tlc-1z-2p.pak - > fwupdate子-的SanDisk TLC- 1Z-2P-1dpc-2 CH-NonCES.pak
│└── ./Sandisk-tlc-1z-2p/version.plist
├── ./Sandisk-tlc-1z-2p-8dpc
│├── ./Sandisk- TLC-1Z-2P-8dpc / fwupdate子-晟碟型TLC-1Z-2P-8dpc-2 CH-CES.pak
│└── ./Sandisk-tlc-1z-2p-8dpc/version.plist
├├── ./ Toshiba-mlc-1y-
2p│├──. / Toshiba-mlc-1y-2p / FWUpdate -Toshiba-mlc-1y-2p- 1dpc - 2ch - NonCES.pak
│├── ./Toshiba-mlc-1y-2p/FWUpdate-Toshiba-mlc-1y-2p-2dpc-2ch-NonCES.pak - > fwupdate子東芝-MLC-1Y-2P-1dpc-2 CH-NonCES.pak
│├── ./Toshiba-mlc-1y-2p/FWUpdate-Toshiba-mlc-1y-2p-4dpc-2ch-NonCES.pak - > fwupdate子東芝-MLC-1Y-2P-1dpc-2 CH-NonCES.pak
│├── ./Toshiba-mlc-1y-2p/FWUpdate-Toshiba-mlc-1y-2p.pak - > fwupdate子東芝-MLC-1Y-2P-1dpc-2 CH-NonCES.pak
│└── ./ Toshiba-mlc-1y-2p / version.plist├──./Toshiba-mlc-
1z - 2p│├── ./Toshiba-mlc- 1z -2p/ FWUpdate -Toshiba-mlc- 1z -2p- 1dpc
- 2ch -NonCES.pak│├──.
/ Toshiba - mlc- 1z - 2p/ FWUpdate - Toshiba- mlc - 1z- 2p - 2dpc - 2ch- NonCES.pak - >fwupdate子東芝-MLC-1Z-2P-1dpc-2 CH-NonCES.pak
│├── ./Toshiba-mlc-1z-2p/FWUpdate-Toshiba-mlc-1z-2p-4dpc-2ch-NonCES.pak - > fwupdate子東芝-MLC-1Z-2P-1dpc-2 CH-NonCES.pak
│├── ./Toshiba-mlc-1z-2p/FWUpdate-Toshiba-mlc-1z-2p.pak - > fwupdate子東芝-MLC- 1Z-2P-1dpc-2 CH-NonCES.pak
│└── ./Toshiba-mlc-1z-2p/version.plist
├── ./Toshiba-tlc-1z-2p
│├── ./Toshiba-tlc- 1Z-2P / fwupdate子東芝型TLC-1Z-2P-1dpc-2 CH-NonCES.pak
│├── ./Toshiba-tlc-1z-2p/FWUpdate-Toshiba-tlc-1z-2p-2dpc-2ch-NonCES .pak - > FWUpdate-Toshiba-tlc-1z-2p-1dpc-2ch-
NonCES.pak│├──./Toshiba-tlc-1z-2p/FWUpdate-Toshiba-tlc-1z-2p-4dpc-2ch-NonCES.pak - > FWUpdate-Toshiba-tlc-1z-2p-1dpc-2ch-
NonCES.pak│├── ./Toshiba-tlc-1z-2p/FWUpdate-Toshiba-tlc-1z-2p.pak - > fwupdate子-東芝TLC-1Z-2P-1dpc-2 CH-NonCES.pak
│└── ./Toshiba-tlc- 1z-2p / version.plist├──./
Toshiba - tlc -1z-2p- 8dpc│├── ./ Toshiba - tlc -1z-2p- 8dpc / FWUpdate - Toshiba - tlc -1z-2p- 8dpc
- 2ch -CES.pak└──./
Toshiba- tlc- 1z - 2p - 8dpc/ version.plist
讓我們看看任何.pak的hexdump的頭部
00000000 46 57 55 42 00 0e 40 01 00 00 00 00 00 00 00 00 |FWUB..@.........|
00000010 10 be 05 00 11 63 6f e7 c0 1f 04 00 1e 56 ea f7 |.....co......V..|
00000020 00 00 00 00 00 00 00 00 20 0d 00 00 ac c9 02 a3 |........ .......|
00000030 10 1d 00 00 8e 17 3c 92 5e 98 b3 ff 46 57 55 45 |......<.^...FWUE|
00000040 02 00 00 00 00 10 0b 51 01 17 01 64 02 08 87 04 |.......Q...d....|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000440 00 00 00 00 0f 09 84 54 46 57 55 65 00 00 00 00 |.......TFWUe....|
00000450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000 41 54 4f 43 36 03 00 00 00 00 00 0e 40 01 00 00 |ATOC6.......@...|
00001010 40 00 00 00 00 80 80 ce 01 00 00 08 b0 21 00 f0 |@............!..|
00001020 05 00 e0 de 03 00 00 1a d8 10 00 20 14 00 10 00 |........... ....|
00001030 00 00 45 54 4f 43 00 00 00 00 00 00 00 00 00 00 |..ETOC..........|
00001040 8e 0a 00 fa 13 00 00 ea 04 00 00 ea 4d 00 00 ea |............M...|
00001050 31 00 00 ea fe ff ff ea 80 5e 00 ea 64 00 00 ea |1........^..d...|
00001060 00 30 4f e1 20 00 13 e3 04 30 1e 05 02 30 5e 15 |.0O. ....0...0^.|
看起來文件中有一些關鍵字[FWUB,FWUE,FWUe,ATOC,ETOC …]到目前為止,有趣的是看到有一個名為“BFH”的目錄。用一個文件“s3e-bfh-loader.bin”。“S3E”之前是在iphone截圖中看起來像是NVMe便宜的代號。看它時:
00000000 0e 00 00 ea fe ff ff ea fe ff ff ea fe ff ff ea |................|
00000010 fe ff ff ea fe ff ff ea 00 00 00 ea fe ff ff ea |................|
這表明該文件實際上是具有中斷向量的原始ARM固件。從近距離觀察IDA時,我們可以看到一些有趣的CMP:
正如人們可以看到的那樣,這些關鍵字顯示為小端。所以看起來bfh文件是一個引導加載程序,它被加載到NVMe中以便安裝.pak,因為它可以清楚地解析它。當更多關注驅動程序時,看起來芯片可以處於正常模式,或稱為“BFH”模式。實際上,在這種模式下,在地址BAR0 + 0x1b18處,值為0xBFBFBFBF。加載的s3e二進製文件讓固件更新工具獲取nand信息並找出需要加載的文件。
int nvme_identify(struct nvme_dev * dev) {
int p;
int brand;
int tech;
int non;
int plane;
int flag;
int dpc;
int dch;
char directory[200];
int dsize;
int die;
const char * brand_list[] = {
"Invalid",
"Hynix",
"Invalid",
"Sandisk",
"Samsung",
"Toshiba"
}; //350
const char * tech_list[] = {
"slc",
"mlc",
"tlc"
}; // 380
const char * plane_list[] = {
"1x",
"1y",
"1z"
}; // 398
const char * die_list[] = {
"a",
"b"
}; //3b0
const int size_list[] = {
64,
128,
256,
512,
1024,
2048
};
const char * non_list[] = {
"Non",
""
};
u32 tst32;
u64 tst64;
u64 tmp;
u64 val;
tst32 = readl(dev - > bar + 0x1b20);
printk("REG1B20 (nand info) %08x\n", tst32);
tst64 = tst32;
if (!(tst32 >> 25)) {
printk("val >> 25 NOK !!!\n");
return 0;
}
tst32 = readl(dev - > bar + 0x1b24);
printk("REG1B24 (nand info )%08x\n", tst32);
tmp = tst32;
tmp = tmp << 32;
tst64 |= tmp;
val = tst64;
p = 1 << ((val >> 12) & 3);
brand = val & 7;
tech = (val >> 7) & 3;
flag = (val >> 25) & 0x7F;
plane = (val >> 3) & 0xF;
die = (val >> 20) & 0xF;
if (!flag) {
dpc = 1;
dch = 1;
non = 0;
} else {
dpc = 1 << ((val >> 32) & 0xf);
dch = 1 << ((val >> 36) & 0x3);
non = ((val >> 38) & 1);
}
if (brand == 1 && tech == 1)
sprintf(directory, "%s-%s-%s-%sdie-%dp", brand_list[brand], tech_list[tech], plane_list[plane], die_list[die], p);
else
sprintf(directory, "%s-%s-%s-%dp", brand_list[brand], tech_list[tech], plane_list[plane], p);
if (!flag) {
printk("%s/FWUpdate-%s.pak\n", directory, directory);
} else {
dsize = (val >> 14) & 0x3;
if (non)
non = 1;
if (((size_list[dsize] >> 3) * dpc * dch) < 0x100)
printk("%s/FWUpdate-%s-%ddpc-%dch-%sCES.pak\n", directory, directory, dpc, dch, non_list[non]);
else
printk("%s-%ddpc/FWUpdate-%s-%ddpc-%dch-%sCES.pak\n", directory, dpc, directory, dpc, dch, non_list[non]);
}
return 0;
}
在那個階段,我添加到我的驅動程序中的示例函數能夠告訴我需要上傳哪個文件。關於上傳過程,地址和長度被設置在2個特殊寄存器中,1被發送到寄存器0x1b10。文件上傳後,寄存器0x1b14變為0x10,這意味著芯片已準備好繼續。通過向0x1b10寫入2,下一步就會發生。該過程首先在BFH模式下發生,一旦s3e二進製文件上傳,NVMe被識別。完成後,.pak會再次上傳,然後可以進行升級。
直接存儲器存取(DMA)
首先,在Bootrom方面,當NVMe啟動並運行在BFH模式下,並等待主機給它啟動DMA的命令時,我們就在這張圖中看到的循環中。如果發現告知DMA的寄存器沒有被設置,那麼當到達發生奇怪事件時,我們會再次分支。
一旦完成,如果一切順利,我們最終會等待主機告訴我們它已準備就緒。請注意“MOVS R0,#0x10”,“STR R0,[R5,#0x2C]”,這正是我們的寄存器告訴我們DMA發生的地方,如前所述,這些寄存器得到的設置為0x10。
最後,DMA如上圖所示在地址0x76828000處複製我們想要的緩衝區。然後,當主機說它準備好了,它跳轉到這個地址:“MOV R0,#0x76828000”,“BLX R0”順便說一下,在s3e-bfh.bin加載器中,我們可以清楚地看到代碼立即自行重新定位到0x00101000(拇指模式為+1)
這裡的想法是查看是否有可能通過JTAG控制NVMe,以便要求它通過PCIe總線執行DMA讀操作。為此,必須將PCI_COMMAND_BUS_MASTER設置為1.我們可以假設,由於芯片使用的是遠程RAM,因此可以充當PCIe主設備。這是內核驅動程序探測功能的一個片段。
sstatic int bfh_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
u64 dma_addr = 0;
void *cpu_addr = NULL;
pci_enable_device(pdev);
pci_set_master(pdev);
cpu_addr = dma_alloc_coherent(NULL, 0x10000, &dma_addr, GFP_DMA32);
memset(cpu_addr, 0x41, 0x10000);
printk("ADDR mem %016llx\n", dma_addr);
return 0;
}
我們的目標是強制DMA發生,只需通過JTAG控制NVMe的ARM,以便讓它轉儲我們在內核中分配的區域,看看我們是否從中獲得數據。