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

📄 disasm.c

📁 反汇编工具原代码,从sourceforge上下的
💻 C
📖 第 1 页 / 共 5 页
字号:
		if(!isdigit(str[strlen(str)-2]) || str[strlen(str)-2] > '7')
			return 0;
		return 1;
	}
	return 0;

};


int strIsBase10Int(const char* str)
{
	char *p;

	if(strlen(str))
	{
		strtoul(str,&p,10);
		if(*p == 0)
			return 1;
	};
	return 0;
};


int DecodeSingleOperand(const char * pLoadAddress, unsigned char *pStart, DefaultOperationSizeAttrib DSize, int iOpIndex, IA32InstructionDecode *pIA32Decode)
{
	char strOperand[16];
	char cAddressingMethod;
	char *strOperandType;
	char *strOutput;
	unsigned char ModRM;
	unsigned int uiOperandSize = 0;
	unsigned int uiAddressSize;
	unsigned char ucI8;
	unsigned short usI16;
	unsigned int uiI32;
	unsigned int uiTemp;
	char strSegOverride[10];
	unsigned char ucSegOverride;
	char strOpSize[20];

	ucSegOverride = GetSegmentOverride(pIA32Decode);
	GetSegmentOverrideStr(ucSegOverride,strSegOverride,sizeof(strSegOverride));
	if(strlen(strSegOverride))
		strcat(strSegOverride,":");

	if(!GetOutputBuffer(iOpIndex,&strOutput,pIA32Decode))
		return 0;
	GetMemoryOperandSizeStr(strOutput,strOpSize,DSize,pIA32Decode);
	if(strlen(strOpSize))
		strcat(strOpSize," ");
	strcpy(strOperand,strOutput);
	if(!strlen(strOutput)||isupperstr(strOperand))
		return 1;
	if(strIsBase10Int(strOutput))
		return 1;
	/* terminate here if strOperand is an FP register */
	if(strIsFPRegister(strOperand))
		return 1;
	cAddressingMethod = strOperand[0];
	strOperandType = strOperand + 1;
	if(strlen(strOperandType))
	{
		uiOperandSize = GetOperandTypeSize(strOperandType);
		if(uiOperandSize & 0xFF000000)
		{
			/* we depend on the operand-size attribute */
			if(DSize == OpSize32)
			{
				if(IA32InstructionPrefixExists(0x66,pIA32Decode))
					/* use 16-bit operand-size */
					uiOperandSize = uiOperandSize & 0x000000FF;
				else
					uiOperandSize = (uiOperandSize & 0x0000FF00) >> 8;
			}
			else
			{	/* Default operand-size is 16-bit */
				if(IA32InstructionPrefixExists(0x66,pIA32Decode))
					/* use 16-bit operand-size */
					uiOperandSize = (uiOperandSize & 0x0000FF00) >> 8;
				else
					uiOperandSize = uiOperandSize & 0x000000FF;
			};
		};
	};
	if(DSize == OpSize32)
	{
		if(IA32InstructionPrefixExists(0x67,pIA32Decode))
			/* use 16-bit address-size */
			uiAddressSize = 16;
		else
			uiAddressSize = 32;
	}
	else
	{	/* Default address-size is 16-bit */
		if(!IA32InstructionPrefixExists(0x67,pIA32Decode))
			/* use 16-bit operand-size */
			uiAddressSize = 16;
		else
			uiAddressSize = 32;
	};
	if(cAddressingMethod == 'e')
	{
		if(IsExplicitRegisterOperand(strOperand))
			return DecodeExplicitGPRegister(DSize,iOpIndex,pIA32Decode);
		else
			return 0;
	};

	switch(cAddressingMethod)
	{ 
	case 'A':
	case 'O':
		/* Direct address - the instruction has no ModRM nor SIB bytes */		
		if(pIA32Decode->SIA32InstructionHelper.boolModRMExists)
			return 0;
		CopyMemory(	&pIA32Decode->SIA32RawInstruction.URawDisplacement.cByteRawDisplacement,
					pStart	+ pIA32Decode->SIA32InstructionHelper.cbRawPrefixes 
							+ pIA32Decode->SIA32InstructionHelper.cbRawOpcode,
					uiAddressSize/8);
		pIA32Decode->SIA32InstructionHelper.cbRawDisplacement = (unsigned char)(uiAddressSize/8);		
		if(uiOperandSize == 6)
		{
			/*
			 * In cases where we deal with 48-bit operand types, documentation is not clear 
			 * about location of the extra two bytes representing the segment part, i.e. where 
			 * do the two bytes fit in the IA32 general instruction format as outlined in 
			 * "IA-32 Software Developer's manual volume 2A: instruction set reference", 
			 * chapter 2, figure 2-1???
			 * So I just assume the two bytes immediately follow the 32-bit displacement, ooh!
			 * For representation of the disassembled code - this case will be treated as a
			 * special case
			 */
			CopyMemory(	pIA32Decode->SIA32RawInstruction.URawImmediate.ca2ByteRawImmediate,
						pStart	+ pIA32Decode->SIA32InstructionHelper.cbRawPrefixes
								+ pIA32Decode->SIA32InstructionHelper.cbRawOpcode
								+ pIA32Decode->SIA32InstructionHelper.boolModRMExists
								+ pIA32Decode->SIA32InstructionHelper.boolSIBExists
								+ pIA32Decode->SIA32InstructionHelper.cbRawDisplacement,
						2);
			pIA32Decode->SIA32InstructionHelper.cbRawImmediate += 2;
			sprintf(strOutput,"0x%04X:[0x%08X]",
					*(unsigned short*)pIA32Decode->SIA32RawInstruction.URawImmediate.ca2ByteRawImmediate,
					*(unsigned int*)pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement);
			return 1;
		};
		if(!strlen(strSegOverride))
				strcpy(strSegOverride,"ds:");
		switch(uiAddressSize)
		{
		case 16:			
			sprintf(strOutput,"%s%s[0x%04X]",strOpSize,strSegOverride,
					*((unsigned short*)pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement));
			break;
		case 32:
			sprintf(strOutput,"%s%s[0x%08X]",strOpSize,strSegOverride,
					*((unsigned int*)pIA32Decode->SIA32RawInstruction.URawDisplacement.ca4ByteRawDisplacement));
			break;
		default:
			return 0;
		}
		return 1;
		
	case 'E':
	case 'Q':
	case 'W':
		/* if the addressing method begins with one of above characters then it is R/M 
		 * we need to determine the actual case. We certainly know that the instruction
		 * does have the ModRM byte
		 */
		if(!pIA32Decode->SIA32InstructionHelper.boolModRMExists)
		{
			ModRM = pStart[pIA32Decode->SIA32InstructionHelper.cbRawPrefixes + pIA32Decode->SIA32InstructionHelper.cbRawOpcode];
			pIA32Decode->SIA32RawInstruction.ModRM = ModRM;
			pIA32Decode->SIA32InstructionHelper.boolModRMExists = 1;
		}
		else
			ModRM = pIA32Decode->SIA32RawInstruction.ModRM;
		if((ModRM & 0xC0) == 0xC0)
			/* we are dealing with a register operand here */
			return DecodeSingleRegisterOperand(DSize,iOpIndex,pIA32Decode);
		else
			/* we are dealing with a memory operand */
			return DecodeMemoryOperand(pStart,DSize,iOpIndex,pIA32Decode);
		
	case 'C':
	case 'D':
	case 'G':
	case 'P':
	case 'R':
	case 'S':
	case 'T':
	case 'V':
		/* definitely registers here */
		if(!pIA32Decode->SIA32InstructionHelper.boolModRMExists)
		{
			ModRM = pStart[pIA32Decode->SIA32InstructionHelper.cbRawPrefixes + pIA32Decode->SIA32InstructionHelper.cbRawOpcode];
			pIA32Decode->SIA32RawInstruction.ModRM = ModRM;
			pIA32Decode->SIA32InstructionHelper.boolModRMExists = 1;
		};
		return DecodeSingleRegisterOperand(DSize,iOpIndex,pIA32Decode);

	case 'M':
		return DecodeMemoryOperand(pStart,DSize,iOpIndex,pIA32Decode);
	case 'I':
		/* immediate */
		CopyMemory(&pIA32Decode->SIA32RawInstruction.URawImmediate.cByteRawImmediate,
				pStart + 
				pIA32Decode->SIA32InstructionHelper.cbRawPrefixes +
				pIA32Decode->SIA32InstructionHelper.cbRawOpcode +
				pIA32Decode->SIA32InstructionHelper.boolModRMExists +
				pIA32Decode->SIA32InstructionHelper.boolSIBExists +
				pIA32Decode->SIA32InstructionHelper.cbRawDisplacement,
				uiOperandSize);
		pIA32Decode->SIA32InstructionHelper.cbRawImmediate += (unsigned char)uiOperandSize;
		switch(uiOperandSize)
		{
		case 1:
			ucI8 = pIA32Decode->SIA32RawInstruction.URawImmediate.cByteRawImmediate;
			sprintf(strOutput,"0x%02X",ucI8);
			return 1;
		case 2:
			usI16 = *((unsigned short*)pIA32Decode->SIA32RawInstruction.URawImmediate.ca2ByteRawImmediate);
			sprintf(strOutput,"0x%04X",usI16);
			return 1;
		case 4:
			uiI32 = *((unsigned int*)pIA32Decode->SIA32RawInstruction.URawImmediate.ca4ByteRawImmediate);
			sprintf(strOutput,"0x%08X",uiI32);
			return 1;
		default:
			return 0;
		};
	case 'J':
		/* relative offset in immediate that needs to be added to the instruction pointer */
		CopyMemory(&pIA32Decode->SIA32RawInstruction.URawImmediate.cByteRawImmediate,
				pStart + 
				pIA32Decode->SIA32InstructionHelper.cbRawPrefixes +
				pIA32Decode->SIA32InstructionHelper.cbRawOpcode +
				pIA32Decode->SIA32InstructionHelper.boolModRMExists +
				pIA32Decode->SIA32InstructionHelper.boolSIBExists +
				pIA32Decode->SIA32InstructionHelper.cbRawDisplacement,
				uiOperandSize);
		pIA32Decode->SIA32InstructionHelper.cbRawImmediate += (unsigned char)uiOperandSize;
		uiTemp = (unsigned int)(pLoadAddress + GetInstructionLength(pIA32Decode));
		switch(uiOperandSize)
		{
		case 1:
			ucI8 = pIA32Decode->SIA32RawInstruction.URawImmediate.cByteRawImmediate;
			sprintf(strOutput,"0x%02X",(char)ucI8 + uiTemp);
			return 1;
		case 2:
			usI16 = *((unsigned short*)pIA32Decode->SIA32RawInstruction.URawImmediate.ca2ByteRawImmediate);
			sprintf(strOutput,"0x%04X",(short)usI16 + uiTemp);
			return 1;
		case 4:
			uiI32 = *((unsigned int*)pIA32Decode->SIA32RawInstruction.URawImmediate.ca4ByteRawImmediate);
			sprintf(strOutput,"0x%08X",(int)uiI32 + uiTemp);
			return 1;
		default:
			return 0;
		};

	case 'X':
		if(uiAddressSize == 16)
			sprintf(strOutput,"%s[si]",strOpSize);
		else
			sprintf(strOutput,"%s[esi]",strOpSize);
		return 1;
	case 'Y':
		if(uiAddressSize == 16)
			sprintf(strOutput,"%s[di]",strOpSize);
		else
			sprintf(strOutput,"%s[edi]",strOpSize);
		return 1;
	default:
		return 0;
	}
};


int DecodeOperands(const char * pLoadAddress, unsigned char *pStart,DefaultOperationSizeAttrib DSize, IA32InstructionDecode *pIA32Decode)
{
	if(strlen(pIA32Decode->SIA32InstructionDescription.strOperandA))
		if(!DecodeSingleOperand(pLoadAddress,pStart,DSize,1,pIA32Decode))
			return 0;		
	if(strlen(pIA32Decode->SIA32InstructionDescription.strOperandB))
		if(!DecodeSingleOperand(pLoadAddress,pStart,DSize,2,pIA32Decode))
			return 0;
	if(strlen(pIA32Decode->SIA32InstructionDescription.strOperandC))
		if(!DecodeSingleOperand(pLoadAddress,pStart,DSize,3,pIA32Decode))
			return 0;
	if(IsExplicitRegisterOperand(pIA32Decode->SIA32InstructionDescription.strOperandA))
		strlwr(pIA32Decode->SIA32InstructionDescription.strOperandA);
	if(IsExplicitRegisterOperand(pIA32Decode->SIA32InstructionDescription.strOperandB))
		strlwr(pIA32Decode->SIA32InstructionDescription.strOperandB);
	if(IsExplicitRegisterOperand(pIA32Decode->SIA32InstructionDescription.strOperandC))
		strlwr(pIA32Decode->SIA32InstructionDescription.strOperandC);
	return 1;
};


void PrintInstruction(const char*pLoadAddress, IA32InstructionDecode *pIA32Decode)
{
	int i;
	char strBuffer[80];
	char strRemainder[80];

	ZeroMemory(strBuffer,sizeof(strBuffer));

	/* first print instruction address, and then raw bytes as they are in memory */
	printf("\n  %08X: ",pLoadAddress);
	for(i = 0; i < pIA32Decode->SIA32InstructionHelper.cbRawPrefixes; i++)
		sprintf(strBuffer + strlen(strBuffer),"%02X ",pIA32Decode->SIA32RawInstruction.caRawPrefixes[i]);
	
	for(i = 0; i < pIA32Decode->SIA32InstructionHelper.cbRawOpcode; i++)
		sprintf(strBuffer + strlen(strBuffer),"%02X ",pIA32Decode->SIA32RawInstruction.URawOpcode.ca2ByteRawOpcode[i]);
	if(pIA32Decode->SIA32InstructionHelper.boolModRMExists)
		sprintf(strBuffer + strlen(strBuffer),"%02X ",pIA32Decode->SIA32RawInstruction.ModRM);
	if(pIA32Decode->SIA32InstructionHelper.boolSIBExists)
		sprintf(strBuffer + strlen(strBuffer),"%02X ",pIA32Decode->SIA32RawInstruction.SIB);
	for(i = 0; i < pIA32Decode->SIA32InstructionHelper.cbRawDisplacement; i++)
		sprintf(strBuffer + strlen(strBuffer),"%02X ",pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement[i]);
	for(i = 0; i < pIA32Decode->SIA32InstructionHelper.cbRawImmediate; i++)
		sprintf(strBuffer + strlen(strBuffer),"%02X ",pIA32Decode->SIA32RawInstruction.URawImmediate.ca2ByteRawImmediate[i]);
	ZeroMemory(strRemainder,sizeof(strRemainder));
	i = _snprintf(strRemainder,17,"%-17s",strBuffer);
	printf("%s",strRemainder);
	if(i < 0)
		strcpy(strRemainder,strBuffer + strlen(strRemainder) + 1);
	else
		ZeroMemory(strRemainder,sizeof(strRemainder));		

	/* Now print the description, taking into account use of prefix */
	if(strlen(pIA32Decode->SIA32InstructionDescription.strPrefix))
	{
		i = strlen(pIA32Decode->SIA32InstructionDescription.strPrefix - 1);
		if(!isspace(pIA32Decode->SIA32InstructionDescription.strPrefix[i]))
			strcat(pIA32Decode->SIA32InstructionDescription.strPrefix," ");
	}
	sprintf(strBuffer,"%s%s",pIA32Decode->SIA32InstructionDescription.strPrefix,
		pIA32Decode->SIA32InstructionDescription.strOpcode);
	printf("  %-12s",strBuffer);
	/* There can never be operand A without operand B, nor operand B without C */
	if(strlen(pIA32Decode->SIA32InstructionDescription.strOperandA))
	{
		printf("%s",pIA32Decode->SIA32InstructionDescription.strOperandA);
		if(strlen(pIA32Decode->SIA32InstructionDescription.strOperandB))
		{
			printf(",%s",pIA32Decode->SIA32InstructionDescription.strOperandB);
			if(strlen(pIA32Decode->SIA32InstructionDescription.strOperandC))
				printf(",%s",pIA32Decode->SIA32InstructionDescription.strOperandC);
		}
	}
	if(strlen(strRemainder))
		printf("\n            %-s",strRemainder);
};


void Disassemble(const char*pLoadAddress,DefaultOperationSizeAttrib DSize,unsigned char *pStart, unsigned char *pEnd)
{
	IA32InstructionDecode IA32Decode;
	int iRet = 1;

	while(pStart < pEnd)
	{
#ifdef _DEBUG
		if(pLoadAddress == (char*)0x0438cca)
 			Sleep(0);
#endif
		ZeroMemory(&IA32Decode,sizeof(IA32Decode));
		iRet = FetchOpcode(pLoadAddress,pStart,&IA32Decode,DSize);
		if(iRet == 0)
			return;
		iRet = DecodeOperands(pLoadAddress,pStart,DSize,&IA32Decode);
		if((iRet == 0)||!strcmpi(IA32Decode.SIA32InstructionDescription.strOpcode,"???"))
		{
			/* the first byte can be either a prefix or the opcode, let's deal with
			 * each case individually - cheating where necessary
			 */
			if(IA32Decode.SIA32InstructionHelper.cbRawPrefixes)
			{
				IA32Decode.SIA32RawInstruction.URawOpcode.cByteRawOpcode = 
					IA32Decode.SIA32RawInstruction.caRawPrefixes[0];
			}
			ZeroMemory(&IA32Decode.SIA32RawInstruction.URawOpcode.cByteRawOpcode + 1,
						sizeof(IA32Decode) - (
						sizeof(IA32Decode.SIA32RawInstruction.caRawPrefixes)
						+ sizeof(IA32Decode.SIA32RawInstruction.URawOpcode.cByteRawOpcode)));
			IA32Decode.SIA32InstructionDescription.strOpcode[0] = 0;
			IA32Decode.SIA32InstructionHelper.cbRawOpcode = 1;
		};
		if(iRet)
			iRet = GetInstructionLength(&IA32Decode);
		else
			iRet = 1;
		PrintInstruction(pLoadAddress,&IA32Decode);
		pStart += iRet;
		pLoadAddress += iRet;
	}
};

⌨️ 快捷键说明

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