static void addToBlob(const line_t *line, void *arg) { blob *b = (blob *)arg; if(line) { const char *l = lineGetData(line); blobAddData(b, (const unsigned char *)l, strlen(l)); } blobAddData(b, (const unsigned char *)"\n", 1); }
int fileblobAddData(fileblob *fb, const unsigned char *data, size_t len) { if(len == 0) return 0; assert(data != NULL); if(fb->fp) { #if defined(MAX_SCAN_SIZE) && (MAX_SCAN_SIZE > 0) const cli_ctx *ctx = fb->ctx; if(fb->isInfected) /* pretend all was written */ return 0; if(ctx) { int do_scan = 1; if(cli_checklimits("fileblobAddData", ctx, fb->bytes_scanned, 0, 0)!=CL_CLEAN) do_scan = 0; if(fb->bytes_scanned > MAX_SCAN_SIZE) do_scan = 0; if(do_scan) { if(ctx->scanned) *ctx->scanned += (unsigned long)len / CL_COUNT_PRECISION; fb->bytes_scanned += (unsigned long)len; if((len > 5) && cli_updatelimits(ctx, len)==CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, 0, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) { cli_dbgmsg("fileblobAddData: found %s\n", cli_get_last_virus_str(ctx->virname)); fb->isInfected = 1; } } } #endif if(fwrite(data, len, 1, fb->fp) != 1) { cli_errmsg("fileblobAddData: Can't write %lu bytes to temporary file %s\n", (unsigned long)len, fb->b.name); return -1; } fb->isNotEmpty = 1; return 0; } return blobAddData(&(fb->b), data, len); }
unsigned char * cli_vba_inflate(int fd, off_t offset, int *size) { unsigned int pos, shift, mask, distance, clean; uint8_t flag; uint16_t token; blob *b; unsigned char buffer[VBA_COMPRESSION_WINDOW]; if(fd < 0) return NULL; b = blobCreate(); if(b == NULL) return NULL; lseek(fd, offset+3, SEEK_SET); /* 1byte ?? , 2byte length ?? */ clean = TRUE; pos = 0; while (cli_readn(fd, &flag, 1) == 1) { for(mask = 1; mask < 0x100; mask<<=1) { unsigned int winpos = pos % VBA_COMPRESSION_WINDOW; if (flag & mask) { uint16_t len; unsigned int srcpos; if(!read_uint16(fd, &token, FALSE)) { blobDestroy(b); if(size) *size = 0; return NULL; } shift = 12 - (winpos > 0x10) - (winpos > 0x20) - (winpos > 0x40) - (winpos > 0x80) - (winpos > 0x100) - (winpos > 0x200) - (winpos > 0x400) - (winpos > 0x800); len = (uint16_t)((token & ((1 << shift) - 1)) + 3); distance = token >> shift; srcpos = pos - distance - 1; if((((srcpos + len) % VBA_COMPRESSION_WINDOW) < winpos) && ((winpos + len) < VBA_COMPRESSION_WINDOW) && (((srcpos % VBA_COMPRESSION_WINDOW) + len) < VBA_COMPRESSION_WINDOW) && (len <= VBA_COMPRESSION_WINDOW)) { srcpos %= VBA_COMPRESSION_WINDOW; memcpy(&buffer[winpos], &buffer[srcpos], len); pos += len; } else while(len-- > 0) { srcpos = (pos - distance - 1) % VBA_COMPRESSION_WINDOW; buffer[pos++ % VBA_COMPRESSION_WINDOW] = buffer[srcpos]; } } else { if((pos != 0) && (winpos == 0) && clean) { if (cli_readn(fd, &token, 2) != 2) { blobDestroy(b); if(size) *size = 0; return NULL; } (void)blobAddData(b, buffer, VBA_COMPRESSION_WINDOW); clean = FALSE; break; } if(cli_readn(fd, &buffer[winpos], 1) == 1) pos++; } clean = TRUE; }