ea_t GetDelayedBranchAdr(void) // if previous instruction is delayed jump return jump adr, else -1 { int16 disp; if (! isFlow(uFlag)) return BADADDR; // Does the previous instruction exist and pass execution flow to the current byte? if (cmd.size <= 0) return BADADDR; int sub = 3; // backward offset to skip 3 previous 1-word instruction ea_t ea = cmd.ea - sub; if (isCode(get_flags_novalue(ea))) // Does flag denote start of an instruction? { int code = get_full_byte(ea); // get the instruction word if ((code & 0xff000000) == 0x61000000) // Branch unconditionally (delayed) return code & 0xffffff; if ((code & 0xffe00000) == 0x6a200000) // BranchD conditionally { disp = code & 0xffff; return cmd.ea + disp; } if ((code & 0xfe200000) == 0x6e200000) // DecrementD and branch conditionally { disp = code & 0xffff; return cmd.ea + disp; } } return BADADDR; }
void CodeEditorDialog::insertVariable(const QString &variable) { if(isCode()) ui->editor->insertPlainText(variable); else ui->editor->insertPlainText("$" + variable); }
void IdaFrontend::createSections(core::image::Image *image) { for (int i = 0; i < get_segm_qty(); i++) { segment_t *idaSegment = getnseg(i); assert(idaSegment != NULL); char segName[MAXSTR]; ssize_t segNameSize = get_segm_name(idaSegment, segName, sizeof(segName) - 1); if(segNameSize < 0) { segName[0] = '\0'; } else if(segNameSize > 0 && segName[0] == '_') { segName[0] = '.'; } auto section = std::make_unique<core::image::Section>( segName, checked_cast<ByteAddr>(idaSegment->startEA), checked_cast<ByteSize>(idaSegment->size()) ); section->setReadable(idaSegment->perm & SEGPERM_READ); section->setWritable(idaSegment->perm & SEGPERM_WRITE); section->setExecutable(idaSegment->perm & SEGPERM_EXEC); section->setCode(idaSegment->type == SEG_CODE); section->setData(idaSegment->type == SEG_DATA); section->setBss(idaSegment->type == SEG_BSS); section->setAllocated(section->isCode() || section->isData() || section->isBss()); section->setExternalByteSource(std::make_unique<IdaByteSource>()); image->addSection(std::move(section)); } }
QString DisassemblerLine::toString(int maxOp) const { const QString someSpace = _(" "); QString str; if (isAssembler()) { if (address) str += _("0x%1 ").arg(address, 0, 16); if (offset) str += _("<+0x%2> ").arg(offset, 4, 16, QLatin1Char('0')); else str += _(" "); str += _(" %1 ").arg(bytes); str += QString(maxOp - bytes.size(), QLatin1Char(' ')); str += data; } else if (isCode()) { str += someSpace; str += QString::number(lineNumber); if (hunk) str += _(" [%1]").arg(hunk); else str += _(" "); str += data; } else { str += someSpace; str += data; } return str; }
QValidator::State CodeSpinBox::validate(QString &text, int &pos) const { if(isCode()) return QValidator::Acceptable; return QSpinBox::validate(text, pos); }
QString CodeDateTimeEdit::textFromDateTime(const QDateTime &dateTime) const { if(isCode()) return codeLineEdit()->text(); return QDateTimeEdit::textFromDateTime(dateTime); }
QString CodeSpinBox::textFromValue(int value) const { if(isCode()) return codeLineEdit()->text(); return QSpinBox::textFromValue(value); }
//TODO: better algo of course!!! //By now - it's full os shitty false positives int assign_type(ea_t address, int *value) { flags_t flags = getFlags(address); if (isHead(flags) && isCode(flags)) { ua_ana0(address); if(cmd.itype == NN_mov) if(cmd.Operands[1].type == o_imm){ *value = cmd.Operands[1].value; return CONSTVALUE; } else return VARVALUE; return VARVALUEVULN; } else{ return UNDEFINED; } return UNDEFINED; }
void VariableLineEdit::insertVariable(const QString &variable) { if(isCode()) insert(variable); else setText(variable); }
void CodeLineEdit::insertVariable(const QString &variable) { //If a validator is set this means that the insertion will fail //In this case, reset the content and set the code mode if(validator()) { if(!text().isEmpty() && QMessageBox::question(this, tr("Insert variable/resource"), tr("Inserting a variable or a resource will replace the current parameter value.\nAre you sure?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) != QMessageBox::Yes) return; setCode(true); setText(QString()); } //Temporarily remove the completer so that we don't get a popup QCompleter *currentCompleter = completer(); if(currentCompleter) { currentCompleter->setParent(0); setCompleter(0); } if(isCode()) insert(variable); else insert("$" + variable); if(currentCompleter) { currentCompleter->setParent(this); setCompleter(currentCompleter); } }
QValidator::State CodeDateTimeEdit::validate(QString &text, int &pos) const { if(isCode()) return QValidator::Acceptable; return QDateTimeEdit::validate(text, pos); }
int Solution::numDecodings(string s) { int len = s.size(); int *dp = new int[len]; fill(dp, dp + len, 0); if (isCode(s,0,1)) dp[0] = 1; for (int i = 1; i < len; i++) { if (isCode(s,i,1)) dp[i] = dp[i - 1]; if (i>0&& isCode(s, i - 1, 2)) dp[i] += (i>=2?dp[i - 2]:1); } return dp[len - 1]; //int ans = 0; //countDecode(s, 0, ans); //return ans; }
QSet<QString> VariableLineEdit::findVariables() const { QSet<QString> back = CodeLineEdit::findVariables(); if(!isCode() && !text().isEmpty()) back.insert(text()); return back; }
//---------------------------------------------------------------------- static int canFlow(void) { if ( isC2() ) return 1; if ( !isFlow(uFlag) ) return 1; // no previous instructions ea_t ea = prevInstruction(cmd.ea); if ( cmd.size == 2 ) // our instruction is long { ; // nothing to do } else { // our instruction short if ( (cmd.ea-ea) == 2 ) // prev instruction long return 1; // can flow always flags_t F = get_flags_novalue(ea); if ( !isCode(F) || !isFlow(F) ) return 1; // no prev instr... ea = prevInstruction(ea); } flags_t F = get_flags_novalue(ea); return !isCode(F) || !isDelayedStop((ushort)get_full_byte(ea)); }
//--------------------------------------------------------------------------- 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); } }
//---------------------------------------------------------------------- static bool canFlow(void) { if ( ! isFlow(uFlag) ) return 1; // no previous instructions ea_t ea = cmd.ea - 4; flags_t F = get_flags_novalue(ea); if ( isFlow(F) && isCode(F) ) { if ( isDelayedStop(get_long(ea)) ) // now or later { ea -= 4; if ( !isCode(get_flags_novalue(ea)) || !isDual(get_long(ea)) ) return 0; return 1; } if ( isFlow(F) ) { ea -= 4; return !isCode(get_flags_novalue(ea)) || !isDelayedStop(get_long(ea)); } } return 1; }
//---------------------------------------------------------------------- ea_t find_first_insn_in_packet(ea_t ea) { while ( (ea & 0x1F) != 0 ) { ea_t ea2 = prev_not_tail(ea); if ( ea2 == BADADDR || !isCode(get_flags_novalue(ea2)) || (get_long(ea2) & BIT0) == 0 ) break; ea = ea2; } return ea; }
ea_t get_next_code(ea_t start) { segment_t *cs = getseg(start); if ( NULL == cs ) return NULL; for ( ; start < cs->endEA; start = get_item_end(start) ) if ( isCode(start) ) return start; return cs->endEA; }
//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; }
// check and create a flat 32 bit jump table -- the most common case static void check_and_create_flat32( jump_table_type_t /*jtt*/, switch_info_ex_t &si) { // check the table contents ea_t table = si.jumps; segment_t *s = getseg(table); if ( s == NULL ) return; size_t maxsize = size_t(s->endEA - table); int size = si.ncases; if ( size > maxsize ) size = (int)maxsize; int i; insn_t saved = cmd; for ( i=0; i < size; i++ ) { ea_t ea = table + 4*i; flags_t F = getFlags(ea); if ( !hasValue(F) ) break; if ( i && (has_any_name(F) || hasRef(F)) ) break; ea_t target = segm_adjust_ea(getseg(table), si.elbase + get_long(ea)); if ( !isLoaded(target) ) break; flags_t F2 = get_flags_novalue(target); if ( isTail(F2) || isData(F2) ) break; if ( !isCode(F2) && !decode_insn(target) ) break; } cmd = saved; size = i; // create the table for ( i=0; i < size; i++ ) { ea_t ea = table + 4*i; doDwrd(ea, 4); op_offset(ea, 0, REF_OFF32, BADADDR, si.elbase); ea_t target = si.elbase + segm_adjust_diff(getseg(table), get_long(ea)); ua_add_cref(0, target, fl_JN); } si.flags |= SWI_J32; if ( si.defjump != BADADDR ) si.flags |= SWI_DEFAULT; si.ncases = (uint16)size; si.startea = cmd.ea; set_switch_info_ex(cmd.ea, &si); }
bool delayed_stop(void) { if (! isFlow(uFlag)) return false; if (cmd.size <= 0 || cmd.size > 2) return false; int sub = 2 - cmd.size; // backward offset to skip the previous 1-word instruction in the case of 2 consecutive 1-word instructions // first, we analyze 1-word instructions ea_t ea = cmd.ea - sub - 1; if (isCode(get_flags_novalue(ea))) { int code = get_full_byte(ea); // get the instruction word switch (code) { case 0xF6E2: // TMS320C54_baccd, // Branch to Location Specified by Accumulator 1111 01ZS 1110 0010 BACC[D] src case 0xF7E2: case 0xF6E6: // TMS320C54_fbaccd, // Far Branch to Location Specified by Accumulator 1111 01ZS 1110 0110 FBACC[D] src case 0xF7E6: case 0xF6E4: // TMS320C54_fretd, // Far Return 1111 01Z0 1110 0100 FRET[D] case 0xF6E5: // TMS320C54_freted, // Enable Interrupts and Far Return From Interrupt 1111 01Z0 1110 0101 FRETE[D] case 0xFE00: // TMS320C54_retd, // Return 1111 11Z0 0000 0000 RET[D] case 0xF6EB: // TMS320C54_reted, // Enable Interrupts and Return From Interrupt 1111 01Z0 1110 1011 RETE[D] case 0xF69B: // TMS320C54_retfd, // Enable Interrupts and Fast Return From Interrupt 1111 01Z0 1001 1011 RETF[D] return true; } } // else, we analyze 2-word instructions ea = cmd.ea - sub - 2; if (isCode(get_flags_novalue(ea))) { int code = get_full_byte(ea); // get the first instruction word if ( code == 0xF273 // TMS320C54_bd, // Branch Unconditionally 1111 00Z0 0111 0011 16-bit constant B[D] pmad || (code & 0xFF80) == 0xFA80) // TMS320C54_fbd, // Far Branch Unconditionally 1111 10Z0 1 7bit constant=pmad(22-16) 16-bit constant=pmad(15-0) FB[D] extpmad return true; } return false; }
int __stdcall GetAsm(__int64 addr, char* buf, int bufLen){ flags_t flags; int sLen=0; flags = getFlags(addr); if(isCode(flags)) { generate_disasm_line((ea_t)addr, buf, bufLen, GENDSM_MULTI_LINE ); sLen = tag_remove(buf, buf, bufLen); } return sLen; }
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 } }
void Solution::countDecode(string s, int start, int&ans) { if (start >= s.size()){ ans++; return; } for (int i = 1; i <= 2; i++) { if (isCode(s, start, i)) { countDecode(s, start + i, ans); } } }
size_t VtableScanner::getVtableMethodsCount ( ea_t curAddress ) { ea_t startTable = BADADDR; ea_t curEntry = 0; // Iterate until we find a result for (; ; curAddress += 4) { flags_t flags = IDAUtils::GetFlags (curAddress); // First iteration if (startTable == BADADDR) { startTable = curAddress; if (!(hasRef (flags) && (has_name (flags) || (flags & FF_LABL)))) { // Start of vtable should have a xref and a name (auto or manual) return 0; } } else if (hasRef (flags)) { // Might mean start of next vtable break; } if (!hasValue (flags) || !isData (flags)) { break; } if ((curEntry = get_long (curAddress))) { flags = IDAUtils::GetFlags (curEntry); if (!hasValue (flags) || !isCode (flags) || get_long (curEntry) == 0) { break; } } } if (startTable != BADADDR) { return (curAddress - startTable) / 4; } else { // No vtable at this EA return 0; } }
//---------------------------------------------------------------------- int find_ar(ea_t *res) { ea_t ea = cmd.ea; for ( int i=0; i < lookback; i++ ) { ea = prevInstruction(ea); if ( !isCode(get_flags_novalue(ea)) ) break; ushort code = (ushort)get_full_byte(ea); if ( isC2() ) { switch ( code >> 11 ) { case 6: // LAR return 0; case 0x18: // LARK *res = toEA(dataSeg(),(code & 0xFF)); return 1; case 0x1A: // LRLK if ( (code & 0xF8FF) == 0xD000 ) { ushort b = (ushort)get_full_byte(ea+1); *res = toEA(dataSeg(), b); return 1; } } continue; } switch ( code >> 11 ) { case 0: // Load AR from addressed data return 0; // LAR found, unknown address case 0x16: // Load AR short immediate *res = toEA(dataSeg(), code & 0xFF); return 1; case 0x17: // Load AR long immediate if ( (code & ~7) == 0xBF08 ) { ushort b = (ushort)get_full_byte(ea+1); *res = toEA(dataSeg(),b); return 1; } } } return 0; }
bool KeyEdit::eventFilter(QObject *object, QEvent *event) { if(isCode()) return QObject::eventFilter(object, event); if(event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if(!mKeyInput.fromEvent(keyEvent)) return true; codeLineEdit()->setText(mKeyInput.toTranslatedText()); return true; } return QObject::eventFilter(object, event); }
QString DisassemblerLine::toString() const { const QString someSpace = _(" "); QString str; if (isAssembler()) { if (address) str += _("0x%1 <+0x%2> ").arg(address, 0, 16) .arg(offset, 4, 16, QLatin1Char('0')); str += _(" "); str += data; } else if (isCode()) { str += someSpace; str += data; } else { str += someSpace; str += data; } return str; }
void CodeLineEdit::openEditor(int line, int column) { if(!mShowEditorButton) return; CodeEditorDialog codeEditorDialog(mCompletionModel, this); codeEditorDialog.setText(text()); codeEditorDialog.setCode(isCode()); codeEditorDialog.setCurrentLine(line); codeEditorDialog.setCurrentColumn(column); codeEditorDialog.setAllowTextCodeChange(mAllowTextCodeChange); if(codeEditorDialog.exec() == QDialog::Accepted) { setText(codeEditorDialog.text()); setCode(codeEditorDialog.isCode()); } }
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; }