Skip to content

Commit 24b1cd4

Browse files
lmzkeplusvic
authored andcommitted
Add option (--scan-list) to scan a list of files and/or directories, one per line.
1 parent cd4e507 commit 24b1cd4

File tree

3 files changed

+135
-2
lines changed

3 files changed

+135
-2
lines changed

docs/commandline.rst

+4
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ Available options are:
127127

128128
Pass file's content as extra data to module.
129129

130+
.. option:: --scan-list
131+
132+
Scan files listed in FILE, one per line.
133+
130134
.. option:: -r --recursive
131135

132136
Recursively search for directories. It follows symlinks.

yara.c

+128-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929

3030
#if !defined(_WIN32) && !defined(__CYGWIN__)
3131

32+
// for getline(3)
33+
#define _POSIX_C_SOURCE 200809L
34+
3235
#include <sys/stat.h>
3336
#include <dirent.h>
3437
#include <unistd.h>
@@ -128,6 +131,7 @@ static char* ext_vars[MAX_ARGS_EXT_VAR + 1];
128131
static char* modules_data[MAX_ARGS_MODULE_DATA + 1];
129132

130133
static bool recursive_search = false;
134+
static bool scan_list_search = false;
131135
static bool show_module_data = false;
132136
static bool show_tags = false;
133137
static bool show_stats = false;
@@ -220,6 +224,9 @@ args_option_t options[] =
220224
OPT_BOOLEAN('r', "recursive", &recursive_search,
221225
"recursively search directories (follows symlinks)"),
222226

227+
OPT_BOOLEAN(0, "scan-list", &scan_list_search,
228+
"scan files listed in FILE, one per line"),
229+
223230
OPT_INTEGER('k', "stack-size", &stack_size,
224231
"set maximum stack size (default=16384)", "SLOTS"),
225232

@@ -387,6 +394,70 @@ static void scan_dir(
387394
}
388395
}
389396

397+
398+
static int populate_scan_list(
399+
const char* filename,
400+
int recursive,
401+
time_t start_time)
402+
{
403+
char* context;
404+
DWORD nread;
405+
406+
HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
407+
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
408+
if (hFile == INVALID_HANDLE_VALUE)
409+
{
410+
fprintf(stderr, "error: could not open file \"%s\".\n", filename);
411+
return ERROR_COULD_NOT_OPEN_FILE;
412+
}
413+
DWORD fileSize = GetFileSize(hFile, NULL);
414+
if (fileSize == INVALID_FILE_SIZE)
415+
{
416+
fprintf(stderr, "error: could not determine size of file \"%s\".\n", filename);
417+
CloseHandle(hFile);
418+
return ERROR_COULD_NOT_READ_FILE;
419+
}
420+
// INVALID_FILE_SIZE is 0xFFFFFFFF, so (+1) will not overflow
421+
char* buf = (char*) VirtualAlloc(NULL, fileSize + 1, MEM_COMMIT, PAGE_READWRITE);
422+
if (buf == NULL)
423+
{
424+
fprintf(stderr, "error: could not allocate memory for file \"%s\".\n", filename);
425+
CloseHandle(hFile);
426+
return ERROR_INSUFFICIENT_MEMORY;
427+
}
428+
DWORD total = 0;
429+
while (total < fileSize)
430+
{
431+
if (!ReadFile(hFile, buf + total, fileSize - total, &nread, NULL))
432+
{
433+
fprintf(stderr, "error: could not read file \"%s\".\n", filename);
434+
CloseHandle(hFile);
435+
return ERROR_COULD_NOT_READ_FILE;
436+
}
437+
total += nread;
438+
}
439+
440+
char* path = strtok_s(buf, "\n", &context);
441+
while (path != NULL)
442+
{
443+
// remove trailing carriage return, if present
444+
if (*path != '\0')
445+
{
446+
char* final = path + strlen(path) - 1;
447+
if (*final == '\r')
448+
*final = '\0';
449+
}
450+
if (is_directory(path))
451+
scan_dir(path, recursive, start_time);
452+
else
453+
file_queue_put(path);
454+
path = strtok_s(NULL, "\n", &context);
455+
}
456+
457+
CloseHandle(hFile);
458+
return ERROR_SUCCESS;
459+
}
460+
390461
#else
391462

392463
static bool is_directory(
@@ -443,6 +514,42 @@ static void scan_dir(
443514
}
444515
}
445516

517+
518+
static int populate_scan_list(
519+
const char* filename,
520+
int recursive,
521+
time_t start_time)
522+
{
523+
size_t nsize = 0;
524+
ssize_t nread;
525+
char* path = NULL;
526+
527+
FILE* fh_scan_list = fopen(filename, "r");
528+
if (fh_scan_list == NULL)
529+
{
530+
fprintf(stderr, "error: could not open file \"%s\".\n", filename);
531+
return ERROR_COULD_NOT_OPEN_FILE;
532+
}
533+
534+
while ((nread = getline(&path, &nsize, fh_scan_list)) != -1)
535+
{
536+
// remove trailing newline
537+
if (nread && path[nread - 1] == '\n')
538+
{
539+
path[nread - 1] = '\0';
540+
nread--;
541+
}
542+
if (is_directory(path))
543+
scan_dir(path, recursive, start_time);
544+
else
545+
file_queue_put(path);
546+
}
547+
548+
free(path);
549+
fclose(fh_scan_list);
550+
return ERROR_SUCCESS;
551+
}
552+
446553
#endif
447554

448555
static void print_string(
@@ -1108,6 +1215,7 @@ int main(
11081215
YR_RULES* rules = NULL;
11091216
YR_SCANNER* scanner = NULL;
11101217

1218+
bool arg_is_dir = false;
11111219
int flags = 0;
11121220
int result, i;
11131221

@@ -1251,7 +1359,14 @@ int main(
12511359
if (fast_scan)
12521360
flags |= SCAN_FLAGS_FAST_MODE;
12531361

1254-
if (is_directory(argv[argc - 1]))
1362+
arg_is_dir = is_directory(argv[argc - 1]);
1363+
1364+
if (scan_list_search && arg_is_dir)
1365+
{
1366+
fprintf(stderr, "error: cannot use a directory as scan list.\n");
1367+
exit_with_code(EXIT_FAILURE);
1368+
}
1369+
else if (scan_list_search || arg_is_dir)
12551370
{
12561371
if (file_queue_init() != 0)
12571372
{
@@ -1291,7 +1406,18 @@ int main(
12911406
}
12921407
}
12931408

1294-
scan_dir(argv[argc - 1], recursive_search, start_time);
1409+
if (arg_is_dir)
1410+
{
1411+
scan_dir(argv[argc - 1], recursive_search, start_time);
1412+
}
1413+
else
1414+
{
1415+
result = populate_scan_list(argv[argc - 1], recursive_search, start_time);
1416+
if (result != ERROR_SUCCESS)
1417+
{
1418+
exit_with_code(EXIT_FAILURE);
1419+
}
1420+
}
12951421

12961422
file_queue_finish();
12971423

yara.man

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ Print the tags associated to the rule.
8080
.B \-r " --recursive"
8181
Scan files in directories recursively. It follows symlinks.
8282
.TP
83+
.BI " --scan-list"
84+
Scan files listed in FILE, one per line.
85+
.TP
8386
.BI \-k " slots" " --stack-size=" slots
8487
Set maximum stack size to the specified number of
8588
.I slots.

0 commit comments

Comments
 (0)