David Raynor 12 years ago
parent 9eff941820
commit 80649b2842
  1. 135
      libclamav/vba_extract.c

@ -1,7 +1,7 @@
/*
* Extract VBA source code for component MS Office Documents
*
* Copyright (C) 2007-2008 Sourcefire, Inc.
* Copyright (C) 2007-2013 Sourcefire, Inc.
*
* Authors: Trog, Nigel Horne
*
@ -178,97 +178,94 @@ static void vba56_test_middle(int fd)
static int
vba_read_project_strings(int fd, int big_endian)
{
unsigned char *buf = NULL;
uint16_t buflen = 0;
int ret = 0;
unsigned char *buf = NULL;
uint16_t buflen = 0;
int ret = 0;
for(;;) {
off_t offset;
uint16_t length;
char *name;
for(;;) {
off_t offset;
uint16_t length;
char *name;
if(!read_uint16(fd, &length, big_endian))
break;
if(!read_uint16(fd, &length, big_endian))
break;
if (length < 6) {
if (lseek(fd, -2, SEEK_CUR) == -1) {
if (length < 6) {
if (lseek(fd, -2, SEEK_CUR) == -1) {
cli_dbgmsg("vba_read_project_strings: call to lseek() has failed\n");
return CL_ESEEK;
}
break;
}
if(length > buflen) {
unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
if(newbuf == NULL) {
if(buf)
free(buf);
return 0;
}
buflen = length;
buf = newbuf;
}
break;
}
if(length > buflen) {
unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
if(newbuf == NULL) {
free(buf);
return 0;
}
buflen = length;
buf = newbuf;
}
offset = lseek(fd, 0, SEEK_CUR);
offset = lseek(fd, 0, SEEK_CUR);
if (offset == -1) {
cli_dbgmsg("vba_read_project_strings: call to lseek() has failed\n");
return CL_ESEEK;
}
if(cli_readn(fd, buf, length) != (int)length) {
cli_dbgmsg("read name failed - rewinding\n");
if (lseek(fd, offset, SEEK_SET) == -1) {
if(cli_readn(fd, buf, length) != (int)length) {
cli_dbgmsg("read name failed - rewinding\n");
if (lseek(fd, offset, SEEK_SET) == -1) {
cli_dbgmsg("call to lseek() in read name failed\n");
return CL_ESEEK;
}
break;
}
name = get_unicode_name((const char *)buf, length, big_endian);
cli_dbgmsg("length: %d, name: %s\n", length, (name) ? name : "[null]");
break;
}
name = get_unicode_name((const char *)buf, length, big_endian);
cli_dbgmsg("length: %d, name: %s\n", length, (name) ? name : "[null]");
if((name == NULL) || (memcmp("*\\", name, 2) != 0) ||
(strchr("ghcd", name[2]) == NULL)) {
/* Not a string */
if (lseek(fd, -(length+2), SEEK_CUR) == -1) {
if((name == NULL) || (memcmp("*\\", name, 2) != 0) ||
(strchr("ghcd", name[2]) == NULL)) {
/* Not a string */
if (lseek(fd, -(length+2), SEEK_CUR) == -1) {
cli_dbgmsg("call to lseek() after get_unicode_name has failed\n");
if (name)
free(name);
free(name);
return CL_ESEEK;
}
if(name)
free(name);
break;
}
free(name);
free(name);
break;
}
free(name);
if(!read_uint16(fd, &length, big_endian)) {
if(buf) {
free(buf);
buf = NULL;
}
break;
}
if(!read_uint16(fd, &length, big_endian)) {
if(buf) {
free(buf);
buf = NULL;
}
break;
}
ret++;
ret++;
if ((length != 0) && (length != 65535)) {
if (lseek(fd, -2, SEEK_CUR) == -1) {
if ((length != 0) && (length != 65535)) {
if (lseek(fd, -2, SEEK_CUR) == -1) {
cli_dbgmsg("call to lseek() has failed\n");
free(buf);
return CL_ESEEK;
}
continue;
}
offset = lseek(fd, 10, SEEK_CUR);
continue;
}
offset = lseek(fd, 10, SEEK_CUR);
if (offset == -1) {
cli_dbgmsg("call to lseek() has failed\n");
return CL_ESEEK;
}
cli_dbgmsg("offset: %lu\n", (unsigned long)offset);
vba56_test_middle(fd);
}
if(buf)
free(buf);
return ret;
cli_dbgmsg("offset: %lu\n", (unsigned long)offset);
vba56_test_middle(fd);
}
free(buf);
return ret;
}
vba_project_t *
@ -312,8 +309,13 @@ cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
}
i = vba_read_project_strings(fd, TRUE);
seekback = lseek(fd, 0, SEEK_CUR);
if ((seekback = lseek(fd, 0, SEEK_CUR)) == -1) {
cli_dbgmsg("vba_readdir: lseek() failed. Unable to guess VBA type\n");
close(fd);
return NULL;
}
if (lseek(fd, sizeof(struct vba56_header), SEEK_SET) == -1) {
cli_dbgmsg("vba_readdir: lseek() failed. Unable to guess VBA type\n");
close(fd);
return NULL;
}
@ -326,9 +328,10 @@ cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
if (i > j) {
big_endian = TRUE;
if (lseek(fd, seekback, SEEK_SET) == -1) {
cli_dbgmsg("vba_readdir: call to lseek() while guessing big-endian has failed\n");
return NULL;
}
cli_dbgmsg("vba_readdir: call to lseek() while guessing big-endian has failed\n");
close(fd);
return NULL;
}
cli_dbgmsg("vba_readdir: Guessing big-endian\n");
} else {
cli_dbgmsg("vba_readdir: Guessing little-endian\n");

Loading…
Cancel
Save