📄 disasm.cpp
字号:
op->farptr.segment= PeekW(codebuf+2);
}
else
{
op->farptr.offset = PeekD(codebuf);
op->farptr.segment= PeekW(codebuf+4);
}
if (U_Size == BIT16)
sprintf(outbuf,"%04X:%04X",op->farptr.segment,op->farptr.offset);
else
sprintf(outbuf,"%04X:%08X",op->farptr.segment,op->farptr.offset);
return op->opersize;
}
/***********************************************************/
DWORD CDisasm::ProcessOpdata(DWORD opdata,POPERITEM op,PSTR outbuf,DWORD codepos)
{
if (BaseAddress == 0x4011cb)
{
BaseAddress = 0x4011cb;
}
op->mode = OP_Invalid;
switch(opdata)
{
case D_NONE:
break;
case D_EB:
case D_EW:
case D_EV:
if (opdata == D_EB)
op->opersize = Global_GetSize(SIZE_B);
else if (opdata == D_EW)
op->opersize = Global_GetSize(SIZE_W);
else
op->opersize = Global_GetSize(SIZE_V);
return Global_MODRM(outbuf,UasmCode+CodeCount,op);
case D_GB:
case D_GW:
case D_GV:
if (opdata == D_GB)
op->opersize = Global_GetSize(SIZE_B);
else if (opdata == D_GW)
op->opersize = Global_GetSize(SIZE_W);
else
op->opersize = Global_GetSize(SIZE_V);
return Global_REG(outbuf,UasmCode+CodeCount,op);
case D_IB:
case D_IW:
case D_IV:
if (opdata == D_IB)
op->opersize = Global_GetSize(SIZE_B);
else if (opdata == D_IW)
op->opersize = Global_GetSize(SIZE_W);
else
op->opersize = Global_GetSize(SIZE_V);
return Global_IMMED(outbuf,UasmCode+codepos,op);
case D_SB:
op->opersize = Global_GetSize(SIZE_B);
return Global_SIGNEDIMMED(outbuf,UasmCode+codepos,op);
case D_SW:
op->opersize = Global_GetSize(SIZE_W);
return Global_SREG(outbuf,UasmCode+CodeCount,op);
case D_MV:
case D_MP:
case D_MA:
if (opdata == D_MV)
op->opersize = Global_GetSize(SIZE_V);
else if (opdata == D_MP)
op->opersize = Global_GetSize(SIZE_P);
else
op->opersize = Global_GetSize(SIZE_A);
return Global_MEMORY(outbuf,UasmCode+CodeCount,op);
case D_OB:
case D_OV:
if (opdata == D_OB)
op->opersize = Global_GetSize(SIZE_B);
else
op->opersize = Global_GetSize(SIZE_V);
return Global_OFFSET(outbuf,UasmCode+codepos,op);
case D_JB:
op->opersize = 1;
return Global_NEARPTR(outbuf,UasmCode+CodeCount,op);
case D_JV:
op->opersize = (U_Size == BIT32) ? 4 : 2;
return Global_NEARPTR(outbuf,UasmCode+CodeCount,op);
case D_JP:
op->opersize = Global_GetSize(SIZE_P);
return Global_FARPTR(outbuf,UasmCode+CodeCount,op);
case D_RD:
case D_CD:
case D_DD:
// Not support now
SetError(ERR_INVALIDCODE);
break;
case D_1:
op->mode = OP_Immed;
op->opersize = 1;
op->immed.immed_value= 1;
strcpy(outbuf,"1");
break;
case D_AL:
case D_CL:
case D_DL:
case D_BL:
case D_AH:
case D_CH:
case D_DH:
case D_BH:
op->mode = OP_Register;
op->opersize = Global_GetSize(SIZE_B);
op->reg.reg_index = opdata-D_AL;
strcpy(outbuf,RegByte[opdata-D_AL]);
break;
case D_AX:
case D_CX:
case D_DX:
case D_BX:
case D_SP:
case D_BP:
case D_SI:
case D_DI:
op->mode = OP_Register;
op->opersize = Global_GetSize(SIZE_W);
op->reg.reg_index = opdata-D_AX;
strcpy(outbuf,RegWord[opdata-D_AX]);
break;
case D_AXV:
case D_CXV:
case D_DXV:
case D_BXV:
case D_SPV:
case D_BPV:
case D_SIV:
case D_DIV:
op->mode = OP_Register;
op->opersize = Global_GetSize(SIZE_V);
op->reg.reg_index = opdata-D_AXV;
if (op->opersize == 2)
strcpy(outbuf,RegWord[opdata-D_AXV]);
else
strcpy(outbuf,RegDWord[opdata-D_AXV]);
break;
case D_ES:
case D_CS:
case D_SS:
case D_DS:
case D_FS:
case D_GS:
op->mode = OP_Segment;
op->opersize = Global_GetSize(SIZE_V);
op->sreg.sreg_index = opdata-D_ES;
strcpy(outbuf,SegReg[opdata-D_ES]);
break;
}
return 0;
}
CString CDisasm::ProcessSegPrefix(POPERITEM op)
{
CString retn;
if (op->mode != OP_Address)
return retn;
DWORD defseg = _DS_;
if (op->addr.base_reg_index == _EBP_ || op->addr.base_reg_index == _ESP_)
defseg = _SS_;
if (SegPrefix != _NOSEG_ && SegPrefix != defseg)
{
retn = SegReg[SegPrefix];
retn += ':';
defseg = SegPrefix;
}
op->addr.seg_index = (BYTE)defseg;
SegPrefix = _NOSEG_;
return retn;
}
void CDisasm::ProcessInstruction( DWORD opcode,
PSTR instname,
DWORD opdata1,
DWORD opdata2,
DWORD opdata3)
{
if (opcode == C_ERROR)
{
SetError(ERR_INVALIDCODE);
return;
}
// Process LOCK and REPZ/REPNZ prefix
if (LockPrefix != NOPREFIX)
{
this->m_idaout->LockName = LockName;
//Putchs(LockName);
//SetBufPtrTox2();
}
if (RepPrefix != NOPREFIX)
{
this->m_idaout->RepName = RepName;
//Putchs(RepName);
//SetBufPtrTox2();
}
xcpu.opcode = (OPCODETYPE)opcode;
xcpu.lockflag = (BYTE)LockPrefix;
xcpu.repeatflag = (BYTE)RepPrefix;
// Process DIFFERENTNAME opcode-property
switch(opcode)
{
case C_CBW:
this->m_idaout->CmdStr = (OpSize == BIT16) ? instname : "CWDE";
break;
case C_CWD:
this->m_idaout->CmdStr = (OpSize == BIT16) ? instname : "CDQ";
break;
case C_JCXZ:
this->m_idaout->CmdStr = (OpSize == BIT16) ? instname : "JECXZ";
break;
default:
this->m_idaout->CmdStr = instname;
switch(opdata1)
{
case D_V:
if (OpSize == BIT32)
this->m_idaout->CmdStr += 'D';
break;
case D_XB:
this->m_idaout->CmdStr += 'B';
break;
case D_XV:
if (OpSize == BIT32)
this->m_idaout->CmdStr += 'D';
else
this->m_idaout->CmdStr += 'W';
break;
}
}
// Ok, now we have completed processing InstName
//SetBufPtrTox2();
// Now we begin to process opdata
char outbuf1[128];
char outbuf2[128];
char outbuf3[128];
DWORD codelen = CodeCount;
codelen += ProcessOpdata(opdata1,&xcpu.op[0],outbuf1,codelen);
codelen += ProcessOpdata(opdata2,&xcpu.op[1],outbuf2,codelen);
codelen += ProcessOpdata(opdata3,&xcpu.op[2],outbuf3,codelen);
// Ok, we have output the result of disassemble based on OPERITEM.
if (xcpu.op[0].mode != OP_Invalid)
{
// Process 1st Opdata WORD PTR prefix
if (xcpu.op[0].mode == OP_Address &&
xcpu.opcode != C_JMP &&
xcpu.opcode != C_CALL &&
xcpu.opcode != C_JMPFAR &&
xcpu.opcode != C_CALLFAR &&
(xcpu.op[1].mode == OP_Immed || xcpu.op[1].mode == OP_Invalid) )
{
switch(xcpu.op[0].opersize)
{
case 1:
this->m_idaout->Par1Ptr = "BYTE PTR ";
break;
case 2:
this->m_idaout->Par1Ptr = "WORD PTR ";
break;
case 4:
this->m_idaout->Par1Ptr = "DWORD PTR ";
break;
}
}
this->m_idaout->Par1SegPrefix = ProcessSegPrefix(&xcpu.op[0]);
this->m_idaout->Par1Str = outbuf1;
}
if (xcpu.op[1].mode != OP_Invalid)
{
// Process 2nd Opdata WORD PTR prefix
if (xcpu.op[1].mode == OP_Address &&
xcpu.op[1].opersize < xcpu.op[0].opersize )
//(xcpu.opcode == C_MOVZX || xcpu.opcode == C_MOVSX))
{
if (xcpu.op[1].opersize == 1)
this->m_idaout->Par2Ptr = "BYTE PTR ";
else
this->m_idaout->Par2Ptr = "WORD PTR ";
}
this->m_idaout->Par2SegPrefix = ProcessSegPrefix(&xcpu.op[1]);
this->m_idaout->Par2Str = outbuf2;
}
if (xcpu.op[2].mode != OP_Invalid)
{
this->m_idaout->Par3Str = outbuf3;
}
CodeCount = codelen;
// Complete it!
// Write code here to simulate instruction.
// VMSimulate(&xpcu);
}
void CDisasm::ProcessGroup(PINSTRUCTION pG,PINSTRUCTION inst)
{
MODRM modrm;
modrm.v = GetByte();
DWORD opdata1 = inst->Opdata1;
DWORD opdata2 = inst->Opdata2;
DWORD opdata3 = inst->Opdata3;
if (pG[modrm.reg].Opdata1 != D_NONE)
opdata1 = pG[modrm.reg].Opdata1;
if (pG[modrm.reg].Opdata2 != D_NONE)
opdata2 = pG[modrm.reg].Opdata2;
if (pG[modrm.reg].Opdata3 != D_NONE)
opdata3 = pG[modrm.reg].Opdata3;
ProcessInstruction( pG[modrm.reg].Opcode,
pG[modrm.reg].InstName,
opdata1,
opdata2,
opdata3
);
}
void CDisasm::DisassemblerOne()
{
BYTE by = GetByteEx();
switch(instruction[by].Opcode)
{
case C_ERROR:
SetError(ERR_INVALIDCODE);
break;
case C_GROUP: // It'a group. If this, InstName specifies the group table.
ProcessGroup((PINSTRUCTION)(instruction[by].InstName),&instruction[by]);
break;
case C_0FH: // It's 0FH instruction. If this, InstName specifies the 0FH table.
by = GetByteEx();
switch(instruction0FH[by].Opcode)
{
case C_ERROR:
break;
case C_GROUP: // It'a group. If this, InstName specifies the group table.
ProcessGroup((PINSTRUCTION)(instruction0FH[by].InstName),&instruction0FH[by]);
break;
default:
ProcessInstruction( instruction0FH[by].Opcode,
instruction0FH[by].InstName,
instruction0FH[by].Opdata1,
instruction0FH[by].Opdata2,
instruction0FH[by].Opdata3
);
break;
}
break;
case C_SEGPREFIX: // Segment Prefix
SegPrefix = instruction[by].Opdata1;
DisassemblerOne();
break;
case C_OPRSIZE: // Operand size change.
OpSizePrefix();
DisassemblerOne();
break;
case C_ADRSIZE: // Address size change.
AdrSizePrefix();
DisassemblerOne();
break;
case C_LOCK: // LOCK prefix
LockPrefix = 1;
LockName = instruction[by].InstName;
DisassemblerOne();
break;
case C_REPZ: // REPZ prefix
RepPrefix = REPZ_PREFIX;
RepName = instruction[by].InstName;
DisassemblerOne();
break;
case C_REPNZ: // REPNZ prefix
RepPrefix = REPNZ_PREFIX;
RepName = instruction[by].InstName;
DisassemblerOne();
break;
default:
ProcessInstruction( instruction[by].Opcode,
instruction[by].InstName,
instruction[by].Opdata1,
instruction[by].Opdata2,
instruction[by].Opdata3
);
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -