📄 disasm.c
字号:
strcpy(strOperandTemplate,strOutput);
if(!strlen(strOutput))
return 1;
cAddressingMethod = strOperandTemplate[0];
strOperandType = strOperandTemplate + 1;
if(strlen(strOperandType))
{
uiTemp = GetOperandTypeSize(strOperandType);
if(uiTemp & 0xFF000000)
{
/* register-size dependant on operand-size attribute */
if(DSize == OpSize16)
{
if(IA32InstructionPrefixExists(0x66,pIA32Decode))
uiTemp = (uiTemp & 0x0000FF00) >> 8;
else
uiTemp = (uiTemp & 0x000000FF);
}
else
{
if(IA32InstructionPrefixExists(0x66,pIA32Decode))
uiTemp = (uiTemp & 0x000000FF);
else
uiTemp = (uiTemp & 0x0000FF00) >> 8;
};
};
};
switch(cAddressingMethod)
{
case 'C':
/* The reg field of the ModR/M byte selects a control register */
switch((ModRM & 0x38)>>3)
{
case 0:
case 2:
case 3:
case 4:
sprintf(strOutput,"cr%d",(ModRM & 0x38)>>3);
return 1;
default:
return 0;
};
case 'D':
/* The reg field of the ModR/M byte selects a debug register */
switch((ModRM & 0x38)>>3)
{
case 0:
case 1:
case 2:
case 3:
case 6:
case 7:
sprintf(strOutput,"dr%d",(ModRM & 0x38)>>3);
return 1;
default:
return 0;
};
case 'E':
/* general-purpose register or memory, if register, use RM and Mod must be 11B */
if((ModRM & 0xC0) != 0xC0)
{
return 0;
};
switch(uiTemp)
{
case 1:
case 2:
case 4:
return DecodeGPRegisterRM(uiTemp,ModRM,strOutput);
default:
return 0;
};
case 'G':
/* general-purpose register using Reg field */
switch(uiTemp)
{
case 1:
case 2:
case 4:
return DecodeGPRegisterReg(uiTemp,ModRM,strOutput);
default:
return 0;
};
case 'P':
/* MMX register using Reg field */
return DecodeMMXRegisterReg(ModRM,strOutput);
case 'Q':
/* MMX registed using RM field */
if((ModRM & 0xC0) != 0xC0)
return 0;
return DecodeMMXRegisterRM(ModRM,strOutput);
case 'R':
if((ModRM & 0xC0) != 0xC0)
return 0;
switch(uiTemp)
{
case 1:
case 2:
case 4:
return DecodeGPRegisterRM(uiTemp,ModRM,strOutput);
default:
return 0;
};
case 'S':
/* The reg field of the ModR/M byte selects a segment register */
return DecodeSegmentRegisterReg(ModRM,strOutput);
case 'T':
sprintf(strOutput,"tr%d",(ModRM & 0x38) >> 3);
return 1;
case 'V':
return DecodeXMMRegisterReg(ModRM,strOutput);
case 'W':
if((ModRM & 0xC0) != 0xC0)
return 0;
return DecodeXMMRegisterRM(ModRM,strOutput);
};
return 0;
}
/*
* GetOperandTypeSize
* Returns value with HO byte set to 80 if the size is dependant on operand-size attribute
* in which case the HO byte of the LO word is set to actual size for 32-bit code, and the
* LO byte of the LO word is set to actual size for 16-bit code.
*
* If the operand size attribute doesn't matter - the HO byte of the return dword is set
* to 00 and the actual size of the operand is returned (on the LO byte)
*/
unsigned int GetOperandTypeSize(const char *strType)
{
unsigned int uTemp = 0;
if(strlen(strType) == 1)
{
switch(strType[0])
{
case 'a':
/* 4 or 16 bytes - depending on operand-size attribute */
uTemp = 0x80000804;
break;
case 'b':
/* byte, regardless of operand-size attribute */
uTemp = 0x00000001;
break;
case 'c':
/* byte or word depending on operand-size attribute */
uTemp = 0x80000201;
break;
case 'd':
/* dword regardless of operand-size attribute */
uTemp = 0x00000004;
break;
case 'p':
/* 32-bit or 48-bit depending of operand-size */
uTemp = 0x80000604;
break;
case 'q':
uTemp = 0x00000008;
break;
case 's':
uTemp = 0x00000006;
break;
case 'v':
uTemp = 0x80000402;
break;
case 'w':
uTemp = 0x00000002;
break;
default:
return 0;
}
}
else
{
if( !strcmp(strType,"dq")||
!strcmp(strType,"pd")||
!strcmp(strType,"ps")||
!strcmp(strType,"sd")||
!strcmp(strType,"ss"))
uTemp = 0x00000010;
else
{
if(!strcmp(strType,"pi"))
uTemp= 0x00000008;
else
{
return 0;
}
}
}
return uTemp;
};
int DecodeExplicitGPRegister(DefaultOperationSizeAttrib DSize, int iOpIndex, IA32InstructionDecode *pIA32Decode)
{
char *strOutput;
char strOperand[64];
if(!GetOutputBuffer(iOpIndex,&strOutput,pIA32Decode))
return 0;
if(!IsExplicitRegisterOperand(strOutput))
return 0;
strcpy(strOperand,strOutput);
if(DSize == OpSize32)
{
if(IA32InstructionPrefixExists(0x66,pIA32Decode))
strcpy(strOutput,strOperand + 1);
else
strcpy(strOutput,strOperand);
}
else
{
if(!IA32InstructionPrefixExists(0x66,pIA32Decode))
strcpy(strOutput,strOperand + 1);
else
strcpy(strOutput,strOperand);
};
strlwr(strOutput);
return 1;
};
int IsExplicitRegisterOperand(const char *strTest)
{
int i;
char *strRegs[] = {
"EAX","AX","AH","AL",
"EBX","BX","BH","BL",
"ECX","CX","CH","CL",
"EDX","DX","DH","DL",
"BP","EBP","SP","ESP","SI","ESI","DI","EDI",
"CS","SS","DS","ES","GS","FS"
};
if((strlen(strTest) == 2) && (isupperstr(strTest)))
for(i = 0; i < ARRAYSIZE(strRegs); i++)
if(!strcmp(strRegs[i],strTest))
return 1;
if((strlen(strTest) == 3) && (strTest[0] == 'e') && isupperstr(strTest + 1))
return IsExplicitRegisterOperand(strTest + 1);
return 0;
};
int DecodeMemoryOperand16(DefaultOperationSizeAttrib DSize, unsigned char *pStart, int iOpIndex, IA32InstructionDecode *pIA32Decode)
{
unsigned char ModRM;
unsigned char ucD8;
unsigned short usD16;
char *strOutput;
char cTemp = '+';
char strSegOverride[10] = "";
char strOpSize[20];
unsigned char ucSegOverride;
if(!pIA32Decode->SIA32InstructionHelper.boolModRMExists)
return 0;
if(!GetOutputBuffer(iOpIndex,&strOutput,pIA32Decode))
return 0;
GetMemoryOperandSizeStr(strOutput,strOpSize,DSize,pIA32Decode);
if(strlen(strOpSize))
strcat(strOpSize," ");
ModRM = pIA32Decode->SIA32RawInstruction.ModRM;
ucSegOverride = GetSegmentOverride(pIA32Decode);
GetSegmentOverrideStr(ucSegOverride,strSegOverride,sizeof(strSegOverride));
if(strlen(strSegOverride))
strcat(strSegOverride,":");
switch((ModRM & 0xC0) >> 6)
{
case 0:
switch(ModRM & 0x07)
{
case 0:
sprintf(strOutput,"%s%s[bx+si]",strOpSize,strSegOverride);
return 1;
case 1:
sprintf(strOutput,"%s%s[bx+di]",strOpSize,strSegOverride);
return 1;
case 2:
sprintf(strOutput,"%s%s[bp+si]",strOpSize,strSegOverride);
return 1;
case 3:
sprintf(strOutput,"%s%s[bp+di]",strOpSize,strSegOverride);
return 1;
case 4:
sprintf(strOutput,"%s%s[si]",strOpSize,strSegOverride);
return 1;
case 6:
/* we have a disp16 value */
pIA32Decode->SIA32InstructionHelper.cbRawDisplacement = 2;
CopyMemory(pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement,
pStart + pIA32Decode->SIA32InstructionHelper.cbRawPrefixes +
pIA32Decode->SIA32InstructionHelper.cbRawOpcode +
pIA32Decode->SIA32InstructionHelper.boolModRMExists,
2);
if(!strlen(strSegOverride))
strcpy(strSegOverride,"ds:");
sprintf(strOutput,"%s%s[0x%02X]",strOpSize,strSegOverride,(unsigned short*)pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement);
return 1;
case 5:
sprintf(strOutput,"%s%s[di]",strOpSize,strSegOverride);
return 1;
case 7:
sprintf(strOutput,"%s%s[bx]",strOpSize,strSegOverride);
return 1;
};
case 1:
/* we have a disp8 value, needs to be sign-extended */
pIA32Decode->SIA32InstructionHelper.cbRawDisplacement = 1;
pIA32Decode->SIA32RawInstruction.URawDisplacement.cByteRawDisplacement =
pStart[pIA32Decode->SIA32InstructionHelper.cbRawPrefixes +
pIA32Decode->SIA32InstructionHelper.cbRawOpcode +
pIA32Decode->SIA32InstructionHelper.boolModRMExists];
ucD8 = pIA32Decode->SIA32RawInstruction.URawDisplacement.cByteRawDisplacement;
if(ucD8 & 0x80)
{
cTemp = '-';
ucD8 = (unsigned char)(((short)-ucD8) & 0x00FF);
}
switch(ModRM & 0x07)
{
case 0:
sprintf(strOutput,"%s%s[bx+si%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 1:
sprintf(strOutput,"%s%s[bx+di%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 2:
sprintf(strOutput,"%s%s[bp+si%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 3:
sprintf(strOutput,"%s%s[bp+di%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 4:
sprintf(strOutput,"%s%s[si%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 5:
sprintf(strOutput,"%s%s[di%cx%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 6:
sprintf(strOutput,"%s%s[bp%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
case 7:
sprintf(strOutput,"%s%s[bx%c0x%02X]",strOpSize,strSegOverride,cTemp,ucD8);
return 1;
};
case 2:
/* we have a disp16 value */
pIA32Decode->SIA32InstructionHelper.cbRawDisplacement = 2;
CopyMemory(pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement,
pStart + pIA32Decode->SIA32InstructionHelper.cbRawPrefixes +
pIA32Decode->SIA32InstructionHelper.cbRawOpcode +
pIA32Decode->SIA32InstructionHelper.boolModRMExists,
2);
usD16 = *(unsigned short*)pIA32Decode->SIA32RawInstruction.URawDisplacement.ca2ByteRawDisplacement;
switch(ModRM & 0x07)
{
case 0:
sprintf(strOutput,"%s%s[bx+si+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 1:
sprintf(strOutput,"%s%s[bx+di+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 2:
sprintf(strOutput,"%s%s[bp+si+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 3:
sprintf(strOutput,"%s%s[bp+di+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 4:
sprintf(strOutput,"%s%s[si+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 5:
sprintf(strOutput,"%s%s[di+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 6:
sprintf(strOutput,"%s%s[bp+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
case 7:
sprintf(strOutput,"%s%s[bx+0x%04X]",strOpSize,strSegOverride,usD16);
return 1;
};
};
return 0;
};
void GetSIBBase(unsigned char SIB, char *strBuffer, int cbBuffer)
{
ZeroMemory(strBuffer,cbBuffer);
switch(SIB & 0x7)
{
case 0:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -