Ejemplo n.º 1
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
bool vfsHDDFile::goto_block(u64 n)
{
	vfsHDD_Block block_info;

	if (m_info.data_block >= m_hdd_info.block_count)
	{
		return false;
	}

	CHECK_ASSERTION(m_hdd.Seek(m_info.data_block * m_hdd_info.block_size) != -1);

	block_info.next_block = m_info.data_block;

	for (u64 i = 0; i < n; ++i)
	{
		if (!block_info.next_block || !block_info.is_used || block_info.next_block >= m_hdd_info.block_count)
		{
			return false;
		}

		CHECK_ASSERTION(m_hdd.Seek(block_info.next_block * m_hdd_info.block_size) != -1);

		m_hdd.Read(&block_info, sizeof(vfsHDD_Block));
	}

	return true;
}
Ejemplo n.º 2
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDDFile::SaveInfo()
{
	CHECK_ASSERTION(m_hdd.Seek(m_info_block * m_hdd_info.block_size) != -1);

	CHECK_ASSERTION(m_hdd.Seek(m_info_block * m_hdd_info.block_size) != -1);

	m_hdd.Write(&m_info, sizeof(vfsHDD_Entry));
}
Ejemplo n.º 3
0
bool CheckDebugSelf(const std::string& self, const std::string& elf)
{
	// Open the SELF file.
	fs::file s(self);

	if (!s)
	{
		LOG_ERROR(LOADER, "Could not open SELF file! (%s)", self.c_str());
		return false;
	}

	// Get the key version.
	CHECK_ASSERTION(s.seek(0x08) != -1);

	u16 key_version;
	s.read(&key_version, sizeof(key_version));

	// Check for DEBUG version.
	if (swap16(key_version) == 0x8000)
	{
		LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header...");

		// Get the real elf offset.
		CHECK_ASSERTION(s.seek(0x10) != -1);

		u64 elf_offset;
		s.read(&elf_offset, sizeof(elf_offset));

		// Start at the real elf offset.
		elf_offset = swap64(elf_offset);

		CHECK_ASSERTION(s.seek(elf_offset) != -1);

		// Write the real ELF file back.
		fs::file e(elf, fom::rewrite);
		if (!e)
		{
			LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
			return false;
		}

		// Copy the data.
		char buf[2048];
		while (ssize_t size = s.read(buf, 2048))
		{
			e.write(buf, size);
		}

		return true;
	}

	// Leave the file untouched.
	return false;
}
Ejemplo n.º 4
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
u64 vfsHDDFile::Read(void* dst, u64 size)
{
	if (!size)
		return 0;

	//vfsDeviceLocker lock(m_hdd);

	const u32 block_size = m_hdd_info.block_size - sizeof(vfsHDD_Block);
	u64 rsize = std::min<u64>(block_size - m_position, size);

	vfsHDD_Block cur_block_info;
	
	CHECK_ASSERTION(m_hdd.Seek(m_cur_block * m_hdd_info.block_size) != -1);

	m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block));
	
	CHECK_ASSERTION(m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block) + m_position) != -1);

	m_hdd.Read(dst, rsize);
	size -= rsize;
	m_position += rsize;
	if (!size)
	{
		return rsize;
	}

	u64 offset = rsize;

	for (; size; size -= rsize, offset += rsize)
	{
		if (!cur_block_info.is_used || !cur_block_info.next_block || cur_block_info.next_block >= m_hdd_info.block_count)
		{
			return offset;
		}

		m_cur_block = cur_block_info.next_block;
		rsize = std::min<u64>(block_size, size);

		CHECK_ASSERTION(m_hdd.Seek(cur_block_info.next_block * m_hdd_info.block_size) != -1);

		m_hdd.Read(&cur_block_info, sizeof(vfsHDD_Block));

		if (m_hdd.Read((u8*)dst + offset, rsize) != rsize)
		{
			return offset;
		}
	}

	m_position = rsize;

	return offset;
}
Ejemplo n.º 5
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size)
{
	fs::file f(path, fom::rewrite);

	static const u64 cur_dir_block = 1;

	vfsHDD_Hdr hdr;
	CreateBlock(hdr);
	hdr.next_block = cur_dir_block;
	hdr.magic = g_hdd_magic;
	hdr.version = g_hdd_version;
	hdr.block_count = (size + block_size) / block_size;
	hdr.block_size = block_size;
	f.write(&hdr, sizeof(vfsHDD_Hdr));

	{
		vfsHDD_Entry entry;
		CreateEntry(entry);
		entry.type = vfsHDD_Entry_Dir;
		entry.data_block = hdr.next_block;
		entry.next_block = 0;

		f.seek(cur_dir_block * hdr.block_size);
		f.write(&entry, sizeof(vfsHDD_Entry));
		f.write(".", 1);
	}

	u8 null = 0;

	CHECK_ASSERTION(f.seek(hdr.block_count * hdr.block_size - sizeof(null)) != -1);
	
	f.write(&null, sizeof(null));
}
Ejemplo n.º 6
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
s32 vfsHDD::OpenDir(const std::string& name)
{
	LOG_WARNING(HLE, "OpenDir(%s)", name.c_str());
	u64 entry_block;

	if (!SearchEntry(name, entry_block))
	{
		return -1;
	}

	CHECK_ASSERTION(m_hdd_file.Seek(entry_block * m_hdd_info.block_size) != -1);
	
	vfsHDD_Entry entry;
	m_hdd_file.Read(&entry, sizeof(vfsHDD_Entry));

	if (entry.type == vfsHDD_Entry_File)
	{
		return 1;
	}

	m_cur_dir_block = entry.data_block;
	ReadEntry(m_cur_dir_block, m_cur_dir);

	return 0;
}
Ejemplo n.º 7
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDD::ReadEntry(u64 block, std::string& name)
{
	CHECK_ASSERTION(m_hdd_file.Seek(block * m_hdd_info.block_size + sizeof(vfsHDD_Entry)) != -1);
	
	name.resize(GetMaxNameLen());
	m_hdd_file.Read(&name.front(), GetMaxNameLen());
}
Ejemplo n.º 8
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDD::WriteEntry(u64 block, const vfsHDD_Entry& data, const std::string& name)
{
	CHECK_ASSERTION(m_hdd_file.Seek(block * m_hdd_info.block_size) != -1);
	
	m_hdd_file.Write(&data, sizeof(vfsHDD_Entry));
	m_hdd_file.Write(name.c_str(), std::min<size_t>(GetMaxNameLen() - 1, name.length() + 1));
}
Ejemplo n.º 9
0
bool fs::dir::close()
{
	g_tls_error = fse::ok;

	if (!m_path)
	{
		return false;
	}

	m_path.reset();

#ifdef _WIN32
	CHECK_ASSERTION(m_dd == -1 || FindClose((HANDLE)m_dd));
#else
	CHECK_ASSERTION(!::closedir((DIR*)m_dd));
#endif

	return true;
}
Ejemplo n.º 10
0
//Copied some from AutoPause.
//Tip: This one doesn't check for the file is being read or not.
//This would always use a 0xFFFFFFFF as end of the pause.bin
void AutoPauseManagerDialog::SaveEntries(void)
{
	fs::file list(fs::get_config_dir() + "pause.bin", fom::rewrite);
	//System calls ID and Function calls ID are all u32 iirc.
	u32 num = 0;
	CHECK_ASSERTION(list.seek(0) != -1);
	for (size_t i = 0; i < m_entries.size(); ++i)
	{
		if (num == 0xFFFFFFFF) continue;
		num = m_entries[i];
		list.write(&num, sizeof(u32));
	}
	num = 0xFFFFFFFF;
	list.write(&num, sizeof(u32));
}
Ejemplo n.º 11
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
vfsHDD::vfsHDD(vfsDevice* device, const std::string& hdd_path)
	: m_hdd_file(device)
	, m_file(m_hdd_file, m_hdd_info)
	, m_hdd_path(hdd_path)
	, vfsFileBase(device)
{
	m_hdd_file.Open(hdd_path, fom::read | fom::write);
	m_hdd_file.Read(&m_hdd_info, sizeof(vfsHDD_Hdr));
	m_cur_dir_block = m_hdd_info.next_block;
	if (!m_hdd_info.block_size)
	{
		LOG_ERROR(HLE, "Bad block size!");
		m_hdd_info.block_size = 2048;
	}

	CHECK_ASSERTION(m_hdd_file.Seek(m_cur_dir_block * m_hdd_info.block_size) != -1);
	
	m_hdd_file.Read(&m_cur_dir, sizeof(vfsHDD_Entry));
}
Ejemplo n.º 12
0
bool IsSelfElf32(const std::string& path)
{
	vfsLocalFile f(nullptr);

	if(!f.Open(path))
		return false;

	SceHeader hdr;
	SelfHeader sh;
	hdr.Load(f);
	sh.Load(f);
	
	// Locate the class byte and check it.
	u8 elf_class[0x8];

	CHECK_ASSERTION(f.Seek(sh.se_elfoff) != -1);

	f.Read(elf_class, 0x8);

	return (elf_class[4] == 1);
}
Ejemplo n.º 13
0
void fnt_MoveAPoint( fnt_LocalGraphicStateType* gs, F26Dot6* x, F26Dot6* y, F26Dot6 delta)
{
	register shortFrac pfProj = gs->pfProj;
	register shortFrac fx = gs->free.x;
	register shortFrac fy = gs->free.y;

	CHECK_PFPROJ( gs );
	CHECK_ASSERTION( gs, x != y );

	if ( pfProj != shortFrac1 )
	{	if ( fx )
			*x += ShortMulDiv( delta, fx, pfProj );
		if ( fy )
			*y += ShortMulDiv( delta, fy, pfProj );
	}
	else
	{	if ( fx )
			*x += ShortFracMul( delta, fx );
		if ( fy )
			*y += ShortFracMul( delta, fy );
	}
}
Ejemplo n.º 14
0
//Copied some from AutoPause.
void AutoPauseManagerDialog::LoadEntries(void)
{
	m_entries.clear();
	m_entries.reserve(16);

	fs::file list(fs::get_config_dir() + "pause.bin");

	if (list)
	{
		//System calls ID and Function calls ID are all u32 iirc.
		u32 num;
		size_t fmax = list.size();
		size_t fcur = 0;
		CHECK_ASSERTION(list.seek(0) != -1);
		while (fcur <= fmax - sizeof(u32))
		{
			list.read(&num, sizeof(u32));
			fcur += sizeof(u32);
			if (num == 0xFFFFFFFF) break;

			m_entries.emplace_back(num);
		}
	}
}
Ejemplo n.º 15
0
	const std::string& entry::as_string() const
	{
		CHECK_ASSERTION(m_type == format::string || m_type == format::array);
		return m_value_string;
	}
Ejemplo n.º 16
0
	entry& entry::operator =(const std::string& value)
	{
		CHECK_ASSERTION(m_type == format::string || m_type == format::array);
		m_value_string = value;
		return *this;
	}
Ejemplo n.º 17
0
	entry& entry::operator =(u32 value)
	{
		CHECK_ASSERTION(m_type == format::integer);
		m_value_integer = value;
		return *this;
	}
Ejemplo n.º 18
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDD::ReadEntry(u64 block, vfsHDD_Entry& data)
{
	CHECK_ASSERTION(m_hdd_file.Seek(block * m_hdd_info.block_size) != -1);

	m_hdd_file.Read(&data, sizeof(vfsHDD_Entry));
}
Ejemplo n.º 19
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDD::WriteEntry(u64 block, const vfsHDD_Entry& data)
{
	CHECK_ASSERTION(m_hdd_file.Seek(block * m_hdd_info.block_size) != -1);
	
	m_hdd_file.Write(&data, sizeof(vfsHDD_Entry));
}
Ejemplo n.º 20
0
	registry load(const std::vector<char>& data)
	{
		registry result;

		// Hack for empty input (TODO)
		if (data.empty())
		{
			return result;
		}

		// Check size
		CHECK_ASSERTION(data.size() >= sizeof(header_t));
		CHECK_ASSERTION((std::uintptr_t)data.data() % 8 == 0);

		// Get header
		const header_t& header = reinterpret_cast<const header_t&>(data[0]);

		// Check magic and version
		CHECK_ASSERTION(header.magic == *(u32*)"\0PSF");
		CHECK_ASSERTION(header.version == 0x101);
		CHECK_ASSERTION(sizeof(header_t) + header.entries_num * sizeof(def_table_t) <= header.off_key_table);
		CHECK_ASSERTION(header.off_key_table <= header.off_data_table);
		CHECK_ASSERTION(header.off_data_table <= data.size());

		// Get indices (alignment should be fine)
		const def_table_t* indices = reinterpret_cast<const def_table_t*>(data.data() + sizeof(header_t));

		// Load entries
		for (u32 i = 0; i < header.entries_num; ++i)
		{
			CHECK_ASSERTION(indices[i].key_off < header.off_data_table - header.off_key_table);

			// Get key name range
			const auto name_ptr = data.begin() + header.off_key_table + indices[i].key_off;
			const auto name_end = std::find(name_ptr , data.begin() + header.off_data_table, '\0');

			// Get name (must be unique)
			std::string key(name_ptr, name_end);

			CHECK_ASSERTION(result.count(key) == 0);
			CHECK_ASSERTION(indices[i].param_len <= indices[i].param_max);
			CHECK_ASSERTION(indices[i].data_off < data.size() - header.off_data_table);
			CHECK_ASSERTION(indices[i].param_max < data.size() - indices[i].data_off);

			// Get data pointer
			const auto value_ptr = data.begin() + header.off_data_table + indices[i].data_off;

			if (indices[i].param_fmt == format::integer && indices[i].param_max == sizeof(u32) && indices[i].param_len == sizeof(u32))
			{
				// Integer data
				result.emplace(std::piecewise_construct,
					std::forward_as_tuple(std::move(key)),
					std::forward_as_tuple(reinterpret_cast<const le_t<u32>&>(*value_ptr)));
			}
			else if (indices[i].param_fmt == format::string || indices[i].param_fmt == format::array)
			{
				// String/array data
				std::string value;

				if (indices[i].param_fmt == format::string)
				{
					// Find null terminator
					value.assign(value_ptr, std::find(value_ptr, value_ptr + indices[i].param_len, '\0'));
				}
				else
				{
					value.assign(value_ptr, value_ptr + indices[i].param_len);
				}

				result.emplace(std::piecewise_construct,
					std::forward_as_tuple(std::move(key)),
					std::forward_as_tuple(indices[i].param_fmt, indices[i].param_max, std::move(value)));
			}
			else
			{
				// Possibly unsupported format, entry ignored
				log.error("Unknown entry format (key='%s', fmt=0x%x, len=0x%x, max=0x%x)", key, indices[i].param_fmt, indices[i].param_len, indices[i].param_max);
			}
		}

		return result;
	}
Ejemplo n.º 21
0
bool SELFDecrypter::DecryptData()
{
	aes_context aes;

	// Calculate the total data size.
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		if (meta_shdr[i].encrypted == 3)
		{
			if ((meta_shdr[i].key_idx <= meta_hdr.key_count - 1) && (meta_shdr[i].iv_idx <= meta_hdr.key_count))
				data_buf_length += meta_shdr[i].data_size;
		}
	}

	// Allocate a buffer to store decrypted data.
	data_buf = (u8*)malloc(data_buf_length);

	// Set initial offset.
	u32 data_buf_offset = 0;

	// Parse the metadata section headers to find the offsets of encrypted data.
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		size_t ctr_nc_off = 0;
		u8 ctr_stream_block[0x10];
		u8 data_key[0x10];
		u8 data_iv[0x10];

		// Check if this is an encrypted section.
		if (meta_shdr[i].encrypted == 3)
		{
			// Make sure the key and iv are not out of boundaries.
			if((meta_shdr[i].key_idx <= meta_hdr.key_count - 1) && (meta_shdr[i].iv_idx <= meta_hdr.key_count))
			{
				// Get the key and iv from the previously stored key buffer.
				memcpy(data_key, data_keys + meta_shdr[i].key_idx * 0x10, 0x10);
				memcpy(data_iv, data_keys + meta_shdr[i].iv_idx * 0x10, 0x10);

				// Allocate a buffer to hold the data.
				u8 *buf = (u8 *)malloc(meta_shdr[i].data_size);

				// Seek to the section data offset and read the encrypted data.
				CHECK_ASSERTION(self_f.Seek(meta_shdr[i].data_offset) != -1);
				self_f.Read(buf, meta_shdr[i].data_size);

				// Zero out our ctr nonce.
				memset(ctr_stream_block, 0, sizeof(ctr_stream_block));

				// Perform AES-CTR encryption on the data blocks.
				aes_setkey_enc(&aes, data_key, 128);
				aes_crypt_ctr(&aes, meta_shdr[i].data_size, &ctr_nc_off, data_iv, ctr_stream_block, buf, buf);

				// Copy the decrypted data.
				memcpy(data_buf + data_buf_offset, buf, meta_shdr[i].data_size);

				// Advance the buffer's offset.
				data_buf_offset += meta_shdr[i].data_size;

				// Release the temporary buffer.
				free(buf);
			}
		}
	}

	return true;
}
Ejemplo n.º 22
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
u64 vfsHDDFile::Write(const void* src, u64 size)
{
	if (!size)
		return 0;

	//vfsDeviceLocker lock(m_hdd);

	const u32 block_size = m_hdd_info.block_size - sizeof(vfsHDD_Block);

	if (!m_cur_block)
	{
		if (!m_info.data_block)
		{
			u64 new_block = FindFreeBlock();

			if (!new_block)
			{
				return 0;
			}

			WriteBlock(new_block, g_used_block);
			m_info.data_block = new_block;
			m_info.size = 0;
			SaveInfo();
		}

		m_cur_block = m_info.data_block;
		m_position = 0;
	}

	u64 wsize = std::min<u64>(block_size - m_position, size);

	vfsHDD_Block block_info;
	ReadBlock(m_cur_block, block_info);

	if (wsize)
	{
		CHECK_ASSERTION(m_hdd.Seek(m_cur_block * m_hdd_info.block_size + sizeof(vfsHDD_Block) + m_position) != -1);

		m_hdd.Write(src, wsize);
		size -= wsize;
		m_info.size += wsize;
		m_position += wsize;
		SaveInfo();

		if (!size)
			return wsize;
	}

	u64 last_block = m_cur_block;
	block_info.is_used = true;
	u64 offset = wsize;

	for (; size; size -= wsize, offset += wsize, m_info.size += wsize)
	{
		u64 new_block = FindFreeBlock();

		if (!new_block)
		{
			m_position = 0;
			SaveInfo();
			return offset;
		}

		m_cur_block = new_block;
		wsize = std::min<u64>(block_size, size);

		block_info.next_block = m_cur_block;
		
		CHECK_ASSERTION(m_hdd.Seek(last_block * m_hdd_info.block_size) != -1);

		if (m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block))
		{
			m_position = 0;
			SaveInfo();
			return offset;
		}

		block_info.next_block = 0;

		CHECK_ASSERTION(m_hdd.Seek(m_cur_block * m_hdd_info.block_size) != -1);

		if (m_hdd.Write(&block_info, sizeof(vfsHDD_Block)) != sizeof(vfsHDD_Block))
		{
			m_position = 0;
			SaveInfo();
			return offset;
		}

		if ((m_position = m_hdd.Write((u8*)src + offset, wsize)) != wsize)
		{
			m_info.size += wsize;
			SaveInfo();
			return offset;
		}

		last_block = m_cur_block;
	}

	SaveInfo();
	m_position = wsize;
	return offset;
}
Ejemplo n.º 23
0
bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32)
{
	// Create a new ELF file.
	fs::file e(elf, fom::rewrite);
	if(!e)
	{
		LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str());
		return false;
	}

	// Set initial offset.
	u32 data_buf_offset = 0;

	if (isElf32)
	{
		// Write ELF header.
		WriteEhdr(e, elf32_hdr);

		// Write program headers.
		for (u32 i = 0; i < elf32_hdr.e_phnum; ++i)
		{
			WritePhdr(e, phdr32_arr[i]);
		}

		for (unsigned int i = 0; i < meta_hdr.section_count; i++)
		{
			// PHDR type.
			if (meta_shdr[i].type == 2)
			{
				// Seek to the program header data offset and write the data.
				CHECK_ASSERTION(e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset) != -1);

				e.write(data_buf + data_buf_offset, meta_shdr[i].data_size);

				// Advance the data buffer offset by data size.
				data_buf_offset += meta_shdr[i].data_size;
			}
		}

		// Write section headers.
		if (self_hdr.se_shdroff != 0)
		{
			CHECK_ASSERTION(e.seek(elf32_hdr.e_shoff) != -1);

			for (u32 i = 0; i < elf32_hdr.e_shnum; ++i)
			{
				WriteShdr(e, shdr32_arr[i]);
			}
		}
	}
	else
	{
		// Write ELF header.
		WriteEhdr(e, elf64_hdr);

		// Write program headers.
		for (u32 i = 0; i < elf64_hdr.e_phnum; ++i)
		{
			WritePhdr(e, phdr64_arr[i]);
		}

		// Write data.
		for (unsigned int i = 0; i < meta_hdr.section_count; i++)
		{
			// PHDR type.
			if (meta_shdr[i].type == 2)
			{
				// Decompress if necessary.
				if (meta_shdr[i].compressed == 2)
				{
					// Allocate a buffer for decompression.
					u8 *decomp_buf = (u8 *)malloc(phdr64_arr[meta_shdr[i].program_idx].p_filesz);

					// Set up memory streams for input/output.
					wxMemoryInputStream decomp_stream_in(data_buf + data_buf_offset, meta_shdr[i].data_size);
					wxMemoryOutputStream decomp_stream_out;

					// Create a Zlib stream, read the data and flush the stream.
					wxZlibInputStream* z_stream = new wxZlibInputStream(decomp_stream_in);
					z_stream->Read(decomp_stream_out);
					delete z_stream;

					// Copy the decompressed result from the stream.
					decomp_stream_out.CopyTo(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz);

					// Seek to the program header data offset and write the data.

					CHECK_ASSERTION(e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset) != -1);

					e.write(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz);

					// Release the decompression buffer.
					free(decomp_buf);
				}
				else
				{
					// Seek to the program header data offset and write the data.
					CHECK_ASSERTION(e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset) != -1);
					
					e.write(data_buf + data_buf_offset, meta_shdr[i].data_size);
				}

				// Advance the data buffer offset by data size.
				data_buf_offset += meta_shdr[i].data_size;
			}
		}

		// Write section headers.
		if (self_hdr.se_shdroff != 0)
		{
			CHECK_ASSERTION(e.seek(elf64_hdr.e_shoff) != -1);

			for (u32 i = 0; i < elf64_hdr.e_shnum; ++i)
			{
				WriteShdr(e, shdr64_arr[i]);
			}
		}
	}

	return true;
}
Ejemplo n.º 24
0
bool SELFDecrypter::LoadHeaders(bool isElf32)
{
	// Read SCE header.
	CHECK_ASSERTION(self_f.Seek(0) != -1);
	sce_hdr.Load(self_f);

	// Check SCE magic.
	if (!sce_hdr.CheckMagic())
	{
		LOG_ERROR(LOADER, "SELF: Not a SELF file!");
		return false;
	}

	// Read SELF header.
	self_hdr.Load(self_f);

	// Read the APP INFO.
	CHECK_ASSERTION(self_f.Seek(self_hdr.se_appinfooff) != -1);
	app_info.Load(self_f);

	// Read ELF header.
	CHECK_ASSERTION(self_f.Seek(self_hdr.se_elfoff) != -1);

	if (isElf32)
		elf32_hdr.Load(self_f);
	else
		elf64_hdr.Load(self_f);

	// Read ELF program headers.
	if (isElf32)
	{
		phdr32_arr.clear();
		if(elf32_hdr.e_phoff == 0 && elf32_hdr.e_phnum)
		{
			LOG_ERROR(LOADER, "SELF: ELF program header offset is null!");
			return false;
		}
		self_f.Seek(self_hdr.se_phdroff);
		for(u32 i = 0; i < elf32_hdr.e_phnum; ++i)
		{
			phdr32_arr.emplace_back();
			phdr32_arr.back().Load(self_f);
		}
	}
	else
	{
		phdr64_arr.clear();

		if (elf64_hdr.e_phoff == 0 && elf64_hdr.e_phnum)
		{
			LOG_ERROR(LOADER, "SELF: ELF program header offset is null!");
			return false;
		}

		CHECK_ASSERTION(self_f.Seek(self_hdr.se_phdroff) != -1);

		for (u32 i = 0; i < elf64_hdr.e_phnum; ++i)
		{
			phdr64_arr.emplace_back();
			phdr64_arr.back().Load(self_f);
		}
	}


	// Read section info.
	secinfo_arr.clear();
	CHECK_ASSERTION(self_f.Seek(self_hdr.se_secinfoff) != -1);

	for(u32 i = 0; i < ((isElf32) ? elf32_hdr.e_phnum : elf64_hdr.e_phnum); ++i)
	{
		secinfo_arr.emplace_back();
		secinfo_arr.back().Load(self_f);
	}

	// Read SCE version info.
	CHECK_ASSERTION(self_f.Seek(self_hdr.se_sceveroff) != -1);
	scev_info.Load(self_f);

	// Read control info.
	ctrlinfo_arr.clear();
	CHECK_ASSERTION(self_f.Seek(self_hdr.se_controloff) != -1);

	u32 i = 0;
	while(i < self_hdr.se_controlsize)
	{
		ctrlinfo_arr.emplace_back();
		ControlInfo &cinfo = ctrlinfo_arr.back();
		cinfo.Load(self_f);
		i += cinfo.size;
	}

	// Read ELF section headers.
	if (isElf32)
	{
		shdr32_arr.clear();

		if (elf32_hdr.e_shoff == 0 && elf32_hdr.e_shnum)
		{
			LOG_WARNING(LOADER, "SELF: ELF section header offset is null!");
			return true;
		}

		CHECK_ASSERTION(self_f.Seek(self_hdr.se_shdroff) != -1);

		for(u32 i = 0; i < elf32_hdr.e_shnum; ++i)
		{
			shdr32_arr.emplace_back();
			shdr32_arr.back().Load(self_f);
		}
	}
	else
	{
		shdr64_arr.clear();
		if (elf64_hdr.e_shoff == 0 && elf64_hdr.e_shnum)
		{
			LOG_WARNING(LOADER, "SELF: ELF section header offset is null!");
			return true;
		}

		CHECK_ASSERTION(self_f.Seek(self_hdr.se_shdroff) != -1);

		for(u32 i = 0; i < elf64_hdr.e_shnum; ++i)
		{
			shdr64_arr.emplace_back();
			shdr64_arr.back().Load(self_f);
		}
	}

	return true;
}
Ejemplo n.º 25
0
bool SELFDecrypter::LoadMetadata()
{
	aes_context aes;
	u32 metadata_info_size = sizeof32(meta_info);
	u8 *metadata_info = (u8 *)malloc(metadata_info_size);
	u32 metadata_headers_size = sce_hdr.se_hsize - (sizeof32(sce_hdr) + sce_hdr.se_meta + sizeof32(meta_info));
	u8 *metadata_headers = (u8 *)malloc(metadata_headers_size);

	// Locate and read the encrypted metadata info.
	CHECK_ASSERTION(self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr)) != -1);
	self_f.Read(metadata_info, metadata_info_size);

	// Locate and read the encrypted metadata header and section header.
	CHECK_ASSERTION(self_f.Seek(sce_hdr.se_meta + sizeof(sce_hdr) + metadata_info_size) != -1);
	self_f.Read(metadata_headers, metadata_headers_size);

	// Find the right keyset from the key vault.
	SELF_KEY keyset = key_v.FindSelfKey(app_info.self_type, sce_hdr.se_flags, app_info.version);

	// Copy the necessary parameters.
	u8 metadata_key[0x20];
	u8 metadata_iv[0x10];
	memcpy(metadata_key, keyset.erk, 0x20);
	memcpy(metadata_iv, keyset.riv, 0x10);

	// Check DEBUG flag.
	if ((sce_hdr.se_flags & 0x8000) != 0x8000)
	{
		// Decrypt the NPDRM layer.
		if (!DecryptNPDRM(metadata_info, metadata_info_size))
			return false;

		// Decrypt the metadata info.
		aes_setkey_dec(&aes, metadata_key, 256);  // AES-256
		aes_crypt_cbc(&aes, AES_DECRYPT, metadata_info_size, metadata_iv, metadata_info, metadata_info);
	}

	// Load the metadata info.
	meta_info.Load(metadata_info);

	// If the padding is not NULL for the key or iv fields, the metadata info
	// is not properly decrypted.
	if ((meta_info.key_pad[0] != 0x00) ||
		(meta_info.iv_pad[0] != 0x00))
	{
		LOG_ERROR(LOADER, "SELF: Failed to decrypt metadata info!");
		return false;
	}

	// Perform AES-CTR encryption on the metadata headers.
	size_t ctr_nc_off = 0;
	u8 ctr_stream_block[0x10];
	aes_setkey_enc(&aes, meta_info.key, 128);
	aes_crypt_ctr(&aes, metadata_headers_size, &ctr_nc_off, meta_info.iv, ctr_stream_block, metadata_headers, metadata_headers);

	// Load the metadata header.
	meta_hdr.Load(metadata_headers);

	// Load the metadata section headers.
	meta_shdr.clear();
	for (unsigned int i = 0; i < meta_hdr.section_count; i++)
	{
		meta_shdr.emplace_back();
		meta_shdr.back().Load(metadata_headers + sizeof(meta_hdr) + sizeof(MetadataSectionHeader) * i);
	}

	// Copy the decrypted data keys.
	data_keys_length = meta_hdr.key_count * 0x10;
	data_keys = (u8 *) malloc (data_keys_length);
	memcpy(data_keys, metadata_headers + sizeof(meta_hdr) + meta_hdr.section_count * sizeof(MetadataSectionHeader), data_keys_length);

	return true;
}
Ejemplo n.º 26
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDDFile::ReadBlock(u64 block, vfsHDD_Block& data)
{
	CHECK_ASSERTION(m_hdd.Seek(block * m_hdd_info.block_size) != -1);
	
	m_hdd.Read(&data, sizeof(vfsHDD_Block));
}
Ejemplo n.º 27
0
Archivo: HDD.cpp Proyecto: ss23/rpcs3
void vfsHDDFile::WriteBlock(u64 block, const vfsHDD_Block& data)
{
	CHECK_ASSERTION(m_hdd.Seek(block * m_hdd_info.block_size) != -1);
	
	m_hdd.Write(&data, sizeof(vfsHDD_Block));
}
Ejemplo n.º 28
0
	u32 entry::as_integer() const
	{
		CHECK_ASSERTION(m_type == format::integer);
		return m_value_integer;
	}