[Libguestfs] [PATCH v9 5/7] New API: internal_yara_scan

Matteo Cafasso noxdafox at gmail.com
Tue Apr 25 20:03:03 UTC 2017


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                            | 86 ++++++++++++++++++++++++++++++++
 generator/actions_yara.ml                |  8 +++
 generator/proc_nr.ml                     |  1 +
 generator/structs.ml                     |  9 ++++
 gobject/Makefile.inc                     |  2 +
 java/Makefile.inc                        |  1 +
 java/com/redhat/et/libguestfs/.gitignore |  1 +
 lib/MAX_PROC_NR                          |  2 +-
 8 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/daemon/yara.c b/daemon/yara.c
index 56eec74ad..0fd09815a 100644
--- a/daemon/yara.c
+++ b/daemon/yara.c
@@ -58,6 +58,8 @@ static bool initialized = false;
 static int compile_rules_file (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.
@@ -125,6 +127,38 @@ do_yara_destroy (void)
   return 0;
 }

+/* Has one FileOut parameter. */
+int
+do_internal_yara_scan (const char *path)
+{
+  int r;
+  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 == -1) {
+    reply_with_perror ("%s", path);
+    return -1;
+  }
+
+  reply (NULL, NULL);  /* Reply message. */
+
+  r = yr_rules_scan_fd (rules, fd, 0, yara_rules_callback, (void *) path, 0);
+  if (r == ERROR_SUCCESS)
+    r = 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.
  */
@@ -184,6 +218,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 r;
+  size_t len;
+  CLEANUP_FREE char *buf = NULL;
+  struct guestfs_int_yara_detection detection;
+
+  detection.yara_name = (char *) name;
+  detection.yara_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);
+
+  r = xdr_guestfs_int_yara_detection (&xdr, &detection);
+  if (r == 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_yara.ml b/generator/actions_yara.ml
index 59c571b9e..1f7decdd4 100644
--- a/generator/actions_yara.ml
+++ b/generator/actions_yara.ml
@@ -53,4 +53,12 @@ Previously loaded rules will be destroyed." };
     longdesc = "\
 Destroy previously loaded Yara rules in order to free libguestfs resources." };

+  { defaults with
+    name = "internal_yara_scan"; added = (1, 37, 12);
+    style = RErr, [Pathname "path"; FileOut "filename"], [];
+    visibility = VInternal;
+    optional = Some "libyara";
+    shortdesc = "scan a file with the loaded yara rules";
+    longdesc = "Internal function for yara_scan." };
+
 ]
diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml
index d471b1a83..c7619638a 100644
--- a/generator/proc_nr.ml
+++ b/generator/proc_nr.ml
@@ -481,6 +481,7 @@ let proc_nr = [
 471, "mksquashfs";
 472, "yara_load";
 473, "yara_destroy";
+474, "internal_yara_scan";
 ]

 (* End of list.  If adding a new entry, add it at the end of the list
diff --git a/generator/structs.ml b/generator/structs.ml
index c1c9b668e..834fa9c54 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 = [
+    "yara_name", FString;
+    "yara_rule", FString;
+    ];
+    s_camel_name = "YaraDetection" };
+
 ] (* end of structs *)

 let lookup_struct name =
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 8fa8599d3..a6dcba022 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 \
@@ -141,6 +142,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 8410b8b89..5f3bb9813 100644
--- a/lib/MAX_PROC_NR
+++ b/lib/MAX_PROC_NR
@@ -1 +1 @@
-473
+474
--
2.11.0




More information about the Libguestfs mailing list