⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfunc.cpp

📁 将exe等可执行文件转化成c程序的反编译程序,先到汇编再到c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -