int sig_add_address(psig_t * sig, short opcodes[256], ea_t ea, bool b, bool line, char options) { unsigned char byte; unsigned char buf[200]; uint32 s, i; bool call; bool cj; ea_t tea; flags_t f; if (line) dline_add(&sig->dl, ea, options); if (is_jump(sig, ea, &call, &cj)) return -1; byte = get_byte_with_optimization(ea); if (remove_instr(byte, ea)) return -1; sig->lines++; opcodes[byte]++; if (!b && !call) { if (cj) { buf[0] = byte; s = 1; } else { s = (uint32)get_item_size(ea); if (s > sizeof(buf)) s = sizeof(buf); get_many_bytes(ea, buf, s); } for (i=0; i<s; i++) { sig->crc_hash += buf[i]; sig->crc_hash += ( sig->crc_hash << 10 ); sig->crc_hash ^= ( sig->crc_hash >> 6 ); } } else if (b)
//------------------------------------------------------------------------------ // Name: do_find // Desc: //------------------------------------------------------------------------------ void DialogReferences::do_find() { bool ok = false; edb::address_t address; const edb::address_t page_size = edb::v1::debugger_core->page_size(); const QString text = ui->txtAddress->text(); if(!text.isEmpty()) { ok = edb::v1::eval_expression(text, &address); } if(ok) { edb::v1::memory_regions().sync(); const QList<IRegion::pointer> regions = edb::v1::memory_regions().regions(); int i = 0; for(const IRegion::pointer ®ion: regions) { // a short circut for speading things up if(region->accessible() || !ui->chkSkipNoAccess->isChecked()) { const edb::address_t page_count = region->size() / page_size; const QVector<quint8> pages = edb::v1::read_pages(region->start(), page_count); if(!pages.isEmpty()) { const quint8 *p = &pages[0]; const quint8 *const pages_end = &pages[0] + region->size(); while(p != pages_end) { if(pages_end - p < edb::v1::pointer_size()) { break; } const edb::address_t addr = p - &pages[0] + region->start(); edb::address_t test_address(0); memcpy(&test_address, p, edb::v1::pointer_size()); if(test_address == address) { auto item = new QListWidgetItem(edb::v1::format_pointer(addr)); item->setData(TypeRole, 'D'); item->setData(AddressRole, addr); ui->listWidget->addItem(item); } edb::Instruction inst(p, pages_end, addr); if(inst) { switch(inst.operation()) { case edb::Instruction::Operation::X86_INS_MOV: // instructions of the form: mov [ADDR], 0xNNNNNNNN Q_ASSERT(inst.operand_count() == 2); if(inst.operands()[0].general_type() == edb::Operand::TYPE_EXPRESSION) { if(inst.operands()[1].general_type() == edb::Operand::TYPE_IMMEDIATE && static_cast<edb::address_t>(inst.operands()[1].immediate()) == address) { auto item = new QListWidgetItem(edb::v1::format_pointer(addr)); item->setData(TypeRole, 'C'); item->setData(AddressRole, addr); ui->listWidget->addItem(item); } } break; case edb::Instruction::Operation::X86_INS_PUSH: // instructions of the form: push 0xNNNNNNNN Q_ASSERT(inst.operand_count() == 1); if(inst.operands()[0].general_type() == edb::Operand::TYPE_IMMEDIATE && static_cast<edb::address_t>(inst.operands()[0].immediate()) == address) { auto item = new QListWidgetItem(edb::v1::format_pointer(addr)); item->setData(TypeRole, 'C'); item->setData(AddressRole, addr); ui->listWidget->addItem(item); } break; default: if(is_jump(inst) || is_call(inst)) { if(inst.operands()[0].general_type() == edb::Operand::TYPE_REL) { if(inst.operands()[0].relative_target() == address) { auto item = new QListWidgetItem(edb::v1::format_pointer(addr)); item->setData(TypeRole, 'C'); item->setData(AddressRole, addr); ui->listWidget->addItem(item); } } } break; } } Q_EMIT updateProgress(util::percentage(i, regions.size(), p - &pages[0], region->size())); ++p; } } } else { Q_EMIT updateProgress(util::percentage(i, regions.size())); } ++i; } } }
void Generator::optimize() { bool flag = true; std::list<std::pair<std::string, std::string>> label_list; std::list<std::pair<std::string, std::string>> var_list; do { auto first_instr = commands_.begin(); auto second_instr = ++commands_.begin(); auto decl_it = first_instr; flag = false; do { if (*first_instr == cmd_wrlab && first_instr->get_first() == op_null && first_instr->get_first()->get_name() == "\ninclude source\\end.inc\n") { decl_it = first_instr; ++first_instr; ++second_instr; } // push a // pop b if(*first_instr == cmd_push && *second_instr == cmd_pop) { // a != b -> mov b, a if (first_instr->get_first() != second_instr->get_first() && second_instr->get_first() == op_register) { commands_.insert(first_instr, Instruction(cmd_mov, second_instr->get_first(), first_instr->get_first())); delete_instr(first_instr, second_instr); flag = true; } if(first_instr->get_first() == second_instr->get_second()) { delete_instr(first_instr, second_instr); flag = true; } } // pop r // push r // -> delete pop && push if(*first_instr == cmd_pop && *second_instr == cmd_push && first_instr->get_first() == second_instr->get_first()) { delete_instr(first_instr, second_instr); flag = true; } // ... // label1: // label2: // ... // -> delete label1 if (*first_instr == cmd_wrlab && *second_instr == cmd_wrlab && first_instr->get_first() == op_label && second_instr->get_first() == op_label) { label_list.push_back(std::make_pair(first_instr->get_first()->get_name(), second_instr->get_first()->get_name())); delete_instr(first_instr); flag = true; } //change deleted labels in jumps if (is_jump(first_instr->get_cmd())) { for each(auto it in label_list) if (it.first == first_instr->get_first()->get_name()) { first_instr->get_first()->set_name(it.second); flag = true; break; } } // jmp label // label: // -> delete jmp if (*first_instr == cmd_jmp && *second_instr == cmd_wrlab && first_instr->get_first()->get_name() == second_instr->get_first()->get_name()) { delete_instr(first_instr); flag = true; } // jmp l1 // jmp l2 // -> delete l2 if (*first_instr == cmd_jmp && *second_instr == cmd_jmp) { second_instr = commands_.erase(second_instr); flag = true; } //mov r, 0 -> xor r, r if (*first_instr == cmd_mov && first_instr->get_first() == op_register && first_instr->get_second()->get_name() == "0") { commands_.insert(first_instr, Instruction(cmd_xor, first_instr->get_first(), first_instr->get_first())); delete_instr(first_instr); flag = true; } // mov r, r // -> delete if (*first_instr == cmd_mov && first_instr->get_first() == first_instr->get_second()) { delete_instr(first_instr); flag = true; } // add r, 0 || sub r, 0 // -> delete if ((*first_instr == cmd_add || *first_instr == cmd_sub) && first_instr->get_second() == "0") { delete_instr(first_instr); flag = true; } // add r, 1 // -> inc r if (*first_instr == cmd_add && first_instr->get_second()->get_name() == "1") { commands_.insert(first_instr, Instruction(cmd_inc, first_instr->get_first())); delete_instr(first_instr); flag = true; } // sub r, 1 // -> dec r if (*first_instr == cmd_sub && first_instr->get_second()->get_name() == "1") { commands_.insert(first_instr, Instruction(cmd_dec, first_instr->get_first())); delete_instr(first_instr); flag = true; } // mov r, 1 // dec r // -> xor r, r if (*first_instr == cmd_mov && *second_instr == cmd_dec && first_instr->get_first() == second_instr->get_first() && first_instr->get_second()->get_name() == "1") { commands_.insert(first_instr, Instruction(cmd_xor, first_instr->get_first(), first_instr->get_first())); delete_instr(first_instr, second_instr); flag = true; } // xor r, r // imul r, i || add a, r || sub a, r || div r, i // -> delete imul/add/sub if (*first_instr == cmd_xor && (((*second_instr == cmd_imul || *second_instr == cmd_idiv) && first_instr->get_first() == second_instr->get_first()) || ((*second_instr == cmd_add || *second_instr == cmd_sub) && first_instr->get_first() == second_instr->get_second()))) { second_instr = commands_.erase(second_instr); flag = true; } // val1 dq 1.2 // val2 dq 1.2 // -> delete val2, and use val1 instead val2 if (*first_instr == cmd_const_decl) { for (auto it = decl_it; it != commands_.end(); ++it) if (*it == cmd_const_decl && first_instr->get_first()->get_name() != (*it).get_first()->get_name() && first_instr->get_second()->get_name() == (*it).get_second()->get_name()) { var_list.push_back(std::make_pair(it->get_first()->get_name(), first_instr->get_first()->get_name())); if (second_instr == it) ++second_instr; it = commands_.erase(it); flag = true; } } if ((*first_instr == cmd_push && first_instr->get_first() == op_memory) || (*first_instr == cmd_mov && first_instr->get_first() == op_register && first_instr->get_second() == op_memory)) for each(auto it in var_list) { if ("qword ptr " + it.first == first_instr->get_first()->get_name()) { first_instr->get_first()->set_name("qword ptr " + it.second); flag = true; break; } else if ("offset " + it.first == first_instr->get_second()->get_name()) { first_instr->get_second()->set_name("offset " + it.second); flag = true; break; } } ++first_instr; ++second_instr; } while (second_instr != commands_.end()); } while(flag); }