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

📄 cfuncstep1.cpp

📁 将exe等可执行文件转化成c程序的反编译程序,先到汇编再到c
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    while (pos)
    {
        AsmCode* pasm = m_asmlist->GetNext(pos);
        if (pasm->iAddRemove != 0)
            continue;
        
        XCPUCODE* pxcpu = &pasm->xcpu;
        if (pxcpu->opcode == C_CALL && pxcpu->op[0].mode == OP_Near)
        {
            CFunc* pfunc = g_Cexe2c->GetFunc(pxcpu->op[0].nearptr.offset);
            if (pfunc == NULL)
                continue;
            if (pfunc->m_IfLibFunc && pfunc->m_functype != NULL)
            {
                CFuncType* fctype = pfunc->m_functype;
                if (!strcmp(fctype->m_internal_name, "_EH_prolog"))
                {
                    strcmp(fctype->m_internal_name, "_EH_prolog");
                    pasm->iAddRemove = 1;

                    AsmCode* pnew;
                    //push ebp
                    pnew = AsmCode::new_AsmCode();
                    pnew->iAddRemove = 2;
                    pnew->xcpu.opcode = C_PUSH;
                    pnew->xcpu.op[0].mode = OP_Register;
                    pnew->xcpu.op[0].opersize = 4;
                    pnew->xcpu.op[0].reg.reg_index = _EBP_;
                    m_asmlist->InsertBefore(pos, pnew);

                    //mov ebp, esp
                    pnew = AsmCode::new_AsmCode();
                    pnew->iAddRemove = 2;
                    pnew->xcpu.opcode = C_MOV;
                    pnew->xcpu.op[0].mode = OP_Register;
                    pnew->xcpu.op[0].opersize = 4;
                    pnew->xcpu.op[0].reg.reg_index = _EBP_;
                    pnew->xcpu.op[1].mode = OP_Register;
                    pnew->xcpu.op[1].opersize = 4;
                    pnew->xcpu.op[1].reg.reg_index = _ESP_;
                    m_asmlist->InsertBefore(pos, pnew);

                }
            }
        }
    }
}
void CFuncLL::Prepare_CallFunc()
{//把本函数中call到的函数都prepare一遍
    POSITION pos = m_asmlist->GetHeadPosition();
    while (pos)
    {
        AsmCode* pasm = m_asmlist->GetNext(pos);
        XCPUCODE* pxcpu = &pasm->xcpu;
        if (pxcpu->opcode == C_CALL && pxcpu->op[0].mode == OP_Near)
        {
            CFunc* pfunc = g_Cexe2c->GetFunc(pxcpu->op[0].nearptr.offset);
            if (pfunc == NULL)
                continue;
            pfunc->PrepareFunc();
        }
    }
}
bool	CFuncLL::Fill_Stack_1()
{//为什么总是true呢
    POSITION pos = m_asmlist->GetHeadPosition();
	AsmCode* pasm = 0;
	if (pos)
		pasm = m_asmlist->GetNext(pos);
	while (pos)
	{
		AsmCode* p0 = pasm;
		pasm = m_asmlist->GetNext(pos);
		if (stack_stack(p0,pasm))
			return true;
	}
	return false;
}

bool	CFuncLL::Check_Stack()
//	检查该函数的stack是否平衡
{
	POSITION pos = this->m_asmlist->GetHeadPosition();
	signed int lastesp = 0;	
	while (pos)
	{
		AsmCode* p = this->m_asmlist->GetNext(pos);
		signed int esp = p->esp_level;
		if (esp == ESP_UNKNOWN)
			return false;
		if (lastesp != ESP_UNKNOWN && lastesp != ESP_IGNORE && esp != lastesp)
			return false;

        if (p->xcpu.IsJxx() || p->xcpu.IsJmpNear())
		{
			ea_t jmpto = p->xcpu.op[0].nearptr.offset;
			AsmCode* p = ea2pasm(jmpto);
			if (esp != p->esp_level)
				return false;
		}
		if (p->xcpu.opcode == C_RET)
		{
			if (esp != 0)
				return false;
		}
		lastesp = p->esp_level_next;
	}
	return true;
}

bool	CFuncLL::Fill_Stack_Info()
{
    AsmCode* pasm = this->m_asmlist->GetHead();
    if (pasm->linear == 0x401150)
    {
        pasm->linear = 0x401150;
    }
	pasm->esp_level = 0;	// I know the first one

	for (int i=0;;i++)
	{ //这里会死循环
		if ((i % 1000) == 0)
			nop();
		if ( Fill_Stack_1() )
			continue;
		break;
	} 
	
	if (! Check_Stack())
		return false;

    return true;
}

int CFuncLL::Get_Ret_Purge()
//return -1 for fail
{
	int retn = -1;
	POSITION pos = this->m_asmlist->GetHeadPosition();
	while (pos)
	{
		AsmCode* pasm = this->m_asmlist->GetNext(pos);
		XCPUCODE* pxcpu = &pasm->xcpu;
		if (pxcpu->opcode == C_RET) //找到了ret语句
		{
			int r = 0;
			if (pxcpu->op[0].mode == OP_Immed)	// means RET n
			{
				r = pxcpu->op[0].immed.immed_value;
			}

			if (retn == -1)
				retn = r;
			else if (retn != r) //两个Ret不一致?
				return -1;
		}
	}
	if (retn == -1)
	{
		//alert_prtf("why not find RET ? func = %x", this->m_head_off);
		//myexit(2);
		//return false;
	}
    return retn;
}

CString CFuncLL::GetLabelName(ea_t ea)
{
    CString retn;

    CFunc* pfunc = g_Cexe2c->GetFunc(ea);
    if (pfunc != NULL)
    {
        retn = pfunc->m_funcname;
        return retn;
    }
    AsmCode* pasm = this->ea2pasm(ea);
    if (pasm != NULL && pasm->h.label.ref_j != NULL)
    {
        retn = pasm->h.label.label_name;
        return retn;
    }
    return retn;
}
void	CFuncLL::prtout_asm(CFunc* pfunc, CVarLL* pvarll, CXmlOutPro* out)
{
    out->XMLbegin(XT_Function, pfunc);

    out->XMLbegin(XT_FuncName, pfunc);
    out->prtt(pfunc->m_funcname);
    out->XMLend(XT_FuncName);
    out->prtspace();
    out->prtt("proc");
    out->endline();

    pvarll->prtout(out);

    out->endline();
    
    this->prtout_asm_1(pvarll, out);

    out->XMLbegin(XT_FuncName, pfunc);
    out->prtt(pfunc->m_funcname);
    out->XMLend(XT_FuncName);
    out->prtspace();
    out->prtt("endp");
    out->endline();
    out->XMLend(XT_Function);
}
void	CFuncLL::prtout_asm_1(CVarLL* pvarll, CXmlOutPro* out)
{   //	按运行代码以ASM显示func,对其中的GAP能指出来

	ea_t last = 0xffffffff;
	POSITION pos = this->m_asmlist->GetHeadPosition();
	while (pos)
	{
		AsmCode* pasm = this->m_asmlist->GetNext(pos);
		if (pasm->iAddRemove == 2)
			continue;
		ea_t ea = pasm->linear;

		char	buf[280];
		DWORD n;
		if (pasm->xcpu.opcode == C_JCASE)
		{
			n = 0;
			sprintf(buf,"case jmp to %x",pasm->xcpu.op[0].nearptr.offset);
		}
		else
        {
            st_IDA_OUT idaout;
            CDisasm the;
            //n = the.Disassembler(buf, ea2ptr(ea), ea);
            n = the.Disassembler_X(ea2ptr(ea), ea, &idaout);
            XCPUCODE* pxcpu = the.get_xcpu();
            if (pxcpu->op[0].mode == OP_Near)
            {
                ea_t linear = pxcpu->op[0].nearptr.offset;
                CString labelname = this->GetLabelName(linear);
                if (!labelname.IsEmpty())
                {
                    idaout.Par1Str = labelname;
                }
            }
            else if (pxcpu->op[0].mode == OP_Address)
            {
                OPERITEM* op = &pxcpu->op[0];
                if (op->addr.base_reg_index == _ESP_
                    || (op->addr.base_reg_index == _NOREG_
                        && op->addr.off_reg_index == _ESP_
                        && op->addr.off_reg_scale == 1))
                {
                    signed int level = pasm->esp_level + op->addr.off_value;
                    st_VarLL* p = pvarll->LookUp_VarLL(level- pvarll->m_VarRange_L);
                    if (p != NULL)
                    {
                        idaout.Par1Str += '.';
                        idaout.Par1Str += p->Name;
                    }
                }
            }
            else if (pxcpu->op[1].mode == OP_Address)
            {
                OPERITEM* op = &pxcpu->op[1];
                if (op->addr.base_reg_index == _ESP_
                    || (op->addr.base_reg_index == _NOREG_
                        && op->addr.off_reg_index == _ESP_
                        && op->addr.off_reg_scale == 1))
                {
                    signed int level = pasm->esp_level + op->addr.off_value;
                    st_VarLL* p = pvarll->LookUp_VarLL(level- pvarll->m_VarRange_L);
                    if (p != NULL)
                    {
                        idaout.Par2Str += '.';
                        idaout.Par2Str += p->Name;
                    }
                }
            }
            idaout.output(buf);
        }
		if (last != 0xffffffff && ea != last)
			out->prtl("//      gap here");
        
        if (pasm->h.label.ref_j != NULL)
        {
            //asm_prtl("%s:", pasm->h.label.label_name);
            out->prtf("%s:", pasm->h.label.label_name);
            out->endline();
        }

        //asm_prtl("%4x %x %s",-pasm->esp_level, ea, buf);
        if (pasm->esp_level == ESP_UNKNOWN)
        {
            out->prtt("    ");  //四个空格的位置要留
        }
        else
            out->prtf("%4x", -pasm->esp_level);
        out->prtspace();
        out->XMLbegin(XT_AsmOffset, (void*)ea);
        out->prtf("%x", ea);
        out->XMLend(XT_AsmOffset);
        out->prtt(buf);
        out->endline();

		last = ea+n;
	}
}


void CFuncLL::GetVarRange(signed int& VarRange_L, signed int& VarRange_H)
{
    /*
    如果一个函数开头是:
   0 401010 SUB    ESP,00000190
 190 401016 LEA    ECX,[ESP+00]    
 则 VarRange_L = -190h
 则 VarRange_H = 0
 写作
    0 401010 SUB    ESP,00000190
  190 401016 LEA    ECX,[ESP+v_00]    
    */
    signed int L = 0;
    signed int H = 0;

	POSITION pos = this->m_asmlist->GetHeadPosition();
	while (pos)
	{
		AsmCode* pasm = this->m_asmlist->GetNext(pos);
        signed int last = pasm->esp_level;
        signed int here = pasm->esp_level_next;
        if (pasm->xcpu.opcode == C_SUB || pasm->xcpu.opcode == C_ADD)
        {
            if (last - here > H - L)
            {
                H = last;
                L = here;
            }
        }
    }
    if (H - L > 0)
    {
        VarRange_H = H;
        VarRange_L = L;
    }
}


void CVarLL::prtout(CXmlOutPro* out)
{
    int curlevel = 0;
    int maxlevel = this->m_VarRange_H - this->m_VarRange_L;

    POSITION pos = this->m_varll_list.GetHeadPosition();
    while (pos)
    {
        st_VarLL* p = this->m_varll_list.GetNext(pos);
        if (curlevel > p->off)
        {
            out->prtl("error, var collapse!!!");
            curlevel = p->off;
        }
        else if (curlevel < p->off)
        {
            out->prtl("gap len = %x", p->off - curlevel);
            curlevel = p->off;
        }
        /*asm_prtl("%s equ %s %x", p->Name, 
                 (p->size == 1) ? "BYTE ptr" :
                 (p->size == 2) ? "WORD ptr" :
                 (p->size == 4) ? "DWORD ptr" : "",
                 p->off); */

        out->prtspace(4);
        out->XMLbegin(XT_Symbol, p);
        out->prtt(p->Name);
        out->XMLend(XT_Symbol);
        out->prtt("equ");
        out->prtspace();
        out->prtt((p->size == 1) ? "BYTE ptr" :
                          (p->size == 2) ? "WORD ptr" :
                          (p->size == 4) ? "DWORD ptr" : "");
        out->prtspace();
        if (p->array != 1)
        {
            out->XMLbegin(XT_Number, NULL);
            out->prtf("%xh", p->array);
            out->XMLend(XT_Number);
            out->prtt("dup");
            out->prtspace();
        }
        out->XMLbegin(XT_Number, NULL);
        out->prtf("%xh", p->off);
        out->XMLend(XT_Number);
        out->endline();

        curlevel += p->size * p->array;
    }
    
    if (curlevel < maxlevel)
    {
        out->prtl("    gap len = %xh", maxlevel - curlevel);
    }
}
st_VarLL* CVarLL::LookUp_VarLL(int off)
{
    POSITION pos = this->m_varll_list.GetHeadPosition();
    while (pos)
    {
        st_VarLL* p = this->m_varll_list.GetNext(pos);
        if (p->off == off)
            return p;
    }
    return NULL;
}
void CVarLL::AddRef(signed int level, int opersize)
{
    if (level < this->m_VarRange_H && level >= this->m_VarRange_L)
    {
    }
    else
        return;
    int off = level - this->m_VarRange_L; //这个是>=0的
    st_VarLL* pnew = this->LookUp_VarLL(off);
    if (pnew != NULL)
        return;
    pnew = new st_VarLL;
    pnew->off = off;
    pnew->size = opersize;
    sprintf(pnew->Name, "v_%x", off);

    if (this->m_varll_list.IsEmpty())
    {
        this->m_varll_list.AddTail(pnew);
    }
    else
    {//有序列表
        POSITION pos = this->m_varll_list.GetHeadPosition();
        while (pos)
        {
            POSITION savpos = pos;
            st_VarLL* p = this->m_varll_list.GetNext(pos);
            if (p->off > off)
            {
                this->m_varll_list.InsertBefore(savpos, pnew);
                return;
            }
        }
        this->m_varll_list.AddTail(pnew);
    }

}
void CFuncLL::VarLL_Analysis_1(CVarLL* pvarll, OPERITEM* op, AsmCode* pasm)
{
    if (op->mode != OP_Address)
        return;
	if (op->addr.base_reg_index == _ESP_
        || (op->addr.base_reg_index == _NOREG_
                        && op->addr.off_reg_index == _ESP_
                        && op->addr.off_reg_scale == 1))
    {
        signed int level = pasm->esp_level + op->addr.off_value;
        pvarll->AddRef(level, op->opersize);
    }
	if (op->addr.base_reg_index == _EBP_)
    {
        //怎么写?
    }
}
void CFuncLL::VarLL_Analysis(CVarLL* pvarll)
{
    POSITION pos = this->m_asmlist->GetHeadPosition();
	while (pos)
	{
		AsmCode* pasm = this->m_asmlist->GetNext(pos);
        if (pasm->xcpu.op[0].mode == OP_Address)
            this->VarLL_Analysis_1(pvarll, &pasm->xcpu.op[0], pasm);
        if (pasm->xcpu.op[1].mode == OP_Address)
            this->VarLL_Analysis_1(pvarll, &pasm->xcpu.op[1], pasm);
    }
}

AsmCode* ea2pasm(ea_t ea, AsmCodeList* m_asmlist)
{
	POSITION pos = m_asmlist->GetHeadPosition();
	while (pos)
	{
		AsmCode* p = m_asmlist->GetNext(pos);
		if (p->linear == ea)
			return p;
	}
	assert_msg(0,"whye here");
	return NULL;
}

void CJxxLabel::Label_Analysis()
{
    POSITION pos = this->m_asmlist->GetHeadPosition();
    while (pos)
    {
		AsmCode* p = this->m_asmlist->GetNext(pos);
        assert(p->h.type == i_Nothing);  //以前没对h分析过

        if (p->xcpu.IsJxx() || p->xcpu.IsJmpNear())
		{
			ea_t jmpto = p->xcpu.op[0].nearptr.offset;
			AsmCode* plabel = ea2pasm(jmpto, m_asmlist);

            p->h.type = i_Jump;
            if (p->xcpu.IsJmpNear())
                p->h.jmp.jmp_type = JMP_jmp;
            p->h.jmp.the_label = plabel;

            if (plabel->h.label.ref_j == NULL)
            {
                plabel->h.label.ref_j = p;
                sprintf(plabel->h.label.label_name, "loc_%x", plabel->linear);
            }
            else
            {
                p->h.jmp.next_ref_of_this_label = plabel->h.label.ref_j;
                plabel->h.label.ref_j = p;
            }
		}
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -