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

📄 disasm.c

📁 反汇编intel32位指令的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

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 + -