示例#1
0
文件: bspatch.c 项目: 1butler1/xpwn
int patch(AbstractFile* in, AbstractFile* out, AbstractFile* patch) {
	unsigned char header[32], buf[8];
	off_t oldsize, newsize;
	off_t bzctrllen, bzdatalen;
	off_t oldpos, newpos;
	int i;
	int cbz2err, dbz2err, ebz2err;
	off_t ctrl[3];
	size_t lenread;
	
	BZStream* cpfbz2;
	BZStream* dpfbz2;
	BZStream* epfbz2;
	
	/* Read header */
	if (patch->read(patch, header, 32) < 32) {
		return -1;
	}
	
	/* Check for appropriate magic */
	if (memcmp(header, "BSDIFF40", 8) != 0)
		return -2;
		
	/* Read lengths from header */
	bzctrllen = offtin(header + 8);
	bzdatalen = offtin(header + 16);
	newsize = offtin(header + 24);

	if((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0))
		return -3;
		
	cpfbz2 = openBZStream(patch, 32, 1024);
	dpfbz2 = openBZStream(patch, 32 + bzctrllen, 1024);
	epfbz2 = openBZStream(patch, 32 + bzctrllen + bzdatalen, 1024);
	
	oldsize = in->getLength(in);
	
	oldpos = 0;
	newpos = 0;
	unsigned char* writeBuffer = (unsigned char*) malloc(BUFFERSIZE);
	unsigned char* readBuffer = (unsigned char*) malloc(BUFFERSIZE);

	while(newpos < newsize) {
		/* Read control data */
		for(i=0;i<=2;i++) {
			lenread = bzRead(&cbz2err, cpfbz2, buf, 8);
			if ((lenread < 8) || ((cbz2err != BZ_OK) &&
			    (cbz2err != BZ_STREAM_END)))
				return -4;
			ctrl[i] = offtin(buf);
		};
			
		/* Sanity-check */
		if((newpos + ctrl[0]) > newsize)
			return -5;

		/* Read diff string */
		unsigned int toRead;
		unsigned int total = ctrl[0];
		while(total > 0) {
			if(total > BUFFERSIZE)
				toRead = BUFFERSIZE;
			else
				toRead = total;

			memset(writeBuffer, 0, toRead);
			lenread = bzRead(&dbz2err, dpfbz2, writeBuffer, toRead);
			if ((lenread < toRead) ||
			    ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
				return -6;

			/* Add old data to diff string */
			in->seek(in, oldpos);
			unsigned int maxRead;
			if((oldpos + toRead) > oldsize)
				maxRead = oldsize - oldpos;
			else
				maxRead = toRead;

			in->read(in, readBuffer, maxRead);
			for(i = 0; i < maxRead; i++) {
				writeBuffer[i] += readBuffer[i];
			}

			out->seek(out, newpos);
			out->write(out, writeBuffer, toRead);

			/* Adjust pointers */
			newpos += toRead;
			oldpos += toRead;
			total -= toRead;
		}

		/* Sanity-check */
		if((newpos + ctrl[1]) > newsize)
			return -7;

		total = ctrl[1];

		while(total > 0){ 
			if(total > BUFFERSIZE)
				toRead = BUFFERSIZE;
			else
				toRead = total;

			/* Read extra string */
			lenread = bzRead(&ebz2err, epfbz2, writeBuffer, toRead);
			if ((lenread < toRead) ||
			    ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
				return -8;

			out->seek(out, newpos);
			out->write(out, writeBuffer, toRead);
			
			/* Adjust pointers */
			newpos += toRead;
			total -= toRead;
		}

		oldpos += ctrl[2];
	};
	
	free(writeBuffer);
	free(readBuffer);

	closeBZStream(cpfbz2);
	closeBZStream(dpfbz2);
	closeBZStream(epfbz2);

	out->close(out);
	in->close(in);

	patch->close(patch);
	return 0;
}
示例#2
0
文件: bspatch.c 项目: Nitaym/xpwn
int patch(AbstractFile* in, AbstractFile* out, AbstractFile* patch) {
	unsigned char header[32], buf[8];
	off_t oldsize, newsize;
	off_t bzctrllen, bzdatalen;
	off_t oldpos, newpos;
	unsigned char *old, *newBuffer;
	int i;
	int cbz2err, dbz2err, ebz2err;
	off_t ctrl[3];
	size_t lenread;
	
	BZStream* cpfbz2;
	BZStream* dpfbz2;
	BZStream* epfbz2;
	
	/* Read header */
	if (patch->read(patch, header, 32) < 32) {
		return -1;
	}
	
	/* Check for appropriate magic */
	if (memcmp(header, "BSDIFF40", 8) != 0)
		return -2;
		
	/* Read lengths from header */
	bzctrllen = offtin(header + 8);
	bzdatalen = offtin(header + 16);
	newsize = offtin(header + 24);

	if((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0))
		return -3;
		
	cpfbz2 = openBZStream(patch, 32, 1024);
	dpfbz2 = openBZStream(patch, 32 + bzctrllen, 1024);
	epfbz2 = openBZStream(patch, 32 + bzctrllen + bzdatalen, 1024);
	
	oldsize = in->getLength(in);
	old = malloc(oldsize + 1);
	in->seek(in, 0);
	in->read(in, old, oldsize);
	in->close(in);
	
	newBuffer = malloc(newsize + 1);
	
	oldpos = 0;
	newpos = 0;
	while(newpos < newsize) {
		/* Read control data */
		for(i=0;i<=2;i++) {
			lenread = bzRead(&cbz2err, cpfbz2, buf, 8);
			if ((lenread < 8) || ((cbz2err != BZ_OK) &&
			    (cbz2err != BZ_STREAM_END)))
				return -4;
			ctrl[i] = offtin(buf);
		};
			
		/* Sanity-check */
		if((newpos + ctrl[0]) > newsize)
			return -5;

		/* Read diff string */
		memset(newBuffer + newpos, 0, ctrl[0]);
		lenread = bzRead(&dbz2err, dpfbz2, newBuffer + newpos, ctrl[0]);
		if ((lenread < ctrl[0]) ||
		    ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END)))
			return -6;

		/* Add old data to diff string */
		for(i = 0; i < ctrl[0]; i++) {
			if(((oldpos + i)>=0) && ((oldpos + i)<oldsize)) {
				newBuffer[newpos + i] += old[oldpos + i];
			}
		}
				
		/* Adjust pointers */
		newpos += ctrl[0];
		oldpos += ctrl[0];

		/* Sanity-check */
		if((newpos + ctrl[1]) > newsize)
			return -7;

		/* Read extra string */
		lenread = bzRead(&ebz2err, epfbz2, newBuffer + newpos, ctrl[1]);
		if ((lenread < ctrl[1]) ||
		    ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END)))
			return -8;
			
		/* Adjust pointers */
		newpos += ctrl[1];
		oldpos += ctrl[2];
	};
	
	closeBZStream(cpfbz2);
	closeBZStream(dpfbz2);
	closeBZStream(epfbz2);
	out->seek(out, 0);

	if(out->write(out, newBuffer, newsize) != newsize)
		return -9;
	out->close(out);
	free(newBuffer);
	free(old);

	patch->close(patch);
	return 0;
}