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

📄 disasm.cpp

📁 将exe等可执行文件转化成c程序的反编译程序,先到汇编再到c
💻 CPP
📖 第 1 页 / 共 4 页
字号:
WORD	PeekW(PBYTE codebuf)
{
	return *(WORD *)codebuf;
}

DWORD	PeekD(PBYTE codebuf)
{
	return *(DWORD *)codebuf;
}

BYTE	CDisasm::GetByte()
{
	return *(UasmCode+CodeCount);
}

WORD	CDisasm::GetWord()
{
	return *(WORD*)(UasmCode+CodeCount);
}

DWORD	CDisasm::GetDWord()
{
	return *(DWORD*)(UasmCode+CodeCount);
}

BYTE	CDisasm::GetByteEx()
{
	BYTE	v = *(UasmCode+CodeCount);
	CodeCount++;
	return v;
}

WORD	CDisasm::GetWordEx()
{
	WORD	v = *(WORD*)(UasmCode+CodeCount);
	CodeCount+=2;
	return v;
}

DWORD	CDisasm::GetDWordEx()
{
	DWORD	v = *(DWORD*)(UasmCode+CodeCount);
	CodeCount+=4;
	return v;
}

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

void	CDisasm::SetError(DWORD errcode)
{
	U_ErrorCode = errcode;
}

/***********************************************************/
// Global Function
// Set all of the field(s) of OPERITEM except **RWFLAG** and **SEG_INDEX**

BYTE CDisasm::Global_GetSize(DWORD srcsize)
{
	switch(srcsize)
	{
	case SIZE_B:
		return 1;

	case SIZE_V:
		if (OpSize == BIT16)
			return 2;
		else
			return 4;

	case SIZE_W:
		return 2;

	case SIZE_D:
		return 4;

	case SIZE_A:
		return 8;

	case SIZE_P:
		if (U_Size == BIT16)
			return 4;
		else if (OpSize == BIT16)
			return 4;
		else
			return 6;
	}
	return 0;
}	
		
DWORD Global_SIB(PSTR outbuf,PBYTE codebuf,POPERITEM op,DWORD mod)
{
	SIB sib;

	sib.v=PeekB(codebuf);

	char buf[128];
	
	op->addr.base_reg_index=sib.base;	
	op->addr.off_reg_index=sib.index;
	if (sib.ss==0)
		op->addr.off_reg_scale=1;
	else if (sib.ss==1)
		op->addr.off_reg_scale=2;
	else if (sib.ss==2)
		op->addr.off_reg_scale=4;
	else
		op->addr.off_reg_scale=8;
	
	// I have some mistakes! The manual say if index equal 4 there are no any scale register,
	// but I understood that's invalid code at first.
	if (sib.index == 4)
	{
		op->addr.off_reg_index	= _NOREG_;
		op->addr.off_reg_scale	= 0;	

		if (sib.base == 5 && mod == 0)
		{
			op->addr.base_reg_index	= _NOREG_;
			op->addr.off_value		= PeekD(codebuf + 1);
			sprintf(buf, "[%08X]", op->addr.off_value);
			return 5;
		}		

		sprintf(buf, "%s", RegDWord[sib.base]);
	}
	else
	{
		if (sib.base == 5 && mod == 0)
		{
			op->addr.base_reg_index	= _NOREG_;
			op->addr.off_value		= PeekD(codebuf + 1);
			sprintf(outbuf, "[%s*%d+%08X]",
				RegDWord[op->addr.off_reg_index],
				op->addr.off_reg_scale,
				op->addr.off_value
				);
			return 5;
		}
			
		sprintf(buf,"%s+%s*%d",
			RegDWord[sib.base],
			RegDWord[sib.index],
			op->addr.off_reg_scale
			);
	}

	if (mod == 1)
	{
		op->addr.off_value=PeekB(codebuf+1);
		sprintf(outbuf,"[%s+%02X]",buf,op->addr.off_value);
		return 2;
	}
	else if (mod == 2)
	{	//Now mod is 2
		op->addr.off_value=PeekD(codebuf+1);
		sprintf(outbuf,"[%s+%08X]",buf,op->addr.off_value);
		return 5;
	}
	else
	{
		sprintf(outbuf,"[%s]",buf);
		return 1;
	}
}

DWORD CDisasm::Global_MEMORY(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	MODRM	modrm;
	DWORD	len=1;

	//BYTE	by;
	//WORD	wo;
	//DWORD	dw;

	modrm.v	= PeekB(codebuf);

	if( AdrSize==BIT32 )
	{
		op->mode		= OP_Address;
		//op->addr.reg_size=sizeof(DWORD);
		op->addr.base_reg_index=modrm.rm;	
		op->addr.off_reg_index=_NOREG_;
		op->addr.off_reg_scale=1;
		op->addr.off_value=0;

		if (modrm.rm==4)
			return Global_SIB(outbuf,codebuf+1,op,modrm.mod)+len;

		if (modrm.rm==5&&modrm.mod==0)
		{
			op->addr.base_reg_index=_NOREG_;
			op->addr.off_value=PeekD(codebuf+1);
			sprintf(outbuf,"[%08X]",op->addr.off_value);
			len+=4;
			return len;
		}	

		if (modrm.mod==0)
		{
			sprintf(outbuf,"[%s]",RegDWord[modrm.rm]);
		}
		else if (modrm.mod==1)
		{
			signed char signoffset = (signed char)PeekB(codebuf+1);
			op->addr.off_value=(DWORD)(signed int)signoffset;
			if (signoffset < 0)
				sprintf(outbuf,"[%s-%02X]",RegDWord[modrm.rm],-signoffset);
			else
				sprintf(outbuf,"[%s+%02X]",RegDWord[modrm.rm],signoffset);
			len+=1;
		}
		else
		{	//mod is 2
			op->addr.off_value=PeekD(codebuf+1);
			sprintf(outbuf,"[%s+%08X]",RegDWord[modrm.rm],op->addr.off_value);
			len+=4;
		}	
	}
	else
	{
		op->mode		= OP_Address;
		//op->addr.reg_size=sizeof(WORD);
		op->addr.base_reg_index=_NOREG_;	
		op->addr.off_reg_index=_NOREG_;
		op->addr.off_reg_scale=1;
		op->addr.off_value=0;

		if (modrm.rm==6&&modrm.mod==0)
		{
			op->addr.off_value=PeekW(codebuf+1);
			sprintf(outbuf,"[%04X]",op->addr.off_value);
			len+=2;
			return len;
		}	

		char *reg16off;
		switch(modrm.rm)
		{
			case 0:
				op->addr.base_reg_index=_BX_;	
				op->addr.off_reg_index=_SI_;
				reg16off="BX+SI";
				break;
			case 1:
				op->addr.base_reg_index=_BX_;	
				op->addr.off_reg_index=_DI_;
				reg16off="BX+DI";
				break;
			case 2:
				op->addr.base_reg_index=_BP_;	
				op->addr.off_reg_index=_SI_;
				reg16off="BP+SI";
				break;
			case 3:
				op->addr.base_reg_index=_BP_;	
				op->addr.off_reg_index=_DI_;
				reg16off="BP+DI";
				break;
			case 4:
				op->addr.base_reg_index=_SI_;	
				reg16off="SI";
				break;
			case 5:
				op->addr.base_reg_index=_DI_;	
				reg16off="DI";
				break;
			case 6:
				op->addr.base_reg_index=_BP_;	
				reg16off="BP";
				break;
			case 7:
				op->addr.base_reg_index=_BX_;	
				reg16off="BX";
		}		
				
		if (modrm.mod==0)
		{
			sprintf(outbuf,"[%s]",reg16off);
		}
		else if (modrm.mod==1)
		{
			signed char signoffset = (signed char)PeekB(codebuf+1);
			op->addr.off_value=(DWORD)(signed int)signoffset;
			if (signoffset < 0)
				sprintf(outbuf,"[%s-%02X]",reg16off,-signoffset);
			else
				sprintf(outbuf,"[%s+%02X]",reg16off,signoffset);
			len+=1;
		}
		else
		{	//mod is 2
			op->addr.off_value=PeekW(codebuf+1);
			sprintf(outbuf,"[%s+%04X]",reg16off,op->addr.off_value);
			len+=2;
		}	
	}	
	return len;
}

DWORD CDisasm::Global_MODRM(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	MODRM	modrm;
	modrm.v	= PeekB(codebuf);

	if (modrm.mod==3)
	{
		op->mode = OP_Register;
		if (op->opersize == 1)
		{
			strcpy(outbuf,RegByte[modrm.rm]);
		}	
		else if (op->opersize == 2)
		{
			strcpy(outbuf,RegWord[modrm.rm]);
		}
		else
		{
			strcpy(outbuf,RegDWord[modrm.rm]);
		}
		op->reg.reg_index=modrm.rm;
		return 1;
	}	
	return Global_MEMORY(outbuf,codebuf,op);
}

DWORD CDisasm::Global_OFFSET(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	op->mode=OP_Address;

	//op->addr.reg_size		= 0;
	op->addr.base_reg_index	= _NOREG_;
	op->addr.off_reg_index	= _NOREG_;
	op->addr.off_reg_scale	= 0;

	if (AdrSize == BIT16)
	{
		op->addr.off_value	= PeekW(codebuf);
		sprintf(outbuf,"[%04X]",op->addr.off_value);
		return sizeof(WORD);
	}
	else
	{
		op->addr.off_value	= PeekW(codebuf);
		sprintf(outbuf,"[%08X]",op->addr.off_value);
		return sizeof(DWORD);
	}
}

DWORD Global_REG(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	MODRM	modrm;

	modrm.v=PeekB(codebuf);

	op->mode = OP_Register;

	if (op->opersize == 1)
	{
		strcpy(outbuf,RegByte[modrm.reg]);
	}	
	else if (op->opersize == 2)
	{
		strcpy(outbuf,RegWord[modrm.reg]);
	}
	else
	{
		strcpy(outbuf,RegDWord[modrm.reg]);
	}
	op->reg.reg_index=modrm.reg;

	return 0;
}

DWORD Global_SREG(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	MODRM	modrm;
	modrm.v	= PeekB(codebuf);

	op->mode = OP_Segment;
	strcpy(outbuf,SegReg[modrm.reg]);
	op->sreg.sreg_index=modrm.reg;

	return 0;
}

DWORD Global_IMMED(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	op->mode = OP_Immed;

	if (op->opersize == 1)
	{
		op->immed.immed_value=(DWORD)(int)(signed char)PeekB(codebuf);
		sprintf(outbuf,"%02X",(BYTE)op->immed.immed_value);
	}
	else if (op->opersize == 2)
	{
		op->immed.immed_value=PeekW(codebuf);
		sprintf(outbuf,"%04X",op->immed.immed_value);
	}
	else
	{
		op->immed.immed_value=PeekD(codebuf);
		sprintf(outbuf,"%08X",op->immed.immed_value);
	}

	return op->opersize;
}

DWORD Global_SIGNEDIMMED(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	op->mode = OP_Immed;

	signed char by = (signed char)PeekB(codebuf);
	if (by < 0)
		sprintf(outbuf,"-%02X",-by);
	else
		sprintf(outbuf,"+%02X",by);
	op->immed.immed_value=(DWORD)(int)by;

	return 1;
}

DWORD CDisasm::Global_NEARPTR(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	op->mode = OP_Near;

	if (op->opersize == 1)
	{
		op->nearptr.offset = BaseAddress + CodeCount + 1 + (int)(char)PeekB(codebuf);
	}
	else if (op->opersize == 2)
	{
		op->nearptr.offset = BaseAddress + CodeCount + 2 + (int)(short)PeekW(codebuf);
	}
	else
	{
		op->nearptr.offset = BaseAddress + CodeCount + 4 + (int)PeekD(codebuf);
	}

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

	return op->opersize;
}

DWORD CDisasm::Global_FARPTR(PSTR outbuf,PBYTE codebuf,POPERITEM op)
{
	op->mode = OP_Far;

	if (op->opersize == 4)
	{
		op->farptr.offset = PeekW(codebuf);

⌨️ 快捷键说明

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