Exemple #1
0
     bool operator()(InputIterator& next, InputIterator end,Token& tok) {
     tok = Token();

     // skip past all nonreturnable delims
     // skip past the returnable only if we are not returning delims
     for (;next!=end && ( is_nonret(*next) || (is_ret(*next) 
       && !return_delims_ ) );++next) { }

     if (next == end) {
       return false;
     }

     // if we are to return delims and we are one a returnable one
     // move past it and stop
     if (is_ret(*next) && return_delims_) {
       tok+=*next;
       ++next;
     }
     else
       // append all the non delim characters
       for (;next!=end && !is_nonret(*next) && !is_ret(*next);++next)
         tok+=*next;


     return true;
   }
//------------------------------------------------------------------------------
// Name: on_tableWidgetCallStack_cellClicked
// Desc: Enables the "Run To Return" button if the selected cell is in the
//			column for return addresses.  Disables it, otherwise.
//------------------------------------------------------------------------------
void DialogBacktrace::on_tableWidgetCallStack_cellClicked(int row, int column)
{
	row = row;	//Not used, and the warning is annoying.

	QPushButton *return_to = ui->pushButtonReturnTo;
	if (is_ret(column)) {
		return_to->setEnabled(true);
	} else {
		return_to->setDisabled(true);
	}
}
//------------------------------------------------------------------------------
// Name: on_pushButtonReturnTo_clicked()
// Desc: Ensures that the selected item is a return address.  If so, sets a
//			breakpoint at that address and continues execution.
//------------------------------------------------------------------------------
void DialogBacktrace::on_pushButtonReturnTo_clicked()
{
	//Make sure our current item is in the RETURN_COLUMN
	QTableWidgetItem *item = table_->currentItem();
	if (!is_ret(item)) { return; }

	bool ok;
	edb::address_t address = address_from_table(&ok, item);

	//If we didn't get a valid address, then fail.
	//TODO: Make sure "ok" actually signifies success of getting an address...
	if (!ok) {
		int base = 16;
		QString msg("Could not return to 0x%x" + QString().number(address, base));
		QMessageBox::information( this,	"Error", msg);
		return;
	}

	//Now that we got the address, we can run.  First check if bp @ that address
	//already exists.
	IBreakpoint::pointer bp = edb::v1::debugger_core->find_breakpoint(address);
	if (bp) {
		edb::v1::debugger_core->resume(edb::DEBUG_CONTINUE);
		return;
	}

	//Using the non-debugger_core version ensures bp is set in a valid region
	edb::v1::create_breakpoint(address);
	bp = edb::v1::debugger_core->find_breakpoint(address);
	if (bp) {
		bp->set_internal(true);
		bp->set_one_time(true);
		edb::v1::debugger_core->resume(edb::DEBUG_CONTINUE);
		return;
	}


}
//------------------------------------------------------------------------------
// Name: do_find
// Desc:
//------------------------------------------------------------------------------
void DialogROPTool::do_find() {

	const QItemSelectionModel *const selModel = ui->tableView->selectionModel();
	const QModelIndexList sel = selModel->selectedRows();

	if(sel.size() == 0) {
		QMessageBox::critical(
			this,
			tr("No Region Selected"),
			tr("You must select a region which is to be scanned for gadgets."));
	} else {

		unique_results_.clear();

		if(IProcess *process = edb::v1::debugger_core->process()) {
			for(const QModelIndex &selected_item: sel) {

				const QModelIndex index = filter_model_->mapToSource(selected_item);
				if(auto region = *reinterpret_cast<const IRegion::pointer *>(index.internalPointer())) {

					edb::address_t start_address     = region->start();
					const edb::address_t end_address = region->end();
					const edb::address_t orig_start  = start_address;

					ByteShiftArray bsa(32);

					while(start_address < end_address) {

						// read in the next byte
						quint8 byte;
						if(process->read_bytes(start_address, &byte, 1)) {
							bsa << byte;

							const quint8       *p = bsa.data();
							const quint8 *const l = p + bsa.size();
							edb::address_t    rva = start_address - bsa.size() + 1;

							QList<edb::Instruction> instruction_list;

							// eat up any NOPs in front...
							Q_FOREVER {
								edb::Instruction inst(p, l, rva);
								if(!is_nop(inst)) {
									break;
								}

								instruction_list << inst;
								p += inst.size();
								rva += inst.size();
							}


							edb::Instruction inst1(p, l, rva);
							if(inst1) {
								instruction_list << inst1;

								if(inst1.operation() == edb::Instruction::Operation::X86_INS_INT && inst1.operands()[0].general_type() == edb::Operand::TYPE_IMMEDIATE && (inst1.operands()[0].immediate() & 0xff) == 0x80) {
									add_gadget(instruction_list);
								} else if(inst1.operation() == edb::Instruction::Operation::X86_INS_SYSENTER) {
									add_gadget(instruction_list);
								} else if(inst1.operation() == edb::Instruction::Operation::X86_INS_SYSCALL) {
									add_gadget(instruction_list);
								} else if(is_ret(inst1)) {
									ui->progressBar->setValue(util::percentage(start_address - orig_start, region->size()));
									++start_address;
									continue;
								} else {

									p += inst1.size();
									rva += inst1.size();

									// eat up any NOPs in between...
									Q_FOREVER {
										edb::Instruction inst(p, l, rva);
										if(!is_nop(inst)) {
											break;
										}

										instruction_list << inst;
										p += inst.size();
										rva += inst.size();
									}

									edb::Instruction inst2(p, l, rva);
									if(is_ret(inst2)) {
										instruction_list << inst2;
										add_gadget(instruction_list);
									} else if(inst2 && inst2.operation() == edb::Instruction::Operation::X86_INS_POP) {
										instruction_list << inst2;
										p += inst2.size();
										rva += inst2.size();

										edb::Instruction inst3(p, l, rva);
										if(inst3 && inst3.operation() == edb::Instruction::Operation::X86_INS_JMP) {

											instruction_list << inst3;

											if(inst2.operand_count() == 1 && inst2.operands()[0].general_type() == edb::Operand::TYPE_REGISTER) {
												if(inst3.operand_count() == 1 && inst3.operands()[0].general_type() == edb::Operand::TYPE_REGISTER) {
													if(inst2.operands()[0].reg() == inst3.operands()[0].reg()) {
														add_gadget(instruction_list);
													}
												}
											}
										}
									}
								}

								// TODO(eteran): catch things like "add rsp, 8; jmp [rsp - 8]" and similar, it's rare,
								// but could happen
							}
						}

						ui->progressBar->setValue(util::percentage(start_address - orig_start, region->size()));
						++start_address;
					}
				}
			}
		}
	}