Beispiel #1
0
int readPrx( const char * file, int heap_id, u8 ** outbuf )
{
	log( "read %s to memory!\n", file );
	int fd = sceIoOpen( file, PSP_O_RDONLY, 0644 );
	if ( fd < 0 )
	{
		log( "failed in opening %s\n", file );
		return -1;
	}
	u8 * inbuf = ( u8 * )sceKernelAllocHeapMemory( heap_id, CXMB_MKCTF_BUF_SIZE / 2 );
	int size = sceIoRead( fd, inbuf, CXMB_MKCTF_BUF_SIZE / 2 );
	if ( inbuf[0x150] == 0x1F && inbuf[0x151] == 0x8B )
	{
		log( "uncompress gzip file!\n" );
		*outbuf = ( u8 * )sceKernelAllocHeapMemory( heap_id, CXMB_MKCTF_BUF_SIZE / 2 );
		int size = sceKernelGzipDecompress( *outbuf, CXMB_MKCTF_BUF_SIZE / 2, &inbuf[0x150], 0 );
		log( "uncompressed size %08x!\n", size );
		sceKernelFreeHeapMemory( heap_id, inbuf );
		if ( size > 0 && size < CXMB_MAX_FILE_SIZE )
		{
			return size;
		}
		else
		{
			sceKernelFreeHeapMemory( heap_id, outbuf );
			return -1;
		}
	}
	else
	{
		*outbuf = inbuf;
		return size;
	}
	return -1;
}
Beispiel #2
0
void uninstall_cxmb()
{
	//free the cxmb heap
	sceKernelFreeHeapMemory( mem_id, ctf_handler );
	sceKernelFreeHeapMemory( mem_id, ctf_header );
	sceKernelDeleteHeap( mem_id );
	ctf_handler = NULL;
	ctf_header = NULL;
}
Beispiel #3
0
int makeDiff( const char * file, const char * ori, int heap_id, int ctf )
{
	log( "detect %s, start to make diff!\n", file );
	u8 * buf = NULL, * buf_ori = NULL;
	int bytes = readPrx( file, heap_id, &buf );
	if ( bytes < 0 )
	{
		log( "failed in read %s!\n", file );
		return -1;
	}
	if ( readPrx( ori, heap_id, &buf_ori ) != bytes )
	{
		log( "failed in read %s!\n", ori );
		sceKernelFreeHeapMemory( heap_id, buf );
		sceKernelFreeHeapMemory( heap_id, buf_ori );
		return -1;
	}
	int sub = ( strstr( file, diff_files[1] ) ? 0xA0: 0xC0 );
	int diff_count = 0;
	unsigned int offset = 0, rec_attr[2];
	int rec = 0;
	memset( rec_attr, 0, 8 );
	while( offset < bytes )
	{
		if ( buf[offset] != buf_ori[offset] )
		{
			if ( !rec )
			{
				rec_attr[0] = offset - sub;
				rec_attr[1] = 0;
				rec = 1;
			}
			rec_attr[1] ++;
		}
		else
		{
			if ( rec )
			{
				log( "diff_start: %08x\nsize: %08x\n", rec_attr[0], rec_attr[1] );
				sceIoWrite( ctf, rec_attr, 8 );
				sceIoWrite( ctf, &buf[rec_attr[0] + sub], rec_attr[1] );
				diff_count ++;
				rec = 0;
			}
		}
		offset ++;
	}
	sceKernelFreeHeapMemory( heap_id, buf_ori );
	sceKernelFreeHeapMemory( heap_id, buf );
	return diff_count;
}
Beispiel #4
0
/*
 * Initialize the System Call table.  It is initialized the very
 * first time a SCE_LIB_SYSCALL_EXPORT resident library is 
 * registered to the system.  The table makes room for
 * SYSCALL_TABLE_FUNCTION_TABLE_ENTRIES functions to be stored
 * in it.  These function pointer slots are initialized to the 
 * address of the function "UndefSyscall", which simply returns an 
 * error, marking a slot as currently being unused.
 * 
 * In addition, the internal SyscallEntryTable linked list is initialized
 * and g_pSysEntControl is set to the top member of it.
 * 
 * @param seed Used to set the start address of the system call table.
 * @param lcSyscallTable Receive a pointer to the allocated system
 *                       call table.
 * 
 * @return 0 on success.
 */
s32 SyscallTableInit(u32 seed, SceSyscallTable **syscallTable) 
{
   u32 i;
   s32 status;
   SceSyscallTable *sysCallTable;  
     
   sysCallTable = sceKernelAllocHeapMemory(g_loadCoreHeap(), SYSCALL_TABLE_SIZE); 
   if (sysCallTable == NULL)
       return SCE_ERROR_KERNEL_ERROR;

   sysCallTable->next = NULL;
   sysCallTable->seed = seed << 2;
   sysCallTable->funcTableSize = SYSCALL_TABLE_FUNCTION_TABLE_SIZE;
   sysCallTable->tableSize = SYSCALL_TABLE_SIZE;
   
   //0x000003B0 - 0x000003C8
   for (i = 0; i < SYSCALL_TABLE_FUNCTION_TABLE_ENTRIES; i++) 
        sysCallTable->syscalls[i] = (void (*)())UndefSyscall;
    
   //0x000003D0 - 0x000003F8
   initialSysEntTable[0].next = NULL;      
   for (i = 0; i < TOP_SYSCALL_ENTRY_TABLE; i++)
        initialSysEntTable[i + 1].next = &initialSysEntTable[i];
   
   g_pFreeSysEnt = &initialSysEntTable[TOP_SYSCALL_ENTRY_TABLE]; //0x0000040C 
   if (g_pFreeSysEnt == NULL) { //0x00000410
       g_pSysEntControl = (SceSysCallEntryTable *)sceKernelAllocHeapMemory(g_loadCoreHeap(), sizeof(SceSysCallEntryTable)); //0x00000498 & 0x000004A4
   }
   else {
       g_pSysEntControl = g_pFreeSysEnt; //0x00000420
       g_pFreeSysEnt = g_pFreeSysEnt->next; //0x0000041C
   }
    
   //0x00000424 - 0x00000440
   /* Initialize the first SYSCALL table entry. */
   g_pSysEntControl->next = NULL; 
   g_pSysEntControl->inUse = SCE_FALSE;
   g_pSysEntControl->numEntries = SYSCALL_TABLE_DEFAULT_ENTRIES;
   g_pSysEntControl->startAddr = 0;
   
   status = sceKernelRegisterSystemCallTable(sysCallTable); //0x0000043C
   if (status != SCE_ERROR_OK) { //0x00000444
       sceKernelFreeHeapMemory(g_loadCoreHeap(), sysCallTable); //0x00000478 & 0x00000484
       return status;
   }
   *syscallTable = sysCallTable;
   return SCE_ERROR_OK; 
}
Beispiel #5
0
int IoOpen_new( PspIoDrvFileArg * arg, char * file, int flags, SceMode mode )
{
	PspIoDrvArg * drv = arg->drv;
	if( ctf_handler && arg->fs_num == 0 )
	{
		ctf_handler[handler_count].num = inCtf( file );
		if ( ctf_handler[handler_count].num >= 0 )
		{
			log( "replace %s\n", file );
			arg->drv = ms_drv;
			int ret = fatms_drv->funcs->IoOpen( arg, theme_file, flags, mode);
			if ( ret < 0 )
			{
				arg->drv = drv;
			}
			else
			{
				ctf_handler[handler_count].offset = fatms_drv->funcs->IoLseek( arg, ctf_header[ctf_handler[handler_count].num].start, PSP_SEEK_SET );
				ctf_handler[handler_count].arg = arg->arg;
				handler_count ++;
				if ( handler_count % 32 == 0 )
				{
					CtfHandler * tmp = sceKernelAllocHeapMemory( mem_id, sizeof( CtfHandler ) * ( handler_count + 32 ) );
					memcpy( tmp, ctf_handler, sizeof( CtfHandler ) * handler_count );
					sceKernelFreeHeapMemory( mem_id, ctf_handler );
					ctf_handler = tmp;
				}
				arg->drv = drv;
				return ret;
			}
		}
	}
	int ret = IoOpen( arg, file, flags, mode );
	if ( strcmp( file, "/vsh/theme/custom_theme.dat" ) == 0 && flags == ( PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC ) )
	{
		t_record = arg->arg;
		log( "open %s flags %08x\ntheme file selected: %s\n", file, flags, selected_theme_file );
	}
	return ret;
}
Beispiel #6
0
/*
 * FreeSysTable
 * 
 * Free a system-call-entry-table of a resident library.  In order
 * to free such a table, we start at the object pointed to by 
 * g_pSysEntControl (normally the top member of the initialSysEntTable 
 * linked list).  We scroll through that data structure until the location 
 * of the to-be-freed table is found and integrate it properly into 
 * the list again, merging it with another free neighbor table if
 * needed.
 * 
 * @param sysTableEntryAddr The address of an allocated SceSysCallEntryTable 
 *                          object.
 * 
 * Returns the address of the freed table on success.
 */
SceSysCallEntryTable *FreeSysTable(u32 sysTableEntryAddr) 
{
    SceSysCallEntryTable *curSysTableEntry = NULL;
    SceSysCallEntryTable *prevSysTableEntry = NULL;
    SceSysCallEntryTable *nextSysTableEntry = NULL;
    
    if (g_pSysEntControl == NULL) //0x000005D4
        return NULL;

    //0x000005DC - 0x000005F4
    /* Search for the location of the to-be-freed table. */
    for (curSysTableEntry = g_pSysEntControl; curSysTableEntry != NULL && 
       curSysTableEntry->startAddr != sysTableEntryAddr; curSysTableEntry = curSysTableEntry->next)
         prevSysTableEntry = curSysTableEntry; 

    if (curSysTableEntry == NULL || curSysTableEntry->inUse == SCE_FALSE) //0x00000614 & 0x00000624
        return NULL;

    /* Once found, mark it as being unused. */
    curSysTableEntry->inUse = SCE_FALSE; //0x00000630 & 0x00000638     
    
    /*
     * If the previous system-call-entry-table is currently being 
     * unused, merge these two tables together.  Integrate the freed 
     * table back into the list of currently free system call 
     * entry-tables if it was unlinked from it during allocation process.
     */
    if (prevSysTableEntry != NULL && prevSysTableEntry->inUse == SCE_FALSE) { //0x00000634        
        prevSysTableEntry->numEntries += curSysTableEntry->numEntries; //0x0000065C & 0x00000664
        prevSysTableEntry->next = curSysTableEntry->next; //0x0000066C 
        
        if (curSysTableEntry >= &initialSysEntTable[0] && curSysTableEntry <= &initialSysEntTable[TOP_SYSCALL_ENTRY_TABLE]) { //0x00000668 & 0x00000678
            curSysTableEntry->next = g_pFreeSysEnt; //0x00000688
            g_pFreeSysEnt = curSysTableEntry; //0x0000068C
            curSysTableEntry = prevSysTableEntry; //0x00000690             
        } 
        else {
            sceKernelFreeHeapMemory(g_loadCoreHeap(), curSysTableEntry); //0x00000730
            curSysTableEntry = prevSysTableEntry;
        }
    }
    /*
     * If both the previous table and the next table are used,
     * or the specified table is the last element and its 
     * previous table is being used, don't merge it.
     */
    if (curSysTableEntry->next == NULL || curSysTableEntry->next->inUse) //0x00000698 - 0x000006A4
        return curSysTableEntry;
    
    /*
     * Here, we merge the upper (next) free system call table with the 
     * specified table by the user.
     */
    nextSysTableEntry = curSysTableEntry->next; //0x00000694
    curSysTableEntry->numEntries += nextSysTableEntry->numEntries; //0x000006BC & 0x000006C4      
    curSysTableEntry->next = nextSysTableEntry->next; //0x000006CC
        
    if (nextSysTableEntry >= &initialSysEntTable[0] && nextSysTableEntry <= &initialSysEntTable[TOP_SYSCALL_ENTRY_TABLE]) { //0x000006C8 & 0x000006D8
        nextSysTableEntry->next = g_pFreeSysEnt; //0x000006E8
        g_pFreeSysEnt = nextSysTableEntry;   
    }
    else {
        sceKernelFreeHeapMemory(g_loadCoreHeap(), nextSysTableEntry); //0x0000070C
    }
    return curSysTableEntry;
}
Beispiel #7
0
int makeCxmbThemeFile( unsigned int cxmb_magic, const char * cxmb_theme_file )
{
	const char * folders_name[] = {
		"/data/cert",
		"/dic",
		"/font",
		"/kd",
		"/kd/resource",
		"/vsh/etc",
		"/vsh/module",
		"/vsh/resource"
	};
	int folders_count = 8;
	const char * support_exts[] = {
		".prx",
		".rco",
		".bmp",
		".pmf",
		".res",
		".pgf",
		".bwfon",
		".rsc",
		".dat",
		".img",
		".bin",
		".cet",
		".dic"
	};
	int exts_count = 13;
	int dfd, heap_id, fd, i, bytes, file_count = 0;
	unsigned int ptf_h[5];
	char path[128], file[128], preview[64];
	u8 * buf;
	// dectect if theme file in conf exist
	int ctf = sceIoOpen( cxmb_theme_file, PSP_O_RDONLY, 0644 );
	if ( ctf >= 0 )
	{
		log( "theme file exist!\n" );
		sceIoClose( ctf );
		return 0;
	}

	dfd = sceIoDopen( "ms0:/cxmb" );
	if ( dfd < 0 )
	{
		log( "no cxmb folder found!\n" );
		return 0;
	}
	sceIoDclose( dfd );

	sprintf( preview, "ms0:/cxmb%s", &cxmb_theme_file[14] );
	preview[strlen( preview ) - 3] = 'p';
	log( "preview: %s\n", preview );
	fd = sceIoOpen( preview, PSP_O_RDONLY, 0644 );
	if ( fd < 0 )
	{
		log( "no preview ptf file found!\n" );
		return 0;
	}
	sceIoLseek( fd, 0x100, PSP_SEEK_SET );
	sceIoRead( fd, ptf_h, 20 );

	// create CXMB_MKCTF_BUF_SIZE + 32kb heap
	heap_id = sceKernelCreateHeap( 2, CXMB_MKCTF_BUF_SIZE + 1024 * 32 , 1, "cxmb_tmp_heap");
	if ( heap_id < 0 )
	{
		log( "failed in create heap in making cxmb theme file!\n" );
		return -1;
	}

	CtfHeader * ch = ( CtfHeader * )sceKernelAllocHeapMemory( heap_id, sizeof( CtfHeader ) * 64 );
	memset( ch, 0, sizeof( CtfHeader ) * 64 );
	SceIoDirent * ent = ( SceIoDirent * )sceKernelAllocHeapMemory( heap_id, sizeof( SceIoDirent ) );
	memset( ent, 0, sizeof( SceIoDirent ) );

	sceIoMkdir( "ms0:/PSP/THEME", 0777 );
	ctf = sceIoOpen( cxmb_theme_file, PSP_O_RDWR | PSP_O_CREAT | PSP_O_TRUNC, 0777 );
	if ( ctf < 0 )
	{
		log( "failed in opening %s\n", cxmb_theme_file );
		sceKernelFreeHeapMemory( heap_id, ent );
		sceKernelFreeHeapMemory( heap_id, ch );
		sceKernelDeleteHeap( heap_id );
		return -1;
	}
	else
	{
		if ( ptf_h[2] == 0 )
			ptf_h[2] = sceIoLseek( fd, 0, PSP_SEEK_END );
		log( "ptf sections size %08x\n", ptf_h[2] );
		buf = sceKernelAllocHeapMemory( heap_id, ptf_h[2] );
		if ( buf )
		{
			sceIoLseek( fd, 0, PSP_SEEK_SET );
			sceIoRead( fd, buf, ptf_h[2] );
			sceIoWrite( ctf, buf, ptf_h[2] );
			sceIoClose( fd );
			sceKernelFreeHeapMemory( heap_id, buf );

			sceIoLseek( ctf, 0x10, PSP_SEEK_SET );
			sceIoWrite( ctf, &cxmb_magic, 4 );
			sceIoLseek( ctf, 0x1C, PSP_SEEK_SET );
			sceIoWrite( ctf, &ptf_h[2], 4 );

			memset( &ptf_h[2], 0, 12 );
			sceIoLseek( ctf, 0x100, PSP_SEEK_SET );
			sceIoWrite( ctf, ptf_h, 20 );
			sceIoLseek( ctf, 0, PSP_SEEK_END );

			for ( i = 0; i < folders_count; i ++ )
			{
				sprintf( path, "ms0:/cxmb%s", folders_name[i] );
				dfd = sceIoDopen( path );
				if ( dfd < 0 )
				{
					log( "folder %s not found!\n", path );
					continue;
				}
				log( "parsing %s\n", path );
				while ( sceIoDread( dfd, ent ) > 0 )
				{
					log( "found %s\n", ent->d_name );
					if ( ( ent->d_stat.st_attr & FIO_SO_IFDIR ) || ent->d_name[0] == '.' )
					{
						log( "ignore %s\n", ent->d_name );
						continue;
					}
					if ( endwithistrs( ent->d_name, support_exts, exts_count ) )
					{
						sprintf( file, "%s/%s", path, ent->d_name );
						sprintf( ch[file_count].name, "%s/%s", folders_name[i], ent->d_name );
						ch[file_count].start = sceIoLseek( ctf, 0, PSP_SEEK_CUR );
						ch[file_count].size = 0;
						if ( cmpistrs( ent->d_name, diff_files, diff_count ) )
						{
							char ori_file[128];
							sprintf( ori_file, "%s/%s", CXMB_SUPPORT_FOLDER, ent->d_name );
							ch[file_count].size = makeDiff( file, ori_file, heap_id, ctf );
						}
						else
						{
							log( "dealing with %s\n", ent->d_name );
							fd = sceIoOpen( file, PSP_O_RDONLY, 0644 );
							if ( fd < 0 )
							{
								log( "failed in opening %s\n", file );
								continue;
							}
							buf = ( u8 * )sceKernelAllocHeapMemory( heap_id, CXMB_MKCTF_BUF_SIZE );
							bytes = sceIoRead( fd, buf, CXMB_MKCTF_BUF_SIZE );
							while( bytes > 0 )
							{
								ch[file_count].size += sceIoWrite( ctf, buf, bytes );
								bytes = sceIoRead( fd, buf, CXMB_MKCTF_BUF_SIZE );
							}
							sceKernelFreeHeapMemory( heap_id, buf );
							sceIoClose( fd );
						}
						if ( ch[file_count].size > 0 && ch[file_count].size < CXMB_MAX_FILE_SIZE )
						{
							log( "start: %08x size: %08x\n", ch[file_count].start, ch[file_count].size );
							file_count ++;
						}
					}
					else
					{
						log( "ignore %s\n", ent->d_name );
					}
				}
				sceIoDclose( dfd );
			}
		}
		else
		{
			log( "failed in allocating %08x heap\n", ptf_h[2] );
		}
	}

	log( "file_count: %d\n", file_count );
	if ( file_count > 0 )
	{
		u8 sha1[20];
		sceKernelUtilsSha1Digest( ( u8 * )ch, sizeof( CtfHeader ) * file_count, sha1 );
		sceIoWrite( ctf, ch, sizeof( CtfHeader ) * file_count );
		sceIoLseek( ctf, 0x14, PSP_SEEK_SET );
		sceIoWrite( ctf, &sha1[0], 4 );
		sceIoWrite( ctf, &file_count, 4 );
		sceIoClose( ctf );
	}
	else
	{
		sceIoClose( ctf );
		sceIoRemove( cxmb_theme_file );
	}
	sceKernelFreeHeapMemory( heap_id, ent );
	sceKernelFreeHeapMemory( heap_id, ch );
	sceKernelDeleteHeap( heap_id );
	return 0;
}