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

📄 disasm.cpp

📁 将exe等可执行文件转化成c程序的反编译程序,先到汇编再到c
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		op->farptr.segment= PeekW(codebuf+2);
	}
	else
	{
		op->farptr.offset = PeekD(codebuf);
		op->farptr.segment= PeekW(codebuf+4);
	}

	if (U_Size == BIT16)
		sprintf(outbuf,"%04X:%04X",op->farptr.segment,op->farptr.offset);
	else
		sprintf(outbuf,"%04X:%08X",op->farptr.segment,op->farptr.offset);

	return op->opersize;
}

/***********************************************************/

DWORD	CDisasm::ProcessOpdata(DWORD opdata,POPERITEM op,PSTR outbuf,DWORD codepos)
{
    if (BaseAddress == 0x4011cb)
    {
        BaseAddress = 0x4011cb;
    }

	op->mode		= OP_Invalid;
	switch(opdata)
	{
	case D_NONE:
		break;
		
	case D_EB:
	case D_EW:
	case D_EV:

		if (opdata == D_EB)
			op->opersize = Global_GetSize(SIZE_B);
		else if (opdata == D_EW)
			op->opersize = Global_GetSize(SIZE_W);
		else
			op->opersize = Global_GetSize(SIZE_V);
		
		return Global_MODRM(outbuf,UasmCode+CodeCount,op);

	case D_GB:
	case D_GW:
	case D_GV:

		if (opdata == D_GB)
			op->opersize = Global_GetSize(SIZE_B);
		else if (opdata == D_GW)
			op->opersize = Global_GetSize(SIZE_W);
		else
			op->opersize = Global_GetSize(SIZE_V);
		
		return Global_REG(outbuf,UasmCode+CodeCount,op);

	case D_IB:
	case D_IW:
	case D_IV:

		if (opdata == D_IB)
			op->opersize = Global_GetSize(SIZE_B);
		else if (opdata == D_IW)
			op->opersize = Global_GetSize(SIZE_W);
		else
			op->opersize = Global_GetSize(SIZE_V);
		
		return Global_IMMED(outbuf,UasmCode+codepos,op);

	case D_SB:
		op->opersize = Global_GetSize(SIZE_B);
		return Global_SIGNEDIMMED(outbuf,UasmCode+codepos,op);
	
	case D_SW:
		op->opersize = Global_GetSize(SIZE_W);
		return Global_SREG(outbuf,UasmCode+CodeCount,op);

	case D_MV:
	case D_MP:
	case D_MA:

		if (opdata == D_MV)
			op->opersize = Global_GetSize(SIZE_V);
		else if (opdata == D_MP)
			op->opersize = Global_GetSize(SIZE_P);
		else
			op->opersize = Global_GetSize(SIZE_A);
	
		return Global_MEMORY(outbuf,UasmCode+CodeCount,op);

	case D_OB:
	case D_OV:
		if (opdata == D_OB)
			op->opersize = Global_GetSize(SIZE_B);
		else
			op->opersize = Global_GetSize(SIZE_V);

		return Global_OFFSET(outbuf,UasmCode+codepos,op);

	case D_JB:
		op->opersize = 1;
		return Global_NEARPTR(outbuf,UasmCode+CodeCount,op);
	
	case D_JV:
		op->opersize = (U_Size == BIT32) ? 4 : 2;
		return Global_NEARPTR(outbuf,UasmCode+CodeCount,op);

	case D_JP:
		op->opersize = Global_GetSize(SIZE_P);
		return Global_FARPTR(outbuf,UasmCode+CodeCount,op);
		
	case D_RD:
	case D_CD:
	case D_DD:
		// Not support now
		SetError(ERR_INVALIDCODE);
		break;

	case D_1:
		op->mode			= OP_Immed;
		op->opersize		= 1;
		op->immed.immed_value= 1;
		strcpy(outbuf,"1");
		break;

	case D_AL:
	case D_CL:
	case D_DL:
	case D_BL:
	case D_AH:
	case D_CH:
	case D_DH:
	case D_BH:
		op->mode			= OP_Register;
		op->opersize		= Global_GetSize(SIZE_B);
		op->reg.reg_index	= opdata-D_AL;
		strcpy(outbuf,RegByte[opdata-D_AL]);
		break;
		
	case D_AX:
	case D_CX:
	case D_DX:
	case D_BX:
	case D_SP:
	case D_BP:
	case D_SI:
	case D_DI:	
		op->mode			= OP_Register;
		op->opersize		= Global_GetSize(SIZE_W);
		op->reg.reg_index	= opdata-D_AX;
		strcpy(outbuf,RegWord[opdata-D_AX]);
		break;

	case D_AXV:
	case D_CXV:
	case D_DXV:
	case D_BXV:
	case D_SPV:
	case D_BPV:
	case D_SIV:
	case D_DIV:	
		op->mode			= OP_Register;
		op->opersize 		= Global_GetSize(SIZE_V);
		op->reg.reg_index	= opdata-D_AXV;

		if (op->opersize == 2)
			strcpy(outbuf,RegWord[opdata-D_AXV]);
		else
			strcpy(outbuf,RegDWord[opdata-D_AXV]);
		
		break;

	case D_ES:
	case D_CS:
	case D_SS:
	case D_DS:
	case D_FS:
	case D_GS:
		op->mode			= OP_Segment;
		op->opersize 		= Global_GetSize(SIZE_V);
		op->sreg.sreg_index	= opdata-D_ES;
		strcpy(outbuf,SegReg[opdata-D_ES]);
		break;
	}
	return 0;
}

CString	CDisasm::ProcessSegPrefix(POPERITEM op)
{
    CString retn;
	if (op->mode != OP_Address)
		return retn;

	DWORD	defseg = _DS_;
	if (op->addr.base_reg_index == _EBP_ || op->addr.base_reg_index == _ESP_)
		defseg = _SS_;

	if (SegPrefix != _NOSEG_ && SegPrefix != defseg)
	{
		retn = SegReg[SegPrefix];
		retn += ':';
		defseg = SegPrefix;
	}

	op->addr.seg_index = (BYTE)defseg;
	SegPrefix = _NOSEG_;
    return retn;
}

void	CDisasm::ProcessInstruction(	DWORD	opcode,
							PSTR	instname,
							DWORD	opdata1,
							DWORD	opdata2,
							DWORD	opdata3)
{
	if (opcode == C_ERROR)
	{
		SetError(ERR_INVALIDCODE);
		return;
	}

	// Process LOCK and REPZ/REPNZ prefix
	if (LockPrefix != NOPREFIX)
	{
        this->m_idaout->LockName = LockName;
		//Putchs(LockName);
		//SetBufPtrTox2();
	}
	if (RepPrefix != NOPREFIX)
	{
        this->m_idaout->RepName = RepName;
		//Putchs(RepName);
		//SetBufPtrTox2();
	}

	xcpu.opcode		= (OPCODETYPE)opcode;
	xcpu.lockflag	= (BYTE)LockPrefix;
	xcpu.repeatflag	= (BYTE)RepPrefix;

	// Process DIFFERENTNAME opcode-property
	switch(opcode)
	{
    case C_CBW: 
        this->m_idaout->CmdStr = (OpSize == BIT16) ? instname : "CWDE";
        break;
		
    case C_CWD:
        this->m_idaout->CmdStr = (OpSize == BIT16) ? instname : "CDQ";
        break;

    case C_JCXZ:
        this->m_idaout->CmdStr = (OpSize == BIT16) ? instname : "JECXZ";
        break;

    default:
        this->m_idaout->CmdStr = instname;
        switch(opdata1)
        {
        case D_V:
            if (OpSize == BIT32)
                this->m_idaout->CmdStr += 'D';
            break;

        case D_XB:
            this->m_idaout->CmdStr += 'B';
            break;

        case D_XV:
            if (OpSize == BIT32)
                this->m_idaout->CmdStr += 'D';
            else
                this->m_idaout->CmdStr += 'W';
            break;
        }
	}
	// Ok, now we have completed processing InstName

	//SetBufPtrTox2();

	// Now we begin to process opdata
	char	outbuf1[128];
	char	outbuf2[128];
	char	outbuf3[128];

	DWORD	codelen = CodeCount;
	codelen += ProcessOpdata(opdata1,&xcpu.op[0],outbuf1,codelen);
	codelen += ProcessOpdata(opdata2,&xcpu.op[1],outbuf2,codelen);
	codelen += ProcessOpdata(opdata3,&xcpu.op[2],outbuf3,codelen);
	// Ok, we have output the result of disassemble based on OPERITEM.

	if (xcpu.op[0].mode != OP_Invalid)
	{
		// Process 1st Opdata WORD PTR prefix
		if (xcpu.op[0].mode == OP_Address &&
			xcpu.opcode != C_JMP &&
			xcpu.opcode != C_CALL &&
			xcpu.opcode != C_JMPFAR &&
			xcpu.opcode != C_CALLFAR &&
			(xcpu.op[1].mode == OP_Immed || xcpu.op[1].mode == OP_Invalid) )
		{
			switch(xcpu.op[0].opersize)
			{
            case 1:
                this->m_idaout->Par1Ptr = "BYTE PTR ";
				break;

			case 2:
                this->m_idaout->Par1Ptr = "WORD PTR ";
                break;
			
			case 4:
                this->m_idaout->Par1Ptr = "DWORD PTR ";
                break;
			}
		}
        this->m_idaout->Par1SegPrefix = ProcessSegPrefix(&xcpu.op[0]);
        this->m_idaout->Par1Str = outbuf1;
	}
	
	if (xcpu.op[1].mode != OP_Invalid)
	{
		// Process 2nd Opdata WORD PTR prefix
		if (xcpu.op[1].mode == OP_Address &&
			xcpu.op[1].opersize < xcpu.op[0].opersize )
			//(xcpu.opcode == C_MOVZX || xcpu.opcode == C_MOVSX))
		{
			if (xcpu.op[1].opersize == 1)
				this->m_idaout->Par2Ptr = "BYTE PTR ";
			else
				this->m_idaout->Par2Ptr = "WORD PTR ";
		}
		this->m_idaout->Par2SegPrefix = ProcessSegPrefix(&xcpu.op[1]);
        this->m_idaout->Par2Str = outbuf2;
	}
	
	if (xcpu.op[2].mode != OP_Invalid)
	{
        this->m_idaout->Par3Str = outbuf3;
	}

	CodeCount = codelen;
	// Complete it!

	// Write code here to simulate instruction.
	// VMSimulate(&xpcu);	
}

void	CDisasm::ProcessGroup(PINSTRUCTION pG,PINSTRUCTION inst)
{
	MODRM	modrm;
	modrm.v	= GetByte();

	DWORD	opdata1 = inst->Opdata1;
	DWORD	opdata2 = inst->Opdata2;
	DWORD	opdata3 = inst->Opdata3;

	if (pG[modrm.reg].Opdata1 != D_NONE)
		opdata1 = pG[modrm.reg].Opdata1;
		
	if (pG[modrm.reg].Opdata2 != D_NONE)
		opdata2 = pG[modrm.reg].Opdata2;

	if (pG[modrm.reg].Opdata3 != D_NONE)
		opdata3 = pG[modrm.reg].Opdata3;
	
	ProcessInstruction(	pG[modrm.reg].Opcode,
						pG[modrm.reg].InstName,
						opdata1,
						opdata2,
						opdata3
						);
}

void	CDisasm::DisassemblerOne()
{
	BYTE by = GetByteEx();
	
	switch(instruction[by].Opcode)
	{
	case C_ERROR:
		SetError(ERR_INVALIDCODE);
		break;
		
	case C_GROUP:		// It'a group. If this, InstName specifies the group table.
		ProcessGroup((PINSTRUCTION)(instruction[by].InstName),&instruction[by]);
		break;

	case C_0FH:			// It's 0FH instruction. If this, InstName specifies the 0FH table.
		by = GetByteEx();
		switch(instruction0FH[by].Opcode)
		{
		case C_ERROR:
			break;

		case C_GROUP:	// It'a group. If this, InstName specifies the group table.
			ProcessGroup((PINSTRUCTION)(instruction0FH[by].InstName),&instruction0FH[by]);
			break;

		default:
			ProcessInstruction(	instruction0FH[by].Opcode,
								instruction0FH[by].InstName,
								instruction0FH[by].Opdata1,
								instruction0FH[by].Opdata2,
								instruction0FH[by].Opdata3
								);
			break;
		}		
		break;
	
	case C_SEGPREFIX:	// Segment Prefix
		SegPrefix		= instruction[by].Opdata1;
		DisassemblerOne();
		break;

	case C_OPRSIZE:		// Operand size change.
		OpSizePrefix();
		DisassemblerOne();
		break;

	case C_ADRSIZE:		// Address size change.
		AdrSizePrefix();
		DisassemblerOne();
		break;

	case C_LOCK:		// LOCK prefix
		LockPrefix	= 1;
		LockName	= instruction[by].InstName;
		DisassemblerOne();
		break;
		
	case C_REPZ:		// REPZ prefix
		RepPrefix	= REPZ_PREFIX;
		RepName		= instruction[by].InstName;
		DisassemblerOne();
		break;

	case C_REPNZ:		// REPNZ prefix
		RepPrefix	= REPNZ_PREFIX;
		RepName		= instruction[by].InstName;
		DisassemblerOne();
		break;

	default:
		ProcessInstruction(	instruction[by].Opcode,
							instruction[by].InstName,
							instruction[by].Opdata1,
							instruction[by].Opdata2,
							instruction[by].Opdata3
							);
		break;
	}
}

⌨️ 快捷键说明

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