2014.07.21 15:00

家用主機秘辛13:欺騙系統核心

ADVERTISEMENT

在先前的系列文章中,提到了幾種PSP的破解案例,在接下來的2篇文章中,筆者將會介紹原文作者Acid_Snake挑選的2個程式範例,在這幾個範例中,可以更進一步看到PSP韌體設計的安全缺陷,以及駭客們如何運用這些漏洞開發出破解程式。

前情提要:

愚蠢錯誤一籮筐

我將跳過由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個參數檢查被漏掉了。

ADVERTISEMENT

▲HEN為Homebrew Enabler的縮寫。這種破解程式大多只有取得使用者模式權限,能夠讓PSP執行自製程式,但可能無法執行遊戲的備份檔案。

用memset覆蓋記憶體內容

這個案例是5.03版韌體核心漏洞,我忘了最初發現的開發者是誰,然而davee利用了這個漏洞開發了HEN。這個核心漏洞存在psheet.prx模組的sceDRMInstallGetFileInfo函數中。它的程式碼如下:

ADVERTISEMENT

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!

ADVERTISEMENT

▲memset指令可以將指定範圍內的位置寫入特定值,經常用於將位元組的位元值初始化為0。(圖片來源:)

下集預告:

原文刊載於

ADVERTISEMENT

感謝原文作者Acid_Snake同意轉載

Original article by Acid_Snake. Translate by konamigood.

延伸閱讀:

ADVERTISEMENT