Advertising (This ad goes away for registered users. You can Login or Register)

VSH plugin for Bluetooth

Forum rules
Forum rule Nº 15 is strictly enforced in this subforum.
JJS
Big Beholder
Posts: 1416
Joined: Mon Sep 27, 2010 2:18 pm
Contact:

Re: VSH plugin for Bluetooth

Post by JJS »

0x8002013A = library not linked yet error

Looks like this is caused by the missing NID translation in the 6.3x HEN. I would have to find the real NID for 6.31 and 6.35 and relink with that. Of course once the NID translation is further completed on the HEN, the plugin will fail again :?.


Edit: Alright, here is a version that should work on 6.20, 6.31 and 6.35. Untested on 6.3x of course :D. In this version I import both the 1.00 kernel NID and the 6.3x NID. Then there is a check on runtime for which function gets linked by the kernel. sctrlHenFindFunction (or something like that) would probably be the better choice, but this should work too.

Code: Select all

#include <pspsdk.h> 
#include <pspkernel.h> 
#include <systemctrl.h> 
#include <psploadcore.h>
#include <string.h>
#include <stdio.h>


PSP_MODULE_INFO("btfree", 0x1000, 0, 0);


// Prototype not in the PSPSDK
int sceKernelQuerySystemCall(void* function);
int sceKernelQuerySystemCall63x(void* function); // Links to the real NID on 6.3x


// Just some error codes I found in the bt module
#define PSP_ERROR_BLUETOOTH_ALREADY_REGISTERED 0x802F0131
#define PSP_ERROR_BLUETOOTH_UNSUPPORTED_DEVICE 0x802F0135


#define MAKE_CALL(f) (0x0c000000 | (((u32)(f) >> 2)  & 0x03ffffff))
#define MAKE_SYSCALL(n) (0x03ffffff & (((u32)(n) << 6) | 0x0000000c))


// Previous start module handler
STMOD_HANDLER previousStartModuleHandler = NULL; 

// Address for the syscall stub in user memory
int blockAddress = 0;

// Firmware versin
int firmware = 0;

// This struct is passed to sub_09498 in bluetooth_plugin_module
typedef struct
{
	u32 stuct_size; // size of this struct = 0x54
	u16 item_number; // first item in array has 1, second has 2
	u16 name[32]; // in unicode
	u16 unknown1;
	u8 major_service_class; // probably this
	u8 major_device_class; // 1 = PC, 2 = phone, 4 = audio/video, 5 = peripheral device
	u8 minor_device_class; // different meaning depending on the major class
	u8 unknown2;
	u32 unknown3; // always the same for a given device
	u16 unknown4; // always the same for a given device
	u16 unknown5;
}
btDeviceInfo;


u32 patchAddresses_620[] = { 0x000095A4, 0x000094A8, 0x000094D4 };
u32 patchAddresses_63x[] = { 0x00013E00, 0x00013D04, 0x00013D30 };
u32* patchAddresses = NULL;


// Function pointer to the original sub_09498 in bluetooth_plugin_module
int (*bluetooth_plugin_module_sub_09498)(int, btDeviceInfo*, int) = NULL;



void fillBufferFromWidechar(unsigned short* inputBuffer, char* outputText)
{
  int i;
  for (i = 0; inputBuffer[i]; i++)
  {
    outputText[i] = inputBuffer[i];
  }

  outputText[i] = 0;
}


void logFilePrintf(char* format, int arg1)
{
	SceUID logfile = sceIoOpen("ef0:/btfree_log.txt", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_APPEND, 0777);

	if (logfile > -1)
	{
		char buffer[100];
		sprintf(buffer, format, arg1);
		sceIoWrite(logfile, buffer, strlen(buffer));
		sceIoClose(logfile);
	}
}



int bluetooth_plugin_module_sub_09498_hook(int unknown, btDeviceInfo* devices, int count)
{
	int k1 = pspSdkSetK1(0);

	if (count > 0)
	{
		// Log the device info
		logFilePrintf("--------------------\n", 0);
		
		char name[32];
		int i;

		for (i = 0; i < count; i++)
		{
			fillBufferFromWidechar(devices[i].name, name);
			logFilePrintf("name         : %s\n", (u32)name);
			logFilePrintf("unknown1     : 0x%08lX\n", (u32)devices[i].unknown1);
			logFilePrintf("major_srv_cl : 0x%08lX\n", (u32)devices[i].major_service_class);
			logFilePrintf("major_dev_cl : 0x%08lX\n", (u32)devices[i].major_device_class);
			logFilePrintf("minor_dev_cl : 0x%08lX\n", (u32)devices[i].minor_device_class);
			logFilePrintf("unknown1     : 0x%08lX\n", (u32)devices[i].unknown2);
			logFilePrintf("unknown2     : 0x%08lX\n", (u32)devices[i].unknown3);
			logFilePrintf("unknown3     : 0x%08lX\n", (u32)devices[i].unknown4);
			logFilePrintf("unknown4     : 0x%08lX\n", (u32)devices[i].unknown5);
			logFilePrintf("\n", 0);

			// Device class can be changed here
			//devices[i].major_device_class = 2;
			//devices[i].minor_device_class = 4;
		}
	}

	pspSdkSetK1(k1);

	// Call the original function
	return bluetooth_plugin_module_sub_09498(unknown, devices, count);
}




int on_module_start(SceModule2* mod) 
{
	// Get active on the Bluetooth VSH plugin
	if (strcmp(mod->modname, "bluetooth_plugin_module") == 0) 
	{ 
		logFilePrintf("Entering on_module_start\n", 0);

		// Store function pointer to the original sub_09498
		bluetooth_plugin_module_sub_09498 = (void*)(mod->text_addr + 0x00009498);
		logFilePrintf("bluetooth_plugin_module_sub_09498 = 0x%08lX\n", (u32)bluetooth_plugin_module_sub_09498);

		// Setup a syscall stub in user memory
		if (blockAddress == 0)
		{
			SceUID blockId = sceKernelAllocPartitionMemory(2, "btfree_stub", PSP_SMEM_Low, 2 * sizeof(int), NULL);
			logFilePrintf("blockId = 0x%08lX\n", (u32)blockId);

			blockAddress = (int)sceKernelGetBlockHeadAddr(blockId);
			logFilePrintf("blockAddress = 0x%08lX\n", (u32)blockAddress);

			// Get syscall of the hook function
			int syscall;
			
			// Look if the regular function is resolved, if not use the 6.3x kernel NID
			if ((u32)&sceKernelQuerySystemCall != 0x0000054C) // syscall 0x15 = not linked
				syscall = sceKernelQuerySystemCall(&bluetooth_plugin_module_sub_09498_hook);
			else
				syscall = sceKernelQuerySystemCall63x(&bluetooth_plugin_module_sub_09498_hook);

			logFilePrintf("syscall = 0x%08lX\n", (u32)syscall);

			// Write syscall stub
			_sw(0x03E00008, blockAddress); // jr $ra
			_sw(MAKE_SYSCALL(syscall), blockAddress + sizeof(int)); // syscall
		}

		// Hook the call to the original function in bluetooth_plugin_module
		_sw(MAKE_CALL(blockAddress), mod->text_addr + patchAddresses[0]);


		// Now patch sub_09498 to accept any device class

		// There is a check for the device type that goes something like this:
		//
		// if (((descriptor & 0x000000FF) == 0x00000005) || (...) || (...)))
		//
		// It gets changed to:
		//
		// if (((descriptor & 0x000000FF) != 0x0000FFFF) || (...) || (...)))
		//
		// The result is obviously that the statement always evaluates as true,
		// therefore no devices are rejected early.

		// write "li $t6, 0xFFFF", was "li $t6, 0x5"
		_sw(0x240EFFFF, mod->text_addr + patchAddresses[1]);

		// write "bne $v0, $t6, loc_000094E4", was "beq $v0, $t6, loc_000094E4"
		_sw(0x144E0003, mod->text_addr + patchAddresses[2]);
	} 

	// Call previously set start module handler if necessary
	if (previousStartModuleHandler)
		return previousStartModuleHandler(mod);
	else
		return 0;
} 



int module_start(SceSize args, void* argp)
{
	// Select patch address set for the firmware
	firmware = sceKernelDevkitVersion();

	logFilePrintf("Firmware version 0x%08lX\n", firmware);

	switch (firmware)
	{
		case 0x06020010:
			patchAddresses = patchAddresses_620;
			break;

		case 0x06030110:
		case 0x06030510:
			patchAddresses = patchAddresses_63x;
			break;
	}

	if (patchAddresses)
	{
		// Establish a handler that gets called before any modules "module_start" function is called.
		// A previous handler gets saved.
		previousStartModuleHandler = sctrlHENSetStartModuleHandler(on_module_start);
	}
	else
	{
		// Unsupported firmware
		logFilePrintf("This firmware is not supported.\n", 0);
	}

	return 0;
}





int module_stop(SceSize args, void* argp)
{
	// Restore the previous start module handler if there was one
	if (previousStartModuleHandler)
		sctrlHENSetStartModuleHandler(previousStartModuleHandler);

	return 0;
}
Advertising
Attachments
btfree3.zip
(5.86 KiB) Downloaded 539 times
thebudds
Moderator
Posts: 428
Joined: Sat Nov 06, 2010 6:56 pm
Location: Somewhere In the next dimension

Re: VSH plugin for Bluetooth

Post by thebudds »

@ JJS

Maybe you should see if you could take a look at the source for Version 0.6.0003(signature) the newest version allows you to tether your ps3 controller to your psp go.
Advertising
Image
Zealhybrid
Posts: 48
Joined: Thu Jan 06, 2011 11:08 am

Re: VSH plugin for Bluetooth

Post by Zealhybrid »

JJS wrote:0x8002013A = library not linked yet error

Looks like this is caused by the missing NID translation in the 6.3x HEN. I would have to find the real NID for 6.31 and 6.35 and relink with that. Of course once the NID translation is further completed on the HEN, the plugin will fail again :?.


Edit: Alright, here is a version that should work on 6.20, 6.31 and 6.35. Untested on 6.3x of course :D. In this version I import both the 1.00 kernel NID and the 6.3x NID. Then there is a check on runtime for which function gets linked by the kernel. sctrlHenFindFunction (or something like that) would probably be the better choice, but this should work too.

Code: Select all

#include <pspsdk.h> 
#include <pspkernel.h> 
#include <systemctrl.h> 
#include <psploadcore.h>
#include <string.h>
#include <stdio.h>


PSP_MODULE_INFO("btfree", 0x1000, 0, 0);


// Prototype not in the PSPSDK
int sceKernelQuerySystemCall(void* function);
int sceKernelQuerySystemCall63x(void* function); // Links to the real NID on 6.3x


// Just some error codes I found in the bt module
#define PSP_ERROR_BLUETOOTH_ALREADY_REGISTERED 0x802F0131
#define PSP_ERROR_BLUETOOTH_UNSUPPORTED_DEVICE 0x802F0135


#define MAKE_CALL(f) (0x0c000000 | (((u32)(f) >> 2)  & 0x03ffffff))
#define MAKE_SYSCALL(n) (0x03ffffff & (((u32)(n) << 6) | 0x0000000c))


// Previous start module handler
STMOD_HANDLER previousStartModuleHandler = NULL; 

// Address for the syscall stub in user memory
int blockAddress = 0;

// Firmware versin
int firmware = 0;

// This struct is passed to sub_09498 in bluetooth_plugin_module
typedef struct
{
	u32 stuct_size; // size of this struct = 0x54
	u16 item_number; // first item in array has 1, second has 2
	u16 name[32]; // in unicode
	u16 unknown1;
	u8 major_service_class; // probably this
	u8 major_device_class; // 1 = PC, 2 = phone, 4 = audio/video, 5 = peripheral device
	u8 minor_device_class; // different meaning depending on the major class
	u8 unknown2;
	u32 unknown3; // always the same for a given device
	u16 unknown4; // always the same for a given device
	u16 unknown5;
}
btDeviceInfo;


u32 patchAddresses_620[] = { 0x000095A4, 0x000094A8, 0x000094D4 };
u32 patchAddresses_63x[] = { 0x00013E00, 0x00013D04, 0x00013D30 };
u32* patchAddresses = NULL;


// Function pointer to the original sub_09498 in bluetooth_plugin_module
int (*bluetooth_plugin_module_sub_09498)(int, btDeviceInfo*, int) = NULL;



void fillBufferFromWidechar(unsigned short* inputBuffer, char* outputText)
{
  int i;
  for (i = 0; inputBuffer[i]; i++)
  {
    outputText[i] = inputBuffer[i];
  }

  outputText[i] = 0;
}


void logFilePrintf(char* format, int arg1)
{
	SceUID logfile = sceIoOpen("ef0:/btfree_log.txt", PSP_O_CREAT | PSP_O_WRONLY | PSP_O_APPEND, 0777);

	if (logfile > -1)
	{
		char buffer[100];
		sprintf(buffer, format, arg1);
		sceIoWrite(logfile, buffer, strlen(buffer));
		sceIoClose(logfile);
	}
}



int bluetooth_plugin_module_sub_09498_hook(int unknown, btDeviceInfo* devices, int count)
{
	int k1 = pspSdkSetK1(0);

	if (count > 0)
	{
		// Log the device info
		logFilePrintf("--------------------\n", 0);
		
		char name[32];
		int i;

		for (i = 0; i < count; i++)
		{
			fillBufferFromWidechar(devices[i].name, name);
			logFilePrintf("name         : %s\n", (u32)name);
			logFilePrintf("unknown1     : 0x%08lX\n", (u32)devices[i].unknown1);
			logFilePrintf("major_srv_cl : 0x%08lX\n", (u32)devices[i].major_service_class);
			logFilePrintf("major_dev_cl : 0x%08lX\n", (u32)devices[i].major_device_class);
			logFilePrintf("minor_dev_cl : 0x%08lX\n", (u32)devices[i].minor_device_class);
			logFilePrintf("unknown1     : 0x%08lX\n", (u32)devices[i].unknown2);
			logFilePrintf("unknown2     : 0x%08lX\n", (u32)devices[i].unknown3);
			logFilePrintf("unknown3     : 0x%08lX\n", (u32)devices[i].unknown4);
			logFilePrintf("unknown4     : 0x%08lX\n", (u32)devices[i].unknown5);
			logFilePrintf("\n", 0);

			// Device class can be changed here
			//devices[i].major_device_class = 2;
			//devices[i].minor_device_class = 4;
		}
	}

	pspSdkSetK1(k1);

	// Call the original function
	return bluetooth_plugin_module_sub_09498(unknown, devices, count);
}




int on_module_start(SceModule2* mod) 
{
	// Get active on the Bluetooth VSH plugin
	if (strcmp(mod->modname, "bluetooth_plugin_module") == 0) 
	{ 
		logFilePrintf("Entering on_module_start\n", 0);

		// Store function pointer to the original sub_09498
		bluetooth_plugin_module_sub_09498 = (void*)(mod->text_addr + 0x00009498);
		logFilePrintf("bluetooth_plugin_module_sub_09498 = 0x%08lX\n", (u32)bluetooth_plugin_module_sub_09498);

		// Setup a syscall stub in user memory
		if (blockAddress == 0)
		{
			SceUID blockId = sceKernelAllocPartitionMemory(2, "btfree_stub", PSP_SMEM_Low, 2 * sizeof(int), NULL);
			logFilePrintf("blockId = 0x%08lX\n", (u32)blockId);

			blockAddress = (int)sceKernelGetBlockHeadAddr(blockId);
			logFilePrintf("blockAddress = 0x%08lX\n", (u32)blockAddress);

			// Get syscall of the hook function
			int syscall;
			
			// Look if the regular function is resolved, if not use the 6.3x kernel NID
			if ((u32)&sceKernelQuerySystemCall != 0x0000054C) // syscall 0x15 = not linked
				syscall = sceKernelQuerySystemCall(&bluetooth_plugin_module_sub_09498_hook);
			else
				syscall = sceKernelQuerySystemCall63x(&bluetooth_plugin_module_sub_09498_hook);

			logFilePrintf("syscall = 0x%08lX\n", (u32)syscall);

			// Write syscall stub
			_sw(0x03E00008, blockAddress); // jr $ra
			_sw(MAKE_SYSCALL(syscall), blockAddress + sizeof(int)); // syscall
		}

		// Hook the call to the original function in bluetooth_plugin_module
		_sw(MAKE_CALL(blockAddress), mod->text_addr + patchAddresses[0]);


		// Now patch sub_09498 to accept any device class

		// There is a check for the device type that goes something like this:
		//
		// if (((descriptor & 0x000000FF) == 0x00000005) || (...) || (...)))
		//
		// It gets changed to:
		//
		// if (((descriptor & 0x000000FF) != 0x0000FFFF) || (...) || (...)))
		//
		// The result is obviously that the statement always evaluates as true,
		// therefore no devices are rejected early.

		// write "li $t6, 0xFFFF", was "li $t6, 0x5"
		_sw(0x240EFFFF, mod->text_addr + patchAddresses[1]);

		// write "bne $v0, $t6, loc_000094E4", was "beq $v0, $t6, loc_000094E4"
		_sw(0x144E0003, mod->text_addr + patchAddresses[2]);
	} 

	// Call previously set start module handler if necessary
	if (previousStartModuleHandler)
		return previousStartModuleHandler(mod);
	else
		return 0;
} 



int module_start(SceSize args, void* argp)
{
	// Select patch address set for the firmware
	firmware = sceKernelDevkitVersion();

	logFilePrintf("Firmware version 0x%08lX\n", firmware);

	switch (firmware)
	{
		case 0x06020010:
			patchAddresses = patchAddresses_620;
			break;

		case 0x06030110:
		case 0x06030510:
			patchAddresses = patchAddresses_63x;
			break;
	}

	if (patchAddresses)
	{
		// Establish a handler that gets called before any modules "module_start" function is called.
		// A previous handler gets saved.
		previousStartModuleHandler = sctrlHENSetStartModuleHandler(on_module_start);
	}
	else
	{
		// Unsupported firmware
		logFilePrintf("This firmware is not supported.\n", 0);
	}

	return 0;
}





int module_stop(SceSize args, void* argp)
{
	// Restore the previous start module handler if there was one
	if (previousStartModuleHandler)
		sctrlHENSetStartModuleHandler(previousStartModuleHandler);

	return 0;
}

AMazing :shock: !! Music streaming to my PC, to my speakers on all my house , right from the PSP. + Music controls :) Thanks ;)

EDIT: Running 6.20 TN-HEN B :P
PIN: 21479D5F
ruyor
Retired Mod
Posts: 776
Joined: Wed Nov 03, 2010 2:29 am
Location: USA
Contact:

Re: VSH plugin for Bluetooth

Post by ruyor »

thebudds wrote:@ JJS

Maybe you should see if you could take a look at the source for Version 0.6.0003(signature) the newest version allows you to tether your ps3 controller to your psp go.
Um, you don't have a sig yet...

He's talking about this JJS:
viewtopic.php?f=17&t=1530
I tested and it does work for DS3>PSP Go pairing.
PCH-1001 - 3.60 - VHBL+PBubbles+HENkaku
PCH-1001 - 3.60 - VHBL+PBubbles+HENkaku
VTE-1001 - 3.60 - VHBL+PBubbles+HENkaku
My PSPs
01g:TA-079v1
01g:TA-086
02g:TA-085v1
02g:TA-085v2
04g:TA-093
09g:TA-095
05g:TA-091
agatio123
Posts: 95
Joined: Sun Dec 12, 2010 3:46 am

Re: VSH plugin for Bluetooth

Post by agatio123 »

can it be a way to tether a psp to pc in networking?
PSP 1000 - 5.00 M33-6
PSP 2000 - 6.39 ME-5
PSP 3000 - 6.20 PRO b6
PSP GO - 6.20 PRO-b6
JJS
Big Beholder
Posts: 1416
Joined: Mon Sep 27, 2010 2:18 pm
Contact:

Re: VSH plugin for Bluetooth

Post by JJS »

To clarify: All the plugin does is: (1) Enable the PSP to see any visible bluetooth device. If it can be registered or connected to is not influenced at all. (2) Log data about the found devices to "ef0:/btfree_log.txt".
agatio123 wrote:can it be a way to tether a psp to pc in networking?
I would consider this the most desirable feature. But the problem is that the PSP natively only supports the DUN profile and not PAN. I am sure that it would be possible to hack PAN into it, but the effort would be quite big.

ruyor wrote:Um, you don't have a sig yet...

He's talking about this JJS:
Thanks for the clarification. Not sure if such a feature is needed after all if another tool can do it. Maybe an approach would be to modify the file(?) where the bluetooth device settings are stored to just copy in the controller pairing.
thedicemaster
Posts: 214
Joined: Mon Nov 15, 2010 1:35 pm

Re: VSH plugin for Bluetooth

Post by thedicemaster »

ruyor: "signature" is part of the driver's name.
the versions of motioninjoy marked with "signature" are signed, so they work straight away while the older versions require driver signature enforcement to be disabled at boot.

JJS: hm, version 2 ran better.
6.35 pro january 6th nightly, btfree 3 still crashes when entering BT settings.

Code: Select all

Firmware version 0x06030510
Entering on_module_start
bluetooth_plugin_module_sub_09498 = 0x0A56C998
blockId = 0x04DB5577
blockAddress = 0x00000100
syscall = 0x00002674
JJS
Big Beholder
Posts: 1416
Joined: Mon Sep 27, 2010 2:18 pm
Contact:

Re: VSH plugin for Bluetooth

Post by JJS »

thedicemaster wrote:6.35 pro january 6th nightly, btfree 3 still crashes when entering BT settings.
I disabled logging in this version, it should run on 6.35 now. Once the HEN is more mature version 3 should run too.
Attachments
btfree3_no_logging.zip
(1.91 KiB) Downloaded 2481 times
thedicemaster
Posts: 214
Joined: Mon Nov 15, 2010 1:35 pm

Re: VSH plugin for Bluetooth

Post by thedicemaster »

works better.
but my pc doesn't appear as an audio device.
the area under "type" is completely empty.

this could perhaps be related to the bluetooth software installed on the PC, i have bluesoleil 8 which is the only BT software i know that works with my BT receiver and allows BT audio gateway.
VityokWohoo
Posts: 6
Joined: Fri Jan 07, 2011 10:36 pm

Re: VSH plugin for Bluetooth

Post by VityokWohoo »

Is it available to add in menu (when you press triangle) item "sent"? For example I'm in "Music", scrolling my files, choose file, than press triangle and see: "Play", "Copy", "Delete", "Information" and item "Sent" (which will be included in plugin).
Sorry for my English.
Locked

Return to “Programming and Security”