Ejemplo n.º 1
0
// Create a code wrapper based on TAP_GetTime. The function allocates a buffer and copies 
// TAP_GetTime into it except for the actual call of the getTime() firmware function. 
// The address of getTime() is replaced with the provided address.
// The wrapped function call supports up to 4 parameters and returns a short value.
// Parameters:
//      functionAddress - address of the FW function to be wrapped
// Returns:
//		Address of the new wrapper
dword* CreateAPIWrapper( dword functionAddress )
{
	int i;
	// TAP_GetTime provides a template for wrapper code. The only thing to be
	// changed is the address of the wrapped function.
	dword *src = (dword*)TAP_GetTime;
	dword *buffer;
	int bufferSize = 0;

	// find the return statement
	while ( src[bufferSize] != JR_CMD )
	{
		++bufferSize;
	}

	// the buffer should include the return statement and the command following
	// the return statement
	bufferSize += 2;

	// allocate memory
	buffer = malloc( sizeof(dword) * bufferSize );
	if ( buffer == NULL )
	{
		TAP_Print( "malloc failed\n" );
		return NULL;
	}

	for ( i = 0; i < bufferSize; ++i, ++src )
	{
		if ( (*src & JAL_MASK) == JAL_CMD )
		{
			// this is the wrapped call to the actual firmware implementation
			// replace it with the call to the provided address
			buffer[i] = JAL(functionAddress);
		}
		else
		{
			buffer[i] = *src;
		}
	}

	return buffer;
}
Ejemplo n.º 2
0
int sbv_patch_enable_lmb()
{
	u8 buf[256];
	slib_exp_lib_t *modload_lib = (slib_exp_lib_t *)buf;
	smod_mod_info_t *loadfile_info = (smod_mod_info_t *)buf;
	void *pStartModule, *pLoadModuleBuffer, *lf_text_start, *patch_addr;
	u32 lf_rpc_dispatch, lf_jump_table, result;
	int nexps, id, i;

	memset(&_slib_cur_exp_lib_list, 0, sizeof(slib_exp_lib_list_t));

	/* Locate the modload export library - it must have at least 16 exports.  */
	if ((nexps = slib_get_exp_lib("modload", modload_lib)) < 16)
		return -1;

	pStartModule = modload_lib->exports[8];
	pLoadModuleBuffer = modload_lib->exports[10];

	/* Now we need to find the loadfile module.  */
	memset(buf, 0, sizeof(smod_mod_info_t));
	if (!(id = smod_get_mod_by_name("LoadModuleByEE", loadfile_info)))
		return -1;

	/* Locate the loadfile RPC dispatch code, where the first 4 instructions look like:
	
	   27bdffe8	addiu	$sp, -24
	   2c820006	sltiu	$v0, $a0, 6
	   14400003	bnez	$v0, +12
	   afbf0010	sw	$ra, 0x10($sp)
	*/
	lf_text_start = (void *)(loadfile_info->text_start + 0x400);
	smem_read(lf_text_start, buf, sizeof buf);

	for (i = 0; i < sizeof buf; i += 4) {
		if ((*(u32 *)(buf + i) == 0x27bdffe8) &&
				(*(u32 *)(buf + i + 4) == 0x2c820006) &&
				(*(u32 *)(buf + i + 8) == 0x14400003) &&
				(*(u32 *)(buf + i + 12) == 0xafbf0010))
			break;
	}
	/* This is a special case: if the IOP was reset with an image that contains a
	   LOADFILE that supports LMB, we won't detect the dispatch routine.  If we
	   even got this far in the code then we can return success.  */
	if (i >= sizeof buf)
		return 0;

	/* We need to extract the address of the jump table, it's only 40 bytes in. */
	lf_rpc_dispatch = (u32)lf_text_start + i;
	smem_read((void *)lf_rpc_dispatch, buf, 40);

	lf_jump_table = (*(u16 *)(buf + 0x1c) << 16) + *(s16 *)(buf + 0x24);

	/* Now we can patch our subversive LoadModuleBuffer RPC call.  */
	SifInitIopHeap();
	if (!(patch_addr = SifAllocIopHeap(sizeof lmb_patch)))
		return -1;

	/* result is where the RPC return structure is stored.  */
	result = (u32)patch_addr + 96;
	lmb_patch[5] = JAL((u32)pLoadModuleBuffer);
	lmb_patch[7] = HI16(result);
	lmb_patch[9] = LO16(result);
	lmb_patch[15] = JAL((u32)pStartModule);

	SyncDCache(lmb_patch, (void *)(lmb_patch + 24));
	smem_write(patch_addr, lmb_patch, sizeof lmb_patch);

	/* Finally.  The last thing to do is to patch the loadfile RPC dispatch routine
	   so that it will jump to entry #6 in it's jump table, and to patch the jump
	   table itself.  */
	ee_kmode_enter();
	*(u32 *)(SUB_VIRT_MEM + lf_rpc_dispatch + 4) = 0x2c820007;
	*(u32 *)(SUB_VIRT_MEM + lf_jump_table + 0x18) = (u32)patch_addr;
	ee_kmode_exit();

	return 0;
}
Ejemplo n.º 3
0
void MIPSEmitter::JAL(const void *func, std::function<void ()> delaySlot) {
	SetJumpTarget(JAL(delaySlot), func);
}