📄 disasm.c
字号:
void AnalyzeOperModrm(void) //分析寻址方式为O,E,M,R的情况,O类寻址方式为直接寻址,操作数偏移直接给出.其它三类操作数在MODRM中
//这可是个大函数,不过结构清晰,容易阅读
//整个函数分三部分,第一部分if负责输出XX PTR,第二个部分switch用来输出段前缀
//第三部分if用来输出操作数,又分为三部分.第一部分处理寻址方式为E,M,R且没有前缀67的情况,第二部份处理寻址方式O,第三部分处理寻址方式E,M,R且有前缀67的情况
{
GetModrm();
if ( ins.modrm.mod!=3 || ins.code_data[8]=='O') //这一组寻址方式除MODRM的mod==11都是存储器寻址,要显示"XX ptr"
{
switch (ins.code_data[9])
{
case 'B': //操作数大小是BYTE
strcpy(ins.asm_code_writing,"BYTE PTR ");
ins.asm_code_writing += 9;
break;
case 'W': //操作数大小是WORD
strcpy(ins.asm_code_writing,"WORD PTR ");
ins.asm_code_writing += 9;
break;
case 'D': //操作数大小是DWORD
strcpy(ins.asm_code_writing,"DWORD PTR ");
ins.asm_code_writing += 10;
break;
case 'V': //操作数大小是WORD或DWORD,根据前缀66判断
if (ins.prefix[0]) //如果前缀66
{
strcpy(ins.asm_code_writing,"WORD PTR ");
ins.asm_code_writing += 9;
}
else
{
strcpy(ins.asm_code_writing,"DOWRD PTR ");
ins.asm_code_writing += 10;
}
break;
case 'P': //操作数是远指针,大小是48位或32位,根据前缀66判断
if (ins.prefix[0])
{
strcpy(ins.asm_code_writing,"FAR WORD PTR ");
ins.asm_code_writing += 13;
}
else
{
strcpy(ins.asm_code_writing,"FAR DWORD PTR ");
ins.asm_code_writing += 14;
}
break;
case 'S': //操作数是6字节伪描述符
strcpy(ins.asm_code_writing,"FWORD PTR ");
ins.asm_code_writing += 10;
break;
}
}
switch (ins.prefix[3]) //输出段前缀
{
case 0x64:
strcpy(ins.asm_code_writing,"FS: ");
ins.asm_code_writing += 4;
break;
case 0x65:
strcpy(ins.asm_code_writing,"GS: ");
ins.asm_code_writing += 4;
break;
case 0x26:
strcpy(ins.asm_code_writing,"ES: ");
ins.asm_code_writing += 4;
break;
case 0x36:
strcpy(ins.asm_code_writing,"SS: ");
ins.asm_code_writing += 4;
break;
case 0x3e:
strcpy(ins.asm_code_writing,"DS: ");
ins.asm_code_writing += 4;
break;
case 0x2e:
strcpy(ins.asm_code_writing,"CS: ");
ins.asm_code_writing += 4;
break;
}
if ( ins.code_data[8]!='O' && !ins.prefix[1]) //处理不是O类寻址方式,且没有前缀67的情况
{
switch (ins.modrm.mod)
{
case 3:
if (ins.prefix[0]) //判断前缀66
{
fseek(RegTable, (ins.modrm.rm<<3)+0x40, SEEK_SET); //从reg_table表读16位寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 2;
}
else
{
fseek(RegTable, ins.modrm.rm<<3, SEEK_SET); //从reg_table表读32位寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
}
ins.operand_len++;
break;
case 2:
case 1:
if ( ins.modrm.rm == 4) //[base+disp+s*index]型
{
* ins.asm_code_writing++ = '[';
fseek(RegTable, ins.sib.base<<3,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
if ( ins.num < 0 ) //如果偏移为负
{
* ins.asm_code_writing++ = '-';
ins.num = (~ins.num) + 1; //变为正数
}
else
* ins.asm_code_writing++ = '+';
NumToText(4); //计算disp
if (ins.sib.index != 4) //取得变址寄存器
{
* ins.asm_code_writing++ = '+';
if (ins.sib.s != 1) //判断比例因子
{
* ins.asm_code_writing++ = ins.sib.s+0x30;
* ins.asm_code_writing++ = '*';
}
fseek(RegTable, ins.sib.index<<3,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
}
* ins.asm_code_writing++ = ']';
if (ins.modrm.mod == 2) //计算ins.operlen
ins.operand_len += 6;
else
ins.operand_len += 3;
}
else //[base+disp]型
{
* ins.asm_code_writing++ = '[';
fseek(RegTable,ins.modrm.rm<<3,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
if ( ins.num < 0 ) //如果偏移为负
{
* ins.asm_code_writing++ = '-';
ins.num = (~ins.num) + 1; //变为正数
}
else
* ins.asm_code_writing++ = '+';
NumToText(4); //计算disp
* ins.asm_code_writing++ = ']';
if (ins.modrm.mod == 2) //计算ins.operlen
ins.operand_len += 5;
else
ins.operand_len += 2;
}
break;
case 0:
if (ins.modrm.rm == 5) //[disp32]型
{
* ins.asm_code_writing++ = '[';
NumToText(4); //计算disp
* ins.asm_code_writing++ = ']';
ins.operand_len += 5;
}
else if (ins.modrm.rm == 4)
{
if (ins.sib.base == 5) //[disp32+s*index]型
{
* ins.asm_code_writing++ = '[';
NumToText(4); //计算disp
if (ins.sib.index != 4) //取得变址寄存器
{
* ins.asm_code_writing++ = '+';
if (ins.sib.s != 1) //判断比例因子
{
* ins.asm_code_writing++ = ins.sib.s+0x30;
* ins.asm_code_writing++ = '*';
}
fseek(RegTable, ins.sib.index<<3,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
}
* ins.asm_code_writing++ = ']';
ins.operand_len += 6;
}
else //[base+s*index]型
{
* ins.asm_code_writing++ = '[';
fseek(RegTable, ins.sib.base<<3, SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
if (ins.sib.index != 4) //取得变址寄存器
{
* ins.asm_code_writing++ = '+';
if (ins.sib.s != 1) //判断比例因子
{
* ins.asm_code_writing++ = ins.sib.s+0x30;
* ins.asm_code_writing++ = '*';
}
fseek(RegTable, ins.sib.index<<3,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
}
* ins.asm_code_writing++ = ']';
ins.operand_len += 2;
}
}
else //[base]型
{
* ins.asm_code_writing++ = '[';
fseek(RegTable, ins.modrm.rm<<3,SEEK_SET); ////从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 3;
* ins.asm_code_writing++ = ']';
ins.operand_len ++;
}
break;
}
}
else if (ins.code_data[8]=='O') //翻译O类指令
{
if ( ins.prefix[1] ) //如果前缀67
{
ins.num = *((long *)(ins.ins_buf+ins.processing)) & 0xffff; //计算16位偏移地址
* ins.asm_code_writing++ = '[';
NumToText(2); //计算操作数偏移
* ins.asm_code_writing++ = ']';
ins.operand_len += 2;
}
else
{
ins.num = *((long *)(ins.ins_buf+ins.processing)); //从指令码中取得32位偏移地址
* ins.asm_code_writing++ = '[';
NumToText(4); //计算disp
* ins.asm_code_writing++ = ']';
ins.operand_len += 4;
}
}
else //处理前缀67且是MODRM寻址的情况
{
switch (ins.modrm.mod)
{
case 2: //[reg+disp]型
case 1:
* ins.asm_code_writing++ = '[';
fseek(RegTable,(ins.modrm.rm<<3)+0x100,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 5;
if ( ins.num < 0 ) //如果偏移为负
{
* ins.asm_code_writing++ = '-';
ins.num = (~ins.num) + 1; //变为正数
}
else
* ins.asm_code_writing++ = '+';
NumToText(2); //计算disp
* ins.asm_code_writing++ = ']';
if (ins.modrm.mod == 2)
ins.operand_len += 3; //计算ins.operand_len
else
ins.operand_len += 2;
ins.operand_len += 3;
break;
case 0:
if (ins.modrm.rm == 5) //[disp16]型
{
* ins.asm_code_writing++ = '[';
NumToText(2); //计算disp
* ins.asm_code_writing++ = ']';
ins.operand_len += 3;
}
else //[reg]型
{
* ins.asm_code_writing++ = '[';
fseek(RegTable,(ins.modrm.rm<<3)+0x100,SEEK_SET); //从reg_table表读寄存器字串
fread( ins.asm_code_writing, 8, 1, RegTable);
ins.asm_code_writing += 5;
* ins.asm_code_writing++ = ']';
ins.operand_len ++;
}
}
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -