Exemple #1
0
format value::pp(bool unicode) const { return unicode ? format(get_unicode_name()) : pp(); }
Exemple #2
0
vba_project_t *
cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
{
	unsigned char *buf;
	const unsigned char vba56_signature[] = { 0xcc, 0x61 };
	uint16_t record_count, buflen, ffff, byte_count;
	uint32_t offset;
	int i, j, fd, big_endian = FALSE;
	vba_project_t *vba_project;
	struct vba56_header v56h;
	off_t seekback;
	char fullname[1024], *hash;

	cli_dbgmsg("in cli_vba_readdir()\n");

	if(dir == NULL)
		return NULL;

	/*
	 * _VBA_PROJECT files are embedded within office documents (OLE2)
	 */
	
	if (!uniq_get(U, "_vba_project", 12, &hash))
		return NULL;
	snprintf(fullname, sizeof(fullname), "%s"PATHSEP"%s_%u", dir, hash, which);
	fullname[sizeof(fullname)-1] = '\0';
	fd = open(fullname, O_RDONLY|O_BINARY);

	if(fd == -1)
		return NULL;

	if(cli_readn(fd, &v56h, sizeof(struct vba56_header)) != sizeof(struct vba56_header)) {
		close(fd);
		return NULL;
	}
	if (memcmp(v56h.magic, vba56_signature, sizeof(v56h.magic)) != 0) {
		close(fd);
		return NULL;
	}

	i = vba_read_project_strings(fd, TRUE);
	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;
	}
	j = vba_read_project_strings(fd, FALSE);
	if(!i && !j) {
		close(fd);
		cli_dbgmsg("vba_readdir: Unable to guess VBA type\n");
		return NULL;
	}
	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");
			close(fd);
			return NULL;
		}
		cli_dbgmsg("vba_readdir: Guessing big-endian\n");
	} else {
		cli_dbgmsg("vba_readdir: Guessing little-endian\n");
	}

	/* junk some more stuff */
	do
		if (cli_readn(fd, &ffff, 2) != 2) {
			close(fd);
			return NULL;
		}
	while(ffff != 0xFFFF);

	/* check for alignment error */
	if(!seekandread(fd, -3, SEEK_CUR, &ffff, sizeof(uint16_t))) {
		close(fd);
		return NULL;
	}
	if (ffff != 0xFFFF) {
		if (lseek(fd, 1, SEEK_CUR) == -1) {
            cli_dbgmsg("call to lseek() while checking alignment error has failed\n");
            close(fd);
            return NULL;
        }
    }

	if(!read_uint16(fd, &ffff, big_endian)) {
		close(fd);
		return NULL;
	}

	if(ffff != 0xFFFF) {
		if (lseek(fd, ffff, SEEK_CUR) == -1) {
            cli_dbgmsg("call to lseek() while checking alignment error has failed\n");
            close(fd);
            return NULL;
        }
    }

	if(!read_uint16(fd, &ffff, big_endian)) {
		close(fd);
		return NULL;
	}

	if(ffff == 0xFFFF)
		ffff = 0;

	if (lseek(fd, ffff + 100, SEEK_CUR) == -1) {
        cli_dbgmsg("call to lseek() failed\n");
        close(fd);
        return NULL;
    }

	if(!read_uint16(fd, &record_count, big_endian)) {
		close(fd);
		return NULL;
	}
	cli_dbgmsg("vba_readdir: VBA Record count %d\n", record_count);
	if (record_count == 0) {
		/* No macros, assume clean */
		close(fd);
		return NULL;
	}
	if (record_count > MAX_VBA_COUNT) {
		/* Almost certainly an error */
		cli_dbgmsg("vba_readdir: VBA Record count too big\n");
		close(fd);
		return NULL;
	}

	vba_project = create_vba_project(record_count, dir, U);
	if(vba_project == NULL) {
		close(fd);
		return NULL;
	}
	buf = NULL;
	buflen = 0;
	for(i = 0; i < record_count; i++) {
		uint16_t length;
		char *ptr;

		vba_project->colls[i] = 0;
		if(!read_uint16(fd, &length, big_endian))
			break;

		if (length == 0) {
			cli_dbgmsg("vba_readdir: zero name length\n");
			break;
		}
		if(length > buflen) {
			unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
			if(newbuf == NULL)
				break;
			buflen = length;
			buf = newbuf;
		}
		if (cli_readn(fd, buf, length) != length) {
			cli_dbgmsg("vba_readdir: read name failed\n");
			break;
		}
		ptr = get_unicode_name((const char *)buf, length, big_endian);
		if(ptr == NULL) break;
		if (!(vba_project->colls[i]=uniq_get(U, ptr, strlen(ptr), &hash))) {
			cli_dbgmsg("vba_readdir: cannot find project %s (%s)\n", ptr, hash);
			free(ptr);
			break;
		}
		cli_dbgmsg("vba_readdir: project name: %s (%s)\n", ptr, hash);
		free(ptr);
		vba_project->name[i] = hash;
		if(!read_uint16(fd, &length, big_endian))
			break;
		lseek(fd, length, SEEK_CUR);

		if(!read_uint16(fd, &ffff, big_endian))
			break;
		if (ffff == 0xFFFF) {
			lseek(fd, 2, SEEK_CUR);
			if(!read_uint16(fd, &ffff, big_endian))
				break;
			lseek(fd, ffff + 8, SEEK_CUR);
		} else
			lseek(fd, ffff + 10, SEEK_CUR);

		if(!read_uint16(fd, &byte_count, big_endian))
			break;
		lseek(fd, (8 * byte_count) + 5, SEEK_CUR);
		if(!read_uint32(fd, &offset, big_endian))
			break;
		cli_dbgmsg("vba_readdir: offset: %u\n", (unsigned int)offset);
		vba_project->offset[i] = offset;
		lseek(fd, 2, SEEK_CUR);
	}

	if(buf)
		free(buf);

	close(fd);

	if(i < record_count) {
		free(vba_project->name);
		free(vba_project->colls);
		free(vba_project->dir);
		free(vba_project->offset);
		free(vba_project);
		return NULL;
	}

	return vba_project;
}
Exemple #3
0
static int
vba_read_project_strings(int fd, int big_endian)
{
	unsigned char *buf = NULL;
	uint16_t buflen = 0;
	int ret = 0;

	for(;;) {
		off_t offset;
		uint16_t length;
		char *name;

		if(!read_uint16(fd, &length, big_endian))
			break;

		if (length < 6) {
			lseek(fd, -2, SEEK_CUR);
			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;
		}

		offset = lseek(fd, 0, SEEK_CUR);

		if(cli_readn(fd, buf, length) != (int)length) {
			cli_dbgmsg("read name failed - rewinding\n");
			lseek(fd, offset, SEEK_SET);
			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 */
			lseek(fd, -(length+2), SEEK_CUR);
			if(name)
				free(name);
			break;
		}
		free(name);

		if(!read_uint16(fd, &length, big_endian)) {
			if(buf)
				free(buf);
			break;
		}

		ret++;

		if ((length != 0) && (length != 65535)) {
			lseek(fd, -2, SEEK_CUR);
			continue;
		}
		offset = lseek(fd, 10, SEEK_CUR);
		cli_dbgmsg("offset: %lu\n", (unsigned long)offset);
		vba56_test_middle(fd);
	}
	if(buf)
		free(buf);
	return ret;
}
Exemple #4
0
/* return count of valid strings found, 0 on error */
static int
vba_read_project_strings(int fd, int big_endian)
{
    unsigned char *buf = NULL;
    uint16_t buflen = 0;
    uint16_t length = 0;
    int ret = 0, getnewlength = 1;

    for(;;) {
        off_t offset;
        char *name;

        /* if no initial name length, exit */
        if(getnewlength && !read_uint16(fd, &length, big_endian)) {
            ret = 0;
            break;
        }
        getnewlength = 0;

        /* if too short, break */
        if (length < 6) {
            if (lseek(fd, -2, SEEK_CUR) == -1) {
                cli_dbgmsg("vba_read_project_strings: call to lseek() has failed\n");
                ret = 0;
            }
            break;
        }
        /* ensure buffer is large enough */
        if(length > buflen) {
            unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
            if(newbuf == NULL) {
                ret = 0;
                break;
            }
            buflen = length;
            buf = newbuf;
        }

        /* save current offset */
        offset = lseek(fd, 0, SEEK_CUR);
        if (offset == -1) {
            cli_dbgmsg("vba_read_project_strings: call to lseek() has failed\n");
            ret = 0;
            break;
        }

        /* if read name failed, break */
        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");
                ret = 0;
            }
            break;
        }
        name = get_unicode_name((const char *)buf, length, big_endian);
        cli_dbgmsg("length: %d, name: %s\n", length, (name) ? name : "[null]");

        /* if invalid name, break */
        if((name == NULL) || (memcmp("*\\", name, 2) != 0) ||
           (strchr("ghcd", name[2]) == NULL)) {
            /* Not a valid string, rewind */
            if (lseek(fd, -(length+2), SEEK_CUR) == -1) {
                cli_dbgmsg("call to lseek() after get_unicode_name has failed\n");
                ret = 0;
            }
            free(name);
            break;
        }
        free(name);

        /* can't get length, break */
        if(!read_uint16(fd, &length, big_endian)) {
            break;
        }

        ret++;

        /* continue on reasonable length value */
        if ((length != 0) && (length != 65535)) {
            continue;
        }

        /* determine offset and run middle test */
        offset = lseek(fd, 10, SEEK_CUR);
        if (offset == -1) {
            cli_dbgmsg("call to lseek() has failed\n");
            ret = 0;
            break;
        }
        cli_dbgmsg("offset: %lu\n", (unsigned long)offset);
        vba56_test_middle(fd);
        getnewlength = 1;
    }

    free(buf);
    return ret;
}
Exemple #5
0
void wm_decode_macro (unsigned char *buff, uint32_t len, int hex_output)
{
    int i, j;
    uint8_t s_length;
    uint16_t w_length, int_val;
    unsigned char *tmp_buff, *tmp_name, *line_start;

    i = 2;
    line_start = buff;
    while (i < len) {
	switch (buff[i]) {
	case 0x65:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    print_hex_buff (line_start, buff + i + 2 + s_length, hex_output);
	    printf ("\n%s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    line_start = buff + i;
	    break;
	case 0x69:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf (" %s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x6a:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf (" \"%s\"", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x6b:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf (" '%s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x6d:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf (" %s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x70:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf ("REM%s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x76:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf (" .%s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x77:
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc (s_length + 1);
	    strncpy ((char *) tmp_buff, (char *) (buff + i + 2), s_length);
	    tmp_buff[s_length] = '\0';
	    printf ("%s", tmp_buff);
	    free (tmp_buff);
	    i += 2 + s_length;
	    break;
	case 0x79:		/* unicode "string" */
	    w_length = (uint16_t) (buff[i + 2] << 8) + buff[i + 1];
	    tmp_buff = (unsigned char *) malloc ((w_length * 2) + 1);
	    memcpy (tmp_buff, buff + i + 3, w_length * 2);
	    tmp_name = (unsigned char *) get_unicode_name ((char *) tmp_buff, w_length * 2);
	    free (tmp_buff);
	    printf ("\"%s\"", tmp_name);
	    free (tmp_name);
	    i += 3 + (w_length * 2);
	    break;

	case 0x7c:		/* unicode 'string */
	    s_length = (uint8_t) buff[i + 1];
	    tmp_buff = (unsigned char *) malloc ((s_length * 2) + 1);
	    memcpy (tmp_buff, buff + i + 2, s_length * 2);
	    tmp_name = (unsigned char *) get_unicode_name ((char *) tmp_buff, s_length * 2);
	    free (tmp_buff);
	    printf ("'%s", tmp_name);
	    free (tmp_name);
	    i += 2 + (s_length * 2);
	    break;

	case 0x66:
	    int_val = (uint8_t) (buff[i + 2] << 8) + buff[i + 1];
	    print_hex_buff (line_start, buff + i + 3, hex_output);
	    printf ("\n%d", int_val);
	    i += 3;
	    line_start = buff + i;
	    break;
	case 0x67:
	    w_length = (uint16_t) (buff[i + 2] << 8) + buff[i + 1];
	    output_token67 (w_length);
	    i += 3;
	    break;
	case 0x68:
	    /* 8-byte float */
	    printf ("(float)");
	    i += 9;
	    break;
	case 0x6c:
	    int_val = (uint16_t) (buff[i + 2] << 8) + buff[i + 1];
	    printf (" %d", int_val);
	    i += 3;
	    break;
	case 0x6e:
	    s_length = (uint8_t) buff[i + 1];
	    for (j = 0; j < s_length; j++) {
		printf (" ");
	    }
	    i += 2;
	    break;
	case 0x6f:
	    s_length = (uint8_t) buff[i + 1];
	    for (j = 0; j < s_length; j++) {
		printf ("\t");
	    }
	    i += 2;
	    break;
	case 0x73:
	    w_length = (uint16_t) (buff[i + 2] << 8) + buff[i + 1];
	    output_token73 (w_length);
	    i += 3;
	    break;
	case 0x64:
	    print_hex_buff (line_start, buff + i + 1, hex_output);
	    printf ("\n");
	    i++;
	    line_start = buff + i;
	    break;
	default:
	    output_token (buff[i]);
	    i++;
	    break;
	}
    }
    print_hex_buff (line_start, buff + i, hex_output);
}