Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Needs to decode other types inside grf #8

Open
carloshenrq opened this issue Mar 4, 2019 · 0 comments
Open

Needs to decode other types inside grf #8

carloshenrq opened this issue Mar 4, 2019 · 0 comments

Comments

@carloshenrq
Copy link
Owner

Needs to add the decrypt and decode methods for files.

https://github.com/carloshenrq/grf/blob/master/includes/libgrf.h#L72-L77

/* do not ask questions about that */
#define GRF_FLAG_FILE 1
#define GRF_FLAG_MIXCRYPT 2
#define GRF_FLAG_DES 4
/* extra custom-flag to delete a file while updating */
#define GRF_FLAG_DELETE 8

https://github.com/carloshenrq/grf/blob/master/src/grf.c#L1104-L1121

GRFEXPORT uint32_t grf_file_get_contents(grf_node fhandler, void *target) {
	void *comp;
	struct grf_handler *handler;
	uint32_t count;
	handler = fhandler->parent;
	if ((fhandler->flags & GRF_FLAG_FILE) == 0) return 0; // not a file
	comp = calloc(1, fhandler->len_aligned + 1024); // seems that we need to allocate 1024 more bytes to decrypt file safely
	lseek(handler->fd, fhandler->pos + GRF_HEADER_SIZE, SEEK_SET);
	count = read(handler->fd, (char *)comp, fhandler->len_aligned);
	if (count != fhandler->len_aligned) { free(comp); return 0; }
	// decrypt (if required)
	//static void decode_des_etc(unsigned char *buf, int len, int type, int cycle) 
	if (fhandler->cycle >= 0) decode_des_etc((unsigned char *)comp, fhandler->len_aligned, (fhandler->cycle)==0, fhandler->cycle);
	// decompress to target...
	count = zlib_buffer_inflate(target, fhandler->size, comp, fhandler->len);
	free(comp);
	return count;
}

https://github.com/carloshenrq/grf/blob/master/src/grf.c#L892-L964

			if (fstat(handler->fd, (struct stat *)&grfstat) != 0) return false;
			if ((handler->table_offset + GRF_HEADER_SIZE) > grfstat.st_size) return false;

			lseek(handler->fd, handler->table_offset + GRF_HEADER_SIZE, SEEK_SET);
			if (read(handler->fd, (void *)&posinfo, sizeof(posinfo)) != sizeof(posinfo)) return false;
			// posinfo[0] = comp size
			// posinfo[1] = decomp size

			if ((handler->table_offset + GRF_HEADER_SIZE + 8 + posinfo[0]) > grfstat.st_size) return false;
			table_comp = malloc(posinfo[0]);
			table = malloc(posinfo[1]);
			if (read(handler->fd, table_comp, posinfo[0]) != posinfo[0]) { free(table); free(table_comp); return false; }
			if (zlib_buffer_inflate(table, posinfo[1], table_comp, posinfo[0]) != posinfo[1]) { free(table); free(table_comp); return false; }

			free(table_comp);

			pos = table;
			pos_max = table + posinfo[1];
			result = handler->filecount;
			wasted_space = grfstat.st_size - GRF_HEADER_SIZE - 8 - posinfo[0]; // in theory, all this space should be used for files
			while(pos < pos_max) {
				size_t av_len = pos_max - pos;
				int fn_len = prv_grf_strnlen((char *)pos, av_len);
				struct grf_table_entry_data tmpentry;
				result--;
				if (fn_len + sizeof(struct grf_table_entry_data) > av_len) { free(table); return false; }
				entry = calloc(1, sizeof(struct grf_node));
				entry->filename = calloc(1, fn_len + 1);
				memcpy(entry->filename, pos, fn_len); // fn_len + 1 is already 0x00
				pos += fn_len + 1;
				memcpy((void *)&tmpentry, pos, sizeof(struct grf_table_entry_data));
				pos += sizeof(struct grf_table_entry_data);
				if ( ((tmpentry.flags & GRF_FLAG_FILE) == 0) || (tmpentry.size == 0)) {
					// do not register "directory" entries and empty(bogus) files
					free(entry->filename);
					free(entry);
					continue;
				}
				entry->flags = tmpentry.flags;
				entry->size = tmpentry.size;
				entry->len = tmpentry.len;
				entry->len_aligned = tmpentry.len_aligned;
				entry->pos = tmpentry.pos;
				entry->parent = handler;
				entry->cycle = -1;
				if (entry->flags & GRF_FLAG_MIXCRYPT) {
					entry->cycle = 1;
					for(int i=10; entry->len>=i; i=i*10) entry->cycle++;
				}
				if (entry->flags & GRF_FLAG_DES) {
					entry->cycle = 0;
				}
				wasted_space -= tmpentry.len_aligned;

				if (last == NULL) {
					last = entry;
					handler->first_node = entry;
				} else {
					last->next = entry;
					entry->prev = last;
					last = entry;
				}
				hash_add_element(handler->fast_table, entry->filename, entry);
				if (--hcall<=0) {
					hcall = 100;
					if (handler->callback != NULL) {
						if (!handler->callback(handler->callback_etc, handler, handler->filecount - result, handler->filecount, entry->filename)) return false;
					}
				}
			}
			free(table);
			break;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant