예제 #1
0
파일: PKG.cpp 프로젝트: komos90/rpcs3
bool PKGLoader::Install(std::string dest)
{
    // Initial checks
    if (!pkg_f.IsOpened())
        return false;

    // TODO: This shouldn't use current dir
    dest.insert(0, 1, '.');
    if (!dest.empty() && dest.back() != '/')
        dest += '/';

    // Fetch title ID from the header.
    char title_id[48];
    pkg_f.Seek(48);
    pkg_f.Read(title_id, 48);

    std::string titleID = std::string(title_id).substr(7, 9);

    if (rExists(dest+titleID)) {
        rMessageDialog d_overwrite(NULL, "Another installation was found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO|rCENTRE);
        if (d_overwrite.ShowModal() != rID_YES) {
            LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str());
            return false;
        }
        // TODO: Remove the following two lines and remove the folder dest+titleID
        LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str());
        return false;
    }
    if (!rMkdir(dest+titleID)) {
        LOG_ERROR(LOADER, "PKG Loader: Could not make the installation directory: %s", titleID.c_str());
        return false;
    }

    // Decrypt and unpack the PKG file.
    if (Unpack(pkg_f, titleID, dest) < 0)
    {
        LOG_ERROR(LOADER, "PKG Loader: Failed to install package!");
        return false;
    }
    else
    {
        LOG_NOTICE(LOADER, "PKG Loader: Package successfully installed in: /dev_hdd0/game/%s", titleID.c_str());
        return true;
    }
}
예제 #2
0
bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
{
	u8 buf[BUF_SIZE];

	dec_pkg_f.Seek(entry.name_offset);
	dec_pkg_f.Read(buf, entry.name_size);
	buf[entry.name_size] = 0;
	
	switch (entry.type & (0xff))
	{
		case PKG_FILE_ENTRY_NPDRM:
		case PKG_FILE_ENTRY_NPDRMEDAT:
		case PKG_FILE_ENTRY_SDAT:
		case PKG_FILE_ENTRY_REGULAR:
		{
			rFile out;
			out.Create(dir + std::string(reinterpret_cast<char *>(buf), entry.name_size));
			dec_pkg_f.Seek(entry.file_offset);

			for (u64 size = 0; size < entry.file_size; ) {
				size += dec_pkg_f.Read(buf, BUF_SIZE);
				if (size > entry.file_size)
					out.Write(buf, BUF_SIZE - (size - entry.file_size));
				else
					out.Write(buf, BUF_SIZE);
			}
			out.Close();
		}
		break;
			
		case PKG_FILE_ENTRY_FOLDER:
			rMkdir(dir + std::string(reinterpret_cast<char *>(buf), entry.name_size));
		break;
	}
	return true;
}
예제 #3
0
int sceNpDrmIsAvailable2(u32 k_licensee_addr, u32 drm_path_addr)
{
	sceNp->Warning("sceNpDrmIsAvailable2(k_licensee_addr=0x%x, drm_path_addr=0x%x)", k_licensee_addr, drm_path_addr);

	std::string drm_path = Memory.ReadString(drm_path_addr);
	if (!Emu.GetVFS().ExistsFile(drm_path))
	{
		sceNp->Warning("sceNpDrmIsAvailable2(): '%s' not found", drm_path.c_str());
		return CELL_ENOENT;
	}

	std::string k_licensee_str = "0";
	u8 k_licensee[0x10];

	if (k_licensee_addr)
	{
		for (int i = 0; i < 0x10; i++)
		{
			k_licensee[i] = Memory.Read8(k_licensee_addr + i);
			k_licensee_str += fmt::Format("%02x", k_licensee[i]);
		}
	}

	sceNp->Warning("sceNpDrmIsAvailable2: Found DRM license file at %s", drm_path.c_str());
	sceNp->Warning("sceNpDrmIsAvailable2: Using k_licensee 0x%s", k_licensee_str.c_str());

	// Set the necessary file paths.
	std::string drm_file_name = fmt::AfterLast(drm_path, '/');

	// TODO: Make more explicit what this actually does (currently it copies "XXXXXXXX" from drm_path (== "/dev_hdd0/game/XXXXXXXXX/*" assumed)
	std::string titleID = drm_path.substr(15, 9);

	// TODO: These shouldn't use current dir
	std::string enc_drm_path = drm_path;
	std::string dec_drm_path = "/dev_hdd1/" + titleID + "/" + drm_file_name;
	std::string rap_path = "/dev_usb000/";

	// Search dev_usb000 for a compatible RAP file. 
	vfsDir *raps_dir = new vfsDir(rap_path);
	if (!raps_dir->IsOpened())
		sceNp->Warning("sceNpDrmIsAvailable2: Can't find RAP file for DRM!");
	else
	{
		const std::vector<DirEntryInfo> &entries = raps_dir->GetEntries();
		for (auto &entry : entries)
		{
			if (entry.name.find(titleID) != std::string::npos)
			{
				rap_path += entry.name;
				break;
			}
		}
	}

	// Create a new directory under dev_hdd1/titleID to hold the decrypted data.
	// TODO: These shouldn't use current dir
	std::string tmp_dir = "./dev_hdd1/" + titleID;
	if (!rExists(tmp_dir))
		rMkdir("./dev_hdd1/" + titleID);

	// Decrypt this EDAT using the supplied k_licensee and matching RAP file.
	std::string enc_drm_path_local, dec_drm_path_local, rap_path_local;
	Emu.GetVFS().GetDevice(enc_drm_path, enc_drm_path_local);
	Emu.GetVFS().GetDevice(dec_drm_path, dec_drm_path_local);
	Emu.GetVFS().GetDevice(rap_path, rap_path_local);

	DecryptEDAT(enc_drm_path_local, dec_drm_path_local, 8, rap_path_local, k_licensee, false);
	return CELL_OK;
}