The internal_yara_scan runs the Yara engine with the previously loaded rules against the given file.
For each rule matching against the scanned file, a struct containing the file name and the rule identifier is returned. The gathered list of yara_detection structs is serialised into XDR format and written to a file. Signed-off-by: Matteo Cafasso <noxda...@gmail.com> --- daemon/yara.c | 86 ++++++++++++++++++++++++++++++++ generator/actions.ml | 10 ++++ generator/structs.ml | 9 ++++ gobject/Makefile.inc | 2 + java/Makefile.inc | 1 + java/com/redhat/et/libguestfs/.gitignore | 1 + lib/MAX_PROC_NR | 2 +- 7 files changed, 110 insertions(+), 1 deletion(-) diff --git a/daemon/yara.c b/daemon/yara.c index cb49593c7..471547341 100644 --- a/daemon/yara.c +++ b/daemon/yara.c @@ -54,6 +54,8 @@ static bool initialized = false; static int compile_rules_file (const char *, const char *); static void compile_error_callback (int, const char *, int, const char *, void *); static void cleanup_destroy_yara_compiler (void *ptr); +static int yara_rules_callback (int , void *, void *); +static int send_detection_info (const char *, YR_RULE *); /* Has one FileIn parameter. * Takes optional arguments, consult optargs_bitmask. @@ -119,6 +121,38 @@ do_yara_destroy (void) return 0; } +/* Has one FileOut parameter. */ +int +do_internal_yara_scan (const char *path) +{ + int ret = 0; + CLEANUP_CLOSE int fd = -1; + + if (rules == NULL) { + reply_with_error ("no yara rules loaded"); + return -1; + } + + CHROOT_IN; + fd = open (path, O_RDONLY|O_CLOEXEC); + CHROOT_OUT; + + if (fd < 0) { + reply_with_perror ("%s", path); + return -1; + } + + reply (NULL, NULL); /* Reply message. */ + + ret = yr_rules_scan_fd (rules, fd, 0, yara_rules_callback, (void *) path, 0); + if (ret == ERROR_SUCCESS) + ret = send_file_end (0); /* File transfer end. */ + else + send_file_end (1); /* Cancel file transfer. */ + + return 0; +} + /* Compile source code rules and load them. * Return ERROR_SUCCESS on success, Yara error code type on error. */ @@ -170,6 +204,58 @@ compile_error_callback(int level, const char *name, int line, fprintf (stderr, "Yara warning (line %d): %s\n", line, message); } +/* Yara scan callback, called by yr_rules_scan_file. + * Return 0 on success, -1 on error. + */ +static int +yara_rules_callback (int code, void *message, void *data) +{ + int ret = 0; + + if (code == CALLBACK_MSG_RULE_MATCHING) + ret = send_detection_info ((const char *)data, (YR_RULE *) message); + + return (ret == 0) ? CALLBACK_CONTINUE : CALLBACK_ERROR; +} + +/* Serialize file path and rule name and send it out. + * Return 0 on success, -1 on error. + */ +static int +send_detection_info (const char *name, YR_RULE *rule) +{ + XDR xdr; + int ret = 0; + size_t len = 0; + CLEANUP_FREE char *buf = NULL; + struct guestfs_int_yara_detection detection; + + detection.name = (char *) name; + detection.rule = (char *) rule->identifier; + + /* Serialize detection struct. */ + buf = malloc (GUESTFS_MAX_CHUNK_SIZE); + if (buf == NULL) { + perror ("malloc"); + return -1; + } + + xdrmem_create (&xdr, buf, GUESTFS_MAX_CHUNK_SIZE, XDR_ENCODE); + + ret = xdr_guestfs_int_yara_detection (&xdr, &detection); + if (ret == 0) { + perror ("xdr_guestfs_int_yara_detection"); + return -1; + } + + len = xdr_getpos (&xdr); + + xdr_destroy (&xdr); + + /* Send serialised yara_detection out. */ + return send_file_write (buf, len); +} + /* Clean up yara handle on daemon exit. */ void yara_finalize (void) __attribute__((destructor)); diff --git a/generator/actions.ml b/generator/actions.ml index 149c4a938..7e62e21af 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -13338,6 +13338,16 @@ but belonging to different files." }; shortdesc = "destroy previously loaded yara rules"; longdesc = "\ Destroy previously loaded Yara rules in order to free libguestfs resources." }; + + { defaults with + name = "internal_yara_scan"; added = (1, 35, 26); + style = RErr, [Pathname "path"; FileOut "filename";], []; + proc_nr = Some 474; + visibility = VInternal; + optional = Some "libyara"; + shortdesc = "scan a file with the loaded yara rules"; + longdesc = "Internal function for yara_scan." }; + ] (* Non-API meta-commands available only in guestfish. diff --git a/generator/structs.ml b/generator/structs.ml index c1c9b668e..01aa3d371 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -469,6 +469,15 @@ let structs = [ ]; s_camel_name = "TSKDirent" }; + (* Yara detection information. *) + { defaults with + s_name = "yara_detection"; + s_cols = [ + "name", FString; + "rule", FString; + ]; + s_camel_name = "YaraDetection" }; + ] (* end of structs *) let lookup_struct name = diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc index b0ebf15d9..4b067d9e0 100644 --- a/gobject/Makefile.inc +++ b/gobject/Makefile.inc @@ -49,6 +49,7 @@ guestfs_gobject_headers= \ include/guestfs-gobject/struct-version.h \ include/guestfs-gobject/struct-xattr.h \ include/guestfs-gobject/struct-xfsinfo.h \ + include/guestfs-gobject/struct-yara_detection.h \ include/guestfs-gobject/optargs-add_domain.h \ include/guestfs-gobject/optargs-add_drive.h \ include/guestfs-gobject/optargs-add_drive_scratch.h \ @@ -142,6 +143,7 @@ guestfs_gobject_sources= \ src/struct-version.c \ src/struct-xattr.c \ src/struct-xfsinfo.c \ + src/struct-yara_detection.c \ src/optargs-add_domain.c \ src/optargs-add_drive.c \ src/optargs-add_drive_scratch.c \ diff --git a/java/Makefile.inc b/java/Makefile.inc index b0ddb5c3d..3a202cee0 100644 --- a/java/Makefile.inc +++ b/java/Makefile.inc @@ -46,4 +46,5 @@ java_built_sources = \ com/redhat/et/libguestfs/Version.java \ com/redhat/et/libguestfs/XAttr.java \ com/redhat/et/libguestfs/XFSInfo.java \ + com/redhat/et/libguestfs/YaraDetection.java \ com/redhat/et/libguestfs/GuestFS.java diff --git a/java/com/redhat/et/libguestfs/.gitignore b/java/com/redhat/et/libguestfs/.gitignore index 89d923949..bc03cb965 100644 --- a/java/com/redhat/et/libguestfs/.gitignore +++ b/java/com/redhat/et/libguestfs/.gitignore @@ -23,3 +23,4 @@ VG.java Version.java XAttr.java XFSInfo.java +YaraDetection.java diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR index 68cfb10d1..5f3bb9813 100644 --- a/lib/MAX_PROC_NR +++ b/lib/MAX_PROC_NR @@ -1 +1 @@ -472 +474 -- 2.11.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs