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

📄 disassemble.c

📁 机器码指令格式
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "disassemble.h"

const char *RepeatPrefixes[] = {"lock", "rep", "repe", "repz", "repne", "repnz"};
const char *AddressPrefixes[] = {"qword", "fword", "dword", "word", "byte"};
const char *SegmentRegisters[] = {"es", "cs", "ss", "ds", "fs", "gs"};
const char *Register32[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
const char *Register16[] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"};
const char *Register8[] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"};
const char *Address16[] = {"bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"};

const char *ArithmeticMnemonic[] = {"add", "or", "adc", "sbb", "and", "sub", "xor", "cmp" };
const char *BCDAdjustMnemonic[] = {"daa", "das", "aaa", "aas", "aam", "aad"};
const char *JxxxMnemonic[] = {"jo", "jb", "jz", "jbe", "js", "jp", "jl", "jle"};
const char *JnxxMnemonic[] = {"jno", "jnb", "jnz", "ja", "jns", "jnp", "jge", "jg"};
const char *StrMnemonic[] = {"", "", "movs", "cmps", "", "stos", "lods", "scas"};
const char *LogicalShiftMnemonic[] = {"rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar"};
const char *LoopMnemonic[] = {"loopnz", "loopz", "loop"};
const char *LogicalArithmeticMnemonic[] = {"test", "???", "not", "neg", "mul", "imul", "div", "idiv"};
const char *FlagMnemonic[] = {"clc", "stc", "cli", "sti", "cld", "std"};
const char *FFOpcodeMnemonic[] = {"inc", "dec", "call", "call", "jmp", "jmp", "push"};
const char *SetxxxMnemonic[] = {"seto", "setb", "sete", "setbe", "sets", "setpe", "setl", "setle"};
const char *SetnxxMnemonic[] = {"setno", "setnb", "setne", "seta", "setns", "setpo", "setge", "setg"};
const char *BTMnemonic[] = {"bt", "bts", "btr", "btc"};

unsigned char *Disassemble(unsigned int LinearAddress, unsigned char *Code, PINSTRUCTION Instruction, char *InstructionStr)
{
	char prefix[MAX_OPERAND_LEN] = "";
	char mnemonic[MAX_MNEMONIC_LEN] = "";
	char operand1[MAX_OPERAND_LEN] = "";
	char operand2[MAX_OPERAND_LEN] = "";
	char operand3[MAX_OPERAND_LEN] = "";
	
	unsigned char *currentCode;
	char prefixFlag; 

	currentCode = Code;
	prefixFlag = 0;
	
	/* initialize Instrction structure */

	Instruction->RepeatPrefix = -1;
	Instruction->SegmentPrefix = -1;
	Instruction->OperandPrefix = -1;
	Instruction->AddressPrefix = -1;

	Instruction->Opcode = -1;
	Instruction->ModRM = -1;
	Instruction->SIB = -1;
	
	Instruction->Displacement = -1;
	Instruction->Immediate = -1;

	Instruction->dFlag = Instruction->wFlag = Instruction->sFlag = -1;

	Instruction->LinearAddress = LinearAddress;

	/* check PREFIXES and save the values, note that prefixes in the same group can only appear once */
	/* and the values assigned to xxxxPrefix in Instruction structure are the indexes of the names */
	/* in corresponding name tables */
	
	while(*currentCode == 0xF0 || *currentCode == 0xF2 || *currentCode == 0xF3 ||
		*currentCode == 0x2E || *currentCode == 0x36 || *currentCode == 0x3E ||
		*currentCode == 0x26 || *currentCode == 0x64 || *currentCode == 0x65 ||
		*currentCode == 0x66 || *currentCode == 0x67)
	{
		switch(*currentCode)
		{
			/* group1: lock and repeat prefixes */

			case 0xF0 :
			{	
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix lock:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->RepeatPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->RepeatPrefix = 0;
						currentCode++;
					}
				}
				
				break;
			}
			case 0xF2 :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix repnz:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->RepeatPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->RepeatPrefix = 5;
						currentCode++;
					}
				}

				break;
			}
			case 0xF3 :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix rep:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->RepeatPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->RepeatPrefix = 1;
						currentCode++;
					}
				}

				break;
			}

			/* group2: segment override prefixes */

			case 0x2E :
			{
				
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix cs:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->SegmentPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->SegmentPrefix = 1;
						currentCode++;
					}
				}

				break;
			}
			case 0x36 :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix ss:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->SegmentPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->SegmentPrefix = 2;
						currentCode++;
					}
				}

				break;
			}
			case 0x3E :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix ds:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->SegmentPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->SegmentPrefix = 3;
						currentCode++;
					}
				}

				break;
			}
			case 0x26 :
			{	
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix es:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->SegmentPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->SegmentPrefix = 0;
						currentCode++;
					}
				}

				break;
			}
			case 0x64 :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix fs:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */
				
					if(Instruction->SegmentPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->SegmentPrefix = 4;
						currentCode++;
					}
				}

				break;
			}
			case 0x65 :
			{	
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix gs:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->SegmentPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->SegmentPrefix = 5;
						currentCode++;
					}
				}

				break;
			}

			/* group3: Operand-size override prefixes */

			case 0x66 :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix datasize:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->OperandPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->OperandPrefix = 0;
						currentCode++;
					}
				}

				break;
			}

			/* group4: Address-size override prefixes */

			case 0x67 :
			{
				if(prefixFlag)
				{
					strcpy(InstructionStr, "prefix addrsize:");
					currentCode++;
					return currentCode;
				}
				else
				{
					/* rescan */

					if(Instruction->AddressPrefix >= 0)
					{
						currentCode = Code;
						prefixFlag = 1;
					}
					else
					{
						Instruction->AddressPrefix = 0;
						currentCode++;
					}
				}
				
				break;
			}
		}
	}

	/* CODE map */

	switch(*currentCode)
	{
		/* Arithmetic operations */

		case 0x00: case 0x01: case 0x02: case 0x03: 
		case 0x08: case 0x09: case 0x0A: case 0x0B: 
		case 0x10: case 0x11: case 0x12: case 0x13: 
		case 0x18: case 0x19: case 0x1A: case 0x1B: 
		case 0x20: case 0x21: case 0x22: case 0x23: 
		case 0x28: case 0x29: case 0x2A: case 0x2B: 
		case 0x30: case 0x31: case 0x32: case 0x33: 
		case 0x38: case 0x39: case 0x3A: case 0x3B: 
		{
			Instruction->Opcode = *currentCode;
			Instruction->dFlag = (*currentCode >> 1) & 1;
			Instruction->wFlag = (*currentCode) & 1;

			sprintf(mnemonic, ArithmeticMnemonic[(*currentCode >> 3) & 0x1F]);
			
			currentCode++;
			currentCode = ParseRegModRM(currentCode, Instruction, operand1, operand2);
			
			break;
		}
		case 0x04: case 0x05: case 0x0C: case 0x0D:	
		case 0x14: case 0x15: case 0x1C: case 0x1D:
		case 0x24: case 0x25: case 0x2C: case 0x2D:
		case 0x34: case 0x35: case 0x3C: case 0x3D:
		{
			Instruction->Opcode = *currentCode;
			Instruction->wFlag = (*currentCode & 1);
			Instruction->sFlag = ! Instruction->wFlag;

			sprintf(mnemonic, ArithmeticMnemonic[(*currentCode >> 3) & 0x1F]);
			
			sprintf(operand1, "%s", Instruction->wFlag ? (Instruction->OperandPrefix >= 0 ? "ax" : "eax") 
				 : "al");

			currentCode++;
			currentCode = ParseImmediate(currentCode, Instruction, operand2);
			
			break;
		}
		case 0x80: case 0x81: case 0x82: case 0x83:
		{
			Instruction->Opcode = *currentCode;
			Instruction->wFlag = (*currentCode & 1);
			Instruction->sFlag = (*currentCode >> 1) & 1;
			
			/* special cases */

			if(*currentCode == 0x80)
			{
				Instruction->sFlag = 1;
			}

			sprintf(mnemonic, ArithmeticMnemonic[(*(currentCode + 1) >> 3) & 7]);

			currentCode++;
			currentCode = ParseModRM(currentCode, Instruction, operand1);
			currentCode = ParseImmediate(currentCode, Instruction, operand2);

			/* special cases */

			if(Instruction->Opcode == 0x83)
			{
				sprintf(operand2, "%X%X", (Instruction->Immediate >> 7 & 1) ? (Instruction->OperandPrefix >= 0 ? 0xFF: 0xFFFFFF) : 0x0, Instruction->Immediate);
			}

			break;
		}
		
		/* push pop operations */

		case 0x06: case 0x07 : case 0x0E: case 0x16: case 0x17: case 0x1E : case 0x1F:
		{
			Instruction->Opcode = *currentCode;

			sprintf(mnemonic, "%s", *currentCode & 1 ? "pop" : "push");
			sprintf(operand1, "%s", SegmentRegisters[(*currentCode >> 3) & 3]);
			currentCode++;

			break;
		}
		case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
		case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F:
		{
			Instruction->Opcode = *currentCode;

			sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "pop" : "push");
			sprintf(operand1, "%s", Instruction->OperandPrefix >= 0 ? Register16[*currentCode & 7] : Register32[*currentCode & 7]);
			currentCode++;
			
			break;
		}
		case 0x60: case 0x61: case 0x9C: case 0x9D:
		{
			Instruction->Opcode = *currentCode;

			sprintf(mnemonic, "%s%c%c", (*currentCode & 1) ? "pop" : "push", 
				(*currentCode >> 7) & 1 ? 'f' : 'a', Instruction->OperandPrefix >= 0 ? 'w' : 'd');
			currentCode++;

			break;
		}
		case 0x68: case 0x6A:
		{
			Instruction->Opcode = *currentCode;
			Instruction->sFlag = (*currentCode >> 1) & 1;
			
			sprintf(mnemonic, "%s", "push");
			currentCode++;
			currentCode = ParseImmediate(currentCode, Instruction, operand1);

			break;
		}
		case 0x8F:
		{
			Instruction->Opcode = *currentCode;
			Instruction->wFlag = (*currentCode) & 1;

			sprintf(mnemonic, "%s", "pop");
			currentCode++;
			currentCode = ParseModRM(currentCode, Instruction, operand1);

			break;
		}
		case 0x27: case 0x2F: case 0x37: case 0x3F:
		{
			Instruction->Opcode = *currentCode;

			sprintf(mnemonic, "%s", BCDAdjustMnemonic[(*currentCode >> 3) & 3]);
			currentCode++;

			break;
		}

		/* inc and dec */
		
		case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
		case 0x48: case 0x49: case 0x4A: case 0x4B: case 0x4C: case 0x4D: case 0x4E: case 0x4F:
		{
			Instruction->Opcode = *currentCode;

			sprintf(mnemonic, "%s", (*currentCode >> 3) & 1 ? "dec" : "inc");
			sprintf(operand1, "%s", Instruction->OperandPrefix >= 0 ? Register16[*currentCode & 7] : Register32[*currentCode & 7]);
			currentCode++;
			
			break;
		}

		/* bound */

		case 0x62:
		{
			Instruction->Opcode = *currentCode;
			Instruction->wFlag = *currentCode & 1;
			Instruction->sFlag = (*currentCode >> 1) & 1;

			sprintf(mnemonic, "%s", "bound");
			sprintf(operand1, "%s", Instruction->OperandPrefix >= 0 ? Register16[(*(currentCode + 1) >> 3) & 7] :
				Register32[(*(currentCode + 1) >> 3) & 7]);
			currentCode++;
			currentCode = ParseModRM(currentCode, Instruction, operand2);
			
			/* special case, the size of memory address must be twice the size of register */

			sprintf(operand3, "%s%s", Instruction->OperandPrefix >= 0 ? "dword " : "qword ",
				strstr(operand2, "ptr"));
			sprintf(operand2, "%s", operand3);
			*operand3 = '\0';

			break;
		}

		/* arpl */

		case 0x63:
		{
			Instruction->Opcode = *currentCode;

			/* special case, the operand size of arpl must be 16-bits */

			Instruction->OperandPrefix = 0;
			Instruction->wFlag = 1;
			Instruction->dFlag = 0;

			sprintf(mnemonic, "%s", "arpl");
			currentCode++;
			currentCode = ParseRegModRM(currentCode, Instruction, operand1, operand2);

			break;
		}
		
		/* imul */

		case 0x69: case 0x6B:
		{
			Instruction->Opcode = *currentCode;
			Instruction->wFlag = *currentCode & 1;
			Instruction->sFlag = (*currentCode >> 1) & 1;
			Instruction->dFlag = (*currentCode >> 1) & 1;

			sprintf(mnemonic, "%s", "imul");
			currentCode++;
			currentCode = ParseRegModRM(currentCode, Instruction, operand1, operand2);
			currentCode = ParseImmediate(currentCode, Instruction, operand3);

			break;
		}
		
		/* ins and outs */

		case 0x6C: case 0x6D: case 0x6E: case 0x6F:
		{
			Instruction->Opcode = *currentCode;
			Instruction->wFlag = *currentCode & 1;
			Instruction->dFlag = (*currentCode >> 1) & 1;
			
			sprintf(prefix, "%s", Instruction->RepeatPrefix > 0 ? RepeatPrefixes[Instruction->RepeatPrefix] : "");
			sprintf(mnemonic, "%s%c", Instruction->dFlag ? "outs" : "ins", Instruction->wFlag ? 
				(Instruction->OperandPrefix >= 0 ? 'w' : 'd') : 'b');
			currentCode++;

			break;
		}
		
		/* jmp instructions j(n)xx */
		
		case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
		case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
		{
			Instruction->Opcode = *currentCode;
			
			sprintf(mnemonic, "%s", *currentCode & 1 ? JnxxMnemonic[(*currentCode >> 1) & 7] : JxxxMnemonic[(*currentCode >> 1) & 7]);
			currentCode++;
			sprintf(operand1, "short %X", Instruction->LinearAddress + *((char*)currentCode) + currentCode - Code + 1);
			currentCode++;

			break;
		}

		/* test */

⌨️ 快捷键说明

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