mazepa.git


mazepa

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

utils.c (6030B)

      1 
      2 /**
      3  * This file contains a collection of utility functions for various tasks.
      4  *
      5  * `file_get_contents`: Reads a file and returns its contents as a null-terminated string.
      6  * The file path is passed as the first argument, and a pointer to the file contents is returned as the second argument.
      7  *
      8  * `remove_repeating_whitespaces`: Removes consecutive whitespace characters from a string and returns the modified string.
      9  *
     10  * `array_get_size`: Returns the size of a dynamically allocated array of int8_t values.
     11  * The array is passed as a pointer to the first element.
     12  *
     13  * `array_free`: Frees a dynamically allocated array of int8_t values.
     14  * The array is passed as a pointer to the first element.
     15  *
     16  * `array_from_string`: Generates a table of strings from a given prefix and suffix.
     17  * The prefix and suffix are passed as strings, and the function returns a dynamically allocated array of strings.
     18  */
     19 
     20 #include "implant.h"
     21 
     22 #include <ctype.h>
     23 #include <fcntl.h>
     24 #include <stddef.h>
     25 #include <stdint.h>
     26 #include <stdio.h>
     27 #include <stdlib.h>
     28 #include <string.h>
     29 #include <strings.h>
     30 #include <sys/stat.h>
     31 #include <sys/types.h>
     32 #include <unistd.h>
     33 
     34 int8_t file_get_contents(int8_t const *path, int8_t **buffer) {
     35     struct stat st = {0};
     36     int fd = 0;
     37     int64_t filesize = 0;
     38     int64_t bytes_read = 0;
     39 
     40     if (NULL == path) {
     41 #ifdef DEBUG
     42         DEBUG_LOG("[%s] path is NULL\n", CLIENT_ID);
     43 #endif
     44         return ERROR;
     45     }
     46 
     47     fd = open((const char *)path, O_RDONLY);
     48     if (0 > fd) {
     49 #ifdef DEBUG
     50         DEBUG_LOG("[%s] Could not open %s: %s\n", CLIENT_ID, path, strerror(errno));
     51 #endif
     52         return ERROR;
     53     }
     54 
     55     /* could use fseek but stat is posix so let's use that */
     56     if (0 > fstat(fd, &st)) {
     57 #ifdef DEBUG
     58         DEBUG_LOG("[%s] Could not call fstat on %s: %s\n", CLIENT_ID, path, strerror(errno));
     59 #endif
     60         close(fd);
     61         return ERROR;
     62     }
     63 
     64     filesize = (int64_t)st.st_size;
     65 
     66     if (!buffer) {
     67 #ifdef DEBUG
     68         DEBUG_LOG("[%s] file_get_contents: buffer addr is NULL\n", CLIENT_ID);
     69 #endif
     70         close(fd);
     71         return ERROR;
     72     }
     73 
     74     *buffer = malloc(sizeof(int8_t) * (uint64_t)(filesize + 1));
     75     if (!buffer || !(*buffer)) {
     76 #ifdef DEBUG
     77         DEBUG_LOG("[%s] file_get_contents: could not allocate memory for %s: %s", CLIENT_ID, path, strerror(errno));
     78 #endif
     79         close(fd);
     80         return ERROR;
     81     }
     82 
     83     /* FIXME(djnn):
     84 
     85        read file by chunks, append to circular-buffer data structure.
     86        we only read small files with this for now though, less syscalls is better probablies.
     87        */
     88 
     89     bytes_read = (int64_t)read(fd, *buffer, (uint64_t)filesize);
     90     if (bytes_read != filesize) {
     91 #ifdef DEBUG
     92         DEBUG_LOG("[%s] Should have read %ld bytes but read %ld (filepath: %s)\n",
     93                   CLIENT_ID,
     94                   st.st_size,
     95                   bytes_read,
     96                   path);
     97 #endif
     98     }
     99 
    100     if (bytes_read < 0) {
    101 #ifdef DEBUG
    102         DEBUG_LOG("[%s] read: %s", CLIENT_ID, strerror(errno));
    103 #endif
    104         close(fd);
    105         if (NULL != buffer) {
    106             free(*buffer);
    107         }
    108         return ERROR;
    109     }
    110 
    111     if (buffer != NULL)
    112         (*buffer)[bytes_read] = '\0';
    113     close(fd);
    114 
    115     return SUCCESSFUL;
    116 }
    117 
    118 static size_t
    119 get_nb_cols(const int8_t *str, int n, int8_t separator) {
    120     size_t i = (size_t)n;
    121     size_t res = 0;
    122 
    123     if (str == NULL || str[0] == '\0')
    124         return 0;
    125     for (; str[i] && str[i] != separator; i++, res++)
    126         ;
    127     return (res);
    128 }
    129 
    130 static size_t
    131 get_nb_rows(const int8_t *str, int8_t separator) {
    132     int i;
    133     size_t res = 0;
    134 
    135     if (str == NULL || str[0] == '\0')
    136         return 0;
    137     if (str == NULL || str[0] == '\0')
    138         return (0);
    139     for (i = 0; str[i] != '\0'; i++)
    140         if (str[i] == separator)
    141             res++;
    142     return (res + 1);
    143 }
    144 
    145 int8_t **
    146 array_from_string(const int8_t *str, int8_t separator) {
    147     size_t i = 0;
    148     size_t malloc_size = 0;
    149     size_t index_str = 0;
    150     int8_t **res = NULL;
    151 
    152     if (str == NULL || *str == 0)
    153         return NULL;
    154 
    155     res = malloc(sizeof(int8_t *) * (get_nb_rows(str, separator) + 1));
    156     if (!res)
    157         return NULL;
    158     for (; i < get_nb_rows(str, separator); i++) {
    159         malloc_size = get_nb_cols(&str[index_str], 0, separator);
    160 
    161         res[i] = malloc(sizeof(int8_t) * (malloc_size + 4));
    162         if (!res[i]) {
    163             res[i] = NULL;
    164             array_free((int8_t **)res);
    165             return NULL;
    166         }
    167 
    168         res[i] = (int8_t *)strncpy((char *)res[i], (const char *)&str[index_str], malloc_size);
    169         res[i][malloc_size] = '\0';
    170 
    171         index_str = index_str + malloc_size + 1;
    172     }
    173 
    174     res[i] = NULL;
    175     return (res);
    176 }
    177 
    178 void array_free(int8_t **tab) {
    179     if (!tab)
    180         return;
    181     for (size_t ctr = 0; tab[ctr] != NULL; ctr++)
    182         free(tab[ctr]);
    183     free(tab);
    184 }
    185 
    186 uint32_t array_get_size(int8_t **array) {
    187     uint32_t ctr = 0;
    188 
    189     if (!array)
    190         return 0;
    191     while (array[ctr++])
    192         ;
    193     return ctr;
    194 }
    195 
    196 int8_t *remove_repeating_whitespaces(int8_t *s) {
    197     size_t i = 0;
    198     size_t x = 0;
    199 
    200     if (!s || !(*s))
    201         return NULL;
    202 
    203     for (; s[i]; ++i)
    204         if (!isspace(s[i]) || (i > 0 && !isspace(s[i - 1])))
    205             s[x++] = s[i];
    206 
    207     s[x] = '\0';
    208     return s;
    209 }
    210 
    211 int8_t ascii_to_hex(char input[STRING_BUFFER_SIZE / 2], char output[STRING_BUFFER_SIZE]) {
    212     int ctr = -1;
    213 
    214     bzero(output, STRING_BUFFER_SIZE);
    215     if (!input)
    216         return ERROR;
    217 
    218     while (input[++ctr] != 0 && ctr < STRING_BUFFER_SIZE / 4) {
    219         snprintf(output + ctr * 2, STRING_BUFFER_SIZE - (ctr * 2), "%02x", (int8_t)input[ctr]);
    220     }
    221     output[STRING_BUFFER_SIZE - 1] = 0;
    222     return SUCCESSFUL;
    223 }
    224 
    225 int8_t hex_to_ascii(char input[STRING_BUFFER_SIZE], char output[STRING_BUFFER_SIZE]) {
    226     int ctr = -1;
    227 
    228     bzero(output, STRING_BUFFER_SIZE);
    229     if (!input)
    230         return ERROR;
    231 
    232     while (input[++ctr] != 0 && (ctr / 2) < STRING_BUFFER_SIZE - 1) {
    233         output[ctr / 2] = (char)strtol(input + ctr, NULL, 16);
    234     }
    235     return SUCCESSFUL;
    236 }