extern int attrlayer_init(void) { elist_init(&loadedlist); elist_init(&dirtylist); attrlayer_load_default(); return 0; }
/* Handle the gdt */ int cmd_gdt() { int ret; int index; int i; listent_t *actual; list_t *h; libkernshsgdt_t *sgdt; char buff[BUFSIZ]; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); XALLOC(__FILE__, __FUNCTION__, __LINE__, h, sizeof(list_t), -1); elist_init(h, "cmd_gdt_list", ASPECT_TYPE_UNKNOW); ret = kernsh_gdt(h); memset(buff, '\0', sizeof(buff)); snprintf(buff, sizeof(buff), "%s\n\n", revm_colorfieldstr("[+] GDT")); revm_output(buff); for (i = 0, index = 0, actual = h->head; index < h->elmnbr; i+=8, index++, actual = actual->next) { sgdt = (libkernshsgdt_t *) actual->data; snprintf(buff, sizeof(buff), "%s%s %s %s\n", revm_coloraddress("%.8lX", (eresi_Addr) sgdt->deb), revm_coloraddress("%.8lX", (eresi_Addr) sgdt->fin), revm_colorstr("@"), revm_coloraddress(XFMT, (eresi_Addr) sgdt->addr)); revm_output(buff); revm_endline(); } revm_output("\n"); elist_destroy(h); if (ret) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Cannot get gdt", -1); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/* Handle the sys_call_table */ int cmd_sct() { int ret; int index; listent_t *actual; list_t *h; libkernshsyscall_t *sct; char buff[BUFSIZ]; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); XALLOC(__FILE__, __FUNCTION__, __LINE__, h, sizeof(list_t), -1); elist_init(h, "cmd_sct_list", ASPECT_TYPE_UNKNOW); ret = kernsh_sct(h); memset(buff, '\0', sizeof(buff)); snprintf(buff, sizeof(buff), "%s\n\n", revm_colorfieldstr("[+] SYS_CALL_TABLE")); revm_output(buff); for (index = 0, actual = h->head; index < h->elmnbr; index++, actual = actual->next) { sct = (libkernshsyscall_t *) actual->data; memset(buff, '\0', sizeof(buff)); snprintf(buff, sizeof(buff), "%s %-40s %s %s\n", revm_colornumber("id:%-10u", (unsigned int)index), revm_colortypestr_fmt("%s", sct->name), revm_colorstr("@"), revm_coloraddress(XFMT, (eresi_Addr) sct->addr)); revm_output(buff); revm_endline(); } revm_output("\n"); elist_destroy(h); if (ret) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Cannot get syscalltable", -1); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * @brief Empty a list */ list_t *elist_empty(char *name) { list_t *list; char *newname; char type; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); list = elist_find(name); if (!list) PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, NULL); type = list->type; hash_del(hash_lists, name); elist_destroy(list); XALLOC(__FILE__, __FUNCTION__, __LINE__, newname, strlen(name) + 1, NULL); strncpy(newname, name, strlen(name)); XALLOC(__FILE__, __FUNCTION__, __LINE__, list, sizeof(list_t), NULL); elist_init(list, newname, type); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, list); }
int main (int argc, char **argv) { elist_init(); int i; for (i = 1; argv[i]; i++) { char *x = NULL; int err = strtoul(argv[i], &x, 10); if (x && *x) { fprintf(stderr, "'%s': unrecognized errno value\n", argv[i]); continue; } if (err < 0 || err > 255) { fprintf(stderr, "%i: out-of-range for an errno value\n", err); continue; } fprintf(stderr, "% 4i %-16s %s\n", err, CONST[err] ? CONST[err] : "-", strerror(err)); } return 0; }
/** * Beginning of the transform command, open a transformation switch */ int cmd_match() { list_t *list; revmexpr_t *ind; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* The first time we enter this command, we have to fetch the params */ list = (list_t *) world.curjob->iter[world.curjob->curloop].container; ind = world.curjob->iter[world.curjob->curloop].curind; if (!list || !ind || strcmp(ind->label, world.curjob->curcmd->param[0]) || list->type != ASPECT_TYPE_EXPR) { PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Match/Rewrite only acts on iterated lists of expressions", -1); } /* We assume that the rewritten expression is the induction variable */ world.curjob->recur[world.curjob->curscope].rwrt.matchexpr = ind; /* Create or flush the transformed expressions output list */ list = elist_find("transformed"); if (list) { elist_empty(list->name); world.curjob->recur[world.curjob->curscope].rwrt.transformed = list; } else { XALLOC(__FILE__, __FUNCTION__, __LINE__, world.curjob->recur[world.curjob->curscope].rwrt.transformed, sizeof(list_t), -1); elist_init(world.curjob->recur[world.curjob->curscope].rwrt.transformed, "transformed", ASPECT_TYPE_EXPR); } world.curjob->recur[world.curjob->curscope].rwrt.idloop = world.curjob->curloop; PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * @brief Set a list by its name (overwrite if existing ) */ int elist_register(list_t *list, char *name) { list_t *h; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); h = hash_get(hash_lists, name); if (h) { if (h->type == ASPECT_TYPE_UNKNOW) h->type = list->type; if (h->type != list->type) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Incompatible lists", -1); if (h->elmnbr) h = elist_empty(name); elist_merge(h, list); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); } XALLOC(__FILE__, __FUNCTION__, __LINE__, h, sizeof(list_t), -1); elist_init(h, name, h->type); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/* Reverse a list */ list_t *elist_reverse(list_t *l) { list_t *newlist; listent_t *nextent; listent_t *curent; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); hash_del(hash_lists, l->name); XALLOC(__FILE__, __FUNCTION__, __LINE__, newlist, sizeof(list_t), NULL); elist_init(newlist, l->name, l->type); /* Copy the list inserting at the beginning all the time */ for (curent = l->head; curent; curent = nextent) { elist_add(newlist, curent->key, curent->data); nextent = curent->next; XFREE(__FILE__, __FUNCTION__, __LINE__, curent); } XFREE(__FILE__, __FUNCTION__, __LINE__, l); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, newlist); }
/** * Reflect command disassemble the block cache of the parameter and create a list of instr exprs */ int cmd_reflect() { container_t *container; container_t *instrcontainer; mjrblock_t *curblock; asm_instr cur; elfsh_Half machine; char logbuf[BUFSIZ]; char logbuf2[BUFSIZ]; eresi_Addr addr; eresi_Addr daddr; u_int off; int ret; aspectype_t *curtype; void *blocdata; int fileoff; list_t *instrlist; revmexpr_t *expr; u_int insnbr; u_int reqnbr; u_int readsize; revmexpr_t *immed; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); curtype = aspect_type_get_by_name("instr"); if (!curtype) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Failed reflection : unknown type : instr", -1); /* Validate parameters */ if (world.curjob->curcmd->argc != 1 && world.curjob->curcmd->argc != 2) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Command expect one or two parameters \n", -1); /* Init proc */ if (!world.curjob->proc) { switch (machine = elfsh_get_arch(world.curjob->curfile->hdr)) { case EM_386: world.curjob->proc = &world.proc_ia32; break; case EM_SPARC: case EM_SPARC32PLUS: case EM_SPARCV9: world.curjob->proc = &world.proc_sparc; break; case EM_ARM: world.curjob->proc = &world.proc_arm; break; case EM_MIPS: case EM_MIPS_RS3_LE: world.curjob->proc = &world.proc_mips; break; default: snprintf(logbuf, sizeof (logbuf), "Architecture %s not supported. No disassembly available\n", elfsh_get_machine_string(machine)); revm_output(logbuf); PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); } } /* Now lookup the block by its addr or symbol */ immed = revm_lookup_param(world.curjob->curcmd->param[0], 1); if (!immed) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Failed to lookup parameter address expr", -1); if (revm_convert_object(immed, ASPECT_TYPE_CADDR) < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid address parameter", 0); addr = (immed->value->immed ? immed->value->immed_val.ent : immed->value->get_obj(immed->value->parent)); /* Analyse the binary if not already done */ /* if (!world.mjr_session.cur->analysed) { maxdepth = (int) config_get_data(CONFIG_CFGDEPTH); ret = mjr_analyse(&world.mjr_session, world.curjob->curfile->hdr->e_entry, maxdepth, 0); if (ret < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Failed analyzing current object", -1); } */ /* One more param enables lightweight mode: lookup data from a binary file section - no CFG needed */ if (world.curjob->curcmd->argc == 2) { immed = revm_lookup_param(world.curjob->curcmd->param[1], 1); if (revm_convert_object(immed, ASPECT_TYPE_INT) < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid size parameter", 0); reqnbr = (immed->value->immed ? (u_int) immed->value->immed_val.ent : (u_int) immed->value->get_obj(immed->value->parent)); if (reqnbr <= 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid instruction number to reflect", -1); readsize = 16 * reqnbr; blocdata = alloca(readsize); } /* Only one param (an addr/symbol) --> Lookup data from a basic block on the CFG */ else { container = mjr_block_get_by_vaddr(world.mjr_session.cur, addr, MJR_BLOCK_GET_STRICT); if (!container) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Failed to find bloc at this virtual address", -1); curblock = (mjrblock_t *) container->data; readsize = curblock->size; blocdata = alloca(readsize); reqnbr = 0; } /* Read data -- could be imported from a remote process, so needs to copy buffer */ fileoff = elfsh_get_foffset_from_vaddr(world.curjob->curfile, addr); if (elfsh_readmemf(world.curjob->curfile, fileoff, blocdata, readsize) != readsize) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Failed to read data to reflect", -1); /* Create the new list of instructions in expression form */ XALLOC(__FILE__, __FUNCTION__, __LINE__, instrlist, sizeof(list_t), -1); snprintf(logbuf2, sizeof(logbuf2), AFMT, addr); elist_init(instrlist, strdup(logbuf2), ASPECT_TYPE_EXPR); /* Reflection all instructions of the basic bloc in the list */ for (insnbr = off = 0; off < readsize; off += ret, insnbr++) { /* If reached the number of requested instruction, stop now even without reaching buffer end */ if (reqnbr && insnbr == reqnbr) break; /* Fetch the current instruction */ ret = asm_read_instr(&cur, (u_char *) blocdata + off, readsize - off + 10, world.curjob->proc); if (ret < 0) { elist_destroy(instrlist); PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to fetch code for basic bloc", -1); } /* Also add the instruction to the current reflected list for this block */ instrcontainer = container_create(curtype->type, (void *) &cur, NULL, NULL, 0); snprintf(logbuf, sizeof (logbuf), "$instr-"XFMT, addr + off); daddr = (eresi_Addr) instrcontainer; expr = revm_inform_type_addr(curtype->name, strdup(logbuf), daddr, NULL, 0, 1); elist_add(instrlist, strdup(logbuf), expr); } /* Reverse instrlist and add it to the hash of lists */ instrlist = elist_reverse(instrlist); hash_add(&instrlists_hash, strdup(logbuf2), instrlist); /* Printing message if we are not in quiet mode */ if (!world.state.revm_quiet) { snprintf(logbuf, sizeof(logbuf), " [*] Code at address " AFMT " reflected succesfully (%u instrs) \n\n", addr, insnbr); revm_output(logbuf); } /* Put the current bloc in the last result variable */ /* revm_expr_destroy_by_name(REVM_VAR_RESULT); revm_expr_copy(expr, REVM_VAR_RESULT); */ PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }
/** * @brief Create container lists * @param container Container holding the lists * @param linktype CONTAINER_LINK_IN or CONTAINER_LINK_OUT for input or output links list * @param uniqid Unique ID to be put into name * @return -1 on error and 0 on success */ int container_linklists_create(container_t *container, u_int linktype, u_int uniqid) { aspectype_t *type; char bufname[BUFSIZ]; char *prefix; list_t *newlist; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* Check for prefix (XXX: change to lookup user-configured prefixes ?) */ switch (container->type) { case ASPECT_TYPE_BLOC: prefix = "bloc"; break; case ASPECT_TYPE_FUNC: prefix = "func"; break; default: type = aspect_type_get_by_id(container->type); if (!type) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unable to find type of container", -1); prefix = type->name; } /* Now really allocate the list */ switch (linktype) { case CONTAINER_LINK_IN: snprintf(bufname, BUFSIZ, "%d_%s_"AFMT"_%s", uniqid, prefix, *(eresi_Addr *) container->data, "inputs"); newlist = elist_find(bufname); if (newlist) container->inlinks = newlist; else { XALLOC(__FILE__, __FUNCTION__, __LINE__, container->inlinks, sizeof(list_t), -1); elist_init(container->inlinks, strdup(bufname), ASPECT_TYPE_LINK); } break; case CONTAINER_LINK_OUT: snprintf(bufname, BUFSIZ, "%d_%s_"AFMT"_%s", uniqid, prefix, *(eresi_Addr *) container->data, "outputs"); newlist = elist_find(bufname); if (newlist) container->outlinks = newlist; else { XALLOC(__FILE__, __FUNCTION__, __LINE__, container->outlinks, sizeof(list_t), -1); elist_init(container->outlinks, strdup(bufname), ASPECT_TYPE_LINK); } break; default: PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown link type", -1); } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }