MCPcopy Create free account
hub / github.com/KasperskyLab/hrtng / GetAssignedAndComparisonVariables

Function GetAssignedAndComparisonVariables

src/unflat.cpp:686–885  ·  view source on GitHub ↗

This function computes all of the preliminary information needed for unflattening.

Source from the content-addressed store, hash-verified

684
685 // This function computes all of the preliminary information needed for unflattening.
686 bool GetAssignedAndComparisonVariables(mbl_array_t *mba)
687 {
688 // Look for the variable that was used in the largest number of jcc comparisons against a constant. This is our "comparison" variable.
689 JZCollector jzc;
690 mba->for_all_topinsns(jzc);
691 if (jzc.m_nMaxJz < 0) {
692 MSG_UF3(("[I] No comparisons seen; failed\n"));
693 return false;
694 }
695#if DEBUG_UF >= 4
696 jzc.ShouldBlacklist();
697#endif
698
699 //it maybe second pass for the same proc already cleared, recalc entropy again
700 if (jzc.m_SeenComparisons[jzc.m_nMaxJz].ShouldBlacklist()) {
701 size_t i = 0; //m_nMaxJz may be with low entropy but still exist flattened blocks, looks for more cmps
702 for (; i < jzc.m_SeenComparisons.size(); ++i) {
703 if (i != jzc.m_nMaxJz && !jzc.m_SeenComparisons[i].ShouldBlacklist()) {
704 jzc.m_nMaxJz = i;
705 break;
706 }
707 }
708 if(i == jzc.m_SeenComparisons.size())
709 return false;
710 }
711
712 MSG_UF1(("[I] ----------------------- Unflattening ---------------------------------\n"));
713 mblock_t *first = GetFirstBlock(mba); // Find the "first" block in the function, the one immediately before the control flow switch.
714 if (!first)
715 return false;
716 MSG_UF1(("[I] found first block %d (ea=%a), dispatcher %d (ea=%a) \n", this->iFirst, mba->get_mblock(this->iFirst)->start, this->iDispatch, mba->get_mblock(this->iDispatch)->start));
717
718 mop_t *opMax = jzc.m_SeenComparisons[jzc.m_nMaxJz].op;// opMax is our "comparison" variable used in the control flow switch.
719 MSG_UF3(("[I] Comparison variable: %s\n", opMax->dstr()));
720 // if there are nested control flow switches, we have to identify the opMax of the dispatcher
721 mblock_t* mb_dispatch = mba->get_mblock(this->iDispatch);
722 mop_t* opMaxMoreLikely = NULL;
723 mop_t* opMaxSub = NULL;
724 for (auto const& sc : jzc.m_SeenComparisons) {
725 if (sc.nSeen >= MIN_NUM_COMPARISONS) {
726 mop_t* op = sc.op;
727 //mlist_t ml;
728 //mb_dispatch->append_use_list(&ml, *op, MUST_ACCESS);
729 opMaxMoreLikely = opMaxSub = NULL;
730 for (minsn_t* p = mb_dispatch->tail; p != NULL; p = p->prev) {
731 //mlist_t def = mb_dispatch->build_def_list(*p, MAY_ACCESS | FULL_XDSU);
732 //if ((def.includes(ml) ||
733 if (isRegOvar(p->l.t) && p->l.equal_mops(*op, EQ_IGNSIZE)) {
734 if (isUfJc(p->opcode))
735 opMaxMoreLikely = op;
736 else if (opMaxMoreLikely != NULL && p->opcode == m_mov && isRegOvar(p->d.t))
737 opMaxSub = &p->d;
738 } else if (p->opcode == m_and && isRegOvar(p->d.t) && p->d.equal_mops(*op, EQ_IGNSIZE))
739 opMaxMoreLikely = op;
740 }
741 if (opMaxMoreLikely != NULL)
742 break;
743 }

Callers

nothing calls this directly

Calls 8

GetFirstBlockFunction · 0.85
isRegOvarFunction · 0.85
isUfJcFunction · 0.85
ComputeDominatorsFunction · 0.85
sizeMethod · 0.80
printMethod · 0.80
beginMethod · 0.80
endMethod · 0.80

Tested by

no test coverage detected