/** * Generate the color pattern for a given color structure * @param t color structure * @param text text to color (not used on this function) * @param pattern pattern will be save on this buffer */ int revm_colorpattern(color_t *t, char *text, char *pattern) { char bo[16], ul[16], fg[16], bg[16]; u_short set = 0; NOPROFILER_IN(); if (t == NULL || (!t->bground && !t->fground && !t->bold && !t->underline)) NOPROFILER_ROUT(-1); /* Set every element */ COLOR_SET_ELEMENT(t->bold, bo, COLOR_BOLD); COLOR_SET_ELEMENT(t->underline, ul, COLOR_UNDERLINE); COLOR_SET_ELEMENT(t->fground, fg, t->fground); COLOR_SET_ELEMENT(t->bground, bg, t->bground); snprintf(pattern, COLOR_TOKEN_LEN - 1, "%%s%s%s%s%sm%%s%s%um%%s", (t->bold > 0 ? bo : ""), (t->underline > 0 ? ul : ""), (t->fground > 0 ? fg : ""), (t->bground > 0 ? bg : ""), S_STARTCOLOR, COLOR_NONE); NOPROFILER_ROUT(0); }
/** * @brief Initialize the hash table */ int elist_init(list_t *h, char *name, u_int type) { list_t *exist; NOPROFILER_IN(); if (type >= aspect_type_nbr) { fprintf(stderr, "Unable to initialize list %s \n", name); PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to initialize list", -1); } exist = elist_find(name); if (exist) { #if 1 //__LIST_DEBUG__ fprintf(stderr, "DEBUG: List %s (%p) already exists in hash with addr %p : NOT CREATING \n", name, h, exist); #endif NOPROFILER_ROUT(1); } #if __LIST_DEBUG__ else fprintf(stderr, "DEBUG: List %s allocated at %p does not exists in hash : CREATING \n", name, h); #endif bzero(h, sizeof(list_t)); h->type = type; h->name = name; hash_add(hash_lists, name, h); NOPROFILER_ROUT(0); }
/** * Build color text * */ char *revm_colorget(char *sp, char *type, void *object) { color_t *t; char pattern[COLOR_TOKEN_LEN]; char text[COLOR_TOKEN_LEN]; char trim_text[COLOR_TOKEN_LEN]; char white_s[COLOR_TOKEN_LEN]; char white_e[COLOR_TOKEN_LEN]; char *pText; NOPROFILER_IN(); if (curtok >= COLOR_TOKENS) { printf("[E] %s:%d %s: WARNING !!!! Token overflow (val:%u)\n", __FILE__, __LINE__, __FUNCTION__, curtok); NOPROFILER_ROUT(NULL); } //printf("Before token = %016llX \n", (eresi_Addr *) object); //snprintf(text, COLOR_TOKEN_LEN - 1, sp, object); if (strchr(sp, 's') == NULL) snprintf(text, COLOR_TOKEN_LEN - 1, sp, *(eresi_Addr *) object); else snprintf(text, COLOR_TOKEN_LEN - 1, sp, object); /* Color isn't activated */ if (!nocolor) NOPROFILER_ROUT(revm_colornothing(sp, object)); t = revm_colortable(type, text); /* Color not found */ if (t == NULL) NOPROFILER_ROUT(revm_colornothing(sp, object)); /* Invalid pattern */ if (revm_colorpattern(t, text, pattern) != 0) NOPROFILER_ROUT(revm_colornothing(sp, object)); pText = text; memset(white_s, 0x00, COLOR_TOKEN_LEN); memset(white_e, 0x00, COLOR_TOKEN_LEN); /* Trim the string from blank char */ if (!trim(text, trim_text, COLOR_TOKEN_LEN, white_s, white_e)) pText = trim_text; snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, pattern, white_s, pText, white_e); NOPROFILER_ROUT(tokens[curtok++]); }
/** * Retrieve a color information structure from a color type * @param type color type * @param text text to color to filter for warnstring type * @return color structure */ color_t *revm_colortable(char *type, char *text) { NOPROFILER_IN(); /* Override color by warning color if we match the alert regex */ if (world.state.revm_use_alert && !regexec(&world.state.revm_alert, text, 0, 0, 0)) NOPROFILER_ROUT(hash_get(&t_color_hash, "warnstring")); NOPROFILER_ROUT(hash_get(&t_color_hash, type)); }
/** * Set workspace configuration to standard I/O */ int revm_std_io(revmjob_t *job) { NOPROFILER_IN(); if (!job) NOPROFILER_ROUT(0); job->ws.io.type = REVM_IO_STD; job->ws.io.input_fd = 0; job->ws.io.input = revm_stdinput; job->ws.io.output_fd = 1; job->ws.io.output = revm_stdoutput; NOPROFILER_ROUT(0); }
/** * Initialize Input/Output hooks */ int revm_initio() { static int done = 0; revmjob_t *initial; u_int i; NOPROFILER_IN(); if (done) NOPROFILER_ROUT(0); done = 1; XALLOC(__FILE__, __FUNCTION__, __LINE__,initial, sizeof(revmjob_t), -1); memset(initial, 0, sizeof(revmjob_t)); hash_init(&initial->recur[0].exprs , "job0_rec0_exprs" , 23, ASPECT_TYPE_EXPR); hash_init(&initial->recur[0].labels, "job0_rec0_labels", 23, ASPECT_TYPE_STR); revm_std_io(initial); initial->ws.active = 1; initial->ws.createtime = time(&initial->ws.createtime); world.initial = world.curjob = initial; hash_init(&world.jobs, "jobs", 11, ASPECT_TYPE_UNKNOW); hash_add(&world.jobs, "local", initial); initial->ws.name = strdup("local"); hash_init(&initial->loaded, "initial_loaded_files", 51, ASPECT_TYPE_UNKNOW); hash_init(&initial->dbgloaded, "initial_dbgloaded_files", 11, ASPECT_TYPE_UNKNOW); for (i = 0; i < REVM_MAXSRCNEST; i++) { initial->recur[i].script = NULL; initial->recur[i].lstcmd = NULL; initial->iter[i].elmidx = REVM_IDX_UNINIT; } initial->recur[0].funcname = "top-level"; profiler_setcolor(revm_endline, revm_colorinstr, revm_colorstr, revm_colorfieldstr, revm_colortypestr, revm_colorend, revm_colorwarn, revm_colorfunction, revm_colorfilename); profiler_setmorecolor(revm_coloradv, revm_colorinstr_fmt, revm_coloraddress, revm_colornumber, revm_colorstr_fmt, revm_colorfieldstr_fmt, revm_colortypestr_fmt, revm_colorwarn_fmt); NOPROFILER_ROUT(0); }
/** * Return without color * @param sp given string (pattern like %s or %d etc ..) * @param object objet to print using the string * @return generate string */ static char *revm_colornothing(char *sp, void *object) { NOPROFILER_IN(); if (!strcmp(sp, "%s")) NOPROFILER_ROUT((char *) object); if (strchr(sp, 's') == NULL) snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, sp, *(eresi_Addr *) object); else snprintf(tokens[curtok], COLOR_TOKEN_LEN - 1, sp, object); NOPROFILER_ROUT(tokens[curtok++]); }
/** * Read a signed leb128 number as describe on the dwarf2 documentation * a little bit optimize * @param data pointer to a buffer where we'll read * @param bread store size readed * @return final value */ long edfmt_read_leb128(void *data, u_int *bread) { long sum = 0; u_int read = 0; u_char c; u_int s = 0; NOPROFILER_IN(); do { c = *(u_char *) (data + read) & 0xFF; read++; sum |= ((long)(c & 127) << s); s += 7; } while ((c & 128) != 0); if ((s < (8 * sizeof(sum))) && (c & 0x40)) sum |= -(((long)1) << s); if (bread) *bread = read; NOPROFILER_ROUT(sum); }
/** * @brief Read input from the current IO file descriptor */ char *revm_read_input() { char tmpbuf[BUFSIZ + 1]; int len; u_char wantmore; NOPROFILER_IN(); /* In case we are scripting, even readline will use a read */ for (wantmore = len = 0; len < BUFSIZ; len++) switch (read(world.curjob->ws.io.input_fd, tmpbuf + len, 1)) { case 1: if (tmpbuf[len] == '\n') { if (len == 0) { //fprintf(stderr, "Read length 0 ... \n"); NOPROFILER_ROUT((char *) REVM_INPUT_VOID); } if (wantmore) { len--; wantmore = 0; continue; } if (world.state.revm_mode == REVM_STATE_EMBEDDED && world.state.revm_side == REVM_SIDE_CLIENT) tmpbuf[len + 1] = 0x00; else tmpbuf[len] = 0x00; goto end; } else if ((len > 2 && tmpbuf[len - 1] == ':' && tmpbuf[len] == ':') || tmpbuf[len] == ',') wantmore = 1; else wantmore = 0; continue; default: *tmpbuf = 0x00; goto end; } end: //fprintf(stderr, "[pid = %u] Read on fd = *%s*\n", getpid(), tmpbuf); NOPROFILER_ROUT((*tmpbuf ? strdup(tmpbuf) : NULL)); }
/** * INPUT IO handler for stdin */ char *revm_stdinput() { char *str; NOPROFILER_IN(); str = NULL; /* Case if we are using readline */ if (revm_is_enabled() && world.state.revm_mode != REVM_STATE_SCRIPT) { str = revm_input_check(); NOPROFILER_ROUT(str); } /* If not, read the stdin file descriptor */ NOPROFILER_ROUT(revm_read_input()); }
/** * @brief Initialize the hash table * @param h Pointer to the hash to initialize * @param name Name of the hash. * @param size Size to document * @param type Type to document * @param Returns 0 on success, -1 on error or 1 if hash already exists. */ int hash_init(hash_t *h, char *name, int size, u_int type) { NOPROFILER_IN(); /* First checks */ /* Initialize the global hash table of lists and the global hash table of hash tables */ if (!hash_hash) { hash_hash = (hash_t *) calloc(sizeof(hash_t), 1); hash_init(hash_hash, "hashes", 51, ASPECT_TYPE_UNKNOW); } if (type >= aspect_type_nbr) { fprintf(stderr, "Unable to initialize hash table %s \n", name); PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to initialize hash table", -1); } if (h != hash_hash && hash_find(name) && h->ent) { #if __DEBUG__ fprint(stderr, "Hash table already exists and initialized\n"); #endif NOPROFILER_ROUT(1); } //printf("INIT HASH %s \n", name); /* Add a new element */ XALLOC(__FILE__, __FUNCTION__, __LINE__, h->ent, size * sizeof(listent_t), -1); h->size = size; h->type = type; h->elmnbr = 0; h->linearity = 0; h->name = name; hash_add(hash_hash, name, h); if (!hash_lists) { hash_lists = (hash_t *) calloc(sizeof(hash_t), 1); hash_init(hash_lists, "lists", 51, ASPECT_TYPE_UNKNOW); } NOPROFILER_ROUT(0); }
/** * Trim a string from blank char and copy it on to argument * @param from source * @param to destination * @param size buffer size * @param start saved starting blank chars (for replace in another place) * @param end saved ending blank chars (for replace in another place) */ static int trim(char *from, char *to, u_int size, char *start, char *end) { u_int len, istart, iend; NOPROFILER_IN(); if (size == 0 || size > COLOR_TOKEN_LEN || from == NULL || to == NULL) NOPROFILER_ROUT(-1); len = strlen(from); /* Speed check */ if (!IS_BLANK(from[0]) && !IS_BLANK(from[len])) NOPROFILER_ROUT(-1); /* Before */ for (istart = 0; istart < len && IS_BLANK(from[istart]); istart++); /* All blank, no modifications */ if (istart == len) NOPROFILER_ROUT(-1); /* After */ for (iend = len; iend > 0 && IS_BLANK(from[iend]); iend--); iend = len - iend; /* Copy the right char on to argument */ strncpy(to, from + istart, len - istart - iend); to[len - istart - iend] = 0x00; if (start) { strncpy(start, from, istart); start[istart] = 0x00; } if (end) { strncpy(end, from + len - iend, iend); end[iend] = 0x00; } NOPROFILER_ROUT(0); }
/** * Set workspace configuration to standard I/O */ int revm_fifo_io(revmjob_t *job) { int fd; int fd2; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); if (!job) { fprintf(stderr, "error: input job is NULL in fifo_io \n"); NOPROFILER_ROUT(0); } /* Remove the FIFO is already existing */ if (world.state.revm_side == REVM_SIDE_CLIENT) { if (!access(REVM_FIFO_C2S, F_OK)) unlink(REVM_FIFO_C2S); if (!access(REVM_FIFO_S2C, F_OK)) unlink(REVM_FIFO_S2C); /* Create the 2 FIFO */ mkfifo(REVM_FIFO_S2C, 0600); mkfifo(REVM_FIFO_C2S, 0600); } /* Register the FIFO as an I/O */ if (!e2dbg_kpresence_get()) { XOPEN(fd, REVM_FIFO_S2C, O_RDWR, 0600, -1); world.fifo_s2c = fd; XOPEN(fd2, REVM_FIFO_C2S, O_RDWR, 0600, -1); world.fifo_c2s = fd2; /* If we are in the embedded server part of the debugger, do all I/O on the FIFO */ if (world.state.revm_side == REVM_SIDE_SERVER) { job->ws.io.input_fd = fd2; job->ws.io.input = revm_stdinput; job->ws.io.output_fd = fd; job->ws.io.output = revm_stdoutput; dup2(fd, 0); } } /* We dont let this between #ifdef's KERNEL to avoid recompiling this code multiple times for the userland and kernel debuggers */ else { job->ws.io.input = NULL; // FIXME: need IO vector ? //job->ws.io.output = ke2dbg_output; } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/* Special functions */ char *revm_coloradv(char *type, char *pattern, char *text) { char *p; NOPROFILER_IN(); p = revm_colorget(pattern, type, text); strncpy(text, p, BUFSIZ); text[BUFSIZ-1] = 0; curtok--; NOPROFILER_ROUT(text); }
/** * @brief Read a new line, avoiding comments and void lines */ char *revm_getln() { char *buf; char *sav; NOPROFILER_IN(); do { buf = world.curjob->ws.io.input(); if (buf == ((char *) REVM_INPUT_VOID)) NOPROFILER_ROUT((char *) REVM_INPUT_VOID); if (buf == NULL) NOPROFILER_ROUT(NULL); if (!*buf) { XFREE(__FILE__, __FUNCTION__, __LINE__,buf); NOPROFILER_ROUT(NULL); } sav = buf; while (IS_BLANK(*sav)) sav++; if (!*sav || *sav == REVM_COMMENT_START) { revm_log(sav); revm_log("\n"); revm_buffer_free(buf); if (world.state.revm_mode == REVM_STATE_INTERACTIVE || world.state.revm_mode == REVM_STATE_EMBEDDED) NOPROFILER_ROUT((char*) REVM_INPUT_VOID); buf = NULL; if (*sav) continue; } if (world.state.revm_mode != REVM_STATE_SCRIPT) { revm_output_nolog("\n"); /* avoid looping with readline */ if (revm_is_enabled() && buf == NULL) NOPROFILER_ROUT((char *) REVM_INPUT_VOID); if (revm_is_enabled()) break; } } while (buf == NULL); NOPROFILER_ROUT(buf); }
/* Return number of color chars (not total size) */ int revm_color_count(char *string) { int count = 0; int len; int i; NOPROFILER_IN(); len = strlen(string); for (i = 0; i < len; i++) { if (string[i] == C_STARTCOLOR) { count++; while (i < len && string[i] != 'm') i++; } } NOPROFILER_ROUT(count); }
/** * Read an unsigned leb128 number as describe on the dwarf2 documentation * a little bit optimize * @param data pointer to a buffer where we'll read * @param bread store size readed * @return final value */ u_long edfmt_read_uleb128(void *data, u_int *bread) { u_long sum = 0; u_int read = 0; u_char c; int s = 0; NOPROFILER_IN(); do { c = *(u_char *) (data + read) & 0xFF; read++; sum |= ((u_long)(c & 127) << s); s += 7; } while ((c & 128) != 0); if (bread) *bread = read; NOPROFILER_ROUT(sum); }
/** * Return total size of colors on a string */ int revm_color_size(char *string) { int size = 0; int len; int i; NOPROFILER_IN(); len = strlen(string); for (i = 0; i < len; i++) { if (string[i] == C_STARTCOLOR) { while (i < len && string[i] != 'm') { size++; i++; } } } NOPROFILER_ROUT(size); }