在先前的系列文章中,提到了幾種PSP的破解案例,在接下來的2篇文章中,筆者將會介紹原文作者Acid_Snake挑選的2個程式範例,在這幾個範例中,可以更進一步看到PSP韌體設計的安全缺陷,以及駭客們如何運用這些漏洞開發出破解程式。
前情提要:
家用主機秘辛1:任天堂紅白機導致的破解風潮
家用主機秘辛2:紅白機的防拷晶片歷史
家用主機秘辛3:正版比盜版問題更多,破解萬惡10NES晶片
家用主機秘辛4:進入光碟時代,PS的保護機制
家用主機秘辛5:數秒內抽換光碟, PS 盜版片也能騙過驗證機制
家用主機秘辛6:最暢銷主機 PS2 的大後門,用壞軌光碟 Swap Magic 破解
家用主機秘辛7:PS2安裝假OS,從記憶卡開機
家用主機秘辛8:PS2連DVD播放功能都暗藏玄機
家用主機秘辛09:大門忘記上鎖的PSP
家用主機秘辛10:緩衝區溢位突破天際
家用主機秘辛11:破解之神Dark_Alex登場
家用主機秘辛12:試玩版遊戲提供免費漏洞
愚蠢錯誤一籮筐
我將跳過由davee利用5.03版本韌體漏洞開發的checkHEN,因為我想把各種破解方式分成2大類。由於後期PSP主機更改了安全機制,所以無法將自製韌體永久性地安裝在主機中,但是PSP 3000型主機還是具有可用的核心漏洞與HEN漏洞(例如之後發展LCFW)。直到6.20版韌體推出後,開發者Total_Noob將6.35版以下韌體可用核心漏洞公開,但由他本人所開發的HEN只能於6.20版韌體中執行。
雖然6.XX年代還有許多其他有趣的故事可以慢慢聊,比如Total_Noob、Neur0n、Team PRO、HBL等等,但是我只想專注於核心漏洞,因為這和系列文章有著共同的主題,就是Sony所犯下的於愚蠢錯誤。這次的問題圍繞在有1個參數檢查被漏掉了。
▲HEN為Homebrew Enabler的縮寫。這種破解程式大多只有取得使用者模式權限,能夠讓PSP執行自製程式,但可能無法執行遊戲的備份檔案。
用memset覆蓋記憶體內容
這個案例是5.03版韌體核心漏洞,我忘了最初發現的開發者是誰,然而davee利用了這個漏洞開發了HEN。這個核心漏洞存在psheet.prx模組的sceDRMInstallGetFileInfo函數中。它的程式碼如下:
sceDRMInstallGetFileInfo:
...
0x000000E0: 0xAFB40010 '....' - sw $s4, 16($sp)
0x000000E4: 0x34620108 '..b4' - ori $v0, $v1, 0x108
0x000000E8: 0x00C0A021 '!...' - move $s4, $a2
0x000000EC: 0xAFB3000C '....' - sw $s3, 12($sp)
0x000000F0: 0x00A09821 '!...' - move $s3, $a1
0x000000F4: 0xAFB10004 '....' - sw $s1, 4($sp)
0x000000F8: 0x00E08821 '!...' - move $s1, $a3
...
0x00000140: 0x02602821 '!(`.' - move $a1, $s3
0x00000144: 0x02402021 '! @.' - move $a0, $s2
0x00000148: 0x02803021 '!0..' - move $a2, $s4
0x0000014C: 0x0C0001E8 '....' - jal sub_000007A0
0x00000150: 0x02203821 '!8 .' - move $a3, $s1
我將部分程式碼省略掉,所以能把出問題的sceIoOpen參數看得更加清楚。假設sceIoOpen會去呼叫另一個子程式以及sub_000007A0,並回傳「argument 0」,之後我們輸入argument 1、argument 2,以及arg3至該程式。然後我們看看sub_000007A0會發生什麼事。
; Subroutine sub_000007A0 - Address 0x000007A0
sub_000007A0: ; Refs: 0x0000014C
...
0x000007C0: 0x00E09821 '!...' - move $s3, $a3
...
0x000007EC: 0x24060108 '...$' - li $a2, 264
0x000007F0: 0x02602021 '! `.' - move $a0, $s3
0x000007F4: 0x0C000928 '(...' - jal memset
0x000007F8: 0x00002821 '!(..' - move $a1, $zr
這個子程式會呼叫memset 2次,在第二次呼叫memset時,arg0(即寫入的目的位置)的數值將由第三個傳入該子程式的參數決定,而這個參數就是我們先前傳入sceDRMInstallGetFileInfo的arg3,由於該動作並沒有經過全盤檢查,所以我們可以透過memset,將包括核心記憶體位置在內大約66條指令強制寫入0。感謝Sony!
▲memset指令可以將指定範圍內的位置寫入特定值,經常用於將位元組的位元值初始化為0。(圖片來源:Microsoft
Developer Network)
[下集預告:繼續欺騙系統核心]
原文刊載於
http://wololo.net/2014/01/18/10-days-of-hacking-day-5-the-psp-part-2
感謝原文作者Acid_Snake同意轉載
Original article by Acid_Snake. Translate by konamigood.
延伸閱讀:
【模擬器改造】掌機性能大提升:PlayStation Portable篇
挑戰 Apple TV,Sony 發表 PS Vita TV 提供影音串流服務,還能用電視玩 PS Vita、PSP 遊戲
PSP 退休後,刷機做3種進階利用,實測給你看
留言列表