📄 dsasm_functions.cpp
字号:
char menemonic[128]="",tempMeme[128]="",Addr[15]="",temp[128]="";
char instr[50]="";
// Get used Register
// Get target register, example:
// 1. add byte ptr [ecx], -> al <-
// 2. add -> al <- ,byte ptr [ecx]
REG=(BYTE)(*(*Opcode+pos+1));
REG>>=3;
REG&=0x07;
//Displacement MOD (none|BYTE/WORD|DWORD)
Extension=(BYTE)(*(*Opcode+pos+1))>>6;
/*
There are 3 types of Displacement to RegMem
00 -> [00] 000 000 ; no byte extention ([RegMem])
40-> [01] 000 000 ; 1 byte extenton ([RegMem+XX])
80 -> [10] 000 000 ; 4 bytes extention ([RegMem+XXXXXXXX])
*/
//===================//
// Bitwise OverRides //
//===================//
// Arpl, Bound, Test, Xchg menemonics are special cases! when alone.
// so we need to set specific static bits for d/w
// We specify Size of Data corresponding to each mnemonic.
switch((BYTE)(*(*Opcode+pos)))
{
case 0x20: { PrefixReg=0; } break; // Force Byte Size Regardless Operands.
case 0x39: case 0x3B: strcpy(RSize,regSize[1]); break; // DWORD
case 0x63: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // DWORD
case 0x62: { RM=REG32; bound=1; Bit_d=1; Bit_w=0; strcpy(RSize,regSize[0]); } break; // QWORD
case 0x69: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // DWORD
case 0x6B: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // DWORD
case 0x84: case 0x86: { Bit_d=0; Bit_w=0; } break; // BYTE
case 0x85: case 0x87: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // DWORD
case 0x80: case 0x82: case 0xC6: case 0xF6:{ Bit_d=0;Bit_w=0; strcpy(RSize,regSize[3]); } break; // BYTE
case 0x81: case 0x83: case 0xC7: case 0xF7: case 0x89:{ Bit_d=0;Bit_w=1; strcpy(RSize,regSize[1]); } break;
case 0x8B: strcpy(RSize,regSize[1]); break; // DWORD
case 0x8C: case 0x8E: { strcpy(RSize,regSize[2]); } break; // WORD
case 0x8D: case 0x8F: { Bit_d=1; Bit_w=1; strcpy(RSize,regSize[1]); } break; // POP/LEA
case 0xC0: { Bit_d=1; Bit_w=0;} break; // BYTE
case 0xC1: { Bit_d=1; Bit_w=1; strcpy(RSize,regSize[1]); } break; // MIX
case 0xC4: case 0xC5: { RM=REG32; Bit_d=1; Bit_w=0; strcpy(RSize,regSize[4]); } break; // LES/LDS
case 0xD0: case 0xD2: { Bit_d=0; Bit_w=0; strcpy(RSize,regSize[3]); } break; // MIX
case 0xD1: case 0xD3: { Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // MIXED
case 0xD8: { UsesFPU=1; Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // FPU
case 0xD9:{
UsesFPU=1; Bit_d=0; Bit_w=0;
switch(REG)
{
case 0: case 2: case 3:strcpy(RSize,regSize[1]); break; // DWORD (REAL4)
case 4: case 6: strcpy(RSize,regSize[6]); break; // 28Bytes
case 5: case 7: strcpy(RSize,regSize[2]); break; // WORD (REAL2)
}
}
break; // FPU
case 0xDA: { UsesFPU=1; Bit_d=0; Bit_w=1; strcpy(RSize,regSize[1]); } break; // FPU
case 0xDB: { UsesFPU=1; Bit_d=0; Bit_w=0; if(REG<4) strcpy(RSize,regSize[1]); else strcpy(RSize,regSize[5]);} break; // FPU
case 0xDC: { UsesFPU=1; Bit_d=0; Bit_w=0; strcpy(RSize,regSize[0]); } break; // FPU
case 0xDD: {
UsesFPU=1; Bit_d=0; Bit_w=0;
switch(REG)
{
case 0: case 1: case 2: case 3: strcpy(RSize,regSize[0]); break; // QWORD
case 4: case 5: case 6: strcpy(RSize,regSize[7]); break; // (108)Byte
case 7: strcpy(RSize,regSize[2]); break; // WORD
}
}
break; // FPU
case 0xDE: { UsesFPU=1; Bit_d=0; Bit_w=0; strcpy(RSize,regSize[2]); } break; // WORD
case 0xDF: {
UsesFPU=1; Bit_d=0; Bit_w=0;
switch(REG)
{
case 0: case 1: case 2: case 3: strcpy(RSize,regSize[2]); break; // WORD
case 4: case 6: strcpy(RSize,regSize[5]); break; // TByte
case 5: case 7: strcpy(RSize,regSize[0]); break; // QWord
}
}
break;
case 0xFE: { Bit_d=0; Bit_w=0; strcpy(RSize,regSize[3]); } break; // BYTE
case 0xFF: {
Bit_d=0; Bit_w=0;
if(REG==3 || REG==5) // FAR JMP/CALL
strcpy(RSize,regSize[4]); // FWORD
else
strcpy(RSize,regSize[1]);
}
break; // DWORD
}
// check for bit register size : 16bit/32bit
if(Bit_w==1)
{
RM=REG32; // 32bit registers set
//if(/*!bound/&& Op==0x62*/)// Special Case
strcpy(RSize,regSize[1]); // dword ptr
}
// check for prefix 0x66 OverRide (change default size)
if(PrefixReg==1)
{
if(!UsesFPU) // FPU DataSize doesn't Change, others are, on prefix 0x66.
{
if(lstrcmp(RSize,"Byte")!=0) // doesn't affect byte mode
{
RM=REG16; // 16bit registers
strcpy(RSize,regSize[2]); // word ptr
if(Op==0x62 || Op==0xC4 || Op==0xC5) // Special Case, 66 Prefix doesn't affect Memory Size.
strcpy(RSize,regSize[1]);
}
}
}
// SCALE INDEX BASE :
SIB=(BYTE)(*(*Opcode+pos+1))&0x07; // Get SIB extension
/*
Exmaple:
--------
format of sib is:
ss iii bbb.
where ss is 2 upper bits for scale
and they represent power (exponent) of 2 for
scale index multipyer.
iii is 3 middle bits for index.
bbb is 3 low bits for base.
*SIB == 4
*NO SIB != 4
0x04 -> 00 000 [100] <- SIB
0x0C -> 00 001 [100] <- SIB
0x64 -> 01 100 [100] <- SIB
0x60 -> 01 100 [000] <- NO SIB
0xB5 -> 10 110 [101] <- NO SIB
0x76 -> 01 110 [110] <- NO SIB
Extract SS II BB information (3rd byte)
=======================================
0x81,0xAC,0x20
0x20 = 00 100 000
Scale: 00 = *1 (not shown)
100 - ESP = not Shown, Cannot be an Index register
000 - EAX = shown
if MOD 10/01 is being used, get displacement data after
the SIB.
*/
// ===================================================//
// AddrPrefix is being used! //
// ===================================================//
if(PrefixAddr==1) // Prefix 0x67 is set, Change Segments/Addressing Modes to 16 bits
{
FOpcode=((BYTE)(*(*Opcode+pos+1))&0x0F); // Get addressing Mode (8 types of mode)
reg1=((BYTE)(*(*Opcode+pos+1))&0x38)>>3;
// Check if we decode POP instruction, which had few valid instruction.
if(Op==0x8F && reg1!=0)
lstrcat((*Disasm)->Remarks,"Invalid Instruction");
// Choose Mode + Segment
switch(FOpcode)
{
case 0x00: case 0x08: wsprintf(Addr,"%s",addr16[0]); /*SEG=SEG_DS;*/ break; // Mode 0:[BX+SI]
case 0x01: case 0x09: wsprintf(Addr,"%s",addr16[1]); /*SEG=SEG_DS;*/ break; // Mode 1:[BX+DI]
case 0x02: case 0x0A: wsprintf(Addr,"%s",addr16[2]); SEG=SEG_SS; break; // Mode 2:[BP+SI]
case 0x03: case 0x0B: wsprintf(Addr,"%s",addr16[3]); SEG=SEG_SS; break; // Mode 3:[BP+DI]
case 0x04: case 0x0C: wsprintf(Addr,"%s",addr16[4]); /*SEG=SEG_DS;*/ break; // Mode 4:[SI]
case 0x05: case 0x0D: wsprintf(Addr,"%s",addr16[5]); /*SEG=SEG_DS;*/ break; // Mode 5:[DI]
case 0x06: case 0x0E: // Mode 6: [BP+XX/XXXX] | [XX]
{
if(Extension==0) // 0x00-0x3F only! has special [XXXX]
{
/*SEG=SEG_DS;*/
SwapWord((BYTE*)(*Opcode+pos+2),&wOp,&wMem);
wsprintf(Addr,"%04X",wMem);
(*(*index))+=2; // read 2 bytes
}
else{ // 0x50-0xBF has [BP+]
SEG=SEG_SS; // SS Segment
wsprintf(Addr,"%s",addr16[7]);
}
}
break;
case 0x07: case 0x0F: wsprintf(Addr,"%s",addr16[6]); /*SEG=SEG_DS;*/ break; // Mode 7: [BX]
}
// Choose used extension
// And Decode properly the menemonic
switch(Extension)
{
case 0: // No extension of bytes to RegMem (except mode 6)
{
wsprintf(tempMeme,"%s ptr %s:[%s]",RSize,segs[SEG],Addr);
SwapDword((BYTE*)(*Opcode+pos),&dwOp,&dwMem);
SwapWord((BYTE*)(*Opcode+pos),&wOp,&wMem);
if(((wOp&0x00FF)&0x0F)==0x06) // 0x00-0x3F with mode 6 only!
{
wsprintf(menemonic,"%08X",dwOp);
(*Disasm)->OpcodeSize=4;
lstrcat((*Disasm)->Opcode,menemonic);
}
else{ // other modes
wsprintf(menemonic,"%04X",wOp);
(*Disasm)->OpcodeSize=2;
lstrcat((*Disasm)->Opcode,menemonic);
}
}
break;
case 1: // 1 Byte Extension to regMem
{
SwapWord((BYTE*)(*Opcode+pos+1),&wOp,&wMem);
FOpcode=wOp&0x00FF;
if(FOpcode>0x7F) // check for signed numbers
{
wsprintf(Aritmathic,"%s",Scale[0]); // '-' Signed Numbers
FOpcode = 0x100-FOpcode; // -XX
}
wsprintf(menemonic,"%02X%04X",Op,wOp);
lstrcat((*Disasm)->Opcode,menemonic);
wsprintf(tempMeme,"%s ptr %s:[%s%s%02X]",RSize,segs[SEG],Addr,Aritmathic,FOpcode);
++(*(*index)); // 1 byte read
(*Disasm)->OpcodeSize=3;
}
break;
case 2: // 2 Bytes Extension to RegMem
{
SwapDword((BYTE*)(*Opcode+pos),&dwOp,&dwMem);
SwapWord((BYTE*)(*Opcode+pos+2),&wOp,&wMem);
wsprintf(menemonic,"%08X",dwOp);
(*Disasm)->OpcodeSize=4;
lstrcat((*Disasm)->Opcode,menemonic);
wsprintf(tempMeme,"%s ptr %s:[%s%s%04X]",RSize,segs[SEG],Addr,Aritmathic,wMem);
(*(*index))+=2; // we read 2 bytes
}
break;
}
// Switch Direction Mode.
// And Build Menemonic from that direction
switch(Bit_d)
{
case 0: // (->)
{
// Check for More Menemonics Addons
switch(Op)// Check for all Cases
{
case 0x6B:
{
// We check Extension because there is a diff
// Reading position of bytes depend on the extension
// 1 = read byte, 3rd position
// 2 = read dword, 6th position
if(Extension==1) // read 1 byte at 3rd position
{
SwapWord((BYTE*)(*Opcode+pos+2),&wOp,&wMem);
FOpcode=wOp&0x00FF;
wsprintf(temp,"%02X",FOpcode);
lstrcat((*Disasm)->Opcode,temp);
}
else{
if(Extension==2) //read byte at 7th position (dword read before)
{
SwapWord((BYTE*)(*Opcode+pos+3),&wOp,&wMem);
FOpcode=wOp&0x00FF;
wsprintf(temp,"%02X",FOpcode);
lstrcat((*Disasm)->Opcode,temp);
}
else
{ // Extension==0
SwapWord((BYTE*)(*Opcode+pos+1),&wOp,&wMem);
FOpcode=wOp&0x00FF;
wsprintf(temp,"%02X",FOpcode);
lstrcat((*Disasm)->Opcode,temp);
}
}
if(FOpcode>0x7F) // check for signed numbers!!
{
FOpcode = 0x100-FOpcode; // -XX (Signed)
wsprintf(Aritmathic,"%s",Scale[0]); // '-' aritmathic (Signed)
}
else
strcpy(Aritmathic,"");
strcpy(instruction,"imul");
wsprintf(temp,"%s %s,%s,%s%02X",instruction,regs[RM][reg2],tempMeme,Aritmathic,FOpcode);
(*(*index))++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -