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 | 87 ++++++++++++++++++++++++++++++++ generator/actions.ml | 10 ++++ generator/structs.ml | 9 ++++ gobject/Makefile.inc | 2 + java/Makefile.inc | 1 + java/com/redhat/et/libguestfs/.gitignore | 1 + src/MAX_PROC_NR | 2 +- 7 files changed, 111 insertions(+), 1 deletion(-) diff --git a/daemon/yara.c b/daemon/yara.c index fe1f69a..8e7d328 100644 --- a/daemon/yara.c +++ b/daemon/yara.c @@ -52,6 +52,8 @@ static int upload_rules_file (char *); static int compile_rules_file (const char *); static int write_callback (void *, const void *, size_t); static void compile_error_callback (int, const char *, int, const char *, void *); +static int yara_rules_callback (int , void *, void *); +static int send_detection_info (const char *, YR_RULE *); /* Has one FileIn parameter. */ int @@ -107,6 +109,39 @@ 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 = 0; + + 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); + yr_finalize (); + 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; +} + /* Upload rules file on a temporary file. * Return 0 on success, -1 on error. */ @@ -209,6 +244,58 @@ compile_error_callback(int level, const char *name, int line, fprintf (stderr, "(%d): Yara warning: %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; + struct guestfs_int_yara_detection detection; + CLEANUP_FREE char *buf = NULL, *fname = NULL; + + 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 tsk_detection out. */ + return send_file_write (buf, len); +} + /* Clean up yara handle on daemon exit. */ void yara_finalize (void) __attribute__((destructor)); void diff --git a/generator/actions.ml b/generator/actions.ml index 152c651..d9006f2 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -13280,6 +13280,16 @@ Previously loaded rules will be destroyed." }; 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, 15); + style = RErr, [Pathname "path"; FileOut "filename";], []; + proc_nr = Some 473; + 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 029bc3a..3fa2ebc 100644 --- a/generator/structs.ml +++ b/generator/structs.ml @@ -468,6 +468,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 149e4c6..a784b62 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 \ @@ -140,6 +141,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 59b55eb..acf2a2f 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 89d9239..bc03cb9 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/src/MAX_PROC_NR b/src/MAX_PROC_NR index 68cfb10..8410b8b 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -472 +473 -- 2.10.2 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs