📄 complexinstr.cpp
字号:
this->Add_Begin_End_1(firstpos,endpos,begin,end);
INSTR_LIST* list = this->m_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
PINSTR p = list->GetNext(pos);
if (p->type == i_Nop)
{
list->RemoveAt(savpos);
}
}
}
void CInstrList::Add_Begin_End_1(POSITION firstpos, POSITION endpos, PINSTR begin, PINSTR end)
{
INSTR_LIST* list = this->m_list;
// 如果first==i_Label,允许其它人call
// 如果last==i_Label,允许其它人call
// 所以插入i_Begin和i_End时,要把它们"分身"
// 因为我要两次借用同一个功能,又不想把它单独写出来,所以写一个for(;;)算了
for (;;)
{
if (begin)
{
PINSTR p = list->GetAt(firstpos);
if (p->type != i_Label)
{
list->InsertBefore(firstpos,begin);
begin = NULL; // 把它清掉,以后不再处理
}
}
if (end)
{
PINSTR p = list->GetAt(endpos);
if (p->type != i_Label)
{
list->InsertBefore(endpos,end);
end = NULL;
}
}
if (begin == NULL && end == NULL)
return; // 都解决掉了,没什么可作的了
PINSTR pnew = new INSTR;
pnew->type = i_Label;
//pnew->label.label_off = p->label.label_off;
pnew->label.ref_instr = 0;
PINSTR p;
if (begin) // 先任取一个吧
{
p = list->GetAt(firstpos);
list->InsertAfter(firstpos,pnew);
list->InsertAfter(firstpos,begin);
begin = NULL; // 把它清掉,以后不再处理
}
else
{
p = list->GetAt(endpos);
list->InsertBefore(endpos,pnew);
list->InsertBefore(endpos,end);
end = NULL; // 把它清掉,以后不再处理
}
pnew->label.label_off = p->label.label_off;
PINSTR p_in = 0;
PINSTR p_out = 0;
PINSTR p1 = p->label.ref_instr;
while (p1)
{
PINSTR pnext = p1->jmp.next_ref_of_this_label;
if (if_Ly_In(p1,firstpos,endpos))
{
p1->jmp.the_label = pnew;
p1->jmp.next_ref_of_this_label = p_in;
p_in = p1;
}
else
{
//p1->jmp.the_label = p; //need not
p1->jmp.next_ref_of_this_label = p_out;
p_out = p1;
}
p1 = pnext;
}
if (p_in) // it must be
pnew->label.ref_instr = p_in;
else
pnew->type = i_Nop; // 因为原来是label,就不用清var了
if (p_out)
p->label.ref_instr = p_out;
else
p->type = i_Nop;
//}
}
}
bool CInstrList::IsSwitchCase_multcomp(PINSTR begin)
{ // 判断是不是多重判断的那一种switch_case
INSTR_LIST* list = this->m_list;
assert(begin->type == i_CplxBegin);
POSITION pos = list->Find(begin);
M_t* v;
int first = 0;
while (pos)
{
POSITION savpos = pos;
PINSTR p = list->GetNext(pos);
first++;
if (first == 1)
continue; // 第一个,肯定是i_CplxBegin,就不用看了
if (first == 2)
{ // 第一条指令,必须是jz sth == n
if (p->type != i_Jump || p->jmp.jmp_type != JMP_jz
|| p->var_r1.type == 0)
return false;
v = p->var_r1.thevar; // 记下来,以后的要跟这个一样才行
continue;
}
if (p->type == i_Jump)
{
if (p->jmp.jmp_type == JMP_jz)
{
if (v != p->var_r1.thevar)
return false;
}
else if (p->jmp.jmp_type == JMP_jmp) // 找到default了
{
if (first < 4) // 检查太少了,不算switch case
return false;
return true;
}
else
return false;
continue;
}
//不是Jump了
if (first < 4) // 检查太少了,不算switch case
return false;
return true;
}
return false;
}
bool CInstrList::IsSwitchCase(PINSTR begin)
{
INSTR_LIST* list = m_list;
assert(begin->type == i_CplxBegin);
POSITION pos = list->Find(begin);
bool first = true;
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_JmpAddr)
{
return true;
}
if (p->type == i_Return)
return false;
if (p->type == i_Label)
return false;
if (p->type == i_Jump)
{ // 只允许有一个jmp
if (first)
first = false;
else
return false;
}
}
return false;
}
void CInstrList::Flow_b(PINSTR pParentNode, POSITION firstpos, POSITION endpos)
{ // 紧凑分析
INSTR_LIST* list = this->m_list;
// last not include
if (firstpos == endpos)
{
//alert_prtf("why firstpos == endpos");
return;
}
PINSTR begin = new INSTR;
PINSTR end = new INSTR;
begin->type = i_CplxBegin;
end->type = i_CplxEnd;
begin->begin.m_end = end;
Add_Begin_End(firstpos, endpos, begin, end);
POSITION pos = endpos;
list->GetPrev(pos); //now it point to i_CplxEnd
assert(list->GetAt(pos) == end);
list->GetPrev(pos); //now it point to last instr in body
PINSTR plast = list->GetAt(pos);
PINSTR plast2 = instr_prev(list,plast); //前一条指令
PINSTR pNode = begin;
pNode->begin.m_break = pParentNode->begin.m_break; // 继承
pNode->begin.m_conti = pParentNode->begin.m_conti; // 继承
PINSTR pfirst = instr_next(list,begin);
PINSTR psecond = instr_next(list,pfirst);
if (pfirst->type == i_Label
|| (pfirst->type == i_Jump && pfirst->jmp.jmp_type == JMP_jmp && psecond->type == i_Label)
)
{ // 这是我认为 break 的条件 !
PINSTR pconti;
if (pfirst->type == i_Label) // 如果是第一种情况
pconti = pfirst;
else
pconti = psecond;
pconti->label.f_conti = true;
if (plast->type == i_Label) // 如果最后一条指令是个label,那它肯定是break
pNode->begin.m_break = plast;
else
pNode->begin.m_break = 0;
pNode->begin.m_conti = pconti;
if (plast->type == i_Label)
{
if (plast2->type == i_Jump
&& plast2->jmp.jmp_type == JMP_jmp
&& plast2->jmp.the_label == pconti)
{ // 这是 while !
pNode->begin.m_not_conti = plast2;
}
}
else if (plast->type == i_Jump
&& plast->jmp.jmp_type == JMP_jmp
&& plast->jmp.the_label == pconti)
{
pNode->begin.m_not_conti = plast;
}
else
{
//do_while的continue 以后再处理
}
}
else if (plast->type == i_Label && IsSwitchCase(begin))
{
pNode->begin.m_break = plast;
//conti not change
// 这是switch_case 的特点,就是只用break,却不用continue,非常特殊。
pNode->begin.type = COMP_switch_case;
//alert("case find 00");
}
else if (plast->type == i_Label && IsSwitchCase_multcomp(begin))
{
pNode->begin.m_break = plast;
//conti not change
// 这是switch_case 的特点,就是只用break,却不用continue,非常特殊。
pNode->begin.type = COMP_switch_case_multcomp;
//alert("case find 01");
}
if (Step_by_Step())
return; // 我们已经加了个i_CplxBegin_End就算干过活了
Flow_c(begin); // 对这个i_CplxBegin再作些处理
}
bool CInstrList::Flow_a(PINSTR pNode)
// 流程分析第一步
// 对这个区间进行分析。以后可以递归
{
INSTR_LIST* list = this->m_list;
assert(pNode->type == i_Begin);
POSITION endpos = list->Find(pNode->begin.m_end);
POSITION firstpos = list->Find(pNode);
list->GetNext(firstpos); // 从第二条指令开始
assert(firstpos);
if (firstpos == endpos)
return false;
return Flow_aa(pNode,firstpos,endpos);
// Flow_a 是指向一个begin_end
// 而Flow_aa是指向一个区间,并不一定是begin_end
}
bool Step_by_Step()
{ // 这是为了在非step_by_step状态时,能提高点速度
// 而在step_by_step状态时,又能使每一步都分得很细
if (g_f_Step_by_Step)
return true;
g_any1_return_TRUE = true;
return false;
}
bool CInstrList::Flow_aa(PINSTR pBlockHeadNode, POSITION firstpos, POSITION endpos)
{ // 松散分析
// return true表示分析有进展
// pBlockHeadNode 是块头的那个begin,用于查询break和continue地址
INSTR_LIST* list = this->m_list;
// 分析目标:离散的label,jmp
// 如果发现 i_CplxBegin, 如果它 begin.type == 0即未被识别,则试图识别
// 如果已经识别,则检查其中的i_Begin_i_End中的东东
assert(firstpos);
assert(endpos);
if (firstpos == endpos)
return false;
POSITION pos = firstpos;
PINSTR p = list->GetNext(pos);
assert(pos);
if (p->type == i_Begin)
{
if (this->Flow_a(p))
return true;
POSITION pos1 = list->Find(p->begin.m_end);
assert(pos1);
return Flow_aa(pBlockHeadNode,pos1,endpos);
}
if (p->type == i_CplxBegin)
{
POSITION pos1 = list->Find(p->begin.m_end);
assert(pos1);
if (Flow_c(p))
{
return true;
}
if (p->begin.type == COMP_unknown)
{ // 这时应该试图识别它
CInstrList_Finger the(list);
if (the.Finger_check_partern(p))
{
//alert("return true");
return true;
}
//alert("return false");
}
return Flow_aa(pBlockHeadNode, pos1, endpos);
}
// 第一步,找到第一个复合指令
if (p->type != i_Jump && p->type != i_Label)
{
assert(pos);
return Flow_aa(pBlockHeadNode, pos, endpos);
}
if (p->type == i_Jump)
{ // 检查是不是break或continue
if (p->jmp.jmp_type == JMP_jmp)
{
if (p->jmp.the_label == pBlockHeadNode->begin.m_break)
{
return Flow_aa(pBlockHeadNode, pos, endpos);
}
if (p->jmp.the_label == pBlockHeadNode->begin.m_conti
&& p != pBlockHeadNode->begin.m_not_conti)
{
return Flow_aa(pBlockHeadNode, pos, endpos);
}
}
}
// 找到了,begin是一个i_Jump 或 i_Label
if (p->type == i_Jump)
{ //it must be jump to follow
PINSTR p1 = p->jmp.the_label; //it jump here
POSITION pos1 = list->Find(p1);
assert(pos1);
while (pos1)
{
if (pos1 == endpos)
break;
if (pos1 == NULL)
{
log_prtl("label = %x",p->jmp.jmpto_off);
}
else if (ifOneStatement(pBlockHeadNode, firstpos,pos1))
{ // 找到一个紧凑结构
Flow_b(pBlockHeadNode, firstpos,pos1);
if (Step_by_Step())
return true; // 可以在这里直接return TRUE了
assert(pos1);
return Flow_aa(pBlockHeadNode, pos1,endpos);
}
//assert(pos1);
list->GetNext(pos1);
}
}
else if (p->type == i_Label)
{
PINSTR p1 = p->label.ref_instr;
POSITION pos1 = list->Find(p1);
while (pos1 && pos1 != endpos)
{
list->GetNext(pos1);
assert(pos1);
if (ifOneStatement(pBlockHeadNode, firstpos,pos1))
{
Flow_b(pBlockHeadNode, firstpos,pos1);
if (Step_by_Step())
return true; // 可以在这里直接return TRUE了
assert(pos1);
return Flow_aa(pBlockHeadNode, pos1,endpos);
}
//assert(pos1);
}
}
return false;
}
/*
有三种分析,一定要分清楚。
一种是,有头有尾,已知这是一个松散的statement,要在其中找到一个个的complex statement
Flow_a(PINSTR phead, INSTR_LIST* list);
对找到的complex,用Flow_b处理
二种,有头有尾,且已知这是一个单一的complex statement,需要自己括自己
Flow_b(INSTR_LIST* list, POSITION firstpos,POSITION endpos);
括住自己后,call一个Flow_c
三种,输入一个单一的complex statement,设法要从中找到包含头的最大的一个statement,并用i_Begin,i_End括起来
再从i_End到尾继续
Flow_c(PINSTR phead, INSTR_LIST* list);
对找到的i_Begin,i_End,用Flow_a继续
*/
// --------------------------------------------------------------
void CFunc_Prt::add_default_entry(CasePrt_List* list, PINSTR thelabel)
{ // delete all same as default
//static function
if (thelabel->type == i_Label)
{
POSITION pos = list->GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
OneCase* p = list->GetNext(pos);
if (p->thelabel->label.label_off == thelabel->label.label_off)
{
//alert_prtf("delete case %d",p->case_n);
list->RemoveAt(savpos);
}
}
}
OneCase* pnew = new OneCase;
pnew->case_n = 0xffffffff; // 不能只检查这一个条件,最后一个才是最重要的
pnew->thelabel = thelabel;
list->AddTail(pnew);
}
void CFunc_Prt::Add_case_entry(CasePrt_List* list, int case_n, PINSTR thelabel)
{ // 必须先把switch case的所有项保存起来,最后一起打印
//alert("add case entry");
//static function
POSITION pos = list->GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
OneCase* p = list->GetNext(pos);
if (p->case_n == case_n)
error("why same case");
if (p->thelabel->label.label_off >= thelabel->label.label_off)
{
pos = savpos;
break;
}
}
OneCase* pnew = new OneCase;
pnew->case_n = case_n;
pnew->thelabel = thelabel;
if (pos)
list->InsertBefore(pos, pnew);
else
list->AddTail(pnew);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -