static Uint32 locate_in_zip(el_zip_file_t* zip, const el_zip_file_entry_t* key)
{
	el_zip_file_entry_t* file;

	if ((zip == 0) || (key == 0))
	{
		LOG_ERROR("Invalid key or zip");

		return 0;
	}

	if (zip->count == 0)
	{
		return 0;
	}

	file = (el_zip_file_entry_t*) bsearch(key, zip->files, zip->count,
		sizeof(el_zip_file_entry_t), compare_el_zip_file_entry);

	if (file != 0)
	{
		unzGoToFilePos64(zip->file, &file->position);

		return 1;
	}
	else
	{
		return 0;
	}
}
Exemple #2
0
int archiveFileOpen(const char *file, int flags, SceMode mode) {
	int res;

	if (!uf)
		return -1;

	const char *archive_path = file + archive_path_start;	
	int name_length = strlen(archive_path);

	FileListEntry *archive_entry = archive_list.head;

	int i;
	for (i = 0; i < archive_list.length; i++) {
		if (archive_entry->name_length == name_length && strcasecmp(archive_entry->name, archive_path) == 0) {
			// Set pos
			unzGoToFilePos64(uf, (unz64_file_pos *)&archive_entry->reserved);

			// Open
			res = unzOpenCurrentFile(uf);
			if (res < 0)
				return res;

			return ARCHIVE_FD;
		}

		// Next
		archive_entry = archive_entry->next;
	}

	return -1;
}
Exemple #3
0
CZipStream::CZipStream(std::shared_ptr<CIOApi> api, const boost::filesystem::path & archive, unz64_file_pos filepos)
{
	zlib_filefunc64_def zlibApi;

	zlibApi = api->getApiStructure();

	file = unzOpen2_64(archive.c_str(), &zlibApi);
	unzGoToFilePos64(file, &filepos);
	unzOpenCurrentFile(file);
}
Exemple #4
0
char *ZipFile::GetFileDataByIdx(size_t fileindex, size_t *len)
{
    if (!uf)
        return NULL;
    if (fileindex >= filenames.Count())
        return NULL;

    int err = -1;
    if (filepos.At(fileindex).num_of_file != INVALID_ZIP_FILE_POS)
        err = unzGoToFilePos64(uf, &filepos.At(fileindex));
    if (err != UNZ_OK) {
        char fileNameA[MAX_PATH];
        UINT cp = (fileinfo.At(fileindex).flag & (1 << 11)) ? CP_UTF8 : CP_ZIP;
        str::conv::ToCodePageBuf(fileNameA, dimof(fileNameA), filenames.At(fileindex), cp);
        err = unzLocateFile(uf, fileNameA, 0);
    }
    if (err != UNZ_OK)
        return NULL;
    err = unzOpenCurrentFilePassword(uf, NULL);
    if (err != UNZ_OK)
        return NULL;

    unsigned int len2 = (unsigned int)fileinfo.At(fileindex).uncompressed_size;
    // overflow check
    if (len2 != fileinfo.At(fileindex).uncompressed_size ||
        len2 + sizeof(WCHAR) < sizeof(WCHAR) ||
        len2 / 1024 > fileinfo.At(fileindex).compressed_size) {
        unzCloseCurrentFile(uf);
        return NULL;
    }

    char *result = (char *)Allocator::Alloc(allocator, len2 + sizeof(WCHAR));
    if (result) {
        unsigned int readBytes = unzReadCurrentFile(uf, result, len2);
        // zero-terminate for convenience
        result[len2] = result[len2 + 1] = '\0';
        if (readBytes != len2) {
            Allocator::Free(allocator, result);
            result = NULL;
        }
        else if (len) {
            *len = len2;
        }
    }

    err = unzCloseCurrentFile(uf);
    if (err != UNZ_OK) {
        // CRC mismatch, file content is likely damaged
        Allocator::Free(allocator, result);
        result = NULL;
    }

    return result;
}
Exemple #5
0
HRESULT WINAPI CZipFs::Close(void)
{
	HRESULT hr = S_OK;
	if (m_handle != INVALID_HANDLE_VALUE && m_handle != NULL)
	{
		hr = (unzCloseCurrentFile((void*)m_handle) == UNZ_OK) ? S_OK : E_FAIL;

		if (SUCCEEDED(hr))
		{
			if (UNZ_OK != unzGoToFilePos64((void*)m_handle, &m_currentFilePos))
				hr = E_UNEXPECTED;
		}
	}
	
	m_handle = INVALID_HANDLE_VALUE;
	m_stream->SetFileHandle(m_handle);
	return hr;
}
Exemple #6
0
int archiveCheckFilesForUnsafeFself() {
	if (!uf)
		return -1;

	FileListEntry *archive_entry = archive_list.head;

	int i;
	for (i = 0; i < archive_list.length; i++) {
		// Set pos
		unzGoToFilePos64(uf, (unz64_file_pos *)&archive_entry->reserved);

		// Open
		if (unzOpenCurrentFile(uf) >= 0) {
			uint32_t magic = 0;
			archiveFileRead(ARCHIVE_FD, &magic, sizeof(uint32_t));

			// SCE magic
			if (magic == 0x00454353) {
				char sce_header[0x84];
				archiveFileRead(ARCHIVE_FD, sce_header, sizeof(sce_header));

				uint64_t elf1_offset = *(uint64_t *)(sce_header + 0x3C);
				uint64_t phdr_offset = *(uint64_t *)(sce_header + 0x44);
				uint64_t section_info_offset = *(uint64_t *)(sce_header + 0x54);

				int i;
				// jump to elf1
				// Until here we have read 0x88 bytes
				for (i = 0; i < elf1_offset - 0x88; i += sizeof(uint32_t)) {
					uint32_t dummy = 0;
					archiveFileRead(ARCHIVE_FD, &dummy, sizeof(uint32_t));
				}

				// Check imports
				char *buffer = malloc(archive_entry->size);
				if (buffer) {
					int size = archiveFileRead(ARCHIVE_FD, buffer, archive_entry->size);

					Elf32_Ehdr *elf1 = (Elf32_Ehdr*)buffer;
					Elf32_Phdr *phdr = (Elf32_Phdr*)(buffer + phdr_offset - elf1_offset);
					segment_info *info = (segment_info*)(buffer + section_info_offset - elf1_offset);
					// segment is elf2 section
					char *segment = buffer + info->offset - elf1_offset;

					// zlib compress magic
					char *uncompressed_buffer = NULL;
					if (segment[0] == 0x78) {
						// uncompressedBuffer will return elf2 section
						uncompressed_buffer = uncompressBuffer(elf1, phdr, info, segment);
						if (uncompressed_buffer) {
							segment = uncompressed_buffer;
						}
					}
					int unsafe = checkForUnsafeImports(segment);

					if (uncompressed_buffer) {
						free(uncompressed_buffer);
					}
					free(buffer);


					if (unsafe) {
						archiveFileClose(ARCHIVE_FD);
						return unsafe;
					}
				}

				// Check authid flag
				uint64_t authid = *(uint64_t *)(sce_header + 0x7C);
				if (authid != 0x2F00000000000002) {
					archiveFileClose(ARCHIVE_FD);
					return 1; // Unsafe
				}
			}

			archiveFileClose(ARCHIVE_FD);
		}

		// Next
		archive_entry = archive_entry->next;
	}

	return 0; // Safe
}