//---------------------------------------------------------------------- static bool add_stkpnt(sval_t delta) { func_t *pfn = get_func(cmd.ea); if ( pfn == NULL ) return false; return add_auto_stkpnt2(pfn, cmd.ea+cmd.size, delta); }
static QStringList get_types(QStringList (*get_func)(Provider *p), const QString &provider) { QStringList out; if(!provider.isEmpty()) { Provider *p = providerForName(provider); if(p) out = get_func(p); } else { ProviderList pl = allProviders(); foreach(Provider *p, pl) mergeList(&out, get_func(p)); } return out; }
void parse_exclude(const char *param) { if (param[0] == '@') { add_exclude_func(get_func(¶m[1])); } else { add_exclude_str(param); } }
void parse_accept(const char *param) { if (param[0] == '@') { add_accept_func(get_func(¶m[1])); } else { add_accept_str(param); } }
CMyComPtr<IInArchive> create_archive_object () { create_object_func_t func = get_func (); CMyComPtr<IInArchive> out; if (func (&CLSID_CFormat7z, &IID_IInArchive, (void**)&out) != S_OK) throw exception_dll_create_class_object (); return out; }
static void toggle_switches(unsigned int type, unsigned int channels) { struct control *control; unsigned int switch_1_mask; int (*get_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, int *); int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, int); snd_mixer_selem_channel_id_t channel_ids[2]; int left, right; int err; control = get_focus_control(type); if (!control) return; if (type == TYPE_PSWITCH) { switch_1_mask = HAS_PSWITCH_1; get_func = snd_mixer_selem_get_playback_switch; set_func = snd_mixer_selem_set_playback_switch; channel_ids[0] = control->pswitch_channels[0]; channel_ids[1] = control->pswitch_channels[1]; } else { switch_1_mask = HAS_CSWITCH_1; get_func = snd_mixer_selem_get_capture_switch; set_func = snd_mixer_selem_set_capture_switch; channel_ids[0] = control->cswitch_channels[0]; channel_ids[1] = control->cswitch_channels[1]; } if (!(control->flags & switch_1_mask)) channels = LEFT; if (channels & LEFT) { err = get_func(control->elem, channel_ids[0], &left); if (err < 0) return; } if (channels & RIGHT) { err = get_func(control->elem, channel_ids[1], &right); if (err < 0) return; } if (channels & LEFT) set_func(control->elem, channel_ids[0], !left); if (channels & RIGHT) set_func(control->elem, channel_ids[1], !right); display_controls(); }
FACT_t run_file_soft (func_t *scope) { char *filename; func_t *in; in = get_func (scope, "in"); filename = array_to_string (get_var (scope, "filename")); return run_file (in, filename, false); }
//---------------------------------------------------------------------- static void add_stkpnt(sval_t v) { if ( !may_trace_sp() ) return; func_t *pfn = get_func(cmd.ea); if ( pfn == NULL ) return; add_auto_stkpnt2(pfn, cmd.ea+cmd.size, v); }
gpointer g_object_new (GType type, const char *first, ...) { gpointer (* real_g_object_new_valist) (GType, const char *, va_list); va_list var_args; GObject *obj; const char *obj_name; real_g_object_new_valist = get_func ("g_object_new_valist"); va_start (var_args, first); obj = real_g_object_new_valist (type, first, var_args); va_end (var_args); obj_name = G_OBJECT_TYPE_NAME (obj); G_LOCK (gobject_list); if (g_hash_table_lookup (gobject_list_state.objects, obj) == NULL && object_filter (obj_name)) { if (display_filter (DISPLAY_FLAG_CREATE)) { g_print (" ++ Created object %p, %s\n", obj, obj_name); print_trace(); } /* FIXME: For thread safety, GWeakRef should be used here, except it * won’t give us notify callbacks. Perhaps an opportunistic combination * of GWeakRef and g_object_weak_ref() — the former for safety, the latter * for notifications (with the knowledge that due to races, some * notifications may get omitted)? * * Alternatively, we could abuse GToggleRef. Inadvisable because other * code could be using it. * * Alternatively, we could switch to a garbage-collection style of * working, where gobject-list runs in its own thread and uses GWeakRefs * to keep track of objects. Periodically, it would check the hash table * and notify of which references have been nullified. */ g_object_weak_ref (obj, _object_finalized, NULL); g_hash_table_insert (gobject_list_state.objects, obj, GUINT_TO_POINTER (TRUE)); g_hash_table_insert (gobject_list_state.added, obj, GUINT_TO_POINTER (TRUE)); } G_UNLOCK (gobject_list); return obj; }
//---------------------------------------------------------------------- static void add_stkpnt(sval_t value) { func_t *pfn = get_func(cmd.ea); if ( pfn == NULL ) return; if ( value & 1 ) value++; add_auto_stkpnt2(pfn, cmd.ea+cmd.size, value); }
// terrible function - tries to identify entries in VTBL int fill_vtbl(char *name, ea_t vtbl, pdb_class *pc = NULL) { if ( NULL == p_pool ) return 0; if ( pc == NULL ) pc = p_pool->find_class(name); if ( !pc ) return -1; // no such class int max = pc->find_right_range(); if ( !max ) return 0; // empty vtbl ? struct vtbl_method *vm; int processed = 0; ///warning("processing %s (%d entries)", pc->m_name, max); ea_t mm = NULL; // message map ea_t cm = NULL; // command map // do_unknown_range(vtbl, max, false); - because first entry in VTBL is death for ( int i = 0; i <= max; i += sizeof(ea_t), vtbl += sizeof(ea_t)) { make_vtbl_entry(vtbl); vm = pc->by_offset(i); if ( vm != NULL ) { processed++; /* check for message map */ if ( !mm ) { mm = is_message_map_func(vtbl, vm->name); if ( mm ) process_message_map(mm, name); } /* check for command map */ if ( !cm ) { cm = is_command_map_func(vtbl, vm->name); if ( cm ) process_command_map(cm); } // set comment for entry in this VTBL rp_set_comment(vtbl, vm->name, false); // set function comment func_t *f = get_func(get_long(vtbl)); if ( f ) { char *fcmt = get_func_cmt(f, true); if ( fcmt ) del_func_cmt(f, false); set_func_cmt(f, vm->name, true); } } } return processed; }
FACT_t get_char_file (func_t *scope) { func_t *file_object; file_object = get_func (scope, "file_object"); if (file_object->usr_data == NULL) FACT_ret_error (scope, "file object is invalid"); return FACT_get_si (fgetc ((FILE *) file_object->usr_data)); }
nasl_func* get_func_ref_by_name(lex_ctxt* ctxt, const char* name) { int h = hash_str(name); nasl_func *f; if ((f = get_func(ctxt, name, h)) != NULL) return f; else return NULL; }
void idaapi PluginMain(int param) { if(param == 0) { // convert the current function func_t* p_func = get_func(get_screen_ea()); if(p_func == NULL) { msg("Not in a function, so can't run PPC Helper!\n"); return; } PPCHelper_ConvertFunction(p_func); } else if(param == 1) { // convert all functions in the database // get address of first function func_t* p_func; ea_t ea = inf.minEA; p_func = get_func(ea); if( !p_func ) p_func = get_next_func(ea); // process all function while( p_func ) { // process function PPCHelper_ConvertFunction(p_func); // get next function p_func = get_next_func(p_func->startEA); } } else { msg("Unknown mode - Please set the mode of execution in the plugins.cfg file\n"); return; } }
//TODO: this is not a f*****g smart function! this is total crap!!! //TODO: kill locating algo by function, Cause there a lot of places, where IDA f*****g sucks, and dont understand bounds of function!!!! //replace by discovery up by the tree ea_t find_instruction_that_changes_operand_backward_smart(ea_t start, op_t operand) { func_t *f = get_func(start); char buf[MAXSTR]; char instr_clean[MAXSTR]; if(f) { ea_t addr = prev_head(start, f->startEA); while (addr != BADADDR) { flags_t flags = getFlags(addr); if (isHead(flags) && isCode(flags)) { ua_ana0(addr); switch(cmd.itype){ case NN_lea: case NN_pop: case NN_shl: case NN_shr: case NN_sal: case NN_sar: case NN_imul: case NN_mul: case NN_idiv: case NN_div: case NN_xor: case NN_or: case NN_not: case NN_neg: case NN_inc: case NN_dec: case NN_add: case NN_sub: case NN_mov: case NN_movsx: case NN_movzx:{ for(int i = 0; cmd.Operands[i].type != o_void; i++){ if((cmd.Operands[i].type == operand.type) && (cmd.Operands[i].reg == operand.reg)){ return addr; } }break; default:break; } } } addr = prev_head(addr, f->startEA); } } return BADADDR; }
//---------------------------------------------------------------------- static void process_operand(op_t &x,int isAlt,int isload) { switch ( x.type ) { case o_reg: break; default: // interr("emu"); break; case o_imm: // if ( !isload ) interr("emu2"); process_immediate_number(x.n); if ( isOff(uFlag, x.n) ) ua_add_off_drefs2(x, dr_O, x.amode & amode_signed ? OOF_SIGNED : 0); break; case o_phrase: if ( !isAlt && isOff(uFlag, x.n) ) { ua_add_off_drefs2(x, isload ? dr_R : dr_W, OOF_ADDR); ea_t ea = calc_target(cmd.ea+x.offb, cmd.ea, x.n, x.addr); ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } break; case o_mem: { ea_t ea = calc_mem(x); ua_add_dref(x.offb, ea, isload ? dr_R : dr_W); ua_dodata2(x.offb, ea, x.dtyp); if ( !isload ) doVar(ea); } break; case o_near: add_near_ref(x, calc_mem(x)); break; case o_textphrase: break; case o_local: // local variables if ( may_create_stkvars() ) { func_t *pfn = get_func(cmd.ea); if ( (pfn != NULL) && (pfn->flags & FUNC_FRAME) && ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) ) op_stkvar(cmd.ea, x.n); } break; } }
slist_t * parse_fct(ea_t ea, char options) { slist_t * sl; psig_t * sig; func_t * fct; int i, k; pflow_chart_t * fchart; short opcodes[256]; char buf[512]; fct = get_func(ea); if (!fct) return NULL; if (!pget_func_name(ea, buf, sizeof(buf))) return NULL; fchart = new pflow_chart_t(fct); sl = siglist_init(fchart->nproper, NULL); if (!sl) return NULL; for (i=0; i<fchart->nproper; i++) { memset(opcodes, '\0', sizeof(opcodes)); sig = sig_init(); if (!sig) { siglist_free(sl); delete fchart; return NULL; } sig_set_start(sig, fchart->blocks[i].startEA); sig_set_name(sig, buf); for (k=0; k<fchart->nsucc(i); k++) sig_add_sref(sig, fchart->blocks[i].succ[k].ea, fchart->blocks[i].succ[k].type, CHECK_REF); sig_add_block(sig, opcodes, fchart->blocks[i].startEA, fchart->blocks[i].endEA, 1, options); sig_calc_sighash(sig, opcodes, 1); siglist_add(sl, sig); } siglist_sort(sl); delete fchart; return sl; }
FACT_t lock_object (func_t *scope) { FACT_t return_value; var_t *obj_name; var_t *obj_var; func_t *obj_func; func_t *search; search = get_func (scope, "search"); obj_name = get_var (scope, "name"); obj_var = get_var (search, array_to_string (obj_name)); if (obj_var == NULL) { obj_func = get_func (search, array_to_string (obj_name)); if (obj_func == NULL) FACT_ret_error (scope->up, "no such object exists"); } if (obj_var != NULL) { return_value.type = VAR_TYPE; obj_var->locked = true; return_value.v_point = obj_var; lock_var_array (obj_var->array_up); } else { return_value.type = FUNCTION_TYPE; obj_func->locked = true; return_value.f_point = obj_func; lock_func_array (obj_func->array_up); } return return_value; }
static inline void print_func_addr(void) { void *f; /* TODO: max length of name? */ char name[256] = { 0 }; printf("Function name: "); if (!fgets(name, sizeof(name), stdin)) return; name[strcspn(name, "\n")] = '\0'; f = get_func(name); if (f) printf("[+] Address of %s: %p\n", name, f); }
//retrieves function names and jump labels void __stdcall GetName(__int64 offset, char* buf, int bufsize){ get_true_name( BADADDR, (ea_t)offset, buf, bufsize ); if(strlen(buf) == 0){ func_t* f = get_func((ea_t)offset); for(int i=0; i < f->llabelqty; i++){ if( f->llabels[i].ea == offset ){ int sz = strlen(f->llabels[i].name); if(sz < bufsize) strcpy(buf,f->llabels[i].name); return; } } } }
//---------------------------------------------------------------------- // trace a function call. // adjuct the stack, determine the execution flow // returns: // true - the called function returns to the caller // false - the called function doesn't return to the caller static bool handle_function_call(ea_t callee) { bool funcflow = true; if ( !func_does_return(callee) ) funcflow = false; if ( should_trace_sp() ) { func_t *caller = get_func(cmd.ea); if ( func_contains(caller, cmd.ea+cmd.size) ) { sval_t delta = calc_func_call_delta(callee); if ( delta != 0 ) add_stkpnt(delta); } } return funcflow; }
//---------------------------------------------------------------------- static sval_t calc_func_call_delta(ea_t callee) { sval_t delta; func_t *pfn = get_func(callee); if ( pfn != NULL ) { delta = pfn->argsize; if ( (pfn->flags & FUNC_FAR) != 0 && cmd.Op1.type == o_near ) delta += 2; // function will pop the code segment } else { delta = get_ind_purged(callee); if ( delta == -1 ) delta = 0; } return delta; }
//-------------------------------------------------------------------------- graph_info_t * graph_info_t::create(ea_t func_ea) { graph_info_t *r = find(func_ea); // not there? create it if ( r == NULL ) { // we need a function! func_t *pfn = get_func(func_ea); if ( pfn == NULL ) return NULL; r = new graph_info_t(); get_title(func_ea, &r->title); r->func_ea = pfn->startEA; instances.push_back(r); } return r; }
nasl_func* insert_nasl_func(lex_ctxt* lexic, const char* fname, tree_cell* decl_node) { int h = hash_str(fname); int i; nasl_func *pf; tree_cell *pc; if (get_func(lexic, fname, h) != NULL) { nasl_perror(lexic, "insert_nasl_func: function '%s' is already defined\n", fname); return NULL; } pf = emalloc(sizeof(nasl_func)); pf->func_name = estrdup(fname); if (decl_node != NULL && decl_node != FAKE_CELL) { for (pc = decl_node->link[0]; pc != NULL; pc = pc->link[0]) if (pc->x.str_val == NULL) pf->nb_unnamed_args ++; else pf->nb_named_args ++; pf->args_names = emalloc(sizeof(char*) * pf->nb_named_args); for (i = 0, pc = decl_node->link[0]; pc != NULL; pc = pc->link[0]) if (pc->x.str_val != NULL) pf->args_names[i ++] = estrdup(pc->x.str_val); /* sort arg names */ qsort(pf->args_names, pf->nb_named_args, sizeof(pf->args_names[0]), strcmp); pf->block = decl_node->link[1]; ref_cell(pf->block); } /* Allow variable number of arguments for user defined functions */ if (decl_node != NULL) pf->nb_unnamed_args = 9999; pf->next_func = lexic->functions[h]; lexic->functions[h] = pf; return pf; }
int rtelnet_port_cmd(int type, char *in, int inlen, char *out, int outlen) { int ret = 0; char buf[OSIZE] = {0}; if(out == NULL) { out = (char *)malloc(OSIZE); if(NULL == out) { return EMALLOC; } } memset(out, 0, outlen); if(!strncmp(in, "get_", 4)) { ret = get_func(in, inlen, buf, sizeof(buf)); } else if(!strncmp(in, "set_", 4)) { ret = set_func(in, inlen, buf, sizeof(buf)); } else if(!strncmp(in, "save", 4)) { ret = save_func(in, inlen, buf, sizeof(buf)); } else if(!strncmp(in, "help", 4)) { ret = help_func(in, inlen, buf, sizeof(buf)); } else { ret = ENOFIND; } if(ret >= 0) { snprintf(out, outlen, "%s cmd success %s\r\n>", in, buf); ret = strlen(out) + 1; } else if(ret == ENOFIND) { snprintf(out, outlen, "%s cmd not found!\r\n>", in); ret = strlen(out) + 1; } else if(ret == ENOPARAM) { snprintf(buf, outlen, "%s failed param wrong!\r\n>", in); ret = strlen(out) + 1; } else { snprintf(out, outlen, "%s cmd faild, %s\r\n>", in, buf); ret = strlen(out) + 1; } return ret; }
//-------------------------------------------------------------------------- int callgraph_t::walk_func(func_t *func, funcs_walk_options_t *opt, int level) { // add a node for this function ea_t func_start = func->startEA; int id = add(func_start); func_item_iterator_t fii; for ( bool fi_ok=fii.set(func); fi_ok; fi_ok=fii.next_code() ) { xrefblk_t xb; for ( bool xb_ok = xb.first_from(fii.current(), XREF_FAR); xb_ok && xb.iscode; xb_ok = xb.next_from() ) { func_t *f = get_func(xb.to); if ( f == NULL ) continue; int id2; if ( !visited(f->startEA, &id2) ) { if ( func_contains(func, xb.to) ) continue; bool skip = false; if ( opt != NULL ) { skip = // skip lib funcs? (((f->flags & FUNC_LIB) != 0) && ((opt->flags & FWO_SKIPLIB) != 0)) // max recursion is off, and limit is reached? || ( ((opt->flags & FWO_RECURSE_UNLIM) == 0) && (level > opt->recurse_limit) ); } if ( skip ) id2 = add(f->startEA); else id2 = walk_func(f, opt, level+1); } create_edge(id, id2); } } return id; }
//-------------------------------------------------------------------------- callgraph_t::funcinfo_t *callgraph_t::get_info(int nid) { funcinfo_t *ret = NULL; do { // returned cached name int_funcinfo_map_t::iterator it = cached_funcs.find(nid); if ( it != cached_funcs.end() ) { ret = &it->second; break; } // node does not exist? int_ea_map_t::const_iterator it_ea = node2ea.find(nid); if ( it_ea == node2ea.end() ) break; func_t *pfn = get_func(it_ea->second); if ( pfn == NULL ) break; funcinfo_t fi; // get name char buf[MAXSTR]; if ( get_func_name(it_ea->second, buf, sizeof(buf)) == NULL ) fi.name = "?"; else fi.name = buf; // get color fi.color = calc_bg_color(pfn->startEA); fi.ea = pfn->startEA; it = cached_funcs.insert(cached_funcs.end(), std::make_pair(nid, fi)); ret = &it->second; } while ( false ); return ret; }
ea_t find_instruction_backward(ea_t start, uint16 itype) { func_t *f = get_func(start); if(f) { ea_t addr = prev_head(start, f->startEA); while (addr != BADADDR) { flags_t flags = getFlags(addr); if (isHead(flags) && isCode(flags)) { ua_ana0(addr); if(cmd.itype == itype)return addr; } addr = prev_head(addr, f->startEA); } } return BADADDR; }
void g_object_unref (gpointer object) { void (* real_g_object_unref) (gpointer); GObject *obj = G_OBJECT (object); const char *obj_name; real_g_object_unref = get_func ("g_object_unref"); obj_name = G_OBJECT_TYPE_NAME (obj); if (object_filter (obj_name) && display_filter (DISPLAY_FLAG_REFS)) { g_print (" - Unreffed object %p, %s; ref_count: %d -> %d\n", obj, obj_name, obj->ref_count, obj->ref_count - 1); print_trace(); } real_g_object_unref (object); }
// The plugin can be passed an integer argument from the plugins.cfg // file. This can be useful when you want the one plug-in to do // something different depending on the hot-key pressed or menu // item selected. void IDAP_run(int arg) { // Get the address of the cursor position ea_t addr = get_screen_ea(); func_t *pfn = get_func(addr); function_analyzer f( pfn->startEA ); f.run_analysis(); msg( "There are %d nodes.\n", f.get_num_nodes() ); for( int i = 1; i <= f.get_num_nodes(); ++i ) { msg( "Node %d: %a\n", i, f.get_node(i) ); } msg( "There are %d edges.\n", f.get_num_edges() ); for( int i = 1; i <= f.get_num_edges(); ++i ) { msg("Edge %d: src %a dst %a\n", i, f.get_edge_src(i), f.get_edge_dst(i) ); } }