@@ -29,6 +29,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
30
30
#if !defined(_WIN32 ) && !defined(__CYGWIN__ )
31
31
32
+ // for getline(3)
33
+ #define _POSIX_C_SOURCE 200809L
34
+
32
35
#include <sys/stat.h>
33
36
#include <dirent.h>
34
37
#include <unistd.h>
@@ -128,6 +131,7 @@ static char* ext_vars[MAX_ARGS_EXT_VAR + 1];
128
131
static char * modules_data [MAX_ARGS_MODULE_DATA + 1 ];
129
132
130
133
static bool recursive_search = false;
134
+ static bool scan_list_search = false;
131
135
static bool show_module_data = false;
132
136
static bool show_tags = false;
133
137
static bool show_stats = false;
@@ -220,6 +224,9 @@ args_option_t options[] =
220
224
OPT_BOOLEAN ('r' , "recursive" , & recursive_search ,
221
225
"recursively search directories (follows symlinks)" ),
222
226
227
+ OPT_BOOLEAN (0 , "scan-list" , & scan_list_search ,
228
+ "scan files listed in FILE, one per line" ),
229
+
223
230
OPT_INTEGER ('k' , "stack-size" , & stack_size ,
224
231
"set maximum stack size (default=16384)" , "SLOTS" ),
225
232
@@ -387,6 +394,70 @@ static void scan_dir(
387
394
}
388
395
}
389
396
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
+
390
461
#else
391
462
392
463
static bool is_directory (
@@ -443,6 +514,42 @@ static void scan_dir(
443
514
}
444
515
}
445
516
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
+
446
553
#endif
447
554
448
555
static void print_string (
@@ -1108,6 +1215,7 @@ int main(
1108
1215
YR_RULES * rules = NULL ;
1109
1216
YR_SCANNER * scanner = NULL ;
1110
1217
1218
+ bool arg_is_dir = false;
1111
1219
int flags = 0 ;
1112
1220
int result , i ;
1113
1221
@@ -1251,7 +1359,14 @@ int main(
1251
1359
if (fast_scan )
1252
1360
flags |= SCAN_FLAGS_FAST_MODE ;
1253
1361
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 )
1255
1370
{
1256
1371
if (file_queue_init () != 0 )
1257
1372
{
@@ -1291,7 +1406,18 @@ int main(
1291
1406
}
1292
1407
}
1293
1408
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
+ }
1295
1421
1296
1422
file_queue_finish ();
1297
1423
0 commit comments