Beispiel #1
0
void ControlInfo::Load(const fs::file& f)
{
	type = Read32(f);
	size = Read32(f);
	next = Read64(f);

	if (type == 1)
	{
		control_flags.ctrl_flag1 = Read32(f);
		control_flags.unknown1 = Read32(f);
		control_flags.unknown2 = Read32(f);
		control_flags.unknown3 = Read32(f);
		control_flags.unknown4 = Read32(f);
		control_flags.unknown5 = Read32(f);
		control_flags.unknown6 = Read32(f);
		control_flags.unknown7 = Read32(f);
	}
	else if (type == 2)
	{
		if (size == 0x30)
		{
			f.read(file_digest_30.digest, 20);
			file_digest_30.unknown = Read64(f);
		}
		else if (size == 0x40)
		{
			f.read(file_digest_40.digest1, 20);
			f.read(file_digest_40.digest2, 20);
			file_digest_40.unknown = Read64(f);
		}
	}
	else if (type == 3)
	{
		npdrm.magic = Read32(f);
		npdrm.unknown1 = Read32(f);
		npdrm.license = Read32(f);
		npdrm.type = Read32(f);
		f.read(npdrm.content_id, 48);
		f.read(npdrm.digest, 16);
		f.read(npdrm.invdigest, 16);
		f.read(npdrm.xordigest, 16);
		npdrm.unknown2 = Read64(f);
		npdrm.unknown3 = Read64(f);
	}
}
Beispiel #2
0
static bool IsSelfElf32(const fs::file& f)
{
	if (!f) return false;

	f.seek(0);

	SceHeader hdr;
	SelfHeader sh;
	hdr.Load(f);
	sh.Load(f);

	// Locate the class byte and check it.
	u8 elf_class[0x8];

	f.seek(sh.se_elfoff);
	f.read(elf_class, 0x8);

	return (elf_class[4] == 1);
}
Beispiel #3
0
static bool CheckDebugSelf(fs::file& s)
{
	if (s.size() < 0x18)
	{
		return false;
	}

	// Get the key version.
	s.seek(0x08);

	const u16 key_version = s.read<le_t<u16>>();

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

		// Get the real elf offset.
		s.seek(0x10);

		// Start at the real elf offset.
		s.seek(key_version == 0x80 ? +s.read<be_t<u64>>() : +s.read<le_t<u64>>());

		// Write the real ELF file back.
		fs::file e = fs::make_stream<std::vector<u8>>();

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

		s = std::move(e);
		return true;
	}

	// Leave the file untouched.
	return false;
}
Beispiel #4
0
void Elf32_Phdr::LoadLE(const fs::file& f)
{
	f.read(this, sizeof(*this));
}
Beispiel #5
0
inline u64 Read64LE(const fs::file& f)
{
	u64 ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #6
0
void Signature::Load(const fs::file& f)
{
	f.read(r, 21);
	f.read(s, 21);
	f.read(padding, 6);
}
Beispiel #7
0
void SectionHash::Load(const fs::file& f)
{
	f.read(sha1, 20);
	f.read(padding, 12);
	f.read(hmac_key, 64);
}
Beispiel #8
0
inline u32 Read32LE(const fs::file& f)
{
	u32 ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #9
0
inline u16 Read16LE(const fs::file& f)
{
	u16 ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #10
0
inline u64 Read64(const fs::file& f)
{
	be_t<u64> ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #11
0
inline u32 Read32(const fs::file& f)
{
	be_t<u32> ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #12
0
inline u16 Read16(const fs::file& f)
{
	be_t<u16> ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #13
0
inline u8 Read8(const fs::file& f)
{
	u8 ret;
	f.read(&ret, sizeof(ret));
	return ret;
}
Beispiel #14
0
	registry load_object(const fs::file& stream)
	{
		registry result;

		// Hack for empty input (TODO)
		if (!stream)
		{
			return result;
		}

		// Get header
		header_t header;
		verify(HERE), stream.read(header);

		// Check magic and version
		verify(HERE),
			header.magic == "\0PSF"_u32,
			header.version == 0x101,
			sizeof(header_t) + header.entries_num * sizeof(def_table_t) <= header.off_key_table,
			header.off_key_table <= header.off_data_table,
			header.off_data_table <= stream.size();

		// Get indices
		std::vector<def_table_t> indices;
		verify(HERE), stream.read(indices, header.entries_num);

		// Get keys
		std::string keys;
		verify(HERE), stream.seek(header.off_key_table) == header.off_key_table;
		verify(HERE), stream.read(keys, header.off_data_table - header.off_key_table);

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

			// Get key name (null-terminated string)
			std::string key(keys.data() + indices[i].key_off);

			// Check entry
			verify(HERE),
				result.count(key) == 0,
				indices[i].param_len <= indices[i].param_max,
				indices[i].data_off < stream.size() - header.off_data_table,
				indices[i].param_max < stream.size() - indices[i].data_off;

			// Seek data pointer
			stream.seek(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
				le_t<u32> value;
				verify(HERE), stream.read(value);

				result.emplace(std::piecewise_construct,
					std::forward_as_tuple(std::move(key)),
					std::forward_as_tuple(value));
			}
			else if (indices[i].param_fmt == format::string || indices[i].param_fmt == format::array)
			{
				// String/array data
				std::string value;
				verify(HERE), stream.read(value, indices[i].param_len);

				if (indices[i].param_fmt == format::string)
				{
					// Find null terminator
					value.resize(std::strlen(value.c_str()));
				}

				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(LOADER, "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;
	}