Permalink
Browse files

Port to 3.30, a fix for 3.21 and a little more changes to the HOWTO.

  • Loading branch information...
1 parent fdb585c commit 464e033e9b32d56a564b21751b59f6dffbf360bc @fungos fungos committed Nov 12, 2010
Showing with 112 additions and 40 deletions.
  1. +40 −37 HOWTO
  2. +4 −1 Makefile
  3. +68 −2 firmware_symbols.h.S
View
77 HOWTO
@@ -54,7 +54,7 @@ d. 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.
+syscall_table define in firmware_symbols.h.S.
e. Then look for the position of the JIG response offset in the dump by
searching for the recognizable string you previously put in there. You can now
@@ -107,10 +107,7 @@ 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.
-h. 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.
-
-i. Now time for patch_func4, search for binary data in IDA and look for the
+h. Now time for patch_func4, search for binary data in IDA and look for the
binary sequence "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
@@ -119,7 +116,7 @@ to, the correct function should be the short one (in my version it has 3
blocks in graph view, the wrong function have way more blocks). Now you found
patch_func4.
-j. Time for patch_func5, this one is easy if you have a supported dump
+i. Time for patch_func5, this one is easy if you have a supported dump
already, right click on it in the sub on the supported firmware and 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
@@ -128,10 +125,10 @@ 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).
-k. Now you need to find the slightly more difficult remaining offsets: memcpy,
+j. 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.
-l. Let's start with MEM_BASE2. Go to 'patch_func5', disable IDA's 'chart' mode,
+k. 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
@@ -145,7 +142,7 @@ 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).
-m. Now let's try to find rtoc_entry1, if you go to the rtoc_entry_1 offset in
+l. 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
@@ -163,7 +160,7 @@ 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.
-n. Now we need to find the slightly harder patch_data1 offset. In your supported
+m. Now we need to find the slightly harder patch_data1 offset. In your supported
firmware 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
@@ -184,39 +181,45 @@ the TOC of your new firmware 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
-o. Now the 'memcpy' function is the only one remaining! 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 differently, 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!
+n. Now the 'memcpy'. 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
+differently, 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!
+
+o. // Write here how to find: patch_func6, patch_func7 (this is syscall_512),
+patch_func8, patch_dup_fromuser (binary search for "7b40052023a01000"), USB*.
p. To find the patch_func9, you should search for the binary "60630019". This
should give you just one match pointing to the instruction "ori %r3, %r3, 0x19".
The patch_func9 address is the XYZ address of the name sub_XYZ and the
patch_func9_offset should be 0x3ec, check that it is a "beq" instruction.
-====
-Go to 0xC00, follow it to (probably) 0xC2C (ori %r3, mtlr %r3. blr) then
-follow it to the syscall handler (oris+ori %r4. mtsrr0 %r4). Watch for the ori
-of negative value.. Then in the syscall handler, find blrl (probably offset
-174), that's the instruction to patch.
+q. To find patch_syscall_func, go to 0xC00, press 'C' to convert it to code if
+it is not, then follow it to (probably) 0xC20 (ori %r3, mtlr %r3, blr) then
+follow it to the syscall handler (oris %r4, %r4, 0x?? - ori %r4, %r4, -0x???,
+mtsrr0 %r4). Watch for the ori of negative value, that is the address of the
+syscall handler, find blrl (probably offset 174), that is the instruction to
+patch. Or search for the binary string "4e800021", it should find 4 entries, 3
+of them are __asm_func_dummy_X. The first one, is the address of the instruction
+'blrl' to be patched.
Step 3 - Finding the elfs
View
5 Makefile
@@ -7,7 +7,7 @@ PPU_OBJCOPY = ppu-objcopy
PPU_CFLAGS =
# This isn't enough, you must also add rules for the filename_fw with the -D define
-SUPPORTED_FIRMWARES = 3.41 3.41_kiosk 3.40 3.21 3.15 3.10 3.01 2.76
+SUPPORTED_FIRMWARES = 3.41 3.41_kiosk 3.40 3.30 3.21 3.15 3.10 3.01 2.76
PAYLOADS = shellcode_egghunt.bin \
shellcode_panic.bin \
@@ -72,6 +72,9 @@ $(ALL_PAYLOADS): *.h.S config.h
%_3_21.o : %.S
$(PPU_CC) $(PPU_CFLAGS) -DFIRMWARE_3_21 -c $< -o $@
+%_3_30.o : %.S
+ $(PPU_CC) $(PPU_CFLAGS) -DFIRMWARE_3_30 -c $< -o $@
+
%_3_40.o : %.S
$(PPU_CC) $(PPU_CFLAGS) -DFIRMWARE_3_40 -c $< -o $@
View
70 firmware_symbols.h.S
@@ -156,6 +156,71 @@
#define elf3_data 0x0022b888
#define elf4_data 0x000d68b8
+#elif defined(FIRMWARE_3_30)
+
+// TOC at 0x33dbc0
+// Shell code addr 0x003dde70
+
+/* Common Symbols */
+#define memcpy 0x0007c014
+#define memset 0x0004d13c
+#define strcpy 0x0004d2e8
+#define strncmp 0x0004d33c
+#define strlen 0x0004d310
+#define pathdup_from_user 0x001b35e0
+#define copy_from_user 0x0000e268
+#define copy_to_user 0x0000e04c
+#define alloc 0x00062080
+#define free 0x000624c0
+#define USBRegisterDriver 0
+#define syscall_table 0x002ea728
+#define USBGetDeviceDescriptor 0x000d28e8
+#define USBOpenEndpoint 0x000d2904
+#define USBControlTransfer 0x000d287c
+#define memory_patch_func 0x0004e814
+#define patch_func1 0x000490a4
+#define patch_func1_offset 0x34
+#define patch_func2 0x0004f074
+#define patch_func2_offset 0x2c
+#define patch_func3 0x002aa678 // hooked_open
+#define patch_func3_offset 0x24
+#define patch_func4 0x0004ed10
+#define patch_func4_offset 0x0
+#define patch_func5 0x000505c8
+#define patch_func5_offset 0x0
+#define patch_func6 0x0002308c
+#define patch_func6_offset 0x0
+#define patch_func7 0x000e8280 // syscall_512
+#define patch_func7_offset 0x0
+#define patch_func8 0x00057248 // lv2_open
+#define patch_func8_offset1 0x68 // lv2open update patch
+#define patch_func8_offset2 0x1cc // lv2open update patch
+#define patch_func9 0x0004f838 // must upgrade error
+#define patch_func9_offset 0x3ec
+#define patch_syscall_func 0x0028f234
+#define patch_data1 0x003b9d10
+#define rtoc_entry_1 0x0ee0
+#define rtoc_entry_2 -0x6a00
+
+#define MEM_BASE2 (0x050b34)
+
+#define RESIDENT_PAYLOAD_MAXSIZE (1296)
+
+#define HASH_TABLE_1 0xA0694B50002C638E // vsh elf
+#define HASH_TABLE_2 0x6B70281A0001E3AA // pkg loader elf
+#define HASH_TABLE_3 0x8C0A948C000CC7E9 // xmb elf
+#define HASH_TABLE_4 0xA2BC087A0005224C // ingame xmb elf
+
+#define elf1_func1 0x005e9fe4
+#define elf1_func1_offset 0x00
+#define elf1_func2 0x002ff224
+#define elf1_func2_offset 0x78 // 0x14?
+#define elf2_func1 0x0002ded0 // run pkg function
+#define elf2_func1_offset 0x374 // patch to run pkg (ignore error 0x80029567)
+
+#define elf3_data 0x0020b258 // xmb 'game' submenu xml conf offset.
+#define elf4_data 0x000d5728 // ingame xmb 'game' submenu xml conf offset.
+
#elif defined(FIRMWARE_3_21)
/* Common Symbols */
@@ -190,10 +255,11 @@
#define patch_func7 0x000e8e6c // syscall_512
#define patch_func7_offset 0x0
#define patch_func8 0x00056c3c // lv2_open
-#define patch_func8_offset1 0xA4 // lv2open update patch
-#define patch_func8_offset2 0x208 // lv2open update patch
+#define patch_func8_offset1 0x68 // lv2open update patch
+#define patch_func8_offset2 0x1cc // lv2open update patch
#define patch_func9 0x0004f30c // must upgrade error
#define patch_func9_offset 0x3ec
+#define patch_syscall_func 0x0028f67c
#define patch_data1 0x003b9a10
#define rtoc_entry_1 0x0d60
#define rtoc_entry_2 -0x6b08

0 comments on commit 464e033

Please sign in to comment.