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(a)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