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 }