Browse code

sigtool: add support for --find-sigs (part of bb#1246)

Tomasz Kojm authored on 2009/10/16 17:12:17
Showing 4 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Oct 16 10:11:56 CEST 2009 (tk)
2
+----------------------------------
3
+ * sigtool: add support for --find-sigs (part of bb#1246)
4
+
1 5
 Fri Oct 16 01:46:28 CEST 2009 (acab)
2 6
 ------------------------------------
3 7
  * win32: res_query compatible interface
... ...
@@ -69,8 +69,11 @@ Execute update script FILE in current directory.
69 69
 \fB\-\-verify\-cdiff=FILE, \-r FILE\fR
70 70
 Verify DIFF against CVD/INCDIR.
71 71
 .TP 
72
-\fB\-l, \-\-list\-sigs\fR
73
-List signature names.
72
+\fB\-l[FILE], \-\-list\-sigs[=FILE]\fR
73
+List all signature names from the local database directory (default) or from FILE.
74
+.TP 
75
+\fB\-fREGEX, \-\-find\-sigs=REGEX\fR
76
+Find and display signatures from the local database directory which match the given REGEX. The whole signature body (name, hex string, etc.) is checked.
74 77
 .SH "EXAMPLES"
75 78
 .LP 
76 79
 .TP 
... ...
@@ -106,6 +106,7 @@ const struct clam_option clam_options[] = {
106 106
     { NULL, "unpack-current", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
107 107
     { NULL, "info", 'i', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
108 108
     { NULL, "list-sigs", 'l', TYPE_STRING, NULL, -1, DATADIR, 0, OPT_SIGTOOL, "", "" },
109
+    { NULL, "find-sigs", 'f', TYPE_STRING, NULL, -1, DATADIR, FLAG_REQUIRED, OPT_SIGTOOL, "", "" },
109 110
     { NULL, "vba", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
110 111
     { NULL, "vba-hex", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
111 112
     { NULL, "diff", 'd', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
... ...
@@ -980,15 +980,14 @@ static int cvdinfo(const struct optstruct *opts)
980 980
     return 0;
981 981
 }
982 982
 
983
-static int listdb(const char *filename);
983
+static int listdb(const char *filename, const regex_t *regex);
984 984
 
985
-static int listdir(const char *dirname)
985
+static int listdir(const char *dirname, const regex_t *regex)
986 986
 {
987 987
 	DIR *dd;
988 988
 	struct dirent *dent;
989 989
 	char *dbfile;
990 990
 
991
-
992 991
     if((dd = opendir(dirname)) == NULL) {
993 992
         mprintf("!listdir: Can't open directory %s\n", dirname);
994 993
         return -1;
... ...
@@ -1021,7 +1020,7 @@ static int listdir(const char *dirname)
1021 1021
 		}
1022 1022
 		sprintf(dbfile, "%s"PATHSEP"%s", dirname, dent->d_name);
1023 1023
 
1024
-		if(listdb(dbfile) == -1) {
1024
+		if(listdb(dbfile, regex) == -1) {
1025 1025
 		    mprintf("!listdb: Error listing database %s\n", dbfile);
1026 1026
 		    free(dbfile);
1027 1027
 		    closedir(dd);
... ...
@@ -1036,7 +1035,7 @@ static int listdir(const char *dirname)
1036 1036
     return 0;
1037 1037
 }
1038 1038
 
1039
-static int listdb(const char *filename)
1039
+static int listdb(const char *filename, const regex_t *regex)
1040 1040
 {
1041 1041
 	FILE *fh;
1042 1042
 	char *buffer, *pt, *start, *dir;
... ...
@@ -1086,7 +1085,7 @@ static int listdb(const char *filename)
1086 1086
 	}
1087 1087
 
1088 1088
 	/* list extracted directory */
1089
-	if(listdir(dir) == -1) {
1089
+	if(listdir(dir, regex) == -1) {
1090 1090
 	    mprintf("!listdb: Can't list directory %s\n", filename);
1091 1091
 	    cli_rmdirs(dir);
1092 1092
 	    free(dir);
... ...
@@ -1102,6 +1101,11 @@ static int listdb(const char *filename)
1102 1102
     if(cli_strbcasestr(filename, ".db")) { /* old style database */
1103 1103
 
1104 1104
 	while(fgets(buffer, FILEBUFF, fh)) {
1105
+	    if(regex) {
1106
+		if(!cli_regexec(regex, buffer, 0, NULL, 0))
1107
+		    mprintf("%s", buffer);
1108
+		continue;
1109
+	    }
1105 1110
 	    line++;
1106 1111
 	    pt = strchr(buffer, '=');
1107 1112
 	    if(!pt) {
... ...
@@ -1123,6 +1127,11 @@ static int listdb(const char *filename)
1123 1123
     } else if(cli_strbcasestr(filename, ".hdb") || cli_strbcasestr(filename, ".hdu") || cli_strbcasestr(filename, ".mdb") || cli_strbcasestr(filename, ".mdu")) { /* hash database */
1124 1124
 
1125 1125
 	while(fgets(buffer, FILEBUFF, fh)) {
1126
+	    if(regex) {
1127
+		if(!cli_regexec(regex, buffer, 0, NULL, 0))
1128
+		    mprintf("%s", buffer);
1129
+		continue;
1130
+	    }
1126 1131
 	    line++;
1127 1132
 	    cli_chomp(buffer);
1128 1133
 	    start = cli_strtok(buffer, 2, ":");
... ...
@@ -1144,6 +1153,11 @@ static int listdb(const char *filename)
1144 1144
     } else if(cli_strbcasestr(filename, ".ndb") || cli_strbcasestr(filename, ".ndu") || cli_strbcasestr(filename, ".ldb") || cli_strbcasestr(filename, ".ldu") || cli_strbcasestr(filename, ".sdb") || cli_strbcasestr(filename, ".zmd") || cli_strbcasestr(filename, ".rmd")) {
1145 1145
 
1146 1146
 	while(fgets(buffer, FILEBUFF, fh)) {
1147
+	    if(regex) {
1148
+		if(!cli_regexec(regex, buffer, 0, NULL, 0))
1149
+		    mprintf("%s", buffer);
1150
+		continue;
1151
+	    }
1147 1152
 	    line++;
1148 1153
 	    cli_chomp(buffer);
1149 1154
 
... ...
@@ -1171,31 +1185,45 @@ static int listdb(const char *filename)
1171 1171
     return 0;
1172 1172
 }
1173 1173
 
1174
-static int listsigs(const struct optstruct *opts)
1174
+static int listsigs(const struct optstruct *opts, int mode)
1175 1175
 {
1176 1176
 	int ret;
1177 1177
 	const char *name;
1178 1178
 	char *dbdir;
1179 1179
 	struct stat sb;
1180
+	regex_t reg;
1180 1181
 
1181 1182
 
1182
-    name = optget(opts, "list-sigs")->strarg;
1183
-    if(stat(name, &sb) == -1) {
1184
-	mprintf("--list-sigs: Can't get status of %s\n", name);
1185
-	return -1;
1186
-    }
1183
+    if(mode == 0) {
1184
+	name = optget(opts, "list-sigs")->strarg;
1185
+	if(stat(name, &sb) == -1) {
1186
+	    mprintf("--list-sigs: Can't get status of %s\n", name);
1187
+	    return -1;
1188
+	}
1187 1189
 
1188
-    mprintf_stdout = 1;
1189
-    if(S_ISDIR(sb.st_mode)) {
1190
-	if(!strcmp(name, DATADIR)) {
1191
-	    dbdir = freshdbdir();
1192
-	    ret = listdir(dbdir);
1193
-	    free(dbdir);
1190
+	mprintf_stdout = 1;
1191
+	if(S_ISDIR(sb.st_mode)) {
1192
+	    if(!strcmp(name, DATADIR)) {
1193
+		dbdir = freshdbdir();
1194
+		ret = listdir(dbdir, NULL);
1195
+		free(dbdir);
1196
+	    } else {
1197
+		ret = listdir(name, NULL);
1198
+	    }
1194 1199
 	} else {
1195
-	    ret = listdir(name);
1200
+	    ret = listdb(name, NULL);
1196 1201
 	}
1202
+
1197 1203
     } else {
1198
-	ret = listdb(name);
1204
+	if(cli_regcomp(&reg, optget(opts, "find-sigs")->strarg, REG_EXTENDED | REG_NOSUB) != 0) {
1205
+	    mprintf("--find-sigs: Can't compile regex\n");
1206
+	    return -1;
1207
+	}
1208
+	mprintf_stdout = 1;
1209
+	dbdir = freshdbdir();
1210
+	ret = listdir(dbdir, &reg);
1211
+	free(dbdir);
1212
+	cli_regfree(&reg);
1199 1213
     }
1200 1214
 
1201 1215
     return ret;
... ...
@@ -1798,6 +1826,7 @@ static void help(void)
1798 1798
     mprintf("    --unpack=FILE          -u FILE         Unpack a CVD/CLD file\n");
1799 1799
     mprintf("    --unpack-current=SHORTNAME             Unpack local CVD/CLD into cwd\n");
1800 1800
     mprintf("    --list-sigs[=FILE]     -l[FILE]        List signature names\n");
1801
+    mprintf("    --find-sigs=REGEX      -fREGEX         Find signatures matching REGEX\n");
1801 1802
     mprintf("    --vba=FILE                             Extract VBA/Word6 macro code\n");
1802 1803
     mprintf("    --vba-hex=FILE                         Extract Word6 macro code with hex values\n");
1803 1804
     mprintf("    --diff=OLD NEW         -d OLD NEW      Create diff for OLD and NEW CVDs\n");
... ...
@@ -1860,7 +1889,9 @@ int main(int argc, char **argv)
1860 1860
     else if(optget(opts, "info")->enabled)
1861 1861
 	ret = cvdinfo(opts);
1862 1862
     else if(optget(opts, "list-sigs")->active)
1863
-	ret = listsigs(opts);
1863
+	ret = listsigs(opts, 0);
1864
+    else if(optget(opts, "find-sigs")->active)
1865
+	ret = listsigs(opts, 1);
1864 1866
     else if(optget(opts, "vba")->enabled || optget(opts, "vba-hex")->enabled)
1865 1867
 	ret = vbadump(opts);
1866 1868
     else if(optget(opts, "diff")->enabled)