git-svn: trunk@1480
Trog authored on 2005/04/15 03:42:13... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Thu Apr 14 19:39:49 BST 2005 (trog) |
|
2 |
+ * libclamav/scanners.c, libclamav/vba_extract.[ch]: |
|
3 |
+ Decode and scan OLE objects embedded in MS Office documents. |
|
4 |
+ |
|
1 | 5 |
Thu Apr 14 14:35:37 BST 2005 (trog) |
2 | 6 |
----------------------------------- |
3 | 7 |
* libclamav/scanners.c: Activate new RAR code. |
... | ... |
@@ -822,7 +822,7 @@ static int cli_scandir(const char *dirname, const char **virname, long int *scan |
822 | 822 |
|
823 | 823 |
static int cli_vba_scandir(const char *dirname, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec) |
824 | 824 |
{ |
825 |
- int ret = CL_CLEAN, i, fd, data_len; |
|
825 |
+ int ret = CL_CLEAN, i, fd, ofd, data_len; |
|
826 | 826 |
vba_project_t *vba_project; |
827 | 827 |
DIR *dd; |
828 | 828 |
struct dirent *dent; |
... | ... |
@@ -926,6 +926,22 @@ static int cli_vba_scandir(const char *dirname, const char **virname, long int * |
926 | 926 |
if(ret != CL_CLEAN) |
927 | 927 |
return ret; |
928 | 928 |
|
929 |
+ /* Check directory for embedded OLE objects */ |
|
930 |
+ fullname = (char *) cli_malloc(strlen(dirname) + 16); |
|
931 |
+ sprintf(fullname, "%s/_1_Ole10Native", dirname); |
|
932 |
+ fd = open(fullname, O_RDONLY); |
|
933 |
+ free(fullname); |
|
934 |
+ if (fd >= 0) { |
|
935 |
+ ofd = cli_decode_ole_object(fd, dirname); |
|
936 |
+ if (ofd >= 0) { |
|
937 |
+ ret = cli_scandesc(ofd, virname, scanned, root, 0, 0); |
|
938 |
+ close(ofd); |
|
939 |
+ } |
|
940 |
+ close(fd); |
|
941 |
+ if(ret != CL_CLEAN) |
|
942 |
+ return ret; |
|
943 |
+ } |
|
944 |
+ |
|
929 | 945 |
if((dd = opendir(dirname)) != NULL) { |
930 | 946 |
#ifdef HAVE_READDIR_R_3 |
931 | 947 |
while(!readdir_r(dd, &result.d, &dent) && dent) { |
... | ... |
@@ -42,6 +42,10 @@ |
42 | 42 |
#define FALSE (0) |
43 | 43 |
#define TRUE (1) |
44 | 44 |
|
45 |
+#ifndef MIN |
|
46 |
+#define MIN(a, b) (((a) < (b)) ? (a) : (b)) |
|
47 |
+#endif |
|
48 |
+ |
|
45 | 49 |
typedef struct vba_version_tag { |
46 | 50 |
unsigned char signature[4]; |
47 | 51 |
const char *name; |
... | ... |
@@ -685,12 +689,97 @@ unsigned char *vba_decompress(int fd, uint32_t offset, int *size) |
685 | 685 |
|
686 | 686 |
} |
687 | 687 |
|
688 |
+static uint32_t ole_copy_file_data(int ifd, int ofd, uint32_t len) |
|
689 |
+{ |
|
690 |
+ unsigned char data[8192]; |
|
691 |
+ unsigned int count, rem; |
|
692 |
+ unsigned int todo; |
|
693 |
+ |
|
694 |
+ rem = len; |
|
695 |
+ |
|
696 |
+ while (rem > 0) { |
|
697 |
+ todo = MIN(8192, rem); |
|
698 |
+ count = cli_readn(ifd, data, todo); |
|
699 |
+ if (count != todo) { |
|
700 |
+ return len-rem; |
|
701 |
+ } |
|
702 |
+ if (cli_writen(ofd, data, count) != count) { |
|
703 |
+ return len-rem-count; |
|
704 |
+ } |
|
705 |
+ rem -= count; |
|
706 |
+ } |
|
707 |
+ return len; |
|
708 |
+} |
|
709 |
+ |
|
710 |
+int cli_decode_ole_object(int fd, const char *dir) |
|
711 |
+{ |
|
712 |
+ int ofd; |
|
713 |
+ struct stat statbuf; |
|
714 |
+ char ch, *fullname; |
|
715 |
+ uint32_t object_size; |
|
716 |
+ |
|
717 |
+ if (fstat(fd, &statbuf) == -1) { |
|
718 |
+ return -1; |
|
719 |
+ } |
|
720 |
+ |
|
721 |
+ if (cli_readn(fd, &object_size, 4) != 4) { |
|
722 |
+ return -1; |
|
723 |
+ } |
|
724 |
+ object_size = vba_endian_convert_32(object_size, FALSE); |
|
725 |
+ |
|
726 |
+ if ((statbuf.st_size - object_size) >= 4) { |
|
727 |
+ /* Probably the OLE type id */ |
|
728 |
+ if (lseek(fd, 2, SEEK_CUR) == -1) { |
|
729 |
+ return -1; |
|
730 |
+ } |
|
731 |
+ |
|
732 |
+ /* Skip attachment name */ |
|
733 |
+ do { |
|
734 |
+ if (cli_readn(fd, &ch, 1) != 1) { |
|
735 |
+ return -1; |
|
736 |
+ } |
|
737 |
+ } while (ch); |
|
738 |
+ |
|
739 |
+ /* Skip attachment full path */ |
|
740 |
+ do { |
|
741 |
+ if (cli_readn(fd, &ch, 1) != 1) { |
|
742 |
+ return -1; |
|
743 |
+ } |
|
744 |
+ } while (ch); |
|
745 |
+ |
|
746 |
+ /* Skip unknown data */ |
|
747 |
+ if (lseek(fd, 8, SEEK_CUR) == -1) { |
|
748 |
+ return -1; |
|
749 |
+ } |
|
750 |
+ |
|
751 |
+ /* Skip attachment full path */ |
|
752 |
+ do { |
|
753 |
+ if (cli_readn(fd, &ch, 1) != 1) { |
|
754 |
+ return -1; |
|
755 |
+ } |
|
756 |
+ } while (ch); |
|
757 |
+ |
|
758 |
+ if (cli_readn(fd, &object_size, 4) != 4) { |
|
759 |
+ return -1; |
|
760 |
+ } |
|
761 |
+ object_size = vba_endian_convert_32(object_size, FALSE); |
|
762 |
+ } |
|
763 |
+ fullname = cli_malloc(strlen(dir) + 18); |
|
764 |
+ sprintf(fullname, "%s/_clam_ole_object", dir); |
|
765 |
+ ofd = open(fullname, O_WRONLY|O_CREAT|O_TRUNC, 0600); |
|
766 |
+ free(fullname); |
|
767 |
+ if (ofd < 0) { |
|
768 |
+ return -1; |
|
769 |
+ } |
|
770 |
+ ole_copy_file_data(fd, ofd, object_size); |
|
771 |
+ lseek(0, ofd, SEEK_SET); |
|
772 |
+ return ofd; |
|
773 |
+} |
|
774 |
+ |
|
688 | 775 |
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ |
689 | 776 |
/* Code to extract Power Point Embedded OLE2 Objects */ |
690 | 777 |
/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ |
691 | 778 |
|
692 |
-#define MIN(a, b) (((a) < (b)) ? (a) : (b)) |
|
693 |
- |
|
694 | 779 |
typedef struct atom_header_tag { |
695 | 780 |
off_t foffset; |
696 | 781 |
uint16_t ver_inst; |
... | ... |
@@ -36,6 +36,7 @@ typedef struct vba_project_tag { |
36 | 36 |
|
37 | 37 |
vba_project_t *vba56_dir_read(const char *dir); |
38 | 38 |
unsigned char *vba_decompress(int fd, uint32_t offset, int *size); |
39 |
+int cli_decode_ole_object(int fd, const char *dir); |
|
39 | 40 |
|
40 | 41 |
char *ppt_vba_read(const char *dir); |
41 | 42 |
|