예제 #1
0
s32 sys_prx_load_module(vm::ptr<const char> path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
{
	sys_prx.Todo("sys_prx_load_module(path=\"%s\", flags=0x%llx, pOpt=0x%x)", path.get_ptr(), flags, pOpt.addr());

	std::string _path = path.get_ptr();
	// Check if the file is SPRX
	std::string local_path;
	Emu.GetVFS().GetDevice(_path, local_path);
	if (IsSelf(local_path)) {
		if (!DecryptSelf(local_path+".prx", local_path)) {
			return CELL_PRX_ERROR_ILLEGAL_LIBRARY;
		}
		_path += ".prx";
	}

	vfsFile f(_path);
	if (!f.IsOpened()) {
		return CELL_PRX_ERROR_UNKNOWN_MODULE;
	}

	// Create the PRX object and return its id
	sys_prx_t* prx = new sys_prx_t();
	prx->size = (u32)f.GetSize();
	prx->address = (u32)Memory.Alloc(prx->size, 4);
	prx->path = (const char*)path;
	
	// Load the PRX into memory
	f.Read(vm::get_ptr(prx->address), prx->size);

	u32 id = sys_prx.GetNewId(prx, TYPE_PRX);
	return id;
}
예제 #2
0
void MainFrame::DecryptSPRXLibraries(wxCommandEvent& WXUNUSED(event))
{
	wxFileDialog ctrl(this, L"Select SPRX files", wxEmptyString, wxEmptyString,
		"SPRX files (*.sprx)|*sprx",
		wxFD_OPEN | wxFD_MULTIPLE);

	if (ctrl.ShowModal() == wxID_CANCEL)
	{
		return;
	}

	wxArrayString modules;
	ctrl.GetPaths(modules);

	LOG_NOTICE(GENERAL, "Decrypting SPRX libraries...");

	for (const wxString& module : modules)
	{
		std::string prx_path = fmt::ToUTF8(module);
		const std::string& prx_dir = fs::get_parent_dir(prx_path);

		if (IsSelf(prx_path))
		{
			const std::size_t prx_ext_pos = prx_path.find_last_of('.');
			const std::string& prx_ext = fmt::to_upper(prx_path.substr(prx_ext_pos != -1 ? prx_ext_pos : prx_path.size()));
			const std::string& prx_name = prx_path.substr(prx_dir.size());

			prx_path.erase(prx_path.size() - 4, 1); // change *.sprx to *.prx

			if (DecryptSelf(prx_path, prx_dir + prx_name))
			{
				LOG_SUCCESS(GENERAL, "Decrypted %s", prx_dir + prx_name);
			}

			else
			{
				LOG_ERROR(GENERAL, "Failed to decrypt %s", prx_dir + prx_name);
			}
		}
	}

	LOG_NOTICE(GENERAL, "Finished decrypting all SPRX libraries.");
}
예제 #3
0
파일: System.cpp 프로젝트: 4iDragon/rpcs3
void Emulator::Load()
{
	Stop();

	try
	{
		Init();

		if (!fs::is_file(m_path))
		{
			LOG_ERROR(LOADER, "File not found: %s", m_path);
			return;
		}

		const std::string& elf_dir = fs::get_parent_dir(m_path);

		if (IsSelf(m_path))
		{
			const std::size_t elf_ext_pos = m_path.find_last_of('.');
			const std::string& elf_ext = fmt::to_upper(m_path.substr(elf_ext_pos != -1 ? elf_ext_pos : m_path.size()));
			const std::string& elf_name = m_path.substr(elf_dir.size());

			if (elf_name.compare(elf_name.find_last_of("/\\", -1, 2) + 1, 9, "EBOOT.BIN", 9) == 0)
			{
				m_path.erase(m_path.size() - 9, 1); // change EBOOT.BIN to BOOT.BIN
			}
			else if (elf_ext == ".SELF" || elf_ext == ".SPRX")
			{
				m_path.erase(m_path.size() - 4, 1); // change *.self to *.elf, *.sprx to *.prx
			}
			else
			{
				m_path += ".decrypted.elf";
			}

			if (!DecryptSelf(m_path, elf_dir + elf_name))
			{
				LOG_ERROR(LOADER, "Failed to decrypt %s", elf_dir + elf_name);
				return;
			}
		}

		SetCPUThreadStop(0);

		LOG_NOTICE(LOADER, "Path: %s", m_path);

		// Load custom config
		if (fs::file cfg_file{ m_path + ".yml" })
		{
			LOG_NOTICE(LOADER, "Custom config: %s.yml", m_path);
			cfg::root.from_string(cfg_file.to_string());
		}

		const fs::file elf_file(m_path);
		ppu_exec_object ppu_exec;
		ppu_prx_object ppu_prx;
		spu_exec_object spu_exec;
		arm_exec_object arm_exec;

		if (!elf_file)
		{
			LOG_ERROR(LOADER, "Failed to open %s", m_path);
			return;
		}
		else if (ppu_exec.open(elf_file) == elf_error::ok)
		{
			// PS3 executable
			m_status = Ready;
			vm::ps3::init();

			if (m_elf_path.empty())
			{
				m_elf_path = "/host_root/" + m_path;
				LOG_NOTICE(LOADER, "Elf path: %s", m_elf_path);
			}

			// Load PARAM.SFO
			const auto _psf = psf::load_object(fs::file(elf_dir + "/../PARAM.SFO"));
			m_title = psf::get_string(_psf, "TITLE", m_path);
			m_title_id = psf::get_string(_psf, "TITLE_ID");
			fs::get_data_dir(m_title_id, m_path);

			LOG_NOTICE(LOADER, "Title: %s", GetTitle());
			LOG_NOTICE(LOADER, "Serial: %s", GetTitleID());

			// Mount all devices
			const std::string& emu_dir_ = g_cfg_vfs_emulator_dir;
			const std::string& emu_dir = emu_dir_.empty() ? fs::get_executable_dir() : emu_dir_;
			const std::string& bdvd_dir = g_cfg_vfs_dev_bdvd;
			const std::string& home_dir = g_cfg_vfs_app_home;

			vfs::mount("dev_hdd0", fmt::replace_all(g_cfg_vfs_dev_hdd0, "$(EmulatorDir)", emu_dir));
			vfs::mount("dev_hdd1", fmt::replace_all(g_cfg_vfs_dev_hdd1, "$(EmulatorDir)", emu_dir));
			vfs::mount("dev_flash", fmt::replace_all(g_cfg_vfs_dev_flash, "$(EmulatorDir)", emu_dir));
			vfs::mount("dev_usb", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir));
			vfs::mount("dev_usb000", fmt::replace_all(g_cfg_vfs_dev_usb000, "$(EmulatorDir)", emu_dir));
			vfs::mount("app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir));

			// Mount /dev_bdvd/ if necessary
			if (bdvd_dir.empty() && fs::is_file(elf_dir + "/../../PS3_DISC.SFB"))
			{
				const auto dir_list = fmt::split(elf_dir, { "/", "\\" });

				// Check latest two directories
				if (dir_list.size() >= 2 && dir_list.back() == "USRDIR" && *(dir_list.end() - 2) == "PS3_GAME")
				{
					vfs::mount("dev_bdvd", elf_dir.substr(0, elf_dir.length() - 15));
				}
				else
				{
					vfs::mount("dev_bdvd", elf_dir + "/../../");
				}

				LOG_NOTICE(LOADER, "Disc: %s", vfs::get("/dev_bdvd"));
			}
			else if (bdvd_dir.size())
			{
				vfs::mount("dev_bdvd", fmt::replace_all(bdvd_dir, "$(EmulatorDir)", emu_dir));
			}

			// Mount /host_root/ if necessary
			if (g_cfg_vfs_allow_host_root)
			{
				vfs::mount("host_root", {});
			}

			LOG_NOTICE(LOADER, "Used configuration:\n%s\n", cfg::root.to_string());

			ppu_load_exec(ppu_exec);

			fxm::import<GSRender>(PURE_EXPR(Emu.GetCallbacks().get_gs_render())); // TODO: must be created in appropriate sys_rsx syscall
		}
		else if (ppu_prx.open(elf_file) == elf_error::ok)
		{
			// PPU PRX (experimental)
			m_status = Ready;
			vm::ps3::init();
			ppu_load_prx(ppu_prx);
		}
		else if (spu_exec.open(elf_file) == elf_error::ok)
		{
			// SPU executable (experimental)
			m_status = Ready;
			vm::ps3::init();
			spu_load_exec(spu_exec);
		}
		else if (arm_exec.open(elf_file) == elf_error::ok)
		{
			// ARMv7 executable
			m_status = Ready;
			vm::psv::init();
			arm_load_exec(arm_exec);
		}
		else
		{
			LOG_ERROR(LOADER, "Invalid or unsupported file format: %s", m_path);

			LOG_WARNING(LOADER, "** ppu_exec -> %s", ppu_exec.get_error());
			LOG_WARNING(LOADER, "** ppu_prx  -> %s", ppu_prx.get_error());
			LOG_WARNING(LOADER, "** spu_exec -> %s", spu_exec.get_error());
			LOG_WARNING(LOADER, "** arm_exec -> %s", arm_exec.get_error());
			return;
		}

		debug::autopause::reload();
		SendDbgCommand(DID_READY_EMU);
		if (g_cfg_autostart) Run();
	}
	catch (const std::exception& e)
	{
		LOG_FATAL(LOADER, "%s thrown: %s", typeid(e).name(), e.what());
		Stop();
	}
}
예제 #4
0
파일: System.cpp 프로젝트: Snake128/rpcs3
void Emulator::Load()
{
	Stop();

	try
	{
		Init();

		if (!fs::is_file(m_path))
		{
			LOG_ERROR(LOADER, "File not found: %s", m_path);
			return;
		}

		const std::string& elf_dir = fs::get_parent_dir(m_path);

		if (IsSelf(m_path))
		{
			const std::size_t elf_ext_pos = m_path.find_last_of('.');
			const std::string& elf_ext = fmt::to_upper(m_path.substr(elf_ext_pos != -1 ? elf_ext_pos : m_path.size()));
			const std::string& elf_name = m_path.substr(elf_dir.size());

			if (elf_name.compare(elf_name.find_last_of("/\\", -1, 2) + 1, 9, "EBOOT.BIN", 9) == 0)
			{
				m_path.erase(m_path.size() - 9, 1); // change EBOOT.BIN to BOOT.BIN
			}
			else if (elf_ext == ".SELF" || elf_ext == ".SPRX")
			{
				m_path.erase(m_path.size() - 4, 1); // change *.self to *.elf, *.sprx to *.prx
			}
			else
			{
				m_path += ".decrypted.elf";
			}

			if (!DecryptSelf(m_path, elf_dir + elf_name))
			{
				LOG_ERROR(LOADER, "Failed to decrypt %s", elf_dir + elf_name);
				return;
			}
		}

		ResetInfo();

		LOG_NOTICE(LOADER, "Path: %s", m_path);

		// Load custom config
		if (fs::file cfg_file{ m_path + ".yml" })
		{
			LOG_NOTICE(LOADER, "Custom config: %s.yml", m_path);
			cfg::root.from_string(cfg_file.to_string());
		}

		const fs::file elf_file(m_path);
		ppu_exec_loader ppu_exec;
		ppu_prx_loader ppu_prx;
		spu_exec_loader spu_exec;
		arm_exec_loader arm_exec;

		if (!elf_file)
		{
			LOG_ERROR(LOADER, "Failed to open %s", m_path);
			return;
		}
		else if (ppu_exec.open(elf_file) == elf_error::ok)
		{
			// PS3 executable
			m_status = Ready;
			vm::ps3::init();

			if (m_elf_path.empty())
			{
				m_elf_path = "/host_root/" + m_path;
				LOG_NOTICE(LOADER, "Elf path: %s", m_elf_path);
			}

			// Load PARAM.SFO
			m_psf = psf::load_object(fs::file(elf_dir + "/../PARAM.SFO"));
			m_title = psf::get_string(m_psf, "TITLE", m_path);
			m_title_id = psf::get_string(m_psf, "TITLE_ID");
			LOG_NOTICE(LOADER, "Title: %s", GetTitle());
			LOG_NOTICE(LOADER, "Serial: %s", GetTitleID());
			LOG_NOTICE(LOADER, "");

			LOG_NOTICE(LOADER, "Used configuration:\n%s\n", cfg::root.to_string());

			// Mount /dev_bdvd/
			if (g_cfg_vfs_dev_bdvd.size() == 0 && fs::is_file(elf_dir + "/../../PS3_DISC.SFB"))
			{
				const auto dir_list = fmt::split(elf_dir, { "/", "\\" });

				// Check latest two directories
				if (dir_list.size() >= 2 && dir_list.back() == "USRDIR" && *(dir_list.end() - 2) == "PS3_GAME")
				{
					g_cfg_vfs_dev_bdvd = elf_dir.substr(0, elf_dir.length() - 15);
				}
				else
				{
					g_cfg_vfs_dev_bdvd = elf_dir + "/../../";
				}
			}

			// Mount /app_home/
			if (g_cfg_vfs_app_home.size() == 0)
			{
				g_cfg_vfs_app_home = elf_dir + '/';
			}

			vfs::dump();

			ppu_exec.load();

			Emu.GetCallbackManager().Init();
			fxm::import<GSRender>(PURE_EXPR(Emu.GetCallbacks().get_gs_render())); // TODO: must be created in appropriate sys_rsx syscall
		}
		else if (ppu_prx.open(elf_file) == elf_error::ok)
		{
			// PPU PRX (experimental)
			m_status = Ready;
			vm::ps3::init();
			ppu_prx.load();
			GetCallbackManager().Init();
		}
		else if (spu_exec.open(elf_file) == elf_error::ok)
		{
			// SPU executable (experimental)
			m_status = Ready;
			vm::ps3::init();
			spu_exec.load();
		}
		else if (arm_exec.open(elf_file) == elf_error::ok)
		{
			// ARMv7 executable
			m_status = Ready;
			vm::psv::init();
			arm_exec.load();
		}
		else
		{
			LOG_ERROR(LOADER, "Invalid or unsupported file format: %s", m_path);

			LOG_WARNING(LOADER, "** ppu_exec_loader -> %s", bijective_find<elf_error>(ppu_exec, "???"));
			LOG_WARNING(LOADER, "** ppu_prx_loader -> %s", bijective_find<elf_error>(ppu_prx, "???"));
			LOG_WARNING(LOADER, "** spu_exec_loader -> %s", bijective_find<elf_error>(spu_exec, "???"));
			LOG_WARNING(LOADER, "** arm_exec_loader -> %s", bijective_find<elf_error>(arm_exec, "???"));
			return;
		}

		debug::autopause::reload();
		SendDbgCommand(DID_READY_EMU);
		if (g_cfg_autostart) Run();
	}
	catch (const std::exception& e)
	{
		LOG_FATAL(LOADER, "%s thrown: %s", typeid(e).name(), e.what());
		Stop();
	}
}