📄 cfunc.cpp
字号:
// Copyright(C) 1999-2005 LiuTaoTao,bookaa@rorsoft.com
#include "stdafx.h"
#include "CISC.H"
#include "cexe2c.h"
#include "CFuncStep1.h"
void fill_func_info( ea_t pos,CFunc* pfnc)
// 填入 CFunc 的一些其它信息
{
sprintf(pfnc->m_funcname,"sub_%x",pos);
}
CFunc::CFunc(ea_t start)
{
m_IfLibFunc = false;
m_VarRange_L = 0; //比如=-40h
m_VarRange_H = 0; //比如= 0
m_head_off = start;
m_nStep = STEP_Init;
m_EBP_base = Not_EBP_based; //invalid
m_stack_purge = 0;
this->ll.m_asmlist = new AsmCodeList; //new_AsmCodeList
this->m_exprs = new CExprManage; //new_CExprManage
m_functype = NULL;
}
CFunc::~CFunc()
{
delete m_instr_list;
if (m_exprs != NULL) delete m_exprs;
delete ll.m_asmlist;
}
void Code_GetArgs(VAR* v,DWORD &maxesp)
{
if (v->type == v_Par)
{
if (v->par_off > maxesp)
maxesp = v->par_off;
}
}
UINT CFunc::GetVaryParaSize(POSITION pos)
{
INSTR_LIST* list = this->m_instr_list;
while (pos)
{
PINSTR pinstr = list->GetNext(pos);
if (pinstr->type == i_EspReport)
{
return pinstr->espreport.howlen;
}
}
return 0;
}
bool CFunc::Func_FillCallParas()
{
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
PINSTR pinstr = list->GetNext(pos);
if (pinstr->type == i_Call)
{
CFuncType* pfctype = pinstr->call.call_func->m_functype;
if (pfctype != NULL && pfctype->m_class != NULL)
{//这是一个ecx->func
PINSTR p = new INSTR; //new_INSTR
p->type = i_CallThis;
p->var_r1.type = v_Reg;
p->var_r1.opsize = BIT32_is_4;
p->var_r1.reg = enum_ECX;
p->call_addon.p_thecall = pinstr;
list->InsertBefore(pos, p); //在i_Call后面加i_CallPara
}
if (pfctype != NULL && pfctype->m_args != 0)
{
PINSTR p = new INSTR; //new_INSTR
p->type = i_CallPara;
p->call_addon.p_thecall = pinstr;
pinstr->call.p_callpara = p;
p->var_r1.type = v_Var;
UINT parasize = pfctype->para_total_size();
if (pfctype->m_varpar)
{
parasize = GetVaryParaSize(pos);
}
p->var_r1.opsize = parasize;
p->var_r1.var_off = stack2varoff(pinstr->call.esp_level);
list->InsertBefore(pos, p); //在i_Call后面加i_CallPara
}
//怎么说?call的返回值会影响eax
{//在每一个call后面加i_CallRet是没有问题的。如果这个函数没有返加值,
//这个i_CallRet肯定会被优化掉
PINSTR p = new INSTR; //new_INSTR
p->type = i_CallRet;
p->call_addon.p_thecall = pinstr;
pinstr->call.p_callret = p;
p->var_w.type = v_Reg;
p->var_w.opsize = BIT32_is_4;
p->var_w.reg = enum_EAX;
list->InsertBefore(pos, p); //在i_Call后面加i_CallRet
}
}
if (pinstr->type == i_CallApi)
{
CApi* papi = pinstr->call.papi;
if (papi != NULL)
{
if (papi->m_functype->para_total_size() != 0)
{
PINSTR p = new INSTR; //new_INSTR
p->type = i_CallPara;
p->call_addon.p_thecall = pinstr;
pinstr->call.p_callpara = p;
p->var_r1.type = v_Var;
p->var_r1.opsize = papi->m_functype->para_total_size();
p->var_r1.var_off = stack2varoff(pinstr->call.esp_level);
list->InsertBefore(pos, p); //在i_Call后面加多个i_CallPara
}
}
//关于返回值
if (papi != NULL)
{
int n = GG_VarType_ID2Size(papi->m_functype->m_retdatatype_id);
if (n == 4 || n == 2 || n == 1)
{
PINSTR p = new INSTR; //new_INSTR
p->type = i_CallRet;
p->call_addon.p_thecall = pinstr;
pinstr->call.p_callret = p;
p->var_w.type = v_Reg;
p->var_w.opsize = n;
p->var_w.reg = enum_EAX;
list->InsertBefore(pos, p); //在i_Call后面加i_CallRet
}
}
}
}
return true;
}
bool CFunc::Step5_GetArgs()
{
if (this->m_stack_purge != 0)
{
this->m_args = m_stack_purge / 4;
return true;
}
DWORD maxesp = 0;
POSITION pos = this->m_instr_list->GetHeadPosition();
while (pos)
{
PINSTR p = this->m_instr_list->GetNext(pos);
Code_GetArgs(&p->var_w,maxesp); //change maxesp if need
Code_GetArgs(&p->var_r1,maxesp);
Code_GetArgs(&p->var_r2,maxesp);
}
this->m_args = maxesp / 4;
return true;
}
bool CFunc::Step2_GetRetPurge()
{
if (this->m_IfLibFunc)
return false;
CFuncLL the(this->ll.m_asmlist);
int retn = the.Get_Ret_Purge();
if (retn == -1)
{
return false;
}
m_stack_purge = retn;
return true;
}
bool CFunc::AddRemoveSomeInstr()
{
CFuncLL the(this->ll.m_asmlist);
the.AddRemoveSomeInstr();
return true;
}
bool CFunc::Step3_FillStackInfo()
{ // 填入stack信息,检查是否平衡。如yes,则nStep = 3
// 如果CFunc是ebp based,一般ebp设一次就不再变,所以可把ebp_based量存CFunc内
m_EBP_base = Not_EBP_based; //invalid
CFuncLL the(this->ll.m_asmlist);
if (this->m_prepareTrue_analysisFalse == false)
{
the.Prepare_CallFunc();
}
if (!the.Fill_Stack_Info())
{
return false;
}
m_EBP_base = the.Get_EBP_base();
the.GetVarRange(this->m_VarRange_L, this->m_VarRange_H);
if (this->m_VarRange_H - this->m_VarRange_L > 0)
{
this->m_varll.Init(this->m_VarRange_L, this->m_VarRange_H);
the.VarLL_Analysis(&this->m_varll);
}
this->m_exprs->m_VarRange_H = this->m_VarRange_H;
this->m_exprs->m_VarRange_L = this->m_VarRange_L;
return true;
}
bool IfValideFuncName(PCSTR pname)
{
if (pname == NULL)
return false;
if (*pname == 0 )
return false;
char c = *pname;
if ( c>='a' && c<='z' )
return true;
if ( c>='A' && c<='Z' )
return true;
if ( c=='_' || c=='~')
return true;
return false;
}
bool VAR::IsSame(VAR* v1,VAR* v2)
{
return (VarCompare(v1,v2) == 1);
}
int VAR::VarCompare(VAR* v1,VAR* v2)
{
// 0: no relationship
// 1: same
// 2: v1 include v2
// 3: v2 include v1
if (v1->type != v2->type)
return 0;
//if (v1->opsize != v2->opsize)
// return false;
DWORD off1,off2;
BYTE siz1 = v1->opsize;
BYTE siz2 = v2->opsize;
switch (v1->type)
{
case v_Volatile:
return 1; //same
case v_Reg:
off1 = v1->reg;
off2 = v2->reg;
break;
case v_Immed:
off1 = v1->d;
off2 = v2->d;
break;
case v_Global:
off1 = v1->off;
off2 = v2->off;
break;
case v_Par:
off1 = v1->par_off;
off2 = v2->par_off;
break;
case v_Var:
off1 = v1->var_off;
off2 = v2->var_off;
break;
case v_Tem:
if (v1->temno != v2->temno)
return false;
if (siz1 != siz2)
return false;
return true;
default:
return false;
}
if (off1 > off2)
{
if (off2 + siz2 > off1)
{
return 3; // 3: v2 include v1
}
}
else if (off1 < off2)
{
if (off1 + siz1 > off2)
{
return 2; // 2: v1 include v2
}
}
else
{ // off1 == off2
if (siz1 == siz2)
return 1; // same
else if (siz1 > siz2)
return 2; // 2: v1 include v2
else
return 3; // 3: v2 include v1
}
return 0;
}
// 在phead所指的complex中,找到第no个statement
PINSTR CFunc::Get_no_Statement(PINSTR phead,int no)
{
PINSTR p = phead;
while (p)
{
p = instr_next(this->m_instr_list,p);
if (p == NULL || p == phead->begin.m_end)
return NULL;
assert(p->type != i_CplxBegin); // 不该在这里遇到这个
if (p->type == i_Begin)
{
if ( no == 0 )
return p;
p = p->begin.m_end;
no--; // 计数,算一个
}
}
return NULL;
}
void CFunc::MakeDownInstr(void* hline)
{
PINSTR p0 = (PINSTR)hline;
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
POSITION savpos = pos;
PINSTR pinstr = list->GetNext(pos);
if (pinstr == p0 && pos != NULL)
{
list->RemoveAt(savpos);
list->InsertAfter(pos, pinstr);
return;
}
}
}
void prt_partern(INSTR_LIST* list,PINSTR phead,PSTR partern_buf);
PCSTR hlcode_name(HLType t)
{
switch (t)
{
case i_Jump: return("i_Jump ");
case i_Label: return("i_Label ");
case i_Begin: return("i_Begin ");
case i_End: return("i_End ");
case i_Assign: return("i_Assign ");
case i_Var: return("i_Var ");
case i_Unknown: return("i_Unknown ");
case i_RetPar: return("i_RetPar ");
case i_Return: return("i_Return ");
case i_Add: return("i_Add ");
case i_Sub: return("i_Sub ");
case i_Xor: return("i_Xor ");
case i_Sar: return("i_Sar ");
case i_And: return("i_And ");
case i_Imul: return("i_Imul ");
case i_Readpointto: return("i_Readpointto ");
case i_Writepointto:return("i_Writepointto");
case i_Cmp: return("i_Cmp ");
case i_Test: return("i_Test ");
case i_Lea: return("i_Lea ");
case i_Address: return("i_Address ");
case i_Call: return("i_Call ");
case i_CallApi: return("i_CallApi ");
case i_CallPara: return("i_CallPara ");
case i_CallThis: return("i_CallThis ");
case i_CallRet: return("i_CallRet ");
case i_CplxBegin: return("i_CplxBegin ");
case i_CplxEnd: return("i_CplxEnd ");
case i_Nop: return("i_Nop ");
case i_JmpAddr: return("i_JmpAddr ");
case i_SignExpand: return("i_SignExpand ");
case i_NosignExpand:return("i_NosignExpand");
case i_GetAddr: return("i_GetAddr ");
case i_EspReport: return("i_EspReport ");
default:
{
static char buf[80];
sprintf(buf, "unknown %x", t);
return(buf);
}
}
//return NULL; //never here
}
void CFunc::report_info()
{
log_prtl("func name = %s", this->m_funcname);
log_prtl("func linear address = %x", this->m_head_off);
if (m_VarRange_L >= 0)
log_prtl("func m_VarRange_L = %x", this->m_VarRange_L);
else
log_prtl("func m_VarRange_L = -%x", -this->m_VarRange_L);
if (m_VarRange_H >= 0)
log_prtl("func m_VarRange_H = %x", this->m_VarRange_H);
else
log_prtl("func m_VarRange_H = -%x", -this->m_VarRange_H);
}
PCSTR my_itoa(int i);
CString PrtAddOn_internal(PCSTR varname, Pst_InstrAddOn pAddOn)
//SuperC_func: 只在<CFunc::prtout_internal>中使用
{
if (pAddOn == NULL)
return varname;
switch (pAddOn->type)
{
case IA_Nothing:
return varname;
case IA_ReadPointTo:
{
CString retn = "*";
retn += PrtAddOn_internal(varname,pAddOn->pChild);
return retn;
}
case IA_AddImmed:
{
CString retn = "(";
retn += PrtAddOn_internal(varname,pAddOn->pChild);
retn += " + ";
retn += my_itoa(pAddOn->addimmed.iAddon);
retn += ")";
return retn;
}
case IA_MulImmed:
{
CString retn = "";
retn += PrtAddOn_internal(varname,pAddOn->pChild);
retn += " * ";
retn += my_itoa(pAddOn->addimmed.iAddon);
retn += "";
return retn;
}
case IA_GetAddress:
{
CString retn = "&";
retn += PrtAddOn_internal(varname,pAddOn->pChild);
return retn;
}
default:
return "Error_PrtAddOn";
}
}
void CFunc::prtout_internal(CXmlOutPro* out)
{
if (this->m_instr_list == NULL)
return;
INSTR_LIST* list = this->m_instr_list;
POSITION pos = list->GetHeadPosition();
while (pos)
{
PINSTR p = list->GetNext(pos);
if (p->type == i_End || p->type == i_CplxEnd)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -