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

📄 cfuncstep1.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"

static void	Add_in_order(EALIST *list, ea_t i)
{
	if (list->IsEmpty())
	{
		list->AddHead(i);
		return;
	}
	POSITION pos = list->GetHeadPosition();
	while (pos)
	{
		POSITION savpos = pos;
		ea_t ea = list->GetNext(pos);
		if (ea == i)
			return;		//	已经有了,就算了
		if (ea > i)
		{
			list->InsertBefore(savpos,i);
			return;
		}
	}
    list->AddTail(i);
}

void    CFuncStep1::check_if_switch_case(ea_t cur_off, CaseList* pcaselist,EALIST* pjxxlist,
                                         XCPUCODE* pxcpu)
{//static function
	if (pxcpu->opcode != C_JMP)
		return;
	if (pxcpu->op[0].mode != OP_Address)
		return;
	if (pxcpu->op[0].addr.base_reg_index != _NOREG_)
		return;
	if (pxcpu->op[0].addr.off_reg_index == _NOREG_)
		return;
	if (pxcpu->op[0].addr.off_reg_scale != 4)
		return;
	if (pxcpu->op[0].addr.off_value <= 0x401000)
		return;
	//alert("switch case find 1");
	//Code_SwitchCase1();

	ea_t ptbl = pxcpu->op[0].addr.off_value;
	//alert_prtf("table is %x",ptbl);
	if (! IfInWorkSpace(ptbl))
		return;		//	确认这个table有效
	
	//alert("switch case find 2");

	ea_t d = Peek_D(ptbl);
	if (! IfInWorkSpace(d))
		return;		//	确认第一条有效
	
	//alert("switch case find 3");

	ea_t break_off = 0;	//	下面,要确定break_off的值
	POSITION pos = pjxxlist->GetHeadPosition();
	while (pos)
	{
		ea_t ea = pjxxlist->GetNext(pos);
		if (ea > cur_off)
		{
			break_off = ea;
			break;
		}
	}
	if (break_off == 0)
		return;		//	没找到条件跳?不对劲
	
	//alert("switch case find 4");


	//if (pjxx->jmp.jmp_type != JMP_ja)
	//	return;		//	不是ja,也不对
	if (d < cur_off || d > break_off)
		return;		//	第一个就没对准,不行

	//alert("switch case find 5");

	//alert("rreally switch case");
	CASE_t *pnew = new CASE_t;
	pnew->jxx_opcode = cur_off;
	pnew->caselist = new EALIST;
	pcaselist->AddHead(pnew);

	for (int i=0;;i++)
	{
		d = Peek_D(ptbl+i*4);
//		if (! IfInWorkSpace(d))
		if (d < cur_off || d > break_off)
			break;
		Add_in_order(pjxxlist,d);
		pnew->caselist->AddTail(d);
	}
}

static bool	any_free_ea(EALIST *jxxlist, EALIST *usedlist, ea_t* pea)
{
	POSITION pos = jxxlist->GetHeadPosition();
	while (pos)
	{
		ea_t ea = jxxlist->GetNext(pos);
		if (! usedlist->Find(ea))
		{
			*pea = ea;
			return true;
		}
	}
	return false;
}
void CFuncStep1::CheckIfJustSwitchCase(CaseList& caselist, ea_t ea)
{
    POSITION pos1 = caselist.GetHeadPosition();
    while (pos1)
    {
        CASE_t *p1 = caselist.GetNext(pos1);
        if (p1->jxx_opcode == ea)	//	really
        {	//	now, add some jcase instruction
            POSITION pos2 = p1->caselist->GetHeadPosition();
            while (pos2)
            {
                ea_t case_ea = p1->caselist->GetNext(pos2);
                assert(case_ea);

                AsmCode *pnew = AsmCode::new_AsmCode();
                pnew->linear = ea;
                pnew->xcpu.opcode = C_JCASE;
                pnew->xcpu.op[0].mode = OP_Near;
                pnew->xcpu.op[0].nearptr.offset = case_ea;
                this->m_asmlist->AddTail(pnew);
                //alert("insert 1 C_JCAES");
            }
            break;	//	only one can be true
        }
    }
}

void CFuncStep1::CreateNewFunc_if_CallNear()
{
	POSITION pos1 = m_asmlist->GetHeadPosition();
	while (pos1)
	{
		AsmCode* pasm = m_asmlist->GetNext(pos1);
		XCPUCODE* pxcpu = &pasm->xcpu;
		if ( pxcpu->opcode == C_CALL && pxcpu->op[0].mode == OP_Near)
		{
			//log_prtl("find Call %x",xcpu.op[0].nearptr.offset);
			g_Cexe2c->func_new(pxcpu->op[0].nearptr.offset);
		}
	}
}
bool	CFuncStep1::Step_1(ea_t head_off)
// 找到函数结束地址,生成asm opcode list
{
	//assert(m_nStep == 0);

	CaseList caselist;
	EALIST jxxlist;
	EALIST usedlist;


    ea_t ea = head_off;
    assert(ea < 0x10000000);
    assert(ea >= 0x400000);

	jxxlist.AddHead(ea);

    while (any_free_ea(&jxxlist,&usedlist,&ea))
    {	//	走遍所有的jxx
		for (;;)
		{
			Add_in_order(&usedlist,ea);

            CDisasm the;
			the.Disasm_OneCode(ea); //ea会递增的

			if (the.get_xcpu()->IsJxx() || the.get_xcpu()->IsJmpNear())
			{
				Add_in_order(&jxxlist, the.get_xcpu()->op[0].nearptr.offset);
			}
			else
			{
				check_if_switch_case(ea,&caselist,&jxxlist, the.get_xcpu());
			}
			if (the.get_xcpu()->opcode == C_RET || the.get_xcpu()->opcode == C_JMP )
				break;
			if (usedlist.Find(ea))
				break;
		}
    }

	POSITION pos = usedlist.GetHeadPosition();
	while (pos)
	{	//	生成asm opcode list
		if (this->m_asmlist == NULL)
		{
			this->m_asmlist = new AsmCodeList;
		}
		
		ea_t ea = usedlist.GetNext(pos);
		AsmCode *p = AsmCode::new_AsmCode();
		p->linear = ea;

        CDisasm the;
		p->opsize = the.Disasm_OneCode(ea);
		p->xcpu = *the.get_xcpu();

		this->m_asmlist->AddTail(p);

		//	查找是不是刚过一个swith case
        this->CheckIfJustSwitchCase(caselist, ea);
	}

	AsmCode *pasm = this->m_asmlist->GetTail();
	m_end_off = pasm->linear + pasm->opsize;
	return true;
}

//==========================================

static bool	isLeave(AsmCode* p)
{	//	如果是leave或mov esp,??之类的指令,则当前stack状态对后面没有影响
	if (p->xcpu.opcode == C_LEAVE)
		return true;
	if (p->xcpu.opcode == C_MOV
		&& (p->xcpu.op[0].mode == OP_Register)
		&& (p->xcpu.op[0].reg.reg_index == _ESP_)	//mov esp,ebp
		)
		return true;
	return false;
}

AsmCode* CFuncLL::ea2pasm(ea_t ea)
{
	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;
}
bool	CFuncLL::stack_stack(AsmCode* p0, AsmCode* p1)
{	//	只要干了任何一件有意义的事,就 return true
    signed int & esp0 = p0->esp_level;
    signed int & esp0_next = p0->esp_level_next;
    signed int & esp1 = p1->esp_level;

	//	首先,是p0自身的建设-------
    if (isLeave(p0))
	{	//p0自身的esp和esp_next无关的情况
		if (esp0_next == ESP_UNKNOWN)
		{
			signed int esp = ESP_UNKNOWN;
			if (Asm_Code_Change_ESP(esp, &p0->xcpu))
			{
				esp0_next = esp;
				return true;
			}
		}
	}
	else
	{
		if (esp0_next == ESP_UNKNOWN)
		{
			if (p0->xcpu.opcode == C_JMP || p0->xcpu.opcode == C_RET)
			{
				esp0_next = ESP_IGNORE;
				return true;
			}
			if (esp0 != ESP_UNKNOWN)
			{
				signed int esp = esp0;
				if ( Asm_Code_Change_ESP(esp, &p0->xcpu) )
				{
					esp0_next = esp;
					return true;
				}
			}
		}
		if (esp0_next != ESP_UNKNOWN
			&& (esp0_next != ESP_IGNORE)
			&& (esp0 == ESP_UNKNOWN)
			)	// 反查
		{
			signed int esp = 0;
			if ( Asm_Code_Change_ESP(esp, &p0->xcpu) )
			{
				//esp0_next = esp0 + esp;
				esp0 = esp0_next - esp;
				return true;
			}
		}
		if (esp0 != ESP_UNKNOWN
			&& esp0_next != ESP_UNKNOWN
			&& p0->xcpu.opcode == C_CALL
			&& p0->xcpu.op[0].mode == OP_Address
			&& p0->xcpu.op[0].addr.base_reg_index == _NOREG_
			&& p0->xcpu.op[0].addr.off_reg_index == _NOREG_
			)
		{
			ea_t address = p0->xcpu.op[0].addr.off_value;
			CApi *papi = g_ApiManage->get_api(address);	//find it
			if (papi)
			{
				if (esp0_next != esp0 + papi->m_stack_purge)
					return false;	//find error
			}
			else
			{	//not find, insert it
                alert_prtf("error not find api %x", address);
				g_ApiManage->new_api(address,esp0_next - esp0);
				return true;
			}
		}
	}

	// Jmp -------------------------
    if (p1->xcpu.IsJxx() || p1->xcpu.IsJmpNear())
	{
		ea_t jmpto = p1->xcpu.op[0].nearptr.offset;
		AsmCode* p = ea2pasm(jmpto);
		if (p->esp_level == ESP_UNKNOWN && esp1 != ESP_UNKNOWN)
		{
			p->esp_level = esp1;
			return true;
		}
		if (p->esp_level != ESP_UNKNOWN && esp1 == ESP_UNKNOWN)
		{
			esp1 = p->esp_level;
			return true;
		}
		if (p->esp_level != ESP_UNKNOWN && esp1 != ESP_UNKNOWN)
		{
			if (p->esp_level != esp1)
				return false;
		}
	}
	// -----------------------------------
	if (p1->xcpu.opcode == C_RET)
	{
		if (esp1 == ESP_UNKNOWN)
		{
			esp1 = 0;
			return true;
		}
		if (esp1 != 0)
			return false;
	}
	// -----------------------------------
	if (esp0_next == ESP_UNKNOWN && esp1 != ESP_UNKNOWN)
	{
		esp0_next = esp1;
		return true;
	}
	if (esp0_next != ESP_UNKNOWN
		&& esp0_next != ESP_IGNORE
		&& esp1 == ESP_UNKNOWN)
	{
		esp1 = esp0_next;
		return true;
	}
	if (esp0_next != ESP_UNKNOWN
		&& esp0_next != ESP_IGNORE
		&& esp1 != ESP_UNKNOWN)
	{	//do some check
		if (esp0_next != esp1)
			return false;
	}
	return false;
}
ea_t FindApiAddress_Reg(DWORD regindex, XCPUCODE* pxcpu1, AsmCodeList* asmlist)
{
    //意思是,我要正确处理call eax
    //到前面去找一个mov eax, [405070]
    ea_t retn = 7;

	POSITION pos = asmlist->GetHeadPosition();
	while (pos)
	{
		AsmCode* p = asmlist->GetNext(pos);
        XCPUCODE* pxcpu = &p->xcpu;
		if (pxcpu == pxcpu1)
			return retn;
        if (pxcpu->opcode == C_MOV
            && pxcpu->op[0].mode == OP_Register
            && pxcpu->op[0].reg.reg_index == regindex)
        {
            if (pxcpu->op[1].mode == OP_Address 
                && pxcpu->op[1].addr.base_reg_index == _NOREG_ 
                && pxcpu->op[1].addr.off_reg_index == _NOREG_
                )   //call [405070]
            {
                ea_t address = pxcpu->op[1].addr.off_value;
                retn = address;
            }
        }
	}
    return retn;
}
bool	CFuncLL::Asm_Code_Change_ESP(int &esp, XCPUCODE* pxcpu)
{//算出来esp,就return true
	//	让我们假定一个func中只出现一次mov ebp,esp
	if (pxcpu->opcode == C_MOV
        && (pxcpu->op[0].mode == OP_Register)
        && (pxcpu->op[0].reg.reg_index == _ESP_)
        && (pxcpu->op[1].mode == OP_Register)
        && (pxcpu->op[1].reg.reg_index == _EBP_))
    {
        if (this->m_EBP_base != Not_EBP_based
            && esp == ESP_UNKNOWN)
        {
            esp = this->m_EBP_base;	//mov esp,ebp
            return true;
        }
    }
	if (pxcpu->opcode == C_MOV
        && (pxcpu->op[0].mode == OP_Register)
        && (pxcpu->op[0].reg.reg_index == _EBP_)
        && (pxcpu->op[1].mode == OP_Register)
        && (pxcpu->op[1].reg.reg_index == _ESP_))
    {
        if (esp != ESP_UNKNOWN
            && this->m_EBP_base == Not_EBP_based)
        {
            this->m_EBP_base = esp;		//mov ebp,esp
            return true;
        }
    }

	if (pxcpu->opcode == C_LEAVE)
	{
		esp = m_EBP_base;	//	mov	esp,ebp
		esp += 4;		//	pop	ebp
	}
	if (pxcpu->opcode == C_PUSH)
		esp -= 4;
	if (pxcpu->opcode == C_POP)
		esp += 4;
	if (pxcpu->opcode == C_SUB)
		if (pxcpu->op[0].mode == OP_Register)
			if (pxcpu->op[0].reg.reg_index == _ESP_)
				if (pxcpu->op[1].mode == OP_Immed)
				{
					esp -= pxcpu->op[1].immed.immed_value;
				}
	if (pxcpu->opcode == C_ADD)
		if (pxcpu->op[0].mode == OP_Register)
			if (pxcpu->op[0].reg.reg_index == _ESP_)
				if (pxcpu->op[1].mode == OP_Immed)
				{
					esp += pxcpu->op[1].immed.immed_value;
				}

	if (pxcpu->opcode == C_CALL)
	{
		if (pxcpu->op[0].mode == OP_Near)
		{
			CFunc* pfunc = g_Cexe2c->GetFunc(pxcpu->op[0].nearptr.offset);
			if (pfunc == NULL)
                return false;
			if (pfunc->m_IfLibFunc)
			{
				//esp += pfunc->m_stack_purge;
				assert(pfunc->m_functype);
				esp += pfunc->m_functype->get_stack_purge();
		        return true;
			}
			if (pfunc->m_nStep < STEP_IDA_1)
				return false;
			esp += pfunc->m_stack_purge;
            return true;
		}
        if (pxcpu->opcode == C_CALL &&
            pxcpu->op[0].mode == OP_Address &&
            pxcpu->op[0].addr.base_reg_index == _NOREG_ &&
            pxcpu->op[0].addr.off_reg_index == _NOREG_
            )   //call [405070]
        {
            ea_t address = pxcpu->op[0].addr.off_value;
            CApi* papi = g_ApiManage->get_api(address);//,stacksub))	//find it
            if (papi)
            {
                esp += papi->m_stack_purge;
                return true;
            }
        }
        if (pxcpu->opcode == C_CALL &&
            pxcpu->op[0].mode == OP_Register
            )   //call eax
        {
            ea_t address = FindApiAddress_Reg(pxcpu->op[0].reg.reg_index, pxcpu, this->m_asmlist);
            CApi* papi = g_ApiManage->get_api(address);//,stacksub))	//find it
            if (papi)
            {
                esp += papi->m_stack_purge;
                return true;
            }
        }
        return false;
	}
    if (esp == ESP_UNKNOWN)
        return false;
	return true;
	//	影响stack的有这几种情况:
	//	enter leave
	//	push ebp,mov ebp,esp,.....,mov esp,ebp,pop ebp
	//	push,pop
	//	call near
	//	ret时检查是否已平衡
	//	对call	[immed]等,暂不考虑s
}



void CFuncLL::AddRemoveSomeInstr()
{
    POSITION pos = m_asmlist->GetHeadPosition();

⌨️ 快捷键说明

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