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

📄 disasm.c

📁 反汇编工具原代码,从sourceforge上下的
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 *
 * File Name: 
 *
 *		disasm.c
 *
 * Summary:
 *
 *		This file was created to be included within a 'disassembler' project for PE 
 *		image files running on x86 and x86-compatible processors.
 *
 *		File contains functions for disassembling IA32 binary instructions
 *
 * 
 *
 * Copyright (C) 2004, Isaac Sigasa [isigasa@ananzi.co.za]
 * All Rights Reserved
 *
 *
 *  
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *		-	Redistributions of source code must retain the above copyright notice, 
 *			this list of conditions and the following disclaimer. 
 *
 *		-	Redistributions in binary form must reproduce the above copyright notice, 
 *			this list of conditions and the following disclaimer in the documentation 
 *			and/or other materials provided with the distribution. 
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 */

#include <stdio.h>
#include <string.h>
#include <windows.h>

#include "Disasm.h"


extern InstructionTemplate _11OpcodeExtensions[0x10][0x8][0x3];
extern InstructionTemplate _1ByteOpcode[0x10][0x10];
extern InstructionTemplate _2ByteOpcode[0x10][0x10][0x5];
extern InstructionTemplate MemOpcodeExtensions[0x10][0x8][0x3];
extern InstructionTemplate FPUModRMReg[0x8][0x8];

extern InstructionTemplate FPUModRMFullD8[0x4][0x10];
extern InstructionTemplate FPUModRMFullD9[0x4][0x10];
extern InstructionTemplate FPUModRMFullDA[0x4][0x10];
extern InstructionTemplate FPUModRMFullDB[0x4][0x10];
extern InstructionTemplate FPUModRMFullDC[0x4][0x10];
extern InstructionTemplate FPUModRMFullDD[0x4][0x10];
extern InstructionTemplate FPUModRMFullDE[0x4][0x10];
extern InstructionTemplate FPUModRMFullDF[0x4][0x10];


int IsIA32InstructionPrefix(unsigned char c)
{
	switch(c)
	{
		case 0xF0:
		case 0xF2:
		case 0xF3:
		case 0x2E:
		case 0x36:
		case 0x3E:
		case 0x26:
		case 0x64:
		case 0x65:
		case 0x66:
		case 0x67:
			return 1;
	};
	return 0;
};


void FetchOperandDescriptors(const InstructionTemplate *pInstructionTemplate, IA32InstructionDecode *pIA32Decode)
{
	int iCol = 0, iTemp = 0;

	if(pInstructionTemplate->strOperandsDescr == N)
		return;
	if(!strlen(pIA32Decode->SIA32InstructionDescription.strOperandA))
	{
		while((pInstructionTemplate->strOperandsDescr[iCol] != 0) && (pInstructionTemplate->strOperandsDescr[iCol] != ','))
		{		
			pIA32Decode->SIA32InstructionDescription.strOperandA[iTemp++] = pInstructionTemplate->strOperandsDescr[iCol];
			iCol++;
		}
	}
	else
		iCol = 0;
	iTemp = 0;
	if(pInstructionTemplate->strOperandsDescr[iCol] == ',')
		iCol++;
	if(!strlen(pIA32Decode->SIA32InstructionDescription.strOperandB))
	{
		while((pInstructionTemplate->strOperandsDescr[iCol] != 0) && (pInstructionTemplate->strOperandsDescr[iCol] != ','))
		{		
			pIA32Decode->SIA32InstructionDescription.strOperandB[iTemp++] = pInstructionTemplate->strOperandsDescr[iCol];
			iCol++;
		};
	}
	else
		iCol = 0;
	iTemp = 0;
	if(pInstructionTemplate->strOperandsDescr[iCol] == ',')
		iCol++;
	if(!strlen(pIA32Decode->SIA32InstructionDescription.strOperandC))
		while((pInstructionTemplate->strOperandsDescr[iCol] != 0) && (pInstructionTemplate->strOperandsDescr[iCol] != ','))
		{			
			pIA32Decode->SIA32InstructionDescription.strOperandC[iTemp++] = pInstructionTemplate->strOperandsDescr[iCol];
			iCol++;
		};
};


unsigned char GetSegmentOverride(IA32InstructionDecode *pIA32Decode)
{
	int i;
	char strSegOverrides[] = {0x2E,0x36,0x3E,0x26,0x64,0x65,0};

	for(i = 0; i < pIA32Decode->SIA32InstructionHelper.cbRawPrefixes; i++)
		if(strchr(strSegOverrides,pIA32Decode->SIA32RawInstruction.caRawPrefixes[i]))
			return pIA32Decode->SIA32RawInstruction.caRawPrefixes[i];
	return 0;
};


void GetSegmentOverrideStr(unsigned char sreg, char*strBuffer, int cbBuffer)
{
	ZeroMemory(strBuffer,cbBuffer);
	switch(sreg)
	{
		case 0x2E:
			strncpy(strBuffer,"cs",cbBuffer);
			break;
		case 0x36:
			strncpy(strBuffer,"ss",cbBuffer);
			break;
		case 0x3E:
			strncpy(strBuffer,"ds",cbBuffer);
			break;
		case 0x26:
			strncpy(strBuffer,"es",cbBuffer);
			break;
		case 0x64:
			strncpy(strBuffer,"fs",cbBuffer);
			break;
		case 0x65:
			strncpy(strBuffer,"gs",cbBuffer);
			break;
	};
};


int FetchPrefixes(const unsigned char *pStart, IA32InstructionDecode *pIA32Decode)
{
	int i;

	ZeroMemory(pIA32Decode->SIA32InstructionDescription.strPrefix,sizeof(pIA32Decode->SIA32InstructionDescription.strPrefix));
	ZeroMemory(pIA32Decode->SIA32RawInstruction.caRawPrefixes,sizeof(pIA32Decode->SIA32RawInstruction.caRawPrefixes));
	pIA32Decode->SIA32InstructionHelper.cbRawPrefixes = 0;
	
	strcat(pIA32Decode->SIA32InstructionDescription.strPrefix,"");

	// Instruction prefixes can only be up to four, so let's probe for at most four times 	
	for(i = 0; i < 4; i++)
	{
		switch(pStart[i])
		{
			case 0xF0:
				if(strlen(pIA32Decode->SIA32InstructionDescription.strPrefix))
					strcat(pIA32Decode->SIA32InstructionDescription.strPrefix," lock");
				else
					strcat(pIA32Decode->SIA32InstructionDescription.strPrefix,"lock");
				break;
			case 0xF2:
				if(strlen(pIA32Decode->SIA32InstructionDescription.strPrefix))
					strcat(pIA32Decode->SIA32InstructionDescription.strPrefix," repne");
				else
					strcat(pIA32Decode->SIA32InstructionDescription.strPrefix,"repne");
				break;
			case 0xF3:
				if(strlen(pIA32Decode->SIA32InstructionDescription.strPrefix))
					strcat(pIA32Decode->SIA32InstructionDescription.strPrefix," rep");
				else
					strcat(pIA32Decode->SIA32InstructionDescription.strPrefix,"rep");
				break;
			case 0x2E:
			case 0x36:
			case 0x3E:
			case 0x26:
			case 0x64:
			case 0x65:
			case 0x66:
			case 0x67:				
				break;
			default:
				return i;
		};
		pIA32Decode->SIA32RawInstruction.caRawPrefixes[i] = pStart[i];
		pIA32Decode->SIA32InstructionHelper.cbRawPrefixes++;			
	};
	return i;
};


int IA32InstructionPrefixExists(unsigned char cPrefix, IA32InstructionDecode *pIA32Decode)
{
	int i;

	for(i = 0; i < pIA32Decode->SIA32InstructionHelper.cbRawPrefixes; i++)
		if(pIA32Decode->SIA32RawInstruction.caRawPrefixes[i] == cPrefix)
			return 1;
	return 0;
};


int FetchFPUInstruction(IA32InstructionDecode *pIA32Decode)
{
	unsigned char ModRM = pIA32Decode->SIA32RawInstruction.ModRM;
	int iRow;
	int iCol;
	InstructionTemplate *pInstructionTemplate = NULL;

	if((ModRM >= 0) && (ModRM <= 0xBF))
	{
		iRow = pIA32Decode->SIA32RawInstruction.URawOpcode.cByteRawOpcode - 0xD8;
		iCol = (ModRM & 0x38) >> 3;

		pInstructionTemplate = &FPUModRMReg[iRow][iCol];
		if(pInstructionTemplate->strOpcode == N)
			return 1;
		strcpy(pIA32Decode->SIA32InstructionDescription.strOpcode,pInstructionTemplate->strOpcode);
		FetchOperandDescriptors(pInstructionTemplate,pIA32Decode);
		return 1;
	};
	iRow = (ModRM & 0xF0) >> 4;
	iRow -= 0x0B + 1;
	iCol = ModRM & 0x0F;

	switch(pIA32Decode->SIA32RawInstruction.URawOpcode.cByteRawOpcode)
	{
	case 0xD8:
		pInstructionTemplate = &FPUModRMFullD8[iRow][iCol];
		break;
	case 0xD9:
		pInstructionTemplate = &FPUModRMFullD9[iRow][iCol];
		break;
	case 0xDA:
		pInstructionTemplate = &FPUModRMFullDA[iRow][iCol];
		break;
	case 0xDB:
		pInstructionTemplate = &FPUModRMFullDB[iRow][iCol];
		break;
	case 0xDC:
		pInstructionTemplate = &FPUModRMFullDC[iRow][iCol];
		break;
	case 0xDD:
		pInstructionTemplate = &FPUModRMFullDD[iRow][iCol];
		break;
	case 0xDE:
		pInstructionTemplate = &FPUModRMFullDE[iRow][iCol];
		break;
	case 0xDF:
		pInstructionTemplate = &FPUModRMFullDF[iRow][iCol];
		break;
	};

	if(((ModRM & 0xF0) >> 4) < 0x0B)
		return 1;
	iRow = (ModRM & 0xF0) >> 4;
	iRow -= 0x0B + 1;
	iCol = ModRM & 0x0F;
	if(pInstructionTemplate->strOpcode == N)
			return 1;
	
	strcpy(pIA32Decode->SIA32InstructionDescription.strOpcode,pInstructionTemplate->strOpcode);
	FetchOperandDescriptors(pInstructionTemplate,pIA32Decode);	

	return 1;
};


int FetchInstructionFrom1ByteOpcodeTable(const unsigned char *pStart,IA32InstructionDecode *pIA32Decode)
{
	unsigned int iRow, iCol;
	InstructionTemplate *pInstructionTemplate;
	unsigned char ucTemp;
	unsigned char ModRM;
	char *pchr1;
	char *pchr2;
	char strTemp[64];

	ucTemp = pIA32Decode->SIA32RawInstruction.URawOpcode.cByteRawOpcode = pStart[0];
	pIA32Decode->SIA32InstructionHelper.cbRawOpcode = 1;

	/* FPU encodings are in 1 byte opcode table and are running from 0xD8 to 0xDF
	 * Let's check if we have an FP instruction and deal with it
	 */
	if((ucTemp >= 0xD8) && (ucTemp <= 0xDF))
	{
		/* if it's an FP instruction - we have an ModRM byte */
		ModRM = pIA32Decode->SIA32RawInstruction.ModRM = pStart[1];
		pIA32Decode->SIA32InstructionHelper.boolModRMExists = 1;
		FetchFPUInstruction(pIA32Decode);
		return 1;
	}
	iRow = (unsigned int)(pStart[0] >> 4);
	iCol = (unsigned int)(pStart[0] & 0x0F);
	pInstructionTemplate = &_1ByteOpcode[iRow][iCol];	
	if(pInstructionTemplate->strOpcode == N)
		return 1;		
	if(!strnicmp(pInstructionTemplate->strOpcode,"__G",strlen("__G")))
	{
		pIA32Decode->SIA32RawInstruction.ModRM = pStart[1];
		pIA32Decode->SIA32InstructionHelper.boolModRMExists = 1;
		pchr1 = pInstructionTemplate->strOpcode + strlen("__G");
		ucTemp = (unsigned char)strtoul(pchr1,&pchr2,10);
		if((ucTemp == 0) || (*pchr2 != 0))
			return 0;

		if((pIA32Decode->SIA32RawInstruction.ModRM & 0xC0) == 0xC0)
			FetchInstructionFromOpcodeExtensionsTable(ucTemp,pStart,_11OpcodeExtensions,pIA32Decode);
		else
			FetchInstructionFromOpcodeExtensionsTable(ucTemp,pStart,MemOpcodeExtensions,pIA32Decode);
	}
	else
		strcpy(pIA32Decode->SIA32InstructionDescription.strOpcode,pInstructionTemplate->strOpcode);
	FetchOperandDescriptors(pInstructionTemplate,pIA32Decode);
	if(strchr(pIA32Decode->SIA32InstructionDescription.strOperandA,'/'))
		if(!strcmp(pIA32Decode->SIA32InstructionDescription.strOpcode,"test"))
		{
			/*
			 * layout of 0xF6 'test' instruction is violating the intergrity provided
			 * by the layout of opcode tables,
			 * so let's treat the 0xF6 opcode separately.
			 * we basically need to swap the operands
			 *
			 */
			strcpy(strTemp,pIA32Decode->SIA32InstructionDescription.strOperandA);
			strcpy(pIA32Decode->SIA32InstructionDescription.strOperandA,pIA32Decode->SIA32InstructionDescription.strOperandB);
			strcpy(pIA32Decode->SIA32InstructionDescription.strOperandB,strTemp);
		}			

	if(strchr(pIA32Decode->SIA32InstructionDescription.strOperandA,'/'))
	{
		pchr1 = pIA32Decode->SIA32InstructionDescription.strOperandB;
		while((*pchr1) && isupper(*pchr1))
			pchr1++;
		if(GetOperandTypeSize(pchr1) == 1)
		{
			pchr1 = strchr(pIA32Decode->SIA32InstructionDescription.strOperandA,'/');
			if(pchr1)
				*pchr1 = 0;
		}
		else
		{
			strcpy(strTemp,strchr(pIA32Decode->SIA32InstructionDescription.strOperandA,'/') + 1);
			strcpy(pIA32Decode->SIA32InstructionDescription.strOperandA,strTemp);
		}
	}
	if(strchr(pIA32Decode->SIA32InstructionDescription.strOperandB,'/'))
	{
		pchr1 = pIA32Decode->SIA32InstructionDescription.strOperandA;
		while((*pchr1) && isupper(*pchr1))
			pchr1++;
		if(GetOperandTypeSize(pchr1) == 1)
		{
			pchr1 = strchr(pIA32Decode->SIA32InstructionDescription.strOperandB,'/');
			if(pchr1)
				*pchr1 = 0;
		}
		else
		{
			strcpy(strTemp,strchr(pIA32Decode->SIA32InstructionDescription.strOperandB,'/') + 1);
			strcpy(pIA32Decode->SIA32InstructionDescription.strOperandB,strTemp);
		}
	}
	return 1;
};


int FetchInstructionFrom2ByteOpcodeTable(const unsigned char *pStart,IA32InstructionDecode *pIA32Decode)
{
	int iRow, iCol, i;
	InstructionTemplate *pInstructionTemplate;
	char *pchr1;

⌨️ 快捷键说明

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