virtual bool idaapi run() { if (qira_address != la) { set_qira_address(la); jumpto(la, -1, 0); // don't UIJMP_ACTIVATE to not steal focus } return false; }
static void idaapi enter_unmatch(void *obj,uint32 n) { psig_t *sig = ui_access_sig(((deng_t *)obj)->ulist, n); if (sig->nfile == 1) jumpto(sig->startEA); else os_copy_to_clipboard(NULL); }
void File::goto_statement(Sti_t &i) { String_t &jumpto(m_instructions[++i]); for (Sti_t p = 0; p < m_instructions.size(); ++p) { if (m_instructions[p] == ":" + jumpto && m_instructions[p - 1] != "goto") { i = p; return; } } }
static bool idaapi ct_object_explorer_click(TCustomControl *v, int shift, void *ud) { int x, y; place_t *place = get_custom_viewer_place(v, true, &x, &y); simpleline_place_t *spl = (simpleline_place_t *)place; int line_num = spl->n; ea_t cur_vt_ea = vtbl_t_list[line_num].ea_begin; jumpto(cur_vt_ea); return true; }
static bool idaapi ct_vtbl_xrefs_window_click(TCustomControl *v, int shift, void *ud) { int x, y; place_t *place = get_custom_viewer_place(v, true, &x, &y); simpleline_place_t *spl = (simpleline_place_t *)place; int line_num = spl->n; ea_t cur_xref_ea = xref_addr[line_num]; jumpto(cur_xref_ea); return true; }
//--------------------------------------------------------------------------- static void idaapi ch_enter(void *obj, uint32 n) { x86seh_ctx_t *ctx = (x86seh_ctx_t *)obj; if ( --n < ctx->handlers.size() ) { ea_t ea = ctx->handlers[n]; if ( !isCode(get_flags_novalue(ea)) ) create_insn(ea); jumpto(ea); } }
void jump_to_vtbl_by_name() { char *res = askstr(0, "", "Class name"); if ( NULL == res || !*res ) return; if ( !check_rt_tree() ) return; struct RP_class *ptr = find_rt_by_name(res); if ( NULL == ptr ) { warning("Class '%s' not found\n", res); return; } if ( NULL == ptr->vtbl ) { msg("Cannot find vtbl for '%s'\n", res); jumpto(ptr->CRuntime); return; } jumpto(ptr->vtbl); }
static bool idaapi menu_callback(void *ud) { int node; slist_t * sl = (slist_t *)ud; if (sl && sl->sigs && sl->sigs[0]->nfile == 1) { node = viewer_get_curnode(sl->gv); if (node >= 0) jumpto(sl->sigs[node]->startEA); } return true; }
//-------------------------------------------------------------------------- static void jump_to_node(graph_info_t *gi, const int nid) { viewer_center_on(gi->gv, nid); int x, y; // will return a place only when a node was previously selected place_t *old_pl = get_custom_viewer_place(gi->gv, false, &x, &y); if ( old_pl != NULL ) { user_graph_place_t *new_pl = (user_graph_place_t *) old_pl->clone(); new_pl->node = nid; jumpto(gi->gv, new_pl, x, y); delete new_pl; } }
void load_sh2_data(linput_t *li) { int version; int csize; ea_t result; sh2regs_struct sh2regs; if (!load_header(li)) return; if (StateCheckRetrieveHeader(li, "CART", &version, &csize) != 0) { error("Invalid CART chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "CS2 ", &version, &csize) != 0) { error("Invalid CS2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "MSH2", &version, &csize) != 0) { error("Invalid MSH2 chunk"); return; } SH2LoadState(li, false, &sh2regs, csize); if (StateCheckRetrieveHeader(li, "SSH2", &version, &csize) != 0) { error("Invalid SSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCSP", &version, &csize) != 0) { error("Invalid SCSP chunk"); return; } SoundLoadState(li, NULL, csize); if (StateCheckRetrieveHeader(li, "SCU ", &version, &csize) != 0) { error("Invalid SCU chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SMPC", &version, &csize) != 0) { error("Invalid SMPC chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP1", &version, &csize) != 0) { error("Invalid VDP1 chunk"); return; } Vdp1LoadState(li, csize); if (StateCheckRetrieveHeader(li, "VDP2", &version, &csize) != 0) { error("Invalid VDP2 chunk"); return; } Vdp2LoadState(li, csize); if (StateCheckRetrieveHeader(li, "OTHR", &version, &csize) != 0) { error("Invalid OTHR chunk"); return; } qlseek(li, 0x10000, SEEK_CUR); // BUP Ram create_load_seg(li, 0x06000000, 0x06100000, 2, "HWRAM"); create_load_seg(li, 0x00200000, 0x00300000, 2, "LWRAM"); identify_vector_table(); find_bios_funcs(); find_parse_ip(0x06000C00, false); find_parse_ip(0x06002000, true); // Look for SBL/SGL and load correct sig if available if ((result = find_string("GFS_SGL ")) != BADADDR) { char version_str[512]; get_lib_version(result, 8, version_str, sizeof(version_str)); msg("SGL detected\n"); if (atof(version_str) <= 2.10) plan_to_apply_idasgn("sgl20a.sig"); else if (atof(version_str) == 2.11) { // SGL 2.1, 3.00, 3.02j plan_to_apply_idasgn("sgl302j.sig"); } else if (atof(version_str) >= 2.12) plan_to_apply_idasgn("sgl302j.sig"); if ((result = find_string("CPK Version")) != BADADDR) { get_lib_version(result, 4, version_str, sizeof(version_str)); plan_to_apply_idasgn("cpksgl.sig"); } } else if ((result = find_string("GFS_SBL ")) != BADADDR) { char version_str[512]; get_lib_version(result, 8, version_str, sizeof(version_str)); msg("SBL detected\n"); plan_to_apply_idasgn("sbl601.sig"); if ((result = find_string("CPK Version")) != BADADDR) { get_lib_version(result, 4, version_str, sizeof(version_str)); plan_to_apply_idasgn("cpksbl.sig"); } } // move cursor to current MSH2 PC jumpto(sh2regs.PC); }
//-------------------------------------------------------------------------- static int idaapi gr_callback(void *ud, int code, va_list va) { bool result = false; switch ( code ) { // a graph node has been double clicked case grcode_dblclicked: // in: graph_viewer_t *gv // selection_item_t *current_item // out: 0-ok, 1-ignore click { DECLARE_GI_VARS; va_arg(va, graph_viewer_t *); selection_item_t *s = va_arg(va, selection_item_t *); if ( s != NULL && s->is_node ) jumpto(fg->get_addr(s->node)); } break; // refresh user-defined graph nodes and edges case grcode_user_refresh: // in: mutable_graph_t *g // out: success { DECLARE_GI_VARS; if ( !gi->is_refresh_needed() ) break; gi->mark_as_refreshed(); fg->reset(); func_t *f = get_func(gi->func_ea); if ( f == NULL ) break; fg->walk_func(f, &fg_opts, 2); mutable_graph_t *mg = va_arg(va, mutable_graph_t *); // we have to resize mg->reset(); mg->resize(fg->count()); callgraph_t::edge_iterator end = fg->end_edges(); for ( callgraph_t::edge_iterator it=fg->begin_edges(); it != end; ++it ) { mg->add_edge(it->id1, it->id2, NULL); } fg->clear_edges(); result = true; } break; // retrieve text for user-defined graph node case grcode_user_text: // in: mutable_graph_t *g // int node // const char **result // bgcolor_t *bg_color (maybe NULL) // out: must return 0, result must be filled // NB: do not use anything calling GDI! { DECLARE_GI_VARS; va_arg(va, mutable_graph_t *); int node = va_arg(va, int); const char **text = va_arg(va, const char **); bgcolor_t *bgcolor = va_arg(va, bgcolor_t *); callgraph_t::funcinfo_t *fi = fg->get_info(node); result = fi != NULL; if ( result ) { *text = fi->name.c_str(); if ( bgcolor != NULL ) *bgcolor = fi->color; } } break; // retrieve hint for the user-defined graph case grcode_user_hint: // in: mutable_graph_t *g // int mousenode // int mouseedge_src // int mouseedge_dst // char **hint // 'hint' must be allocated by qalloc() or qstrdup() // out: 0-use default hint, 1-use proposed hint { DECLARE_GI_VARS; va_arg(va, mutable_graph_t *); int mousenode = va_argi(va, int); va_argi(va, int); va_argi(va, int); char **hint = va_arg(va, char **); ea_t addr; if ( mousenode != -1 && (addr = fg->get_addr(mousenode)) != BADADDR ) { char *lines[50]; int nl = generate_disassembly(addr, lines, qnumber(lines), NULL, false); qstring all_lines; for ( int i = 0; i < nl; i++) { if ( i != 0 ) all_lines += "\n"; all_lines += lines[i]; qfree(lines[i]); } *hint = all_lines.extract(); } result = true; // use our hint } break; // graph is being destroyed case grcode_destroyed: { DECLARE_GI_VAR; graph_info_t::destroy(gi); } break; } return (int)result; }
int main(int argc, char *argv[]) { char c; FILE *inputf; int skiptoend, opencount, closecount, i, usech; long *loopstarts, *loopsts = calloc(LOOP_DEPTH, sizeof(long)); STACK_TYPE *stack, *stackstart = calloc(MAX, sizeof(STACK_TYPE)); if (argc == 2) { i = 1; } else if (argc == 3 && !strcmp(argv[1], "-c")) { usech = 1; i = 2; } else if (argc == 3 && !strcmp(argv[1], "-n")) { usech = 0; i = 2; } else { fprintf(stderr, "Invalid command\nThe valid command format is ./brainfuck [-c | -n] <filename>\n"); exit(1); } inputf = fopen(argv[i], "r"); if (!inputf) { fprintf(stderr, "Cannot open file %s\n", argv[i]); exit(1); } // give error if no memory if (!stackstart || !loopsts) { fprintf(stderr, "Memory allocation error\n"); exit(1); } inits(stackstart); initl(loopsts); stack = stackstart; loopstarts = loopsts; skiptoend = opencount = closecount = 0; // go through each character while ((c = fgetc(inputf)) != EOF) { // skip to first ] that isn't enclosed by an [ if (skiptoend) { if (c == '[') opencount++; if (c == ']') closecount++; if (c != ']' || (opencount - closecount)) continue; } switch (c) { case '+': ++*stack; break; case '-': --*stack; break; case '>': if (stack < stackstart + MAX - 1) // keep stack position within range ++stack; break; case '<': if (stack > stackstart) // keep stack position within range --stack; break; case ',': if (usech) *stack = getchar(); else scanf("%lld", stack); break; case '.': if (usech) putchar((char) *stack); else printf("%lld\n", (unsigned long long) *stack); break; case '[': if (!*stack) { skiptoend = opencount = 1; closecount = 0; } else if (!inloop(CURRENTPOS - 1)) { // check if I've already come here ++loopstarts; // inc(loopstart, 0); *loopstarts = CURRENTPOS - 1; // loopstart is located at the [ } break; case ']': if (!skiptoend) { // if the loop is continuing jumpto(*loopstarts); // go back to the [ } else { *loopstarts = 0; --loopstarts; // continue after the ] skiptoend = opencount = closecount = 0; } break; } } if (usech) putchar('\n'); fclose(inputf); free(loopsts); free(stackstart); // free(stack); }
//-------------------------------------------------------------------------- static int idaapi gr_callback(void *ud, int code, va_list va) { bool result = false; switch (code) { // refresh user-defined graph nodes and edges case grcode_user_refresh: // in: mutable_graph_t *g // out: success { DECLARE_GI_VARS; func_t *f = get_func(gi->func_ea); if (f == NULL) break; graph_builder_t gb(*fg); // Graph builder helper class gb.apply_to(&gi->vu->cfunc->body, NULL); mutable_graph_t *mg = va_arg(va, mutable_graph_t *); // we have to resize mg->resize(fg->count()); callgraph_t::edge_iterator end = fg->end_edges(); for (callgraph_t::edge_iterator it = fg->begin_edges(); it != end; ++it) { mg->add_edge(it->id1, it->id2, NULL); } fg->clear_edges(); result = true; } break; // retrieve text for user-defined graph node case grcode_user_text: //mutable_graph_t *g // int node // const char **result // bgcolor_t *bg_color (maybe NULL) // out: must return 0, result must be filled // NB: do not use anything calling GDI! { DECLARE_GI_VARS; va_arg(va, mutable_graph_t *); int node = va_arg(va, int); const char **text = va_arg(va, const char **); bgcolor_t *bgcolor = va_arg(va, bgcolor_t *); callgraph_t::nodeinfo_t *ni = fg->get_info(node); result = ni != NULL; if (result) { *text = ni->name.c_str(); if (bgcolor != NULL) *bgcolor = ni->color; } } break; case grcode_user_hint: { DECLARE_GI_VARS; va_arg(va, mutable_graph_t *); int mousenode = va_argi(va, int); int to = va_argi(va, int); int from = va_argi(va, int); char **hint = va_arg(va, char **); callgraph_t::nodeinfo_t *ni = fg->get_info(mousenode); result = ni != NULL; if (result && ni->ea != BADADDR) { qstring s = get_text_disasm(ni->ea); *hint = qstrdup(s.c_str()); } } break; case grcode_dblclicked: { DECLARE_GI_VARS; graph_viewer_t *v = va_arg(va, graph_viewer_t *); selection_item_t *s = va_arg(va, selection_item_t *); callgraph_t::nodeinfo_t *ni = fg->get_info(s->node); result = ni != NULL; if (result && s->is_node && ni->ea != BADADDR) jumpto(ni->ea); } break; } return (int)result; }
static void idaapi enter_list(slist_t * sl,uint32 n) { jumpto(ui_access_sig(sl, n)->startEA); os_copy_to_clipboard(NULL); }
//-------------------------------------------------------------------------- static int idaapi callback( void * /*user_data*/, int notification_code, va_list va) { static int stage = 0; static bool is_dll; static char needed_file[QMAXPATH]; switch ( notification_code ) { case dbg_process_start: case dbg_process_attach: get_input_file_path(needed_file, sizeof(needed_file)); // no break case dbg_library_load: if ( stage == 0 ) { const debug_event_t *pev = va_arg(va, const debug_event_t *); if ( !strieq(pev->modinfo.name, needed_file) ) break; if ( notification_code == dbg_library_load ) is_dll = true; // remember the current module bounds if ( pev->modinfo.rebase_to != BADADDR ) curmod.startEA = pev->modinfo.rebase_to; else curmod.startEA = pev->modinfo.base; curmod.endEA = curmod.startEA + pev->modinfo.size; deb(IDA_DEBUG_PLUGIN, "UUNP: module space %a-%a\n", curmod.startEA, curmod.endEA); ++stage; } break; case dbg_library_unload: if ( stage != 0 && is_dll ) { const debug_event_t *pev = va_arg(va, const debug_event_t *); if ( curmod.startEA == pev->modinfo.base || curmod.startEA == pev->modinfo.rebase_to ) { deb(IDA_DEBUG_PLUGIN, "UUNP: unload unpacked module\n"); if ( stage > 2 ) enable_step_trace(false); stage = 0; curmod.startEA = 0; curmod.endEA = 0; _hide_wait_box(); } } break; case dbg_run_to: // Parameters: const debug_event_t *event dbg->stopped_at_debug_event(true); bp_gpa = get_name_ea(BADADDR, "kernel32_GetProcAddress"); #ifndef __X64__ if( (LONG)GetVersion() < 0 ) // win9x mode -- use thunk's { is_9x = true; win9x_resolve_gpa_thunk(); } #endif if ( bp_gpa == BADADDR ) { bring_debugger_to_front(); warning("Sorry, could not find kernel32.GetProcAddress"); FORCE_STOP: stage = 4; // last stage clear_requests_queue(); request_exit_process(); run_requests(); break; } else if( !my_add_bpt(bp_gpa) ) { bring_debugger_to_front(); warning("Sorry, can not set bpt to kernel32.GetProcAddress"); goto FORCE_STOP; } else { ++stage; set_wait_box("Waiting for a call to GetProcAddress()"); } continue_process(); break; case dbg_bpt: // A user defined breakpoint was reached. // Parameters: thid_t tid // ea_t breakpoint_ea // int *warn = -1 // Return (in *warn): // -1 - to display a breakpoint warning dialog // if the process is suspended. // 0 - to never display a breakpoint warning dialog. // 1 - to always display a breakpoint warning dialog. { thid_t tid = va_arg(va, thid_t); qnotused(tid); ea_t ea = va_arg(va, ea_t); //int *warn = va_arg(va, int*); if ( stage == 2 ) { if ( ea == bp_gpa ) { regval_t rv; if ( get_reg_val(REGNAME_ESP, &rv) ) { ea_t esp = ea_t(rv.ival); invalidate_dbgmem_contents(esp, 1024); ea_t gpa_caller = getPtr(esp); if ( !is_library_entry(gpa_caller) ) { ea_t nameaddr; if ( ptrSz == 4 ) { nameaddr = get_long(esp+8); } else { get_reg_val(REGNAME_ECX, &rv); nameaddr = ea_t(rv.ival); } invalidate_dbgmem_contents(nameaddr, 1024); char name[MAXSTR]; size_t len = get_max_ascii_length(nameaddr, ASCSTR_C, ALOPT_IGNHEADS); name[0] = '\0'; get_ascii_contents2(nameaddr, len, ASCSTR_C, name, sizeof(name)); if ( !ignore_win32_api(name) ) { deb(IDA_DEBUG_PLUGIN, "%a: found a call to GetProcAddress(%s)\n", gpa_caller, name); if ( !my_del_bpt(bp_gpa) || !my_add_bpt(gpa_caller) ) error("Can not modify breakpoint"); } } } } else if ( ea == bpt_ea ) { my_del_bpt(ea); if ( !is_library_entry(ea) ) { msg("Uunp: reached unpacker code at %a, switching to trace mode\n", ea); enable_step_trace(true); ++stage; uint64 eax; if ( get_reg_val(REGNAME_EAX, &eax) ) an_imported_func = ea_t(eax); set_wait_box("Waiting for the unpacker to finish"); } else { warning("%a: bpt in library code", ea); // how can it be? my_add_bpt(bp_gpa); } } // not our bpt? skip it else { // hide the wait box to allow others plugins to properly stop _hide_wait_box(); break; } } } // while continue_process() would work here too, request+run is more universal // because they do not ignore the request queue request_continue_process(); run_requests(); break; case dbg_trace: // A step occured (one instruction was executed). This event // notification is only generated if step tracing is enabled. // Parameter: none if ( stage == 3 ) { thid_t tid = va_arg(va, thid_t); qnotused(tid); ea_t ip = va_arg(va, ea_t); // ip reached the OEP range? if ( oep_area.contains(ip) ) { // stop the trace mode enable_step_trace(false); msg("Uunp: reached OEP %a\n", ip); set_wait_box("Reanalyzing the unpacked code"); // reanalyze the unpacked code do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND); auto_make_code(ip); // plan to make code noUsed(oep_area.startEA, oep_area.endEA); // plan to reanalyze auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL); // plan to analyze move_entry(ip); // mark the program's entry point _hide_wait_box(); // inform the user bring_debugger_to_front(); if ( askyn_c(1, "HIDECANCEL\n" "The universal unpacker has finished its work.\n" "Do you want to take a memory snapshot and stop now?\n" "(you can do it yourself if you want)\n") > 0 ) { set_wait_box("Recreating the import table"); invalidate_dbgmem_config(); if ( is_9x ) find_thunked_imports(); create_impdir(); set_wait_box("Storing resources to 'resource.res'"); if ( resfile[0] != '\0' ) extract_resource(resfile); _hide_wait_box(); if ( take_memory_snapshot(true) ) goto FORCE_STOP; } suspend_process(); unhook_from_notification_point(HT_DBG, callback, NULL); } } break; case dbg_process_exit: { stage = 0; // stop the tracing _hide_wait_box(); unhook_from_notification_point(HT_DBG, callback, NULL); if ( success ) jumpto(inf.beginEA, -1); else tell_about_failure(); } break; case dbg_exception:// Parameters: const debug_event_t *event // int *warn = -1 // Return (in *warn): // -1 - to display an exception warning dialog // if the process is suspended. // 0 - to never display an exception warning dialog. // 1 - to always display an exception warning dialog. { // const debug_event_t *event = va_arg(va, const debug_event_t *); // int *warn = va_arg(va, int *); // FIXME: handle code which uses SEH to unpack itself if ( askyn_c(1, "AUTOHIDE DATABASE\n" "HIDECANCEL\n" "An exception occurred in the program.\n" "UUNP does not support exceptions yet.\n" "The execution has been suspended.\n" "Do you want to continue the unpacking?") <= 0 ) { _hide_wait_box(); stage = 0; enable_step_trace(false); // stop the trace mode suspend_process(); } else { continue_process(); } } break; case dbg_request_error: // An error occured during the processing of a request. // Parameters: ui_notification_t failed_command // dbg_notification_t failed_dbg_notification { ui_notification_t failed_cmd = va_arg(va, ui_notification_t); dbg_notification_t failed_dbg_notification = va_arg(va, dbg_notification_t); _hide_wait_box(); stage = 0; warning("dbg request error: command: %d notification: %d", failed_cmd, failed_dbg_notification); } break; } return 0; }
void load_68k_data(linput_t *li) { int version; int csize; ea_t pc; if (!load_header(li)) return; if (StateCheckRetrieveHeader(li, "CART", &version, &csize) != 0) { error("Invalid CART chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "CS2 ", &version, &csize) != 0) { error("Invalid CS2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "MSH2", &version, &csize) != 0) { error("Invalid MSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SSH2", &version, &csize) != 0) { error("Invalid SSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCSP", &version, &csize) != 0) { error("Invalid SCSP chunk"); return; } SoundLoadState(li, &pc, csize); if (StateCheckRetrieveHeader(li, "SCU ", &version, &csize) != 0) { error("Invalid SCU chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SMPC", &version, &csize) != 0) { error("Invalid SMPC chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP1", &version, &csize) != 0) { error("Invalid VDP1 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP2", &version, &csize) != 0) { error("Invalid VDP2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "OTHR", &version, &csize) != 0) { error("Invalid OTHR chunk"); return; } for (int i = 0x000004; i < 0x0000EC; i+=4) make_vector(i, NULL); // move cursor to current 68K PC jumpto(pc); }
void load_scudsp_data(linput_t *li) { int version; int csize; ea_t pc; if (!load_header(li)) return; if (StateCheckRetrieveHeader(li, "CART", &version, &csize) != 0) { error("Invalid CART chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "CS2 ", &version, &csize) != 0) { error("Invalid CS2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "MSH2", &version, &csize) != 0) { error("Invalid MSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SSH2", &version, &csize) != 0) { error("Invalid SSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCSP", &version, &csize) != 0) { error("Invalid SCSP chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCU ", &version, &csize) != 0) { error("Invalid SCU chunk"); return; } ScuLoadState(li, &pc, csize); if (StateCheckRetrieveHeader(li, "SMPC", &version, &csize) != 0) { error("Invalid SMPC chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP1", &version, &csize) != 0) { error("Invalid VDP1 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP2", &version, &csize) != 0) { error("Invalid VDP2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "OTHR", &version, &csize) != 0) { error("Invalid OTHR chunk"); return; } // move cursor to current SCU DSP PC jumpto(pc); }
//------------------------------------------------------------------------- // function that is called when the user hits Enter static void idaapi enter_cb(void *obj,uint32 n) { entrylist_t &li = *(entrylist_t *)obj; jumpto(li[n-1].ea); }
statement* parser::stat() { statement *s = new statement; if(accept(t_let)) { expect(t_id); std::string id = last.value; if (accept(t_lparen)) // let f(x) = x^2 { s->type = t_def; defstatement *d = new defstatement; d->name = id; while (!accept(t_rparen)) { expect(t_id); d->args.push_back(last.value); if(!accept(t_comma)) { expect(t_rparen); break; } } expect(t_equals); block* b = new block; //build a new block, with a return statement that returns the expression: statement* rs = new statement; returnstatement* r = new returnstatement; r->expr = expr(); rs->type = t_return; rs->stat.returnstat = r; b->statements.push_back(rs); d->entrypoint = b; s->stat.defstat = d; // (above is equivalent to "def f(x) return x^2 end", but feels a bit more mathsy.) } else { s->type = t_let; assignment *a = new assignment; a->lvalue.isarray = false; a->lvalue.str = id; value* temp = NULL; while (t.type == t_lsquareb || t.type == t_dot || t.type == t_colon || t.type == t_lparen) { if (accept(t_lsquareb)) { value* arr = new value; //create a new array-key pair. arr->negative = false; arr->expd = false; arr->type = t_lsquareb; arr->arritem = new arrayitem; if (a->lvalue.isarray) { arr->arritem->array = a->lvalue.ai->array; } else //last one was a function, or this is the first loop. { a->lvalue.isarray = true; a->lvalue.ai = new arrayitem; if (temp == NULL) //this must be the first loop, else the function call would have made this non-null. { arr->arritem->array = new value; arr->arritem->array->type = t_id; arr->arritem->array->var = id; } else // last loop was a functioncall. { arr->arritem->array = temp; temp = NULL; //signal to loop end that the last loop was not a function call. } } arr->arritem->index = expr(); a->lvalue.ai->array = arr; //stuff old lvalue array inside arr, make arr the new lvalue array - previous array-key pair becomes new array. at the end, we just return v; this is the top-level array-index pair. At runtime, top-level array is evaluated recursively. expect(t_rsquareb); //array is actually a value that contains an arrayitem that contains an array - this is so that id variables can be treated in the same way as arr-key pairs. } else if (accept(t_dot) || accept(t_colon)) { value* arr = new value; arr->negative = false; // arrrr, I'm a pirate arr->expd = false; arr->type = t_lsquareb; arr->arritem = new arrayitem; if (a->lvalue.isarray) { arr->arritem->array = a->lvalue.ai->array; } else //last one was a function, or this is the first loop. { a->lvalue.isarray = true; a->lvalue.ai = new arrayitem; if (temp == NULL) //this must be the first loop, else the function call would have made this non-null. { arr->arritem->array = new value; arr->arritem->array->type = t_id; arr->arritem->array->var = id; } else // last loop was a functioncall. { arr->arritem->array = temp; temp = NULL; //signal to loop end that the last loop was not a function call. } } if (last.type == t_colon) arr->arritem->pass_self = true; expect(t_id); arr->arritem->index = new expression(); arr->arritem->index->comparisons.push_back(new comparison()); arr->arritem->index->comparisons[0]->a = new sum(); arr->arritem->index->comparisons[0]->a->terms.push_back(new term()); arr->arritem->index->comparisons[0]->a->terms[0]->values.push_back(new value); arr->arritem->index->comparisons[0]->a->terms[0]->values[0]->type = t_string; arr->arritem->index->comparisons[0]->a->terms[0]->values[0]->var = last.value; //build a whole tree - thank god this only happens at parse-time. a->lvalue.ai->array = arr; //stuff old lvalue array inside arr, make arr the new lvalue array - previous array-key pair becomes new array. at the end, we just return v; this is the top-level array-index pair. At runtime, top-level array is evaluated recursively. } else if (accept(t_lparen)) { procedurecall *p = new procedurecall; if (a->lvalue.isarray) { p->name = a->lvalue.ai->array; a->lvalue.isarray = false; } else if (temp != NULL) { p->name = temp; temp = NULL; } else // this must be the first loop - array indexes make isarray true, and functioncalls make temp non-null. { p->name = new value; p->name->type = t_id; p->name->negative = false; p->name->expd = false; p->name->var = id; } while (!accept(t_rparen)) { p->args.push_back(expr()); if(!accept(t_comma)) { expect(t_rparen); break; } } temp = new value(); temp->type = n_procedure; temp->proccall = p; temp->negative = false; temp->expd = false; } } if (temp != NULL) throw(error("Error: cannot assign to expression")); a->ismultiple = false; while (accept(t_comma)) { a->ismultiple = true; assg_lvalue lv; lv.isarray = false; expect(t_id); lv.str = last.value; if (t.type == t_lsquareb) { lv.isarray = true; lv.ai = new arrayitem; lv.ai->array = new value; lv.ai->array->negative = false; lv.ai->array->expd = false; lv.ai->array->type = t_id; lv.ai->array->var = lv.str; while (accept(t_lsquareb)) { value* arr = new value; arr->negative = false; arr->expd = false; arr->type = t_lsquareb; arr->arritem = new arrayitem; arr->arritem->array = lv.ai->array; arr->arritem->index = expr(); lv.ai->array = arr; //stuff old array inside arr, make arr the new array - previous array-index pair becomes new array. at the end, we just return a; this is the top-level array-index pair. At runtime, top-level array is evaluated recursively. expect(t_rsquareb); } } a->extra_lvalues.push_back(lv); } expect(t_equals); a->rvalue = expr(); for (unsigned int i = 0; i < a->extra_lvalues.size(); i++) { expect(t_comma); a->extra_rvalues.push_back(expr()); } s->stat.assignstat = a; } } else if (accept(t_while)) { s->type = t_while; whilestatement *w = new whilestatement; w->cond = expr(); expect(t_do); w->whileblock = blk(); s->stat.whilestat = w; expect(t_end); } else if (accept(t_if)) { s->type = t_if; ifstatement *i = new ifstatement; i->cond = expr(); expect(t_then); i->ifblock = blk(); while(accept(t_elseif)) { ifstatement *elseif = new ifstatement; elseif->haselse = false; elseif->cond = expr(); expect(t_then); elseif->ifblock = blk(); i->elseifs.push_back(elseif); } if (accept(t_else)) { i->haselse = true; i->elseblock = blk(); } else i->haselse = false; expect(t_end); s->stat.ifstat = i; } else if (accept(t_for)) { s->type = t_for; forstatement *f = new forstatement; expect(t_id); f->id = last.value; expect(t_equals); f->a = expr(); expect(t_to); f->b = expr(); expect(t_do); f->forblock = blk(); expect(t_end); s->stat.forstat = f; } else if (accept(t_func)) { s->type = t_func; functioncall *f = new functioncall; f->id = funcnames[last.value]; expect(t_lparen); while (!accept(t_rparen)) { f->args.push_back(expr()); if (!accept(t_comma)) { expect(t_rparen); break; } } s->stat.funcstat = f; } else if (accept(t_id)) { std::string id = last.value; if (accept(t_equals)) { s->type = s_plot_exp; explicitplot *p = new explicitplot; p->rangevar = id; p->expr = expr(); s->stat.expplot = p; } else if (accept(t_lparen)) { s->type = n_procedure; procedurecall *p = new procedurecall; p->name = new value(); p->name->type = t_id; p->name->var = id; while (!accept(t_rparen)) { p->args.push_back(expr()); if(!accept(t_comma)) { expect(t_rparen); break; } } s->stat.procstat = p; } else { s->type = s_plot_imp; implicitplot *p = new implicitplot; accepted_equals = false; accepted_ineq = false; jumpto(tindex - 1); //jump back to the id we accepted p->expr = expr(); //parse an expression, stuff it into the plot statement p->haseq = accepted_equals; p->hasineq = accepted_ineq; s->stat.impplot = p; } } else if (accept(t_plot)) { s->type = s_plot_imp; implicitplot *p = new implicitplot; accepted_equals = false; accepted_ineq = false; p->expr = expr(); //parse an expression, stuff it into the plot statement p->haseq = accepted_equals; p->hasineq = accepted_ineq; s->stat.impplot = p; } else if (accept(t_def)) { s->type = t_def; expect(t_id); defstatement *d = new defstatement; d->name = last.value; expect(t_lparen); while (!accept(t_rparen)) { expect(t_id); d->args.push_back(last.value); if(!accept(t_comma)) { expect(t_rparen); break; } } d->entrypoint = blk(); expect(t_end); s->stat.defstat = d; } else if (accept(t_return)) { s->type = t_return; returnstatement *r = new returnstatement; r->expr = expr(); s->stat.returnstat = r; } else if (accept(t_par)) { expect(t_id); s->type = t_par; parametricplot *p = new parametricplot; p->ismulti = false; p->givenfrom = false; p->givento = false; p->givenstep = false; p->parname = last.value; if (accept(t_from)) { p->givenfrom = true; p->from = expr(); } if (accept(t_to)) { p->to = expr(); p->givento = true; } if (accept(t_step)) { p->step = expr(); p->givenstep = true; } if (accept(t_comma)) { expect(t_id); parametricplot *q = new parametricplot; q->ismulti = false; q->givenfrom = false; q->givento = false; q->givenstep = false; q->parname = last.value; if (accept(t_from)) { q->givenfrom = true; q->from = expr(); } if (accept(t_to)) { q->to = expr(); q->givento = true; } if (accept(t_step)) { q->step = expr(); q->givenstep = true; } p->extraparams = q; p->ismulti = true; } while (accept(t_id)) { assignment *a = new assignment; a->lvalue.str = last.value; a->lvalue.isarray = false; expect(t_equals); a->rvalue = expr(); p->assignments.push_back(a); } s->stat.parplot = p; expect(t_end); } else { s->type = t_eof; delete s; throw(e_nostatement); } return s; }
/************************************************************************ * dasm * * - dasm is the application main window. * * - everything the main window does is in this routine (for now) and * * where a response is quick it appears in one of its helper functions * * later in this file, otherwise it has been substantial enough to * * warrant its own file and routines........ * * - this is long * ************************************************************************/ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { HDC hdc; TEXTMETRIC tm; POINT point; lptr scrll; int killcount; g_hMainWnd=hwnd; RECT tmp_rect; switch(message) { case WM_COMMAND: switch(LOWORD(wParam)) { case file_exit: SendMessage(g_hMainWnd,WM_CLOSE,0,0); break; case file_save: savefile_text(hwnd,true,false); break; case get_comment: getcomment(); break; case jump_to: jumpto(); break; case change_oep: changeoep(); break; case save_database: savedb(); break; case load_database: loaddb(); break; case save_asm: savefile_text(hwnd,false,false); break; case block_saveasm: savefile_text(hwnd,false,true); break; case block_savetext: savefile_text(hwnd,true,true); break; case cm_decrypt: decrypterdialog(); break; case file_open: newfile(); break; case view_segment: segviewer(); break; case view_names: namesviewer(); break; case view_imports: importsviewer(); break; case view_exports: exportsviewer(); break; case view_xrefs: xrefsviewer(); break; case make_code: g_scheduler.addtask(user_makecode,priority_userrequest,nlptr,NULL); break; case make_dword: g_scheduler.addtask(user_makedword,priority_userrequest,nlptr,NULL); break; case float_single: g_scheduler.addtask(user_makesingle,priority_userrequest,nlptr,NULL); break; case float_double: g_scheduler.addtask(user_makedouble,priority_userrequest,nlptr,NULL); break; case float_longdouble: g_scheduler.addtask(user_makelongdouble,priority_userrequest,nlptr,NULL); break; case make_word: g_scheduler.addtask(user_makeword,priority_userrequest,nlptr,NULL); break; case make_string: g_scheduler.addtask(user_makestring,priority_userrequest,nlptr,NULL); break; case pascal_string: g_scheduler.addtask(user_pascalstring,priority_userrequest,nlptr,NULL); break; case uc_string: g_scheduler.addtask(user_ucstring,priority_userrequest,nlptr,NULL); break; case up_string: g_scheduler.addtask(user_upstring,priority_userrequest,nlptr,NULL); break; case dos_string: g_scheduler.addtask(user_dosstring,priority_userrequest,nlptr,NULL); break; case general_string: g_scheduler.addtask(user_generalstring,priority_userrequest,nlptr,NULL); break; case argover_dec: g_scheduler.addtask(user_argoverdec,priority_userrequest,nlptr,NULL); break; case arg_single: g_scheduler.addtask(user_argsingle,priority_userrequest,nlptr,NULL); break; case argover_hex: g_scheduler.addtask(user_argoverhex,priority_userrequest,nlptr,NULL); break; case argnegate: g_scheduler.addtask(user_argnegate,priority_userrequest,nlptr,NULL); break; case offset_dseg: g_scheduler.addtask(user_argoveroffsetdseg,priority_userrequest,nlptr,NULL); break; case argover_char: g_scheduler.addtask(user_argoverchar,priority_userrequest,nlptr,NULL); break; case undefine_line: g_scheduler.addtask(user_undefineline,priority_userrequest,nlptr,NULL); break; case undefine_lines: g_scheduler.addtask(user_undefinelines,priority_userrequest,nlptr,NULL); break; case undefine_lines_long: g_scheduler.addtask(user_undefinelines_long,priority_userrequest,nlptr,NULL); break; case block_undefine: g_scheduler.addtask(user_undefineblock,priority_userrequest,nlptr,NULL); break; case block_view: blockview(); break; case block_top: g_scheduler.addtask(user_marktopblock,priority_userrequest,nlptr,NULL); break; case block_bottom: g_scheduler.addtask(user_markbottomblock,priority_userrequest,nlptr,NULL); break; case line_jumpto: g_scheduler.addtask(user_jumpto,priority_userrequest,nlptr,NULL); break; case line_jumptoarg2: g_scheduler.addtask(user_jumptoarg2,priority_userrequest,nlptr,NULL); break; case Name_Location: namelocation(); break; case help_short: DialogBox(g_hInst,MAKEINTRESOURCE(help_shortcuts),hwnd,(DLGPROC)helpshortcuts); break; case help_about: DialogBox(g_hInst,MAKEINTRESOURCE(D_help_about),hwnd,(DLGPROC)habox); break; case Jump_Back: g_scheduler.addtask(user_jumpback,priority_userrequest,nlptr,NULL); break; case main_search: searchengine(); break; case search_again: searchmore(); break; case set_bg_color: g_options.bgcolor=choosecolour(g_options.bgcolor); GetClientRect(g_hMainWnd,&tmp_rect); InvalidateRect(g_hMainWnd,&tmp_rect,true); g_scheduler.addtask(windowupdate,priority_window,nlptr,NULL); break; case set_high_color: g_options.highcolor=choosecolour(g_options.highcolor); GetClientRect(g_hMainWnd,&tmp_rect); InvalidateRect(g_hMainWnd,&tmp_rect,true); g_scheduler.addtask(windowupdate,priority_window,nlptr,NULL); break; case set_text_color: g_options.textcolor=choosecolour(g_options.textcolor); GetClientRect(g_hMainWnd,&tmp_rect); InvalidateRect(g_hMainWnd,&tmp_rect,true); g_scheduler.addtask(windowupdate,priority_window,nlptr,NULL); break; case font_system: g_options.font=systemfont; setupfont(); break; case font_courier: g_options.font=courierfont; setupfont(); break; case font_courier10: g_options.font=courierfont10; setupfont(); break; case font_courier12: g_options.font=courierfont12; setupfont(); break; case font_ansi: g_options.font=ansifont; setupfont(); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } break; case WM_CHAR: if(charinputenabled) switch(wParam) { case 'c': g_scheduler.addtask(user_makecode,priority_userrequest,nlptr,NULL); break; case 'C': g_scheduler.addtask(user_argoverchar,priority_userrequest,nlptr,NULL); break; case 'd': g_scheduler.addtask(user_makedword,priority_userrequest,nlptr,NULL); break; case 'D': g_scheduler.addtask(user_argoverdec,priority_userrequest,nlptr,NULL); break; case 'H': g_scheduler.addtask(user_argoverhex,priority_userrequest,nlptr,NULL); break; case '-': g_scheduler.addtask(user_argnegate,priority_userrequest,nlptr,NULL); break; case 'n': namelocation(); break; case ';': getcomment(); break; case 'o': g_scheduler.addtask(user_argoveroffsetdseg,priority_userrequest,nlptr,NULL); break; case 'p': g_scheduler.addtask(user_pascalstring,priority_userrequest,nlptr,NULL); break; case 's': g_scheduler.addtask(user_makestring,priority_userrequest,nlptr,NULL); break; case 'u': g_scheduler.addtask(user_undefineline,priority_userrequest,nlptr,NULL); break; case 'U': g_scheduler.addtask(user_undefinelines,priority_userrequest,nlptr,NULL); break; case 'w': g_scheduler.addtask(user_makeword,priority_userrequest,nlptr,NULL); break; case 't': g_scheduler.addtask(user_marktopblock,priority_userrequest,nlptr,NULL); break; case 'b': g_scheduler.addtask(user_markbottomblock,priority_userrequest,nlptr,NULL); break; default: break; } break; case WM_LBUTTONDOWN: dio.setpos(HIWORD(lParam)); break; case WM_RBUTTONDOWN: dio.setpos(HIWORD(lParam)); point.x=LOWORD(lParam); point.y=HIWORD(lParam); ClientToScreen(g_hMainWnd,&point); TrackPopupMenu(rmenu,0,point.x,point.y,0,g_hMainWnd,NULL); break; case WM_PAINT: if(!KillThread) DoPaint(hwnd,cxChar,cyChar); else PaintBack(hwnd); ValidateRect(g_hMainWnd,NULL); break; case WM_CLOSE: if(MessageBox(g_hMainWnd,"Are you sure that you want to exit Borg ?\n\rHit Yes To Exit\n\rHit No to Stay","Borg Disassembler", MB_ICONEXCLAMATION|MB_YESNO)==IDNO) break; g_scheduler.stopthread(); g_scheduler.addtask(quitborg,priority_quit,nlptr,NULL); KillThread=true; if(InThread) SetThreadPriority(ThreadHandle,THREAD_PRIORITY_TIME_CRITICAL); DestroyWindow(g_hMainWnd); return 0; case WM_DESTROY: save_reg_entries(); KillThread=true; killcount=0; Sleep(0); SetPriorityClass(ThreadHandle,HIGH_PRIORITY_CLASS); if(InThread) while(TestThread()) { killcount++; if(killcount>2) { // this is a nasty way of getting out. // sometimes the thread just will not exit nicely when its busy. if(TerminateThread(ThreadHandle,1)) { CloseHandle(ThreadHandle); break; } } } DeleteCriticalSection(&g_hCs); PostQuitMessage(0); break; case WM_SIZE: if(wParam==SIZE_MAXIMIZED) g_options.winmax=true; else if (wParam==SIZE_RESTORED) g_options.winmax=false; mainwndsize.top=0; mainwndsize.left=0; mainwndsize.right=LOWORD(lParam); mainwndsize.bottom=HIWORD(lParam); GetWindowRect(hwndStatusBar,&StatusWindowSize); GetWindowRect(g_hMainWnd,&mainwnd); MoveWindow(hwndStatusBar,0,mainwndsize.bottom-StatusWindowSize.bottom+StatusWindowSize.top, mainwndsize.right,StatusWindowSize.bottom-StatusWindowSize.top,true); break; case WM_MOUSEWHEEL: if (GET_KEYSTATE_WPARAM(wParam) & MK_SHIFT) { scrll.assign(0,GET_WHEEL_DELTA_WPARAM(wParam)/WHEEL_DELTA); g_scheduler.addtask(hscroll,priority_userrequest,scrll,NULL); } else { scrll.assign(0,-GET_WHEEL_DELTA_WPARAM(wParam)/WHEEL_DELTA); if(InThread) g_scheduler.addtask(scrolling,priority_userrequest,scrll,NULL); } break; case WM_VSCROLL: switch(LOWORD(wParam)) { case SB_TOP: break; case SB_BOTTOM: break; case SB_LINEUP: scrll.assign(0,-1); if(InThread) g_scheduler.addtask(scrolling,priority_userrequest,scrll,NULL); break; case SB_LINEDOWN: scrll.assign(0,1); if(InThread) g_scheduler.addtask(scrolling,priority_userrequest,scrll,NULL); break; case SB_PAGEUP: scrll.assign(0,-mainwndsize.bottom/cyChar+1); if(InThread) g_scheduler.addtask(scrolling,priority_userrequest,scrll,NULL); break; case SB_PAGEDOWN: scrll.assign(0,mainwndsize.bottom/cyChar-1); if(InThread) g_scheduler.addtask(scrolling,priority_userrequest,scrll,NULL); break; case SB_THUMBPOSITION: scrll.assign(0,HIWORD(wParam)); if(InThread) g_scheduler.addtask(vthumbposition,priority_userrequest,scrll,NULL); break; default: break; } break; case WM_HSCROLL: switch(LOWORD(wParam)) { case SB_LINEUP: scrll.assign(0,-1); g_scheduler.addtask(hscroll,priority_userrequest,scrll,NULL); break; case SB_LINEDOWN: scrll.assign(0,1); g_scheduler.addtask(hscroll,priority_userrequest,scrll,NULL); break; case SB_PAGEUP: scrll.assign(0,-8); g_scheduler.addtask(hscroll,priority_userrequest,scrll,NULL); break; case SB_PAGEDOWN: scrll.assign(0,8); g_scheduler.addtask(hscroll,priority_userrequest,scrll,NULL); break; case SB_THUMBPOSITION: scrll.assign(0,HIWORD(wParam)); if(InThread) g_scheduler.addtask(hthumbposition,priority_userrequest,scrll,NULL); break; default: break; } break; case WM_REPEATNAMEVIEW: namesviewer(); break; case WM_REPEATXREFVIEW: xrefsviewer(); break; // maximises window, used when the reg is read in at the start to maximise // the main window after initialisation of it case WM_MAXITOUT: ShowWindow(g_hMainWnd,SW_MAXIMIZE); break; case WM_CREATE: optionsinit(); hdc=GetDC(hwnd); SelectObject(hdc,GetStockObject(ANSI_FIXED_FONT)); GetTextMetrics(hdc,&tm); cxChar=tm.tmAveCharWidth; cyChar=tm.tmHeight+tm.tmExternalLeading; ReleaseDC(hwnd,hdc); InitializeCriticalSection(&g_hCs); hwndStatusBar=CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|CCS_BOTTOM, "No File Loaded",hwnd,2); GetWindowRect(hwndStatusBar,&StatusWindowSize); GetWindowRect(g_hMainWnd,&mainwnd); SetScrollRange(hwnd,SB_VERT,0,VERTSCROLLRANGE,false); SetScrollPos(hwnd,SB_VERT,0,false); KillThread=false; InThread=false; rmenu=LoadMenu(g_hInst,MAKEINTRESOURCE(right_click_menu)); rmenu=GetSubMenu(rmenu,0); load_reg_entries(); setupfont(); break; case WM_KEYDOWN: if(!charinputenabled) break; switch(wParam) { case VK_HOME: SendMessage(hwnd,WM_VSCROLL,SB_TOP,0L); break; case VK_PRIOR: SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0L); break; case VK_NEXT: SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0L); break; case VK_DOWN: SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0L); break; case VK_UP: SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0L); break; case VK_LEFT: SendMessage(hwnd,WM_HSCROLL,SB_PAGEUP,0L); break; case VK_RIGHT: SendMessage(hwnd,WM_HSCROLL,SB_PAGEDOWN,0L); break; case VK_RETURN: if(GetKeyState(VK_SHIFT)&0x8000) g_scheduler.addtask(user_jumptoarg2,priority_userrequest,nlptr,NULL); else g_scheduler.addtask(user_jumpto,priority_userrequest,nlptr,NULL); break; case VK_ESCAPE: g_scheduler.addtask(user_jumpback,priority_userrequest,nlptr,NULL); break; case VK_F1: DialogBox(g_hInst,MAKEINTRESOURCE(help_shortcuts),hwnd,(DLGPROC)helpshortcuts); break; case VK_F3: searchmore(); break; default: break; } break; default: return DefWindowProc(hwnd,message,wParam,lParam); } return 0; }
//------------------------------------------------------------------------- // function that is called when the user hits Enter static void idaapi enter_cb(void *obj,uint32 n) { netnode *node = (netnode *)obj; jumpto(node->altval(n-1)); }
bool wrapped_jumpto(ea_t ea) { return jumpto(ea, -1); }