Browse code

endian fixes

git-svn: trunk@1710

Tomasz Kojm authored on 2005/08/29 23:39:39
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Mon Aug 29 16:38:06 CEST 2005 (tk)
2
+----------------------------------
3
+  * libclamav/elf.c: detect file endianness and properly analyse executables on
4
+		     different architectures
5
+
1 6
 Thu Aug 25 04:54:51 CEST 2005 (tk)
2 7
 ----------------------------------
3 8
   * libclamav/elf.[ch]: new files (initial version of ELF scanning module),
... ...
@@ -35,27 +35,30 @@
35 35
 
36 36
 #define DETECT_BROKEN		    (options & CL_SCAN_BLOCKBROKEN)
37 37
 
38
-#if WORDS_BIGENDIAN == 0
39
-#define EC16(v)	(v)
40
-#define EC32(v) (v)
41
-#else
38
+static short need_conversion = 0;
39
+
42 40
 static inline uint16_t EC16(uint16_t v)
43 41
 {
44
-    return ((v >> 8) + (v << 8));
42
+    if(!need_conversion)
43
+	return v;
44
+    else
45
+	return ((v >> 8) + (v << 8));
45 46
 }
46 47
 
47 48
 static inline uint32_t EC32(uint32_t v)
48 49
 {
49
-    return ((v >> 24) | ((v & 0x00FF0000) >> 8) | ((v & 0x0000FF00) << 8) | (v << 24));
50
+    if(!need_conversion)
51
+	return v;
52
+    else
53
+	return ((v >> 24) | ((v & 0x00FF0000) >> 8) | ((v & 0x0000FF00) << 8) | (v << 24));
50 54
 }
51
-#endif
52 55
 
53 56
 int cli_scanelf(int desc, 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)
54 57
 {
55 58
 	struct elf_file_hdr32 file_hdr;
56 59
 	struct elf_section_hdr32 *section_hdr;
57 60
 	uint16_t shnum, shentsize;
58
-	uint32_t entry, shoff;
61
+	uint32_t entry, shoff, image;
59 62
 	int i;
60 63
 
61 64
     cli_dbgmsg("in cli_elfheader\n");
... ...
@@ -71,6 +74,29 @@ int cli_scanelf(int desc, const char **virname, long int *scanned, const struct
71 71
 	return CL_CLEAN;
72 72
     }
73 73
 
74
+    if(file_hdr.e_ident[4] != 1) {
75
+	cli_dbgmsg("ELF: 64-bit binaries not supported\n");
76
+	return CL_CLEAN;
77
+    }
78
+
79
+    if(file_hdr.e_ident[5] == 1) {
80
+	image =  0x8048000;
81
+#if WORDS_BIGENDIAN == 0
82
+	cli_dbgmsg("ELF: File is little-endian - conversion not required\n");
83
+#else
84
+	cli_dbgmsg("ELF: File is little-endian - data conversion enabled\n");
85
+	need_conversion = 1;
86
+#endif
87
+    } else {
88
+	image =  0x10000;
89
+#if WORDS_BIGENDIAN == 0
90
+	cli_dbgmsg("ELF: File is big-endian - data conversion enabled\n");
91
+	need_conversion = 1;
92
+#else
93
+	cli_dbgmsg("ELF: File is big-endian - conversion not required\n");
94
+#endif
95
+    }
96
+
74 97
     switch(EC16(file_hdr.e_type)) {
75 98
 	case 0x0: /* ET_NONE */
76 99
 	    cli_dbgmsg("ELF: File type: None\n");
... ...
@@ -138,7 +164,7 @@ int cli_scanelf(int desc, const char **virname, long int *scanned, const struct
138 138
 
139 139
     entry = EC32(file_hdr.e_entry);
140 140
     cli_dbgmsg("ELF: Entry point address: 0x%.8x\n", entry);
141
-    cli_dbgmsg("ELF: Entry point offset: 0x%.8x (%d)\n", entry - 0x8048000, entry - 0x8048000);
141
+    cli_dbgmsg("ELF: Entry point offset: 0x%.8x (%d)\n", entry - image, entry - image);
142 142
 
143 143
     shnum = EC16(file_hdr.e_shnum);
144 144
     cli_dbgmsg("ELF: Number of sections: %d\n", shnum);
... ...
@@ -177,7 +203,7 @@ int cli_scanelf(int desc, const char **virname, long int *scanned, const struct
177 177
 
178 178
     section_hdr = (struct elf_section_hdr32 *) cli_calloc(shnum, shentsize);
179 179
     if(!section_hdr) {
180
-	cli_dbgmsg("ELF: Can't allocate memory for section headers\n");
180
+	cli_errmsg("ELF: Can't allocate memory for section headers\n");
181 181
 	return CL_EMEM;
182 182
     }
183 183