示例#1
0
void _start()
{
	asm(
		"lis %r1, 0x1ab5 ;"
		"ori %r1, %r1, 0xd138 ;"
	);
	unsigned int coreinit_handle;
	OSDynLoad_Acquire("coreinit", &coreinit_handle);
	unsigned int(*MEMGetTotalFreeSizeForExpHeap)(void*expHeap);
	OSDynLoad_FindExport(coreinit_handle, 0, "MEMGetTotalFreeSizeForExpHeap", &MEMGetTotalFreeSizeForExpHeap);
	unsigned char *str;
	void *expHeap = (void*)0;
	float expSize = 0.f;
	/* this area appears semi-safe to search through */
	for(str = (unsigned char*)0x15000000; str < (unsigned char*)0x25000000; str+=4)
	{
		if(*(unsigned int*)str == 0x45585048)
		{
			void *tmpHeap = str;
			float tmpSize = (float)MEMGetTotalFreeSizeForExpHeap(tmpHeap);
			if(tmpSize > expSize)
			{
				expHeap = tmpHeap;
				expSize = tmpSize;
			}
		}
	}
	if(expHeap != (void*)0)
	{
		char buf[64];
		__os_snprintf(buf,64,"Biggest ExpHeap is %08x with %.2fMB left", expHeap, expSize/1024/1024);
		OSFatal(buf);
	}
	OSFatal("No Heaps found!");
}
示例#2
0
void start()
{
    asm("stwu %r1,-0x2000(%r1)");
    unsigned int * start = (unsigned int*)BUFFER_ADDR;
    int i;
  
    for (i = 0; i < 150; start += 1) {
        if (*start == CODE_START) i++;
    }
    
    memcpy((void *)BUFFER_ADDR, (void *)BUFFER_ADDR + 0x800, 0x600);
    
    unsigned int * code_addr = (unsigned int *)(BUFFER_ADDR + 0x2C);
    unsigned int * code_addr_2 = (unsigned int *)(BUFFER_ADDR + 0x44);    
    *code_addr = (int)start;
    *code_addr_2 = (int)start;
    
    asm(
        "lis %r1, 0x1dd7 ;"
        "ori %r1, %r1, 0xb814 ;"
    );
    rop();

     /* Debug printing */
    char msg[255];
    __os_snprintf(msg, 255, "0x%08x 0x%08x", *code_addr, start);
    OSFatal(msg);
}
示例#3
0
void start()
{
    /* Set up a different stack */
    asm("stwu %r1,-0x2000(%r1)");

    /* Remove the OSPanic() callback */
    unsigned int *ospanic_cb = (unsigned int*)OSPANIC_CB;
    ospanic_cb[0] = ospanic_cb[1] = 0;

    /* Copy another version of the ROP buffer over the original */
    unsigned int *ropbuf = (unsigned int*)BUFFER_ADDR;
    memcpy(ropbuf, (void*)BUFFER_ADDR + 0x1000, 0x5c0);

    /* Look for the code buffer (checking the start, middle, and end) */
    unsigned int *codebuf = (unsigned int*)BUFFER_ADDR;
    while (codebuf < (unsigned int*)0x20000000)
    {
        if (*codebuf == CODE_START &&
                codebuf[0x4000/4] == ropbuf[0x190/4] &&
                codebuf[0x7FFC/4] == ropbuf[0x194/4]) break;
        codebuf++;
    }
    if (codebuf == 0x20000000) OSFatal("Code not found");

    /* Modify the ROP buffer to copy the code spray into the JIT */
    ropbuf[0x318/4] = &ropbuf[0xa0/4];
    ropbuf[0xdc/4] = codebuf + 1;
    ropbuf[0xe0/4] = 0x8000;

    /* Perform ROP again */
    rop(BUFFER_ADDR + 0x30c);
}
示例#4
0
/* Start of our code */
void _start()
{
  /* Load a good stack */
  asm(
      "lis %r1, 0x1ab5 ;"
      "ori %r1, %r1, 0xd138 ;"
  );
 
  /* Get a handle to coreinit.rpl */
  unsigned int coreinit_handle;
  OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);

  /* OS memory allocation functions */
  void* (*OSAllocFromSystem)(uint32_t size, int align);

  /* OS thread functions */
  bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint16_t attr);
  int32_t (*OSResumeThread)(void *thread);

  /* Exit function */
  void (*_Exit)();

  /* Read the addresses of the functions */
  OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
  OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
  OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
  OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);

  /* Create a string argument */
  char *str = OSAllocFromSystem(6, 1);
  str[0] = 'H';
  str[1] = 'e';
  str[2] = 'l';
  str[3] = 'l';
  str[4] = 'o';
  str[5] = 0;

  /* Allocate a stack for the thread */
  uint32_t stack = (uint32_t) OSAllocFromSystem(0x1000, 0x10);
  stack += 0x1000;

  /* Create the thread */
  void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8);
  bool ret = OSCreateThread(thread, OSFatal, (int)str, null, stack, 0x1000, 0, 1);
  if (ret == false)
  {
	  OSFatal("Failed to create thread");
  }

  /* Schedule it for execution */
  OSResumeThread(thread);

  /* Infinite loop */
  while(1);
}
示例#5
0
文件: loader.c 项目: dibas/smashd
void _start() 
{
    /* Load a good stack */
    asm(
        "lis %r1, 0x1ab5 ;"
        "ori %r1, %r1, 0xd138 ;"
    );

	/* Get a handle to coreinit.rpl */
	uint32_t coreinit_h;
	OSDynLoad_Acquire("coreinit.rpl", &coreinit_h);

	/* Memory allocation and FS functions */
	void* (*OSAllocFromSystem)(uint32_t size, int align);
	int (*FSInit)();
	int (*FSAddClient)(void *client, int unk1);
	int (*FSInitCmdBlock)(void *cmd);
	int (*FSOpenDir)(void *client, void *cmd, char *path, uint32_t *dir_handle, int unk1);
	int (*FSReadDir)(void *client, void *cmd, uint32_t dir_handle, void *buffer, int unk1);
	
	int (*FSGetMountSource)(void *client, void *cmd, int type, mount_source *source, int unk1);
	int (*FSMount)(void *client, void *cmd, mount_source *source, char *mountpath, uint32_t pathlength, int unk1);
	int (*FSOpenFile)(void *client, void *cmd, char *filepath, char *amode, uint32_t *file_handle, int unk1);
	int (*FSReadFile)(void *client, void *cmd, void *buffer, uint32_t size, uint32_t length, uint32_t file_handle, int unk1, int unk2);

	OSDynLoad_FindExport(coreinit_h, 0, "OSAllocFromSystem", &OSAllocFromSystem);
	OSDynLoad_FindExport(coreinit_h, 0, "FSInit", &FSInit);
	OSDynLoad_FindExport(coreinit_h, 0, "FSAddClient", &FSAddClient);
	OSDynLoad_FindExport(coreinit_h, 0, "FSInitCmdBlock", &FSInitCmdBlock);
	OSDynLoad_FindExport(coreinit_h, 0, "FSOpenDir", &FSOpenDir);
	OSDynLoad_FindExport(coreinit_h, 0, "FSReadDir", &FSReadDir);

	OSDynLoad_FindExport(coreinit_h, 0, "FSGetMountSource", &FSGetMountSource);
	OSDynLoad_FindExport(coreinit_h, 0, "FSMount", &FSMount);
	OSDynLoad_FindExport(coreinit_h, 0, "FSOpenFile", &FSOpenFile);
	OSDynLoad_FindExport(coreinit_h, 0, "FSReadFile", &FSReadFile);

	FSInit();

	/* Set up the client and command blocks */
	void *client = OSAllocFromSystem(0x1700, 0x20);
	void *cmd = OSAllocFromSystem(0xA80, 0x20);
	if (!(client && cmd)) OSFatal("Failed to allocate client and command block");

	FSAddClient(client, 0);
	FSInitCmdBlock(cmd);

	// todo: check permissions and throw exception if no mounting permissions available

	// OSLockMutex - Probably not. It's a single thread, nothing else can access this, Cross-F does this here
	mount_source m_source; // allocate mount source

	int ms_result = FSGetMountSource(client, cmd, 0, &m_source, 0); // type 0 = external device

	if(ms_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSGetMountSource returned error code %d", ms_result);
		OSFatal(buf);
	}

	char mountPath[128]; // usually /vol/external01
	int m_result = FSMount(client, cmd, &m_source, mountPath, sizeof(mountPath), -1); 

	if(m_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSMount returned error code %d", m_result);
		OSFatal(buf);
	}
	// OSUnlockMutex

	char defaultMountPath[] = "/vol/external01";

	if(!strcmp(mountPath, defaultMountPath)) {
		char buf[256];
		__os_snprintf(buf, 256, "FSMount returned nonstandard mount path: %s", mountPath);
		OSFatal(buf);
	}

	uint32_t file_handle;
	int open_result = FSOpenFile(client, cmd, "/vol/external01/SMASHD.txt", "r", &file_handle, 0);

	if(open_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSOpenFile returned error code %d", open_result);
		OSFatal(buf);
	}

	uint32_t *file_buffer = OSAllocFromSystem(0x200, 0x20);
	int read_result = FSReadFile(client, cmd, file_buffer, 1, 25, file_handle, 0, -1); // todo: is size correct? one char one byte; read whole file, not just a few bytes

	if(read_result != 0) {
		char buf[256];
		__os_snprintf(buf, 256, "FSReadFile returned error code %d", read_result);
		OSFatal(buf);
	}

	char *message = (char*)&file_buffer[25];
	OSFatal(message);
}
示例#6
0
void _start()
{
  /* Load a good stack */
  asm(
      "lis %r1, 0x1ab5 ;"
      "ori %r1, %r1, 0xd138 ;"
  );
 
  /* Get a handle to coreinit.rpl, dmae.rpl, and nsysnet.rpl */
  unsigned int coreinit_handle, dmae_handle, nsysnet_handle;
  OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
  OSDynLoad_Acquire("dmae.rpl", &dmae_handle);
  OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle);

  /* Cache, DMA, and socket functions */
  void (*DCFlushRange)(void *addr, unsigned int length);
  void (*DCInvalidateRange)(void *addr, unsigned int length);
  unsigned long long (*DMAECopyMem)(void *dst, void *src, unsigned int nwords, int endian);
  int (*DMAEWaitDone)(unsigned long long ret);
  int (*socket)(int family, int type, int proto);
  int (*connect)(int fd, struct sockaddr *addr, int addrlen);
  int (*send)(int fd, const void *buffer, int len, int flags);

  /* Read the addresses of the functions */
  OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
  OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange);
  OSDynLoad_FindExport(dmae_handle, 0, "DMAECopyMem", &DMAECopyMem);
  OSDynLoad_FindExport(dmae_handle, 0, "DMAEWaitDone", &DMAEWaitDone);
  OSDynLoad_FindExport(nsysnet_handle, 0, "socket", &socket);
  OSDynLoad_FindExport(nsysnet_handle, 0, "connect", &connect);
  OSDynLoad_FindExport(nsysnet_handle, 0, "send", &send);

  /* Set up our socket address structure */
  struct sockaddr sin;
  sin.sin_family = AF_INET;
  sin.sin_port = 12345;
  sin.sin_addr.s_addr = PC_IP;
  int i;
  for (i = 0; i < 8; i++)
  {
    sin.sin_zero[i] = 0;
  }

  /* Connect to the PC */
  int pc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  int status = connect(pc, &sin, 0x10);
  if (status) OSFatal("Error connecting to PC server");

  /* Cache stuff */
  DCFlushRange(0x01000000, 0x20);
  DCInvalidateRange(0x1dd7b820, 0x20);

  /* Do the copy */
  int success = DMAEWaitDone(DMAECopyMem(0x1dd7b820, 0x01000000, 2, 0));
  if (success)
  {
	  send(pc, "Success", 8, 0);
  }
  else
  {
	  send(pc, "Fail", 5, 0);
  }
  while(1);
}
示例#7
0
void _start()
{
	/* Get a handle to coreinit.rpl */
	unsigned int coreinit_handle;
	OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
	//OS memory functions
	void* (*memcpy)(void *dest, void *src, uint32_t length);
	void* (*memset)(void * dest, uint32_t value, uint32_t bytes);
	void* (*OSAllocFromSystem)(uint32_t size, int align);
	void (*OSFreeToSystem)(void *ptr);
	OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &memcpy);
	OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem);
	
	void (*OSCoherencyBarrier)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSCoherencyBarrier", &OSCoherencyBarrier);
	
	void (*_Exit)();
	OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
	
	//DC memory functions
	void (*DCFlushRangeNoSync)(void *buffer, uint32_t length);
	void (*DCInvalidateRange)(void *buffer, uint32_t length);
  	OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRangeNoSync", &DCFlushRangeNoSync);
	OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange);
	
	//LC memory functions
	void* (*LCAlloc)( uint32_t bytes );
	void (*LCDealloc)();
	uint32_t (*LCHardwareIsAvailable)();
	uint32_t (*LCIsDMAEnabled)();
	void (*LCEnableDMA)();
	void (*LCDisableDMA)();
	void (*LCLoadDMABlocks)(void* lc_addr, void* src_addr, uint32_t blocks);
	void (*LCStoreDMABlocks)(void* dest_addr, void* lc_addr, uint32_t blocks);
	void (*LCWaitDMAQueue)( uint32_t length );
	OSDynLoad_FindExport(coreinit_handle, 0, "LCAlloc", &LCAlloc);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCDealloc", &LCDealloc);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCHardwareIsAvailable", &LCHardwareIsAvailable);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCIsDMAEnabled", &LCIsDMAEnabled);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCEnableDMA", &LCEnableDMA);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCDisableDMA", &LCDisableDMA);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCLoadDMABlocks", &LCLoadDMABlocks);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCStoreDMABlocks", &LCStoreDMABlocks);
	OSDynLoad_FindExport(coreinit_handle, 0, "LCWaitDMAQueue", &LCWaitDMAQueue);
		
	//Used for keeping track of vairables to print to screen
	char output[1000];
	
	//Alloc 64 byte alligned space
	void* src_addr=OSAllocFromSystem(512,64);
	void* dest_addr=OSAllocFromSystem(512,64);
	
	//Store some debug values
	__os_snprintf(output, 1000, "src_addr:%02x,",(uint32_t)src_addr);
	__os_snprintf(output+strlen(output), 255, "dest_addr: %02x,", (uint32_t)dest_addr);
	
	//Number of 32bit blocks to copy. Must be multiple of 2 between [0,127]
	uint32_t blocks=2; //2 32bit blocks
	
	//Do something to the source
	memset(src_addr,1,64);
	
	//Grab values for debug
	uint32_t * src_val=src_addr;
	uint32_t * dest_val=dest_addr;
	__os_snprintf(output+strlen(output), 255, "Old src_val: %02x\n",src_val[0]);
	__os_snprintf(output+strlen(output), 255, "Old dest_val: %02x,",dest_val[0]);
	
	//Get some locked cache address space
	void *lc_addr=LCAlloc(512); //512 Minmum. Must be multiple of 512.
	
	//Calculate size from blocks to flush/invalidate range properly
	uint32_t size;
	//If blocks is set to 0, the transaction will default to 128 blocks
	if(blocks==0)
	{
		size=32*128;
	}
	else
	{
		size=32*blocks;
	}
	//Flush the range at the source to ensure cache gets written back to memory.
	DCFlushRangeNoSync(src_addr,size);
	//Invalidate the range at the destination
	DCInvalidateRange(dest_addr,size);
	//Sync
	OSCoherencyBarrier();
	
	//Check to see of DMA hardware is avaliable
	if(LCHardwareIsAvailable()!=1)
	{
		OSFatal("Hardware is not avaliable.");
	}

	//Gets the current state of DMA, so we can restore it after our copy
	uint32_t dmaState=LCIsDMAEnabled();

	//Checks to see if DMA is enabled, if not it will try to enable it.
	if(dmaState!=1)
	{
		LCEnableDMA();
		dmaState=LCIsDMAEnabled();
		if(dmaState!=1)
		{
			OSFatal("Can't enable DMA");
		}
	}
	
	//Load memory to locked cache
	LCLoadDMABlocks(lc_addr,src_addr,blocks);
	LCWaitDMAQueue(0);
	
	//Store memory from locked cache
	LCStoreDMABlocks(dest_addr,lc_addr,blocks);
	LCWaitDMAQueue(0);

	//If DMA was not previously enabled, then disable it to restore state.
	if(dmaState!=1)
	{
		LCDisableDMA();
		dmaState=LCIsDMAEnabled();
		//If DMA failed to disable, return error code
		if(dmaState!=1)
		{
			OSFatal("Couldn't Disable DMA");
		}
	}
	__os_snprintf(output+strlen(output), 255, "New src_val: %02x,",src_val[0]);
	__os_snprintf(output+strlen(output), 255, "New dest_val: %02x,",dest_val[0]);
	
	//Cleanup
	LCDealloc(lc_addr);
	OSFreeToSystem(dest_addr);
	OSFreeToSystem(src_addr);
    OSFatal(output);
}
示例#8
0
文件: main.c 项目: Relys/wut
int main(int argc, char **argv)
{
	OSFatal("my first rpx");
	return 0;
}
示例#9
0
extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
    if(gAppStatus == 2) {
        //"No, we don't want to patch stuff again.");
        return EXIT_RELAUNCH_ON_LOAD;
    }

    InitOSFunctionPointers();
    InitSocketFunctionPointers(); //For logging
    InitSysFunctionPointers();
    InitFSFunctionPointers();
    InitGX2FunctionPointers();
    InitSysFunctionPointers();
    InitVPadFunctionPointers();
    InitPadScoreFunctionPointers();
    InitAXFunctionPointers();
    InitProcUIFunctionPointers();

    log_init();

    DEBUG_FUNCTION_LINE("We have %d kb for plugins.\n",(PLUGIN_LOCATION_END_ADDRESS-getApplicationEndAddr())/1024);
    //setup_os_exceptions();

    DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION);
    DEBUG_FUNCTION_LINE("Sizeof dyn_linking_relocation_data_t %d\n",sizeof(dyn_linking_relocation_data_t));
    Init();

    init_kernel_syscalls();
    wups_init_kernel_syscalls();

    gGameTitleID = OSGetTitleID();

    int32_t result = 0;

    //Reset everything when were going back to the Mii Maker
    if(isInMiiMakerHBL()) {
        CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
        // Restore patches as the patched functions could change.
        RestorePatches();

        DynamicLinkingHelper::getInstance()->clearAll();

        //PluginLoader * pluginLoader  = PluginLoader::getInstance();
        //std::vector<PluginInformation *> pluginList = pluginLoader->getPluginInformation("sd:/wiiu/plugins/");
        //pluginLoader->loadAndLinkPlugins(pluginList);
        //pluginLoader->clearPluginInformation(pluginList);

        //!*******************************************************************
        //!                    Initialize heap memory                        *
        //!*******************************************************************
        DEBUG_FUNCTION_LINE("Initialize memory management\n");
        memoryInitialize();

        DEBUG_FUNCTION_LINE("Start main application\n");
        result = Application::instance()->exec();
        DEBUG_FUNCTION_LINE("Main application stopped result: %d\n",result);

        DEBUG_FUNCTION_LINE("Application::destroyInstance\n");
        Application::destroyInstance();

        DEBUG_FUNCTION_LINE("Release memory\n");
        memoryRelease();
        CSettings::destroyInstance();
        PluginLoader::destroyInstance();
    }

    if(result == APPLICATION_CLOSE_APPLY_MEMORY) {
        if(!MemoryMapping::isMemoryMapped()) {
            MemoryMapping::setupMemoryMapping();
        }
    }

    DEBUG_FUNCTION_LINE("Do relocations\n");

    std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
    DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size());

    if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)) {
        OSFatal("fillRelocations failed.");
    }

    if(!isInMiiMakerHBL()) {
        DEBUG_FUNCTION_LINE("Apply patches.\n");
        ApplyPatchesAndCallHookStartingApp();
        ConfigUtils::loadConfigFromSD();

        if(MemoryMapping::isMemoryMapped()) {
            DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
            readAndPrintSegmentRegister(NULL,NULL);
            MemoryMapping::readTestValuesFromMemory();
        } else {
            DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
            DEBUG_FUNCTION_LINE("<---------------- COPY PASTE ME START-----------------> \n");
            DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
            DEBUG_FUNCTION_LINE("Mapping was't done. Running %016llX\n",gGameTitleID);
            readAndPrintSegmentRegister(NULL,NULL);
            DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
            DEBUG_FUNCTION_LINE("<----------------- COPY PASTE ME END -----------------> \n");
            DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n");
        }
        return EXIT_RELAUNCH_ON_LOAD;
    }

    if(result == APPLICATION_CLOSE_APPLY || result == APPLICATION_CLOSE_APPLY_MEMORY) {
        CallHook(WUPS_LOADER_HOOK_INIT_KERNEL);
        CallHook(WUPS_LOADER_HOOK_INIT_FS);
        CallHook(WUPS_LOADER_HOOK_INIT_OVERLAY);
        CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN);
        DEBUG_FUNCTION_LINE("Loading the system menu.\n");
        DeInit();
        SYSLaunchMenu();
        return EXIT_RELAUNCH_ON_LOAD;
    }

    DEBUG_FUNCTION_LINE("Let's go to back to the Homebrew Launcher\n");
    DEBUG_FUNCTION_LINE("Restoring the patched functions\n");
    RestorePatches();
    DEBUG_FUNCTION_LINE("Calling the plugin deinit hook\n");
    CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN);
    DEBUG_FUNCTION_LINE("Unmounting SD/USB devices\n");
    DeInit();
    DEBUG_FUNCTION_LINE("Bye bye!\n");
    return EXIT_SUCCESS;
}
示例#10
0
/* Install an exception handler */
int _start(int argc, char **argv)
{
	/* Get a handle to coreinit.rpl and nsysnet.rpl */
	unsigned int coreinit_handle, nsysnet_handle;
	OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
	OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle);

	/* Memory and cache functions */
	unsigned int (*OSEffectiveToPhysical)(void *ptr);
	void (*DCFlushRange)(void *addr, unsigned int len);
	void (*DCInvalidateRange)(void *addr, unsigned int len);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &OSEffectiveToPhysical);
	OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange);
	OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange);

	/* Kernel is mapped */
	if (OSEffectiveToPhysical((void*)0xA0000000) == 0xC0000000)
	{
		/* Patches installed */
		if (*((unsigned int*)(0xA0000000 + (0xFFF00B40 - 0xC0000000))) == 1)
		{
			/* Socket functions */
			int (*socket_lib_init)();
			int (*get_socket_rm_fd)();
			int (*socket)(int family, int type, int proto);
			int (*connect)(int fd, struct sockaddr *addr, int addrlen);
			OSDynLoad_FindExport(nsysnet_handle, 0, "socket_lib_init", &socket_lib_init);
			OSDynLoad_FindExport(nsysnet_handle, 0, "get_socket_rm_fd", &get_socket_rm_fd);
			OSDynLoad_FindExport(nsysnet_handle, 0, "socket", &socket);
			OSDynLoad_FindExport(nsysnet_handle, 0, "connect", &connect);

			/* Init the sockets library */
			socket_lib_init();

			/* Set up our socket address structure */
			struct sockaddr sin;
			sin.sin_family = AF_INET;
			sin.sin_port = 12345;
			sin.sin_addr.s_addr = PC_IP;
			int i;
			for (i = 0; i < 8; i++)
			{
				sin.sin_zero[i] = 0;
			}

			/* Connect to the PC */
			int pc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
			int status = connect(pc, &sin, 0x10);
			if (status) OSFatal("Error connecting to PC");

			/* Store the socket info in a place the kernel can access */
			unsigned int sock_info[4] = {1, (unsigned int)get_socket_rm_fd(), (unsigned int)pc, 0};
			memcpy((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), sock_info, 0x10);
			DCFlushRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20);
			DCInvalidateRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20);
		}
		/* Patches not yet installed, but they will be next time */
		else
		{
			/* Signify patches installed, socket data still invalid, spinlock 0 */
			*((unsigned int*)(0xA0000000 + (0xFFF00B40 - 0xC0000000))) = 1;
			*((unsigned int*)(0xA0000000 + (0xFFF00B44 - 0xC0000000))) = -1;
			*((unsigned int*)(0xA0000000 + (0xFFF00B48 - 0xC0000000))) = -1;
			*((unsigned int*)(0xA0000000 + (0xFFF00B4C - 0xC0000000))) = 0;
			DCFlushRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20);
			DCInvalidateRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20);
		}
	}

	/* Return to main() */
#if VER == 532
	int (*main)(int argc, char **argv) = (int (*)(int,char**)) (*((unsigned int*)0x1005D180));
#elif VER == 550
	int (*main)(int argc, char **argv) = (int (*)(int,char**)) (*((unsigned int*)0x1005E040));
#else
	int (*main)(int argc, char **argv) = (int (*)(int,char**)) (*((unsigned int*)0x0));
#endif
	return main(argc, argv);
}
示例#11
0
/* Callback for UHS event wait */
static void uhs_event_cb(int status, void *context)
{
	OSFatal("Event");
}
示例#12
0
void InitOSFunctionPointers(void)
{
    unsigned int *funcPointer = 0;
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //! Lib handle functions
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (int (*)(const char*, unsigned *))OS_SPECIFICS->addr_OSDynLoad_Acquire);
    EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport);

    OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);

    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //! System functions
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    OS_FIND_EXPORT(coreinit_handle, OSFatal);
    OS_FIND_EXPORT(coreinit_handle, OSGetTitleID);
    OS_FIND_EXPORT(coreinit_handle, OSSetExceptionCallback);
    OS_FIND_EXPORT(coreinit_handle, DCFlushRange);
    OS_FIND_EXPORT(coreinit_handle, ICInvalidateRange);
    OS_FIND_EXPORT(coreinit_handle, OSEffectiveToPhysical);
    OS_FIND_EXPORT(coreinit_handle, __os_snprintf);
    OS_FIND_EXPORT(coreinit_handle, __gh_errno_ptr);
    OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &__Exit);
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //! Thread functions
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    OS_FIND_EXPORT(coreinit_handle, OSCreateThread);
    OS_FIND_EXPORT(coreinit_handle, OSResumeThread);
    OS_FIND_EXPORT(coreinit_handle, OSSuspendThread);
    OS_FIND_EXPORT(coreinit_handle, OSIsThreadTerminated);
    OS_FIND_EXPORT(coreinit_handle, OSIsThreadSuspended);
    OS_FIND_EXPORT(coreinit_handle, OSJoinThread);
    OS_FIND_EXPORT(coreinit_handle, OSSetThreadPriority);
    OS_FIND_EXPORT(coreinit_handle, OSDetachThread);
    OS_FIND_EXPORT(coreinit_handle, OSSleepTicks);
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //! Mutex functions
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    OS_FIND_EXPORT(coreinit_handle, OSInitMutex);
    OS_FIND_EXPORT(coreinit_handle, OSLockMutex);
    OS_FIND_EXPORT(coreinit_handle, OSUnlockMutex);
    OS_FIND_EXPORT(coreinit_handle, OSTryLockMutex);

    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //! Memory functions
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx);
    OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeap", &pMEMAllocFromDefaultHeap);
    OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap);

    OS_FIND_EXPORT(coreinit_handle, MEMGetBaseHeapHandle);
    OS_FIND_EXPORT(coreinit_handle, MEMGetAllocatableSizeForFrmHeapEx);
    OS_FIND_EXPORT(coreinit_handle, MEMAllocFromFrmHeapEx);
    OS_FIND_EXPORT(coreinit_handle, MEMFreeToFrmHeap);
    OS_FIND_EXPORT(coreinit_handle, MEMAllocFromExpHeapEx);
    OS_FIND_EXPORT(coreinit_handle, MEMCreateExpHeapEx);
    OS_FIND_EXPORT(coreinit_handle, MEMDestroyExpHeap);
    OS_FIND_EXPORT(coreinit_handle, MEMFreeToExpHeap);

    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    //! Special non library functions
    //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    if(OS_FIRMWARE == 550)
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x01010180);
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0101006C);
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x0100080C);
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF184E4);
    }
    else if(OS_FIRMWARE == 532 || OS_FIRMWARE == 540)
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100FFA4);                // loader.elf
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100FE90);  // loader.elf
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007EC);              // loader.elf
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF18558);           // kernel.elf

        EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19D00);           // loader.elf
        EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13C3C);         // loader.elf
    }
    else if(OS_FIRMWARE == 500 || OS_FIRMWARE == 510)
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100FBC4);
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100FAB0);
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007EC);
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF18534);

        EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19D00);
        EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13C3C);
    }
    else if(OS_FIRMWARE == 410)
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100F78C);
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100F678);
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007F8);
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF166DC);

        EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19CC0);
        EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13BFC);
    }
    else if(OS_FIRMWARE == 400) // same for 4.0.2 and 4.0.3
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100F78C);
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100F678);
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007F8);
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15E70);

        EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19CC0);
        EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13BFC);
    }
    else if(OS_FIRMWARE == 310)
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100C4E4);
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100C3D4);
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010004D8);
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15A0C);

        EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19340);
        EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE1329C);
    }
    else if(OS_FIRMWARE == 300 || OS_FIRMWARE == 301)
    {
        EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100C4E4);
        EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100C3D4);
        EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010004D8);
        EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15974);

        EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19340);
        EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE1329C);
    }
    else
    {
        OSFatal("Missing all OS specific addresses.");
    }
}
示例#13
0
void _start()
{
	asm(
		"lis %r1, 0x1ab5 ;"
		"ori %r1, %r1, 0xd138 ;"
	);
	unsigned int coreinit_handle, gx2_handle;
	OSDynLoad_Acquire("coreinit", &coreinit_handle);
	OSDynLoad_Acquire("gx2", &gx2_handle);
	//OS Memory functions
	void*(*memset)(void * dest, unsigned int value, unsigned int bytes);
	void*(*OSAllocFromSystem)(unsigned int size, int align);
	void(*OSFreeToSystem)(void *ptr);
	//IM functions
	int(*IM_Open)();
	int(*IM_Close)(int fd);
	int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b);

	//OS Memory functions
	OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem);
	//IM functions
	OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open);
	OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close);
	OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState);
	//Restart system to get lib access
	int fd = IM_Open();
	void *mem = OSAllocFromSystem(0x100, 64);
	memset(mem, 0, 0x100);
	//set restart flag to force quit browser
	IM_SetDeviceState(fd, mem, 3, 0, 0); 
	IM_Close(fd);
	OSFreeToSystem(mem);
	//wait a bit for browser end
	unsigned int t1 = 0x1FFFFFFF;
	while(t1--) ;

	/* Get the framebuffer of the TV or DRC */
	void(*GX2SwapScanBuffers)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers);
	unsigned char *abuseFunc = (unsigned char*)GX2SwapScanBuffers;
	unsigned short f_hi = *(unsigned short*)(abuseFunc+0x12);
	unsigned short f_lo = *(unsigned short*)(abuseFunc+0x16);
	unsigned int gx2settingBase = (((f_lo & 0x8000) ? (f_hi-1) : f_hi) << 16) | f_lo;
	unsigned int args[2];
	args[0] = *((unsigned int*)(gx2settingBase + 0x304));
	args[1] = *((unsigned int*)(gx2settingBase + 0x304 + 0x20));
	int(*OSGetCoreId)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId);
	void(*OSTestThreadCancel)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSTestThreadCancel", &OSTestThreadCancel);
	void(*GX2Shutdown)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown);
	int(*GX2GetMainCoreId)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId);

	/* Prepare for our own death */
	void*(*OSGetCurrentThread)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCurrentThread", &OSGetCurrentThread);
	void *myBorkedThread = OSGetCurrentThread();
	int (*OSSuspendThread)(void *thread);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSSuspendThread", &OSSuspendThread);

	/* Prepare for thread startups */
	int (*OSCreateThread)(void *thread, void *entry, int argc, void *args, unsigned int stack, unsigned int stack_size, int priority, unsigned short attr);
	int (*OSResumeThread)(void *thread);
	int (*OSIsThreadTerminated)(void *thread);

	OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread);
	OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated);

	/* Allocate a stack for the thread */
	unsigned int stack = (unsigned int) OSAllocFromSystem(0x1000, 0x10);
	stack += 0x1000;
	/* Create the thread */
	void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8);
	
	if(OSGetCoreId() != GX2GetMainCoreId()) //needed for access without crashing
	{
		int ret = OSCreateThread(thread, GX2Shutdown, 0, (void*)0, stack, 0x1000, 0, 0x10 | (1<<GX2GetMainCoreId()));
		if (ret == 0)
			OSFatal("Failed to create thread");
		/* Schedule it for execution */
		OSResumeThread(thread);
		while(OSIsThreadTerminated(thread) == 0) ;
	}
	else //same core, easy
		GX2Shutdown();

	//current thread is broken, switch to a working one in core 1
	int ret = OSCreateThread(thread, myGXthread, 2, args, stack, 0x1000, 0, 0xA);
	if (ret == 0)
		OSFatal("Failed to create thread");

	/* Schedule it for execution */
	OSResumeThread(thread);
	/* SO UGLY but it works magically */
	while(1) ;
	//would be better but again, crashes 5.3.2
	//OSSuspendThread(myBorkedThread);
	//OSFatal("I am still not dead!");
}
示例#14
0
void myGXthread(int argc, int *argv)
{
	if(argc != 2) OSFatal("GX Thread did not start proper!");
	unsigned int *tv_fb = (unsigned int*)argv[0];
	unsigned int *drc_fb = (unsigned int*)argv[1];
	unsigned int coreinit_handle, gx2_handle;
	OSDynLoad_Acquire("coreinit", &coreinit_handle);
	OSDynLoad_Acquire("gx2", &gx2_handle);

	void(*GX2Init)(void *args);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Init", &GX2Init);
	GX2Init((void*)0);

	int(*OSGetCoreId)();
	OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId);
	void(*GX2SwapScanBuffers)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers);
	void(*GX2Shutdown)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown);
	int(*GX2GetMainCoreId)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId);
	if(OSGetCoreId() != GX2GetMainCoreId()) OSFatal("GX Not switched!");

	void(*GX2DrawDone)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2DrawDone", &GX2DrawDone);
	void(*GX2Flush)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Flush", &GX2Flush);
	//void(*GX2SwapScanBuffers)();
	//OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers);
	void(*GX2WaitForVsync)();
	OSDynLoad_FindExport(gx2_handle, 0, "GX2WaitForVsync", &GX2WaitForVsync);
	//Make sure buffer is usable for GX
	void(*GX2Invalidate)(unsigned int flags,void *buffer,unsigned int size);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2Invalidate", &GX2Invalidate);
	GX2Invalidate(0x40,tv_fb,(1280*720*4)*2);
	GX2Invalidate(0x40,drc_fb,(854*480*4)*2);
	//set it!
	int(*GX2SetTVBuffer)(void *buffer,unsigned int size,unsigned int flag1,unsigned int flag2,unsigned int flag3);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SetTVBuffer", &GX2SetTVBuffer);
	int(*GX2SetDRCBuffer)(void *buffer,unsigned int size,unsigned int flag1,unsigned int flag2,unsigned int flag3);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SetDRCBuffer", &GX2SetDRCBuffer);
	GX2SetTVBuffer(tv_fb,(1280*720*4)*2,3,0x1A,2); //test gradient demo setup for show
	GX2SetDRCBuffer(drc_fb,(854*480*4)*2,1,0x1A,2); //will look broken, no color buffer setup yet
	/* Draw is far from complete */
	/*void(*GX2DrawEx)(int type, int count, int start, int instances);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2DrawEx", &GX2DrawEx);
	void(*GX2SetAttribBuffer)(int index, int size, int vtxStride, void *buf);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SetAttribBuffer", &GX2SetAttribBuffer);
	float myclearer[8] =
	{
		0.0f,  0.0f,
		1.0f,  0.0f,
		0.0f,  1.0f,
		1.0f,  1.0f
	};
	GX2Invalidate(0x40, myclearer, sizeof(myclearer));*/

	GX2ColorBuffer myCBuf;
	setupColorBuffer(&myCBuf, gx2_handle);

	void(*GX2ClearColor)(GX2ColorBuffer *buffer, float r, float g, float b, float a);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2ClearColor", &GX2ClearColor);

	void(*GX2SwapBuffers)(GX2ColorBuffer *buffer);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapBuffers", &GX2SwapBuffers);

	void(*GX2CopyColorBufferToScanBuffer)(GX2ColorBuffer *buffer, unsigned int target);
	OSDynLoad_FindExport(gx2_handle, 0, "GX2CopyColorBufferToScanBuffer", &GX2CopyColorBufferToScanBuffer);

	float val = 1;
	float valInc = -0.005;
	val += valInc;
	while(val < 1)
	{
		val += valInc;
		//GX2SetAttribBuffer(0,sizeof(mybuf),8,mybuf);
		//GX2DrawEx(6,4,0,1);
		GX2ClearColor(&myCBuf, val, val, val, 1);
		GX2Invalidate(0x40, myCBuf.surface.imagePtr,myCBuf.surface.imageSize);
		GX2DrawDone();
		GX2Flush();
		GX2CopyColorBufferToScanBuffer(&myCBuf,1);
		GX2SwapScanBuffers();
		GX2Flush();
		GX2WaitForVsync();
		if(val <= 0) valInc = 0.005;
	}
	//clear for browser (needed?)
	GX2Shutdown();

	void(*_Exit)();
	OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit);
	_Exit();
}