[Libguestfs] [PATCH 4/6] New API: internal_yara_scan

Matteo Cafasso noxdafox at gmail.com
Wed Nov 2 19:26:22 UTC 2016


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 <noxdafox at gmail.com>
---
 daemon/yara.c                            | 99 ++++++++++++++++++++++++++++++++
 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, 123 insertions(+), 1 deletion(-)

diff --git a/daemon/yara.c b/daemon/yara.c
index a6b9fe2..099401c 100644
--- a/daemon/yara.c
+++ b/daemon/yara.c
@@ -49,6 +49,8 @@ static YR_RULES *rules = NULL;
 static int upload_rules_file (char *);
 static int compile_rules_file (const char *);
 static int write_callback (void *, const void *, size_t);
+static int yara_rules_callback (int , void *, void *);
+static int send_detection_info (const char *, YR_RULE *);

 /* Has one FileIn parameter. */
 int
@@ -112,6 +114,51 @@ 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;
+  }
+
+  ret = yr_initialize ();
+  if (ret != ERROR_SUCCESS) {
+    reply_with_error ("failed initializing yara");
+    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. */
+
+  ret = yr_finalize ();
+  if (ret != ERROR_SUCCESS) {
+    reply_with_error ("failed finalizing yara");
+    return -1;
+  }
+
+  return 0;
+}
+
 /* Upload rules file on a temporary file.
  * Return 0 on success, -1 on error.
  */
@@ -206,6 +253,58 @@ write_callback (void *data_vp, const void *buf, size_t len)
   return 0;
 }

+/* 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);
+}
+
 int
 optgroup_libyara_available (void)
 {
diff --git a/generator/actions.ml b/generator/actions.ml
index 966e012..61211f4 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -13277,6 +13277,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.1




More information about the Libguestfs mailing list