//----------------------------------------------------------------------------- // Function: run // // run is a plugin_t function. It is executed when the plugin is run. // // The argument 'arg' can be passed by adding an entry in // plugins.cfg or passed manually via IDC: // // success RunPlugin(string name, long arg); //----------------------------------------------------------------------------- void runPlugin(int arg) { ea_t ea = get_screen_ea(); int WcharCount = 0; //inf.strtype = ASCSTR_UNICODE; msg("\nCurrent addr is 0x%x and the byte are :\n",ea); while (1) { msg("%.2x ", get_byte(ea)); WcharCount ++; if (get_byte(ea) ==0 && get_byte(ea+1) == 0) //Detect the end of the unicode string { msg("\nWhole length is :0x%X.",WcharCount+2); break; } ea ++; } if (!make_ascii_string(get_screen_ea(),0/*WcharCount + 2*/,ASCSTR_UNICODE)) //+2 to fix up the last two 0. { msg("\nError:Convert to string failed.\n"); }else{ msg("\Convert to string success.\n"); } }
// 插件可以从plugins.cfg文件中,被传进一个整型参数。 // 当按下不同的热键或者菜单时,您需要一个插件做不同 // 的事情时,这非常有用。 void __stdcall IDAP_run(int arg) { char szBuf[512] = {0}; #ifdef __EA64__ sprintf(szBuf, "0x%llX", get_screen_ea()); #else sprintf(szBuf, "0x%08X", get_screen_ea()); #endif SnedClipData(szBuf, strlen(szBuf)); msg("SendScreenAddrClip: %s\n", szBuf); return; }
void process_VTBL() { // check_rt_tree(); ea_t curr = get_screen_ea(); if ( !is_contain_ptr(curr) ) return; if ( !check_rpd_count() ) return; char *name = NULL; bool free_name = false; bool named = false; pdb_class *pc = try_to_find_this_or_parent(curr, &name, &free_name, &named); if ( !pc ) { msg("Cannot detect class for VTBL at %X\n", curr); return; } msg("Class %s\n", name); fill_vtbl(name, curr, pc); if ( !named ) mark_name_from_static_RT(curr); if ( free_name ) qfree(name); }
// 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) { msg("%s run()\n", IDAP_name); // Disassemble the instruction at the cursor position, store it in // the global accessible "cmd" structure. // ua_out(get_screen_ea(), false); decode_insn( get_screen_ea() ); // Display information about the first operand msg("itype = %u size = %zu\n", cmd.itype, cmd.size ); for( unsigned int n = 0; n < UA_MAXOP ; ++n ) { if( cmd.Operands[n].type == o_void ) break; msg("Operand %u n = %d type = %d reg = %d value = %a addr = %a\n", n, cmd.Operands[n].n, cmd.Operands[n].type, cmd.Operands[n].reg, cmd.Operands[n].value, cmd.Operands[n].addr); } char calleeName[MAXSTR]; get_func_name(cmd.Op1.addr, calleeName, sizeof(calleeName)); msg("Callee Name: \"%s\"", calleeName); return; }
void __stdcall IDAP_run(int arg) { //msg("IDAP_run arg: %d \ng_Index:%d \ng_Path :%s\n", arg, g_Index, g_szIniPath); // 插件的实体 //在LOG中显示一个字符串 msg("============开始复制字符串==============\n"); uval_t nAddres = get_screen_ea(); int i = 0; int j = 0; UINT32 size = 0; int nCover = 0; USHORT checkmask = 0; char *lpBuf = (char *)malloc(0x1000); memset(lpBuf, 0, 0x1000); if (GetAsyncKeyState(VK_SHIFT) & 0x8000) { if(AskUsingForm_c(dialog, &nAddres, &g_Index, &g_CheckClip) == 1) { WriteIniFile(); if(!isLoaded(nAddres)) { msg("地址无效!读取数据失败!\n"); return; } else { size = ReadString(nAddres, lpBuf); } } } else { size = ReadString(get_screen_ea(), lpBuf); } if(g_CheckClip && size) { msg("已将结果发送至送剪切板!\n"); SnedClipData(lpBuf, size); } msg("使用%s编码打印字符串:\n%s\n", g_CodeTable[g_Index], lpBuf); free(lpBuf); return; }
/* * 模式说明 * 1、MODE_ARMOP_Code -> 使用ARM指令修改CODE * 2、MODE_ARMOP_SysCall -> 注释系统调用 */ int Arm_Moudle(int inFlag){ static int Mode_Bit = MODE_ARMOPC32_JMP; static int ModeOption = 0; ea_t _ThisEa = get_screen_ea(); if (inFlag != Flag_Again) if (AskUsingForm_c(ASK_ARM_UI, &ModeOption) == 0) return NULL; if (MODE_ARMOP_Code == ModeOption){ if (inFlag != Flag_Again) if (AskUsingForm_c(ASK_CODE_UI, &Mode_Bit) == 0) return NULL; if (MODE_ARMOPC16_JMP == Mode_Bit){ _ThisEa &= 0xFFFFFFFE; patch_long(_ThisEa, 0xE7FE); } else if (MODE_ARMOPC16_NOP == Mode_Bit){ _ThisEa &= 0xFFFFFFFE; patch_word(_ThisEa, 0xC046); } else if (MODE_ARMOPC32_JMP == Mode_Bit){ _ThisEa &= 0xFFFFFFFC; patch_long(_ThisEa, 0xEAFFFFFE); } else if (MODE_ARMOPC32_NOP == Mode_Bit){ _ThisEa &= 0xFFFFFFFC; patch_long(_ThisEa, 0xE1A00000); } } else if(MODE_ARMOP_SysCall == ModeOption){ //自动获取, ulong Sys_No = get_32bit(get_screen_ea()) & 0xFFF; if (AskUsingForm_c(ASK_SYSCALL_UI, &Sys_No) == 0)return 0; if (SysCall::getName(Sys_No) != NULL){ set_cmt(get_screen_ea(), SysCall::getName(Sys_No), 1); } } return NULL; }
void run(int) { netnode n("$ vmm functions"); ea_t ea = get_screen_ea(); // get current address if ( !isCode(get_flags_novalue(ea)) ) return; // not an instruction ea_t callee = n.altval(ea)-1; // get the callee address from the database char buf[MAXSTR]; qsnprintf(buf, sizeof(buf), form, help); if ( AskUsingForm_c(buf, &callee) ) { n.altset(ea, callee+1); // save the new address noUsed(ea); // reanalyze the current instruction } }
static int idaapi hook(void *user_data, int event_id, va_list va) { static ea_t old_addr = 0; ea_t addr; if (event_id == view_curpos) { addr = get_screen_ea(); if (old_addr != addr) { if (isCode(getFlags(addr))) { // don't update the address if it's already the qira address if (addr != qira_address) { set_qira_address(addr); update_address("iaddr", addr); } } else { update_address("daddr", addr); } } old_addr = addr; } return 0; }
void process_VTBL2() { ea_t curr = get_screen_ea(); if ( !is_contain_ptr(curr) ) return; if ( !check_rpd_count() ) return; char *ask = askstr(0, "", "Class name"); if ( !ask || !*ask ) return; pdb_class *pc = p_pool->find_class(ask); if ( !pc ) { warning("Don`t known class '%s'", ask); return; } fill_vtbl(ask, curr, pc); }
// 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) { // The "meat" of your plug-in msg("%s run()\n", IDAP_name); xrefblk_t xb; // Get the address of the cursor position ea_t addr = get_screen_ea(); // Loop through all cross references for(bool res = xb.first_to(addr, XREF_FAR); res; res = xb.next_to()) { msg("[1] From: %a, To: %a, Type: %d, IsCode: %d\n", xb.from, xb.to, xb.type, xb.iscode); } for(bool res = xb.first_from(addr, XREF_FAR); res; res = xb.next_from()) { msg("[2] From: %a, To: %a, Type: %d, IsCode: %d\n", xb.from, xb.to, xb.type, xb.iscode); } }
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; } }
// 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) ); } }
void idaapi run(int) { static const char * nname; if ( ph.id == PLFM_MIPS ) nname = "$ mips"; else if ( ph.id == PLFM_ARM ) nname = " $arm"; else nname = "$ vmm functions"; netnode n(nname); ea_t ea = get_screen_ea(); // get current address if ( !isCode(get_flags_novalue(ea)) ) return; // not an instruction ea_t callee = n.altval(ea)-1; // get the callee address from the database // remove thumb bit for arm if ( ph.id == PLFM_ARM ) callee &= ~1; char buf[MAXSTR]; qsnprintf(buf, sizeof(buf), form, help); if ( AskUsingForm_c(buf, &callee) ) { if ( callee == BADADDR ) { n.altdel(ea); } else { if ( ph.id == PLFM_ARM && (callee & 1) == 0 ) { // if we're calling a thumb function, set bit 0 sel_t tbit = getSR(callee, T); if ( tbit != 0 && tbit != BADSEL ) callee |= 1; } n.altset(ea, callee+1); // save the new address } noUsed(ea); // reanalyze the current instruction } }
//--------------------------------------------------------------------------- // Redraw the chart void __fastcall TChatForm::RefreshChart(TObject *Sender) { ea_t ea1, ea2; // check the selection if ( callui(ui_readsel, &ea1, &ea2).cnd ) { char buf[MAXSTR]; qsnprintf(buf, sizeof(buf), "0x%a", ea1); Edit1->Text = buf; qsnprintf(buf, sizeof(buf), "0x%a", ea2); Edit2->Text = buf; } // get the starting and ending addresses char err[MAXSTR]; ea_t here = get_screen_ea(); if ( !calcexpr_long(here, Edit1->Text.c_str(), &ea1, err, sizeof(err)) ) { warning("%s", err); BringToFront(); return; } if ( !calcexpr_long(here, Edit2->Text.c_str(), &ea2, err, sizeof(err)) ) { warning("%s", err); BringToFront(); return; } // fill the data show_wait_box("HIDECANCEL\nGenerating the graph"); ch->Series[0]->Clear(); while ( ea1 < ea2 ) { char label[MAXSTR]; ea2str(ea1, label, sizeof(label)); // generation of the label text takes time, you may want to remove it ch->Series[0]->AddXY(ea1, get_byte(ea1), label, TColor(clTeeColor)); ea1 = next_not_tail(ea1); } hide_wait_box(); }
//-------------------------------------------------------------------------- void run(int /*arg*/) { ea_t ea = get_screen_ea(); if ( askaddr(&ea, "Please enter the disassembly address") && isEnabled(ea) ) // address belongs to disassembly { int flags = calc_default_idaplace_flags(); linearray_t ln(&flags); idaplace_t pl; pl.ea = ea; pl.lnnum = 0; ln.set_place(&pl); msg("printing disassembly lines:\n"); int n = ln.get_linecnt(); // how many lines for this address? for ( int i=0; i < n; i++ ) // process all of them { char *line = ln.down(); // get line char buf[MAXSTR]; tag_remove(line, buf, sizeof(buf)); // remove color codes msg("%d: %s\n", i, buf); // display it on the message window } msg("total %d lines\n", n); } }
//--------------------------------------------------------------------------- // The main function - called when the user selects the menu item static bool idaapi callback(void *) { // Calculate the default values to display in the form ea_t screen_ea = get_screen_ea(); segment_t *s = getseg(screen_ea); if ( s == NULL || !isCode(get_flags_novalue(screen_ea)) ) { warning("AUTOHIDE NONE\nThe cursor must be on the table jump instruction"); return false; } ea_t startea = screen_ea; while ( true ) { ea_t prev = prev_not_tail(startea); if ( !is_switch_insn(prev) ) break; startea = prev; } ea_t jumps = get_first_dref_from(screen_ea); uval_t jelsize = s->abytes(); uval_t jtsize = 0; if ( jumps != BADADDR ) { decode_insn(screen_ea); jtsize = guess_table_size(jumps); } uval_t shift = 0; uval_t elbase = 0; char input[MAXSTR]; input[0] = '\0'; ea_t defea = BADADDR; uval_t lowcase = 0; ushort jflags = 0; ushort vflags = 0; ea_t vtable = BADADDR; ea_t vtsize = 0; ea_t velsize = s->abytes(); reg_info_t ri; ri.size = 0; // If switch information is present in the database, use it for defaults switch_info_ex_t si; if ( get_switch_info_ex(screen_ea, &si, sizeof(si)) > 0 ) { jumps = si.jumps; jtsize = si.ncases; startea = si.startea; elbase = si.elbase; jelsize = si.get_jtable_element_size(); shift = si.get_shift(); defea = (si.flags & SWI_DEFAULT) ? si.defjump : BADADDR; if ( si.regnum != -1 ) get_reg_name(si.regnum, get_dtyp_size(si.regdtyp), input, sizeof(input)); if ( si.flags & SWI_SIGNED ) jflags |= 2; if ( si.flags2 & SWI2_SUBTRACT ) jflags |= 4; if ( si.flags & SWI_SPARSE ) { jflags |= 1; vtable = si.values; vtsize = jtsize; velsize = si.get_vtable_element_size(); if ( si.flags2 & SWI2_INDIRECT ) { vflags |= 1; jtsize = si.jcases; } if ( si.flags & SWI_JMP_INV ) vflags |= 2; } else { lowcase = si.lowcase; } } // Now display the form and let the user edit the attributes while ( AskUsingForm_c(main_form, &jumps, &jtsize, &jelsize, &shift, &elbase, &startea, input, &lowcase, &defea, &jflags) ) { if ( !check_table(jumps, jelsize, jtsize) ) continue; if ( shift > 3 ) { warning("AUTOHIDE NONE\nInvalid shift value (allowed values are 0..3)"); continue; } if ( !isCode(get_flags_novalue(startea)) ) { warning("AUTOHIDE NONE\nInvalid switch idiom start %a (must be an instruction", startea); continue; } ri.reg = -1; if ( input[0] != '\0' && !parse_reg_name(input, &ri) ) { warning("AUTOHIDE NONE\nUnknown input register: %s", input); continue; } if ( defea != BADADDR && !isCode(get_flags_novalue(defea)) ) { warning("AUTOHIDE NONE\nInvalid default jump %a (must be an instruction", defea); continue; } if ( jflags & 1 ) // value table is present { bool vok = false; while ( AskUsingForm_c(value_form, &vflags, &vtable, &vtsize, &velsize) ) { if ( (vflags & 1) == 0 ) vtsize = jtsize; if ( check_table(vtable, velsize, vtsize) ) { vok = true; break; } } if ( !vok ) break; } // ok, got and validated all params -- fill the structure si.flags = SWI_EXTENDED; si.flags2 = 0; if ( jflags & 2 ) si.flags |= SWI_SIGNED; if ( jflags & 4 ) si.flags2 |= SWI2_SUBTRACT; si.jumps = jumps; si.ncases = ushort(jtsize); si.startea = startea; si.elbase = elbase; if ( elbase != 0 ) si.flags |= SWI_ELBASE; si.set_jtable_element_size((int)jelsize); si.set_shift((int)shift); if ( defea != BADADDR ) { si.flags |= SWI_DEFAULT; si.defjump = defea; } if ( ri.reg != -1 ) si.set_expr(ri.reg, get_dtyp_by_size(ri.size)); if ( jflags & 1 ) // value table is present { si.flags |= SWI_SPARSE; si.values = vtable; si.set_vtable_element_size((int)velsize); if ( (vflags & 1) != 0 ) { si.flags2 |= SWI2_INDIRECT; si.jcases = (int)jtsize; si.ncases = (ushort)vtsize; } if ( (vflags & 2) != 0 ) si.flags |= SWI_JMP_INV; } else { si.lowcase = lowcase; } // ready, store it set_switch_info_ex(screen_ea, &si); create_switch_table(screen_ea, &si); setFlbits(screen_ea, FF_JUMP); create_insn(screen_ea); info("AUTOHIDE REGISTRY\nSwitch information has been stored"); break; } return true; }
void idaapi PIC_run(int arg) { ea_t curr_addr; int n_funcz, i; func_t *curr_func; if ( is_first ) { got_addr = get_name_ea(BADADDR, got_name); if ( BADADDR == got_addr ) { got_addr = get_name_ea(BADADDR,got_name1); if ( BADADDR != got_addr ) { got_addr = get_long(got_addr); } else { got_addr = get_name_ea(BADADDR, got_name2); } } is_first = false; // 2 Nov 2005: dirty hack, bcs get_name_ea("_got") return BADADDR segment_t *s; if ( BADADDR == got_addr ) { s = get_segm_by_name(".got"); if ( s != NULL ) got_addr = s->startEA; } // 14 oct 2009 s = get_segm_by_name(".got.plt"); if ( s != NULL ) got_plt_addr = s->startEA; } if ( BADADDR == got_addr ) { msg("Cannot resolve _got address. Bad plugin initialization"); return; } #ifdef PIC_DEBUG RP_TRACE1( "got_addr %X\n", got_addr ); #endif switch (arg) { case 0: /* only function under current EA */ curr_addr = get_screen_ea(); #ifdef PIC_DEBUG RP_TRACE1( "curr_addr %X\n", curr_addr ); #endif /* next I had to resolve function */ curr_func = get_func(curr_addr); if ( NULL == curr_func ) { warning("Cannot operate not on function, address %X\n", curr_addr); return; } #if defined(PIC_DEBUG) || defined(PIC_SHOW) rp_log_fp = fopen(log_filename, "w+t"); #endif process_PIC(curr_func->startEA, curr_func->endEA); #if defined(PIC_DEBUG) || defined(PIC_SHOW) if ( NULL != rp_log_fp ) { fclose(rp_log_fp); rp_log_fp = NULL; } #endif break; case 1: /* process all defined functions */ #if defined(PIC_DEBUG) || defined(PIC_SHOW) rp_log_fp = fopen(log_filename, "w+t"); #endif n_funcz = get_func_qty(); if ( !n_funcz ) { warning("No functions defined!"); return; } for ( i = 0; i < n_funcz; i++ ) { curr_func = getn_func(i); if ( NULL == curr_func ) { RP_TRACE1("PIC: cannot get func N %d\n", i); continue; } process_PIC(curr_func->startEA, curr_func->endEA); } #if defined(PIC_DEBUG) || defined(PIC_SHOW) if ( NULL != rp_log_fp ) { fclose(rp_log_fp); rp_log_fp = NULL; } #endif break; default: warning("PIC: Unknown arg %d", arg); break; } /* switch */ }
//-------------------------------------------------------------------------- void idaapi run(int arg) { if ( arg == -1 ) { load_options(); show_options(); return; } func_t *pfn = get_func(get_screen_ea()); if ( pfn == NULL ) { warning("Please position the cursor in a function first!"); return; } load_options(); qstring title; graph_info_t::get_title(pfn->startEA, &title); HWND hwnd = NULL; TForm *form = create_tform(title.c_str(), &hwnd); if ( hwnd != NULL ) { // window is new, but instance is in the list? graph_info_t *gi = graph_info_t::find(title.c_str()); if ( gi != NULL ) { // in that case let us "recycle" the instance gi->func_ea = pfn->startEA; } else { // we create a new instance gi = graph_info_t::create(pfn->startEA); } if ( gi != NULL ) { // get a unique graph id netnode id; id.create(); gi->mark_for_refresh(); gi->form = form; gi->gv = create_graph_viewer(form, id, gr_callback, gi, 0); open_tform(form, FORM_MDI|FORM_TAB|FORM_MENU); if ( gi->gv != NULL ) { viewer_fit_window(gi->gv); viewer_add_menu_item(gi->gv, "Options", menu_options_cb, gi, "O", 0); viewer_add_menu_item(gi->gv, "Goto to first node", menu_home_cb, gi, "H", 0); viewer_add_menu_item(gi->gv, "Refresh", menu_refresh_cb, gi, "R", 0); viewer_add_menu_item(gi->gv, "Search first", menu_searchfirst_cb, gi, "S", 0); viewer_add_menu_item(gi->gv, "Search next", menu_searchnext_cb, gi, "N", 0); } else { graph_info_t::destroy(gi); gi = NULL; } } // failed to creat a graph view? if ( gi == NULL ) { warning("Failed to create call graph window!\n"); return; } } else { graph_info_t *gi = graph_info_t::find(title.c_str()); if ( gi != NULL ) { gi->refresh(); open_tform(gi->form, FORM_MDI|FORM_TAB|FORM_MENU); } } }
ByteAddr IdaFrontend::screenAddress() { return checked_cast<ByteAddr>(get_screen_ea()); }
// arg & 1: decompile to C code (1) or normally (0) // arg & 2: print instruction list before splitting into nodes // arg & 4: dump current instruction // arg & 8: process all functions void idaapi run(int arg) { msg("Running The Desquirr decompiler plugin\n"); IdaPro* idapro; if (PLFM_386 == ph.id) idapro = new IdaX86(); else if (PLFM_ARM == ph.id) idapro = new IdaArm(); else { msg("Unexpected processor module\n"); return; } Frontend_ptr frontend(idapro); Frontend::Set(frontend); if (arg & 4) { idapro->DumpInsn(get_screen_ea()); return; } CodeStyle style = (arg & 1) ? C_STYLE : LISTING_STYLE; for (func_t *function= (arg&8)?get_next_func(0) : get_func(get_screen_ea()) ; function ; function= (arg&8)?get_next_func(function->startEA):0) { if (function->flags & FUNC_LIB) msg("Warning: Library function\n"); Instruction_list instructions; msg("-> Creating instruction list\n"); idapro->FillList(function, instructions); if (arg & 2) { msg("Instruction list:\n"); GenerateCode(instructions, style); break; } Node_list nodes; msg("-> Creating node list\n"); Node::CreateList(instructions, nodes); //if (g_bDumpNodeContents) DumpList(nodes); msg("-> Update uses and definitions\n"); UpdateUsesAndDefinitions(nodes); //if (g_bDumpNodeContents) DumpList(nodes); msg("-> Live register analysis\n"); Node::LiveRegisterAnalysis(nodes); //if (g_bDumpNodeContents) DumpList(nodes); msg("-> Finding DU chains\n"); Node::FindDefintionUseChains(nodes); if (g_bDumpNodeContents) DumpList(nodes); msg("-> Data flow analysis\n"); { DataFlowAnalysis analysis(nodes); analysis.AnalyzeNodeList(); // want destructor to run here :-) } if (g_bDumpNodeContents) DumpList(nodes); msg("Basic block list:\n"); GenerateCode(nodes, style); } }
//-------------------------------------------------------------------------- // 0 - run uunp interactively // 1 - run without questions // 2 - run manual reconstruction void idaapi run(int arg) { if ( arg == 2 ) { area_t impdir = area_t(0, 0); ea_t oep; netnode n; // Settings never stored before? if ( n.create("$ uunp") ) { // Populate default values oep = get_screen_ea(); segment_t *s = getseg(oep); if ( s != NULL ) { oep_area.startEA = s->startEA; oep_area.endEA = s->endEA; } } else { // Restore previous settings oep = n.altval(0); oep_area.startEA = n.altval(1); oep_area.endEA = n.altval(2); impdir.startEA = n.altval(3); impdir.endEA = n.altval(4); } if ( !AskUsingForm_c( "Reconstruction parameters\n" "\n" " <~O~riginal entrypoint:N:128:32::>\n" " <Code ~s~tart address:N:128:32::>\n" " <Code ~e~nd address :N:128:32::>\n" "\n" " <IAT s~t~art address:N:128:32::>\n" " <IAT e~n~d address:N:128:32::>\n" "\n", &oep, &oep_area.startEA, &oep_area.endEA, &impdir.startEA, &impdir.endEA) ) { // Cancelled? return; } // Invalid settings? if ( impdir.startEA == 0 || impdir.endEA == 0 ) { msg("Invalid import address table boundaries"); return; } // Store settings n.altset(0, oep); n.altset(1, oep_area.startEA); n.altset(2, oep_area.endEA); n.altset(3, impdir.startEA); n.altset(4, impdir.endEA); if ( !create_impdir(impdir) ) return; // reanalyze the unpacked code do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND); auto_make_code(oep); noUsed(oep_area.startEA, oep_area.endEA); auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL); // mark the program's entry point move_entry(oep); take_memory_snapshot(true); return; } // Determine the original entry point area for ( segment_t *s = get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { if ( s->type != SEG_GRP ) { oep_area = *s; break; } } if ( arg == 0 && askyn_c(0, "HIDECANCEL\n" "AUTOHIDE REGISTRY\n" "Universal PE unpacker\n" "\n" "IMPORTANT INFORMATION, PLEASE READ CAREFULLY!\n" "\n" "This plugin will start the program execution and try to suspend it\n" "as soon as the packer finishes its work. Since there might be many\n" "variations in packers and packing methods, the execution might go out\n" "of control. There are many ways how things can go wrong, but since you\n" "have the source code of this plugin, you can modify it as you wish.\n" "\n" "Do you really want to launch the program?\n") <= 0 ) { return; } success = false; set_file_ext(resfile, sizeof(resfile), database_idb, "res"); if ( arg == 0 && !AskUsingForm_c( "Uunp parameters\n" "IDA will suspend the program when the execution reaches\n" "the original entry point area. The default values are in\n" "this dialog box. Please verify them and correct if you wish.\n" "\n" "ORIGINAL ENTRY POINT AREA\n" " <~S~tart address:N:128:32::>\n" " <~E~nd address :N:128:32::>\n" "\n" "OUTPUT RESOURCE FILE NAME\n" " <~R~esource file:A:256:32::>\n" "\n", &oep_area.startEA, &oep_area.endEA, resfile) ) { return; } if ( !hook_to_notification_point(HT_DBG, callback, NULL) ) { warning("Could not hook to notification point\n"); return; } if ( dbg == NULL ) load_debugger("win32", false); // Let's start the debugger if ( !run_to(inf.beginEA) ) { warning("Sorry, could not start the process"); unhook_from_notification_point(HT_DBG, callback, NULL); } }
// 插件可以从plugins.cfg文件中,被传进一个整型参数。 // 当按下不同的热键或者菜单时,您需要一个插件做不同 // 的事情时,这非常有用。 void __stdcall IDAP_run(int arg) { // 插件的实体 //在LOG中显示一个字符串 char *lpInBuf = NULL; char *lpTmpBuf = NULL; char *lpFilePath = NULL; char szValue[MAXSTR + 1] = ""; char szInValue[MAXSTR + 1] = ""; // char szTmp[100] = {0}; int nPatchLogFlags = 1; uval_t nAddres = get_screen_ea(); asize_t nCount = 1; USHORT nWriteRadio = 0; //单选按钮 USHORT nSerializeRadio = -1; //单选按钮 USHORT checkmask = 0; asize_t j = 0; asize_t i = 0; // qstrncpy(szInValue,"",sizeof(szInValue)); if(AskUsingForm_c(dialog, szInValue, &nAddres, &nCount, &nWriteRadio, &nSerializeRadio, &checkmask) == 1) { if(checkmask & 1) { nAddres = get_screen_ea(); } size_t len = strlen(szInValue); for(i = 0; i < len; i++) { if(szInValue[i] != ' ') { szValue[j++] = szInValue[i]; } } len = strlen(szValue); size_t nHexLen = len / 2; if(!len) { if( lpFilePath = askfile_cv(0, "*.*", "OpenPath", 0)) { FILE* handle = fopen(lpFilePath, "rb"); if(handle == NULL) { warning("打开文件失败 Error!\n"); return; } fseek(handle, 0, SEEK_END); nHexLen = ftell(handle); fseek(handle, 0, SEEK_SET); lpTmpBuf = (char *)malloc(nHexLen + 1); memset(lpTmpBuf, 0, nHexLen + 1); fread(lpTmpBuf, 1, nHexLen, handle); fclose(handle); strcpy(szValue, lpFilePath); } else { warning("请输入数据"); return; } } else if(len % 2) { warning("数据长度不是2的倍数"); return; } else { for(i = 0;i < len;i++) { if(!isxdigit(szValue[i])) { warning("数据中含有非16进制值"); return; } } lpTmpBuf = (char *) malloc(nHexLen * 2 + 1); memset(lpTmpBuf, 0, nHexLen * 2 + 1); for(i = 0; i < nHexLen; i++) { sscanf(&szValue[i * 2],"%02x",lpTmpBuf + i); } } if(nSerializeRadio >= 0) { asize_t nSerializeSize = (nSerializeRadio + 1) * 4; asize_t nSerializeCount = nHexLen * nCount / nSerializeSize; for(i = 0; i < nSerializeCount; i++) { reversedbuf((unsigned char*)lpTmpBuf + nSerializeSize *i, nSerializeSize); } } lpInBuf = (char*)malloc(nHexLen * nCount * 2 + 1); memset(lpInBuf, 0, nHexLen * nCount * 2 + 1); for(i = 0; i < nCount; i++) { memcpy(lpInBuf + i * nHexLen, lpTmpBuf, nHexLen); } free(lpTmpBuf); msg("==============修补数据库数据==============\n"); msg("String Value = %s\n",szValue); #ifdef __EA64__ msg("Addres:0x%llX ValueSize = 0x%llX Index:%d check = %d\n",nAddres, nHexLen, nCount,checkmask); #else msg("Addres:0x%08X ValueSize = 0x%08X Index:%d check = %d\n",nAddres, nHexLen, nCount,checkmask); #endif if(!nWriteRadio) { msg("WriteData \n",nWriteRadio); } else { msg("XorWrite Data \n",nWriteRadio); } if( nHexLen * nCount > 0x100) { nPatchLogFlags = askyn_c(0, "%s", "是否打印日志!(默认不打印)\n因为数据量过大会影响IDA会假死!\nNo或Cancel表示不打印日志!\n"); } //////////////////// uint32 nSum = 0; uchar *mem = NULL; if(isLoaded(nAddres) && isLoaded(nAddres + nCount * nHexLen - 1)) { mem = (uchar *)malloc(nCount * nHexLen + 1); if(mem == NULL) { warning("malloc 函数执行失败!"); return; } get_many_bytes(nAddres,mem, nCount * nHexLen); if(nPatchLogFlags > 0) { msg("原始数据:\n"); for(i = 0; i < nCount * nHexLen; i++) { msg("%02X", mem[i]); } msg("\n"); } } else { if(!isLoaded(nAddres)) { warning("数据地址错误: 0x%p",nAddres); } else { warning("写入数据长度过大"); } return; } /////////////////////////// // long nValue = 0; for(j = 0;j < nCount;j++) { for(i = 0;i < nHexLen; i++) { // memcpy(szTmp,&szInValue[j * len + i * 2],2); //sscanf(&szValue[i * 2],"%02x",&nValue); if(nWriteRadio == 1) { lpInBuf[nSum] ^= mem[nSum]; } mem[nSum++] = lpInBuf[nSum]; } } put_many_bytes(nAddres, mem, nSum); if(nPatchLogFlags > 0) { msg("补丁数据:\n"); for(i = 0; i < nSum; i++) { msg("%02X", mem[i]); } msg("\n"); } refresh_idaview_anyway(); //刷新反汇编窗口 free(mem); free(lpInBuf); } return; }
//-------------------------------------------------------------------------- // // The plugin method // // This is the main function of plugin. // void idaapi run(int /*arg*/) { char title[MAXSTR]; // Let's display the functions called from the current one // or from the selected area // First we determine the working area func_item_iterator_t fii; bool ok; ea_t ea1, ea2; if ( callui(ui_readsel, &ea1, &ea2).cnd ) // the selection is present? { callui(ui_unmarksel); // unmark selection qsnprintf(title, sizeof(title), "Functions called from %08a..%08a", ea1, ea2); ok = fii.set_range(ea1, ea2); } else // nothing is selected { func_t *pfn = get_func(get_screen_ea()); // try the current function if ( pfn == NULL ) { warning("Please position the cursor on a function or select an area"); return; } ok = fii.set(pfn); static const char str[] = "Functions called from "; char *ptr = qstpncpy(title, str, sizeof(title)); get_func_name(pfn->startEA, ptr, sizeof(title)-(ptr-title)); } // We are going to remember the call instruction addresses // in a netnode // altval(i) will contain the address of the call instruction netnode *node = new netnode; node->create(); int counter = 0; while ( ok ) { ea_t ea = fii.current(); if ( is_call_insn(ea) ) // a call instruction is found node->altset(counter++, ea);//get_first_fcref_from(ea)); ok = fii.next_code(); } // altval(-1) will contain the number of pairs node->altset(-1, counter); // now open the window choose2(0, // non-modal window -1, -1, -1, -1, // position is determined by the OS node, // pass the created netnode to the window qnumber(header), // number of columns widths, // widths of columns sizer, // function that returns number of lines desc, // function that generates a line title, // window title -1, // use the default icon for the window 0, // position the cursor on the first line NULL, // "kill" callback NULL, // "new" callback NULL, // "update" callback NULL, // "edit" callback enter_cb, // function to call when the user pressed Enter destroy_cb, // function to call when the window is closed NULL, // use default popup menu items NULL); // use the same icon for all lines }
ea_t wrapped_get_screen_ea(void) { return get_screen_ea(); }