summaryrefslogtreecommitdiff
path: root/plugins/lnxsyscalls/db.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-06-17 16:11:45 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-06-17 16:11:45 (GMT)
commit378be1ab322dce8e8377d692829d6877758e5960 (patch)
tree17dc518687a45649caa68304cc2a5750a0a50554 /plugins/lnxsyscalls/db.c
parent1f7e9506775f66a3a5f2859779d33b914eee8ef4 (diff)
Annotated linux kernel syscalls using a new plugin.
Diffstat (limited to 'plugins/lnxsyscalls/db.c')
-rw-r--r--plugins/lnxsyscalls/db.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/plugins/lnxsyscalls/db.c b/plugins/lnxsyscalls/db.c
new file mode 100644
index 0000000..d6325b5
--- /dev/null
+++ b/plugins/lnxsyscalls/db.c
@@ -0,0 +1,245 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * db.c - constitution d'identités d'appels depuis une base de données
+ *
+ * Copyright (C) 2018 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "db.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+
+
+#include <i18n.h>
+
+
+#include <core/paths.h>
+#include <plugins/plugin-int.h>
+
+
+
+/******************************************************************************
+* *
+* Paramètres : plugin = greffon à manipuler. *
+* *
+* Description : Ouvre la base de connaissances quant aux appels système. *
+* *
+* Retour : Base de données SQLite disponible ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+sqlite3 *open_syscalls_database(const GPluginModule *plugin)
+{
+ sqlite3 *result; /* Base de données à renvoyer */
+ char *filename; /* Chemin vers la base */
+ int ret; /* Bilan d'un appel */
+
+ filename = find_plugin_file("lnxsyscalls", "linux-syscalls.db");
+
+ if (filename == NULL)
+ {
+ g_plugin_module_log_simple_message(plugin, LMT_ERROR, _("Unable to find the syscalls database"));
+ result = NULL;
+ }
+
+ else
+ {
+ ret = sqlite3_open(filename, &result);
+
+ if (ret != SQLITE_OK)
+ {
+ g_plugin_module_log_simple_message(plugin, LMT_ERROR, _("Unable to load the syscalls database"));
+ result = NULL;
+ }
+
+ free(filename);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : db = base de données SQLite à clôturer. *
+* *
+* Description : Ferme la base de connaissances quant aux appels système. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void close_syscalls_database(sqlite3 *db)
+{
+#ifndef NDEBUG
+ int ret; /* Bilan d'un appel */
+#endif
+
+#ifndef NDEBUG
+
+ ret = sqlite3_close(db);
+ assert(ret == SQLITE_OK);
+
+#else
+
+ sqlite3_close(db);
+
+#endif
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : db = base de données SQLite à consulter. *
+* plugin = greffon à manipuler. *
+* *
+* Description : Présente le contenu de la base des appels système. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void introduce_syscalls_database(sqlite3 *db, const GPluginModule *plugin)
+{
+ const char *sql; /* Requête SQL à construire */
+ sqlite3_stmt *stmt; /* Déclaration mise en place */
+ int ret; /* Bilan d'un appel à SQLite */
+
+ sql = "SELECT arch, COUNT(nr) FROM Syscalls GROUP BY arch ORDER BY arch;";
+
+ ret = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ if (ret != SQLITE_OK)
+ {
+ g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
+ _("Can't prepare statment '%s' (ret=%d): %s"),
+ sql, ret, sqlite3_errmsg(db));
+ goto isd_exit;
+ }
+
+ for (ret = sqlite3_step(stmt); ret == SQLITE_ROW; ret = sqlite3_step(stmt))
+ {
+ g_plugin_module_log_variadic_message(plugin, LMT_INFO,
+ _("The database contains %d syscalls for the '%s' architecture"),
+ sqlite3_column_int(stmt, 1),
+ (char *)sqlite3_column_text(stmt, 0));
+ }
+
+ sqlite3_finalize(stmt);
+
+ isd_exit:
+
+ ;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : db = base de données SQLite à consulter. *
+* plugin = greffon à manipuler. *
+* arch = architecture visée par la procédure. *
+* : nr = indice de l'appel système à décrire. *
+* *
+* Description : Construit l'identité d'un appel système pour un indice donné.*
+* *
+* Retour : Structure mise en place ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+syscall_info_t *extract_from_syscalls_database(sqlite3 *db, const GPluginModule *plugin, const char *arch, unsigned int nr)
+{
+ syscall_info_t *result; /* Description à retourner */
+ const char *sql; /* Requête SQL à construire */
+ size_t i; /* Boucle de parcours */
+ sqlite3_stmt *stmt; /* Déclaration mise en place */
+ int ret; /* Bilan d'un appel à SQLite */
+ const char *arg; /* Eventuel argument d'appel */
+
+ result = NULL;
+
+ sql = "SELECT name, arg_0, arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, filename, line" \
+ " FROM Syscalls" \
+ " WHERE arch = ? AND nr = ?;";
+
+ ret = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ if (ret != SQLITE_OK)
+ {
+ g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
+ _("Can't prepare statment '%s' (ret=%d): %s"),
+ sql, ret, sqlite3_errmsg(db));
+ goto efsd_exit;
+ }
+
+ ret = sqlite3_bind_text(stmt, 1, arch, -1, NULL);
+ if (ret != SQLITE_OK)
+ {
+ g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
+ _("Can't bind value for parameter nb 0 in '%s' (ret=%d): %s"),
+ sql, ret, sqlite3_errmsg(db));
+ goto efsd_clean_exit;
+ }
+
+ ret = sqlite3_bind_int(stmt, 2, nr);
+ if (ret != SQLITE_OK)
+ {
+ g_plugin_module_log_variadic_message(plugin, LMT_ERROR,
+ _("Can't bind value for parameter nb 1 in '%s' (ret=%d): %s"),
+ sql, ret, sqlite3_errmsg(db));
+ goto efsd_clean_exit;
+ }
+
+ ret = sqlite3_step(stmt);
+
+ if (ret == SQLITE_ROW)
+ {
+ result = create_syscall_info(nr, (char *)sqlite3_column_text(stmt, 0));
+
+ for (i = 0; i < 6; i++)
+ {
+ arg = (char *)sqlite3_column_text(stmt, 1 + i);
+
+ if (arg != NULL)
+ append_arg_to_syscall_info(result, arg);
+
+ }
+
+ }
+
+ efsd_clean_exit:
+
+ sqlite3_finalize(stmt);
+
+ efsd_exit:
+
+ return result;
+
+}