KaKaRoTo on How to Port PL3 to an Exploitable PS3 FW - 改機

Lydia avatar
By Lydia
at 2010-10-05T22:17

Table of Contents

KaKaRoTo 大大解釋了如何自己 DIY 破解 <3.41 版的韌體,
原文很長只看了前半段,
大概就是用含有特製韌體的破解棒去暴力法找 JIG 模組在記憶體中的位置,
直到找到 JIG 模組的位址,
然後把韌體換成 dump lv2 的韌體,
利用網路把 lv2 dump 出來(用 wireshark 接住封包),
把 dump 出來的韌體存成 .pcap,
然後利用 tools/dump_lv2_pcap_to_bin 抓出真正的 lv2 本體的 image,
再用 IDA 反組譯,
利用用特定的 magic number 找出特定的 system call 或是 function 的 address,
然後修改 3.41 版的破解棒的原始碼中各 system call 和 function 的 address
好像還有一堆東西要修正,
沒全部看完,放著有空慢慢研究,
PS3 真是台不錯的"玩具"

=====================
原文連結 : http://0rz.tw/qzUBC

Today KaKaRoTo detailed how to port PL3 to an exploitable PS3 Firmware via
Github (linked above).

To quote: "How to port to a new Firmware (but < 3.41) :

First disable the JIG mode, and try to bruteforce the position of the payload
with a panic payload (add 'b panic' at payload_start in dump_lv2.S), until
you can get a hit reliably (see [url]http://pastie.org/1195108[/url]).

Then replace the payload with the original dump_lv2 payload, and connect the
ps3 through ethernet to your PC and run wireshark to capture your dump... Run
the payload, then once the ps3 panics (to tell you it's done), you can save
your wireshark dump to a file in .pcap format.

Then run the tools/dump_lv2_pcap_to_bin program to dump the lv2 binary from
the pcap file captured by wireshark.

Open the dump with IDA, set the processor to 'ppc', then run the
dump_lv2_analyzer.idc IDC file from the tools directory to get it analyzed
and follow the instructions (set TOC table in IDA options).

Once you are done, set the TOC_TABLE value in PSFreedom/PSGroove and set the
syscall_table define in macros.h.S.

Then look for the position of the JIG response offset in the dump by
searching for a recognizable string you previously put in there. You can now
set the JIG response address in PSGroove/PSFreedom and test JIG mode with a
panic payload and the egghunter shellcode.

You can then start looking for the various patch_funcX functions... (For this
you will most likely need a clean/unmodified dump of an already supported
firmware, so you can compare the asm code to find the right offsets)

The first step would be to go to label 'syscall_open' (set by the IDC) and
look for the hooked_open, as well as alloc/free. Then follow the hooked_open
proc to find the 'strlen' symbol (first bl in the function).

Once you have those, you should go to the strlen function then can disable
the 'chart' mode in IDA (press spacebar), then look at the function right
below strlen, it will be strncmp, and the function right above strlen will be
strcpy. You can also find memset here, if you scroll up from strcpy, the
memset function will be 4 functions above strcpy (so 3 functions are between
them).

Now you need to find the functions to patch.. let's start with function 1 :
search for binary data in IDA and look for "3960006344000022", it should give
you one match. go to it, and that's your patch_func1, the data being patched
is right after the 'hvsc' call, so count the number of instructions since the
start of patch_func1 up to, and including, the 'hvsc' instruction, and
multiply by 4, that should give you patch_func1_offset.

Now to find the patch_func2, search for binary data in IDA and look for :
"380000013FE08001", it should give you one result, that's your patch_func2.
Now find the first 'bl' inside that function, and count how many instructions
are before the 'bl' (excluding the bl instruction), multiply by 4 and that's
your patch_func2_offset. Now that function that gets branched to in the 'bl'
instruction at patch_func2 + patch_func2_offset, that's your
'memory_patch_func'. Now scroll a bit lower, and you should see a "ld %r28,
qword_XYZXYZ", that qword entry in the TOC is the 'rtoc_entry_2' value. Press
the 'q' key while selecting it to make IDA transform it into
"-0xABCD(%rtoc)".. the -0xABCD is the value you want for rtoc_entry_2.

Now for patch_func3, that's the easiest, it's the 'hooked_open' function you
found in the syscall_open earlier. The offset should be 0 here.

Now time for patch_func4, search for binary data in IDA and look for :
"3C00800160000017", it should give you two results. Look at them both, and
compare with the original function from a supported firmware dump. It should
be pretty obvious which one is patch_func4.. one of them is exactly the same,
the other is extremely different. Now you found patch_func4

Time for patch_func5, this one is easy too, if you right click on it in the
support firmware's dump and you choose "Chart of xrefs to", you will see that
it gets called by almost every system call, so choose any one of those
syscalls and go to them, for the sake of this guide, let's say we choose
randomly syscall_29 Go to syscall_29 in the new dump and compare it with the
other dump, and you should spot the patch_func5 right away, it should be the
fourth 'bl' call and the last 'bl' before the 'bne' of the first block of
this syscall (in IDA chart view).

Now you need to find the slightly more difficult remaining offsets : memcpy,
patch_data1, rtoc_entry_1, and the overwritten function to use for MEM_BASE2.

Let's start with MEM_BASE2. Go to 'patch_func5', disable IDA's 'chart' mode,
then scroll down, all the way to the end of patch_func5, you will find a
total of 4 functions separating patch_func5 with the function in MEM_BASE2...
With MEM_BASE2 being the 5th function stacked after patch_func5. You can also
add 0x56C to the patch_func5 and see if it gives you the right function, it
should but it's not guaranteed.. it will at least get you closer. You should
now switch back to 'chart' mode in IDA and quickly compare that function's
flowchart with the one from the supported firmware's dump. They should be the
same. Now let's make sure that the RESIDENT_PAYLOAD_MAXSIZE is correct.. go
to the end of this function, remove IDA's chart mode, and right where you see
the comment "End of function sub_XYZ", take that position, substract it from
MEM_BASE2 and you've got your RESIDENT_PAYLOAD_MAXSIZE (should be 1296).

Now let's try to find rtoc_entry1.. if you go to the rtoc_entry_1 offset in
the supported firmware's dump (TOC+rtoc_entry_1), press 'N' and rename that
data into 'rtoc_entry_1'. You will see IDA shows a 'DATA XREF' next to it
that points to a function, click on it. you found the function that uses that
TOC entry. Now disable chart mode in IDA and scroll up to the previous
function, you will find a small function that calls lv1_pause! This is our
chance, looking at the hex values of the "li %r11, 9; hvsc", start a binary
search in the new firmware's IDA instance and look for "3960000944000022" It
should give you a single result, go to it, you found your lv1_pause call in
the function just above the one using rtoc_entry1, disable IDA's chart mode,
scroll down to the function below it and reenable chart mode. Now compare
this function with the one from the supported firmware, you should see that
there is a 'ld %r9, rtoc_entry_1' right below a 'bl __asm_func_dummy_X'. So
look for that 'bl' in your dump (should be the first one), and you will find
the rtoc_entry_1 being referenced in the line right below it. select it and
press 'Q' in IDA to make it show you the actual offset value in the
"0xABCD(%rtoc)" form. You found rtoc_entry_1

Now we need to find the slightly harder patch_data1 offset. In your supported
firmware's dump, go to the patch_data1 offset, press 'N' and rename it. Now
you will see a "DATA XREF" next to it which points to a "ROM:.." location,
click on it. You will find yourself on an entry in the TOC... rename that
entry as 'patch_data1_toc' and look for the "DATA XREF" that uses it, there
should be two functions shown that references that patch_data1_toc entry, try
them both, first rename them into something easier to read, like
'patch_data1_func1' and 'patch_data1_func2', then go to each function and
right click on it and choose "Chart of xrefs to". Both functions should only
be called by one other function in its 'xrefs to' chart. One of the
'patch_data1_funcX' function will be called by some other random sub_XYZ
function, but the other one will be called by syscall_470.. yeay, we got an
entry point to this! Now go to syscall_470. Switch back to your new dump and
also go there to syscall_470, now compare both syscalls, it should be fairly
easy to spot the patch_data1_func1 function in the syscall, it would be the
last 'bl' in the flowchart. Now jump to it and look for the reference to
patch_data1_toc, it should be the first 'ld' instruction of the
patch_data1_func1 function, now you found it, jump to it. You are now in the
TOC of your new firmware's dump, and you see the value that TOC entry points
to.. it should be 0x80000000XYABCDEF. That's your patch_data1 value.. remove
the 0x80000000 prefix, and set the XYABCDEF value as the patch_data1 in
macros.h.S

Now the 'memcpy' function is the only one remainingd! This one is easy to
find but the technique is a bit trickier.. Through all of this, we didn't yet
find by luck a function that uses memcpy (unlike
alloc/free/strlen/strcpy/strncmp), so we need to find it different, if we go
to memcpy, we cannot ask IDA to draw a "Chart of xrefs to" for it, don't even
try it, it's used in so many places that IDA or the chart-viewer app will
freeze! What we can do however is disable IDA's "chart" mode, and go to the
memcpy function declaration, then we should see IDA being nice enough to give
two "CODE XREF".. let's follow those two and see who calls those functions,
and try to drill down from there until we find the memcpy location. Luckily,
one of those two functions uses hypercalls as you can see the
'lv1_undocumented_function_109' and 'lv1_undocumented_function_107' comments
as soon as we enter one of the xref functions (if you don't see this maybe
IDA gave you different xrefs, it's ok, continue reading). So we see that
memcpy is used between a hvsc 109 and a hvsc 107. We can't really do a binary
search on the "li %r11, 0x6B; hvsc" since there's a "ld %r7, 0x10(%r31)" in
the middle, and a different kernel build might use a different register or a
different offset to %r31, so let's stay safe, and let's search only for the
"li %r11, 0x6B", so open the binary search of IDA and search for "3960006B".
It should give you 3 results (maybe not, depending on the dump you're
analyzing). Go to each one of them, they should appear as the only hypercall
in the function for two of them, but for one of the functions found, it will
be between a call to hvsc 109 and hvsc 107. You found your memcpy!

All right, we're done with the first part of the analysis, this whole thing
should have taken about an hour to do or less (unless you're writing a guide
at the same time :p).

Now let's start part 2, finding the hashes for the hash table and the offsets
for the user-space ELF files. Let's compile our payloads, add the version
we're trying to add in the Makefile by adding it to SUPPORTED_FIRMWARES and
by adding a rule for %_X_YZ.o: %.s which defines the -DFIRMWARE_X_YZ, then
type make. In the project, replace the default_payload_X_YZ by
payload_dump_elfs_X_YZ in order to use the payload_dump_elfs.

Now connect the PS3 with the ethernet cable to the PC and run wireshark, let
it boot, it should in theory be able to boot into the XMB if you found all
the correct offsets. Once it boots, you will see a lot of packets being
captured by wireshark. let it finish booting, then turn it off, save the
wireshark dump to a file, then run the ./tools/dump_elfs_pcap_to_bin utility
on the .pcap file,
giving it a directory to output the files to.

Now search (grep) for the word 'category_game' in that directory, and it
should give you one file matching the string, the filename of that file will
be the value of HASH_TABLE_3 (prefix it with '0x'). Hex edit that file. In
it, you will find multiple references to 'category_game', you only need to
find the one that says 'category_game.xml#root' then followed by a few 0x00
values. The value of 'elf3_data' is the offset where the '.xml' starts in
that string.

Now look for a file with a size of 6MB or 7MB. This is the VSH (XMB) ELF
file, its filename is the HASH_TABLE_1 value. Open that file in IDA and let
it analyze it, it will complain a few times about wrong sizes and missing
stuff, ignore those warnings. Then once it loads and finishes the file
analyzis, do a binary search for "68000001540007FE". It should find two
results, you need the first one. The two results point to very similar
functions, but one of them contains a 'nop' after the 'bl' while the other
doesn't. The one you want is the one without the 'nop'. The offset of this
function is the elf1_func1 offset. But be aware that IDA will load the data
with a start address of 0x1000, so make sure you substract 0x1000 from the
offset reported by IDA before setting it to elf1_func1.

Now let's find elf1_func2, do a binary search for "396000013803FF7F". It
should find one result, go to it, it should be a "li %r11, 1; addi %r0, %r3,
-0x81" instructions, the offset for elf1_func2 that you need is the offset of
the instruction "lhz %r3, 4(%r31)" just above that. You have found the
elf1_func2 offset, but don't forget to substract 0x1000 from the offset
reported by IDA.

You are ready for the second set of elf dumps! Now recompile everything and
run the exploit once more, but DO NOT connect the ethernet cable! Let the PS3
boot and connect your PS3 controller. You should now see the "Install package
files" option in the XMB. Congratulations! But it's not finished.

Now insert a USB device with a homebrew .pkg file on it, and then connect the
ethernet cable to your PC. Once the ethernet cable is connected, open the
"Install package files" menu and click on your .pkg to install it. It will
fail with a 0x80029519 error. It's ok! You can also see a new set of packets
just got captured by wireshark. Now you have two choices, either you open an
existing application installed on your PS3, and once you do that, press the
PS button on your controller to open the in-game XMB (which will freeze). Or
you can just shut down your PS3 and do this later.

Now save your wireshark dump to a new .pcap file, and extract its content
with the tools/dump_elfs_pcap_to_bin utility. You will find a few new files
extracted but you need to notice the output of the tool! The very first file
it will write is the HASH_TABLE_2 value, it should be about 280K or 300K in
size.

Open the file in IDA and set the processor type to 'ppc' then click ok. Now
search for the binary value "3929FFFF793D0FE0", it should give you one
result, open it, you will see random data (this is not a full ELF, only part
of it, so IDA cannot analyze it). press the 'C' key for IDA to transform it
into code. You should see the instructions "addi %r9, %r9, -1; rldicl %r29,
%r9, 1, 63". What you need is the offset of the 'rldicl' instruction.. so the
result of the search + 4 bytes. That's the elf2_func1 value that you want..
Note that since this wasn't analyzed by IDA and not recognized as an ELF, so
the data is not shifted so the offset value given to you by IDA is the offset
you want, do not substract 0x1000 from it, use it as is!

Now the only thing remaining is the HASH_TABLE_4 and elf4_data! If you did
open a game earlier for the second set of elf dumps, and tried to access the
in-game XMB, then skip this step, otherwise... : Now recompile everything and
rerun the exploit, you should now be able to both install and run homebrew
applications! once you have installed and ran an application, connect the
ethernet cable to your PC, start wireshark, then you can press the PS button
on the controller to bring the in-game XMB. It will crash, but that's all you
need. Now shut down the PS3, and save the wireshark dump and run the
tools/dump_elfs_pcap_to_bin on it.

Now this is where we join for the final step, search in the files (grep) for
the "category_game.xml" string, you should find one file (if you only search
for "category_game", you will find two files, you need the biggest file of
the two) Now you need to do the same thing as for elf3_data, look for the
'cateogry_game' string in the file with a hex editor until you find
"category_game.xml#root" followed by a few 0x00, and you need the offset of
the start of the ".xml". That's your elf4_data! Don't forget to copy the
filename (prefixed with '0x') to the HASH_TABLE_4 value.

You can now disable the dump_elfs payload and return everything back to
normal, i.e. use default_payload. Everything should work now! Congratulations!

Now you just need to test it, boot it up, look for the menu, install a .pkg
file and try to run it, then make sure the in-game XMB works as it should and
you're done! git commit all your changes, push them and make sure they get
integrated with the upstream repository!

All this should take between one and two hours of work.

Good luck!"

--
Tags: 改機

All Comments

Open Backup Manager v1.14.2

Yuri avatar
By Yuri
at 2010-10-05T22:14
http://www.ps3-hacks.com/2010/10/03/open-manager-v1-14-released/ 系統需求: * PSGroove/PSFreedom 1.1 w/ peek andamp; poke memory call instructions * Hermes Cha ...

Sony Versus PS3 JailBreaks

Zanna avatar
By Zanna
at 2010-10-05T21:47
前幾天的舊聞了, Garyopa 在他的 Wikileaks 上面放了許多 SCEA 提交給法官的證物, 裡面包含了證物 A~X, 有興趣的可以去原文的連結點開來看, 內容主要是針對販賣破解棒的網站, 如證物C 中的 htt://www.shoppsjailbreak.com 另外還有部分是因為網站的網址包 ...

請問有人還記得dms4.0操作法嗎?

Agatha avatar
By Agatha
at 2010-10-05T21:44
PS2後期的改機晶片 幾年前改的 因為以前我把它預設成開機直接進HDL介面 可是現在我想進正常bios 整理記憶卡檔案 請問操作步驟還有人記得嗎 好像是按住哪一顆再開機 但我試不出來 年代久遠 忘了 懇請高人指點 - ...

PS2可以玩PS1的MGS1備份片第二片嗎?

Andy avatar
By Andy
at 2010-10-05T21:43
請問一下前輩 我可以用PS2玩PS1的MGS1備份片嗎? 我可以順利玩第一片 不過換到第二片的時候總是顯示光碟非正版 不過我開機時直接放第二片進去就可以正常進入 但是這樣開始遊戲只會顯示請放第一片 這樣是我的晶片有問題? 或是PS2不支援兩片以上的PS1遊戲?? - ...

CBFAN releases SafeImg

Jacky avatar
By Jacky
at 2010-10-05T15:31
CBFAN 放出了 SafeImg 這個可以檢查 pkg 檔和 Rip PS3 遊戲檔的工具, 基本功能有 : 1. 顯示自製 pkg 檔的資訊 2. 切割大於 4GB 的檔案成為 Open backup manager 的格式 3. 去除不要的檔案 4. 去除電影檔 5. 去除更新檔或是隱藏更新檔 To ...