首页
社区
课程
招聘
[原创]一个32位长度反汇编引擎以及对xfish LDE的进一步优化
发表于: 2009-8-10 23:08 8841

[原创]一个32位长度反汇编引擎以及对xfish LDE的进一步优化

2009-8-10 23:08
8841

这里有两个主题,不过都是关于LDE的,所以放在一起了。

主题一:一个32位长度反汇编引擎
和xfish的那个不同,这里的解析过程是模仿CPU解码。这个代码实际上是ASM Community窥来的,只是稍作修改。

#include "lde.h"

int LDE(const unsigned char *func) 
{ 
	int operandSize = 4;
	int FPU = 0;
	const unsigned char* pOrigin = func;
	
	//跳过F0h,F2h,F3h,66h,67h,2Eh,26h,36h,3Eh,64h,65h等前缀,
	//以及D8h-DFh等ESC(转移操作码)	
	while (*func == 0xF0 ||
		   *func == 0xF2 ||
		   *func == 0xF3 ||
		   *func == 0x66 ||
		   *func == 0x67 ||
		   *func == 0x2E ||
		   *func == 0x3E ||
		   *func == 0x26 ||
		   *func == 0x36 ||
		   *func == 0x64 ||
		   *func == 0x65 ||
		   (*func & 0xF8) == 0xD8	//D8-DF
		  ) 
	{ 
		if (*func == 0x66)
		{ 
			operandSize = 2;
		} 
		else if ( (*func & 0xF8)==0xD8 )
		{ 
			FPU = *func++;
			break;
		}
		
		func++;
	} 
	
	//跳过双字节操作码转义字节0Fh
	bool twoByte = false;
	if (*func == 0x0F)
	{
		twoByte = true;
		func++;
	}
	
	//跳过主操作码
	unsigned char opcode = *func++;
	
	//跳过ModR/M字节
	unsigned char modRM = 0xFF;
	if (FPU)
	{ 
		if ( (opcode & 0xC0) != 0xC0 ) 
		{ 
			modRM = opcode; 
		}
	}
	else if (!twoByte) 
	{ 
		if ((opcode & 0xC4) == 0x00 || 
			(opcode & 0xF4) == 0x60 && ((opcode & 0x0A) == 0x02 || (opcode & 0x09) == 0x9) || 
			(opcode & 0xF0) == 0x80 || 
			(opcode & 0xF8) == 0xC0 && (opcode & 0x0E) != 0x02 || 
			(opcode & 0xFC) == 0xD0 || 
			(opcode & 0xF6) == 0xF6
			) 
		{ 
			modRM = *func++; 
		}
	}
	else 
	{ 
		if ((opcode & 0xF0) == 0x00 && (opcode & 0x0F) >= 0x04 && (opcode & 0x0D) != 0x0D || 
			(opcode & 0xF0) == 0x30 || 
			opcode == 0x77 || 
			(opcode & 0xF0) == 0x80 || 
			(opcode & 0xF0) == 0xA0 && (opcode & 0x07) <= 0x02 || 
			(opcode & 0xF8) == 0xC8
			) 
		{ 
			// No mod R/M byte 
		} 
		else 
		{ 
			modRM = *func++; 
		} 
	} 
	
	//跳过SIB字节
	if ( (modRM & 0x07) == 0x04 && (modRM>>6 & 3) != 3  )
	{
		unsigned char SIB = *func;
		func += 1;
		if ((SIB & 0x7) == 5)
		{
			func += 4;  // disp32
		}
	}
	if ( (modRM & 0xC5) == 0x05 )
	{
		func += 4;   // disp32, no base 
	}
	if ( (modRM & 0xC0) == 0x40 )
	{
		func += 1;   // disp8
	}
	if ( (modRM & 0xC0) == 0x80 )
	{
		func += 4;   // disp32
	}
	
	//跳过立即数
	if (FPU)
	{
		// Can't have immediate operand
	}
	else if (!twoByte)
	{
		if ((opcode & 0xC7) == 0x04 ||
			(opcode & 0xFE) == 0x6A ||   // PUSH/POP/IMUL
			(opcode & 0xF0) == 0x70 ||   // Jcc
			opcode == 0x80 ||
			opcode == 0x83 ||
			(opcode & 0xFD) == 0xA0 ||   // MOV
			opcode == 0xA8 ||			 // TEST
			opcode == 0xB0 ||			 // MOV
			(opcode & 0xFE) == 0xC0 ||   // RCL
			opcode == 0xC6 ||			 // MOV
			opcode == 0xCD ||			 // INT
			(opcode & 0xFE) == 0xD4 ||   // AAD/AAM
			(opcode & 0xF8) == 0xE0 ||   // LOOP/JCXZ
			opcode == 0xEB ||
			opcode == 0xF6 && (modRM & 0x30) == 0x00   // TEST
			)
		{ 
			func += 1; 
		} 
		else if( (opcode & 0xF7) == 0xC2 ) 
		{ 
			func += 2;   // RET 
		} 
		else if( (opcode & 0xFC) == 0x80 || 
				 (opcode & 0xC7) == 0x05 || 
				 (opcode & 0xFE) == 0xE8 ||      // CALL/Jcc 
				 (opcode & 0xFE) == 0x68 || 
				 (opcode & 0xFC) == 0xA0 || 
				 (opcode & 0xEE) == 0xA8 || 
				 opcode == 0xC7 || 
				 opcode == 0xF7 && (modRM & 0x30) == 0x00
				) 
		{ 
			func += operandSize; 
		} 
	} 
	else 
	{ 
		if ( opcode == 0xBA ||			// BT 
			 opcode == 0x0F ||			// 3DNow! 
			 (opcode & 0xFC) == 0x70 ||  // PSLLW 
			 (opcode & 0xF7) == 0xA4 ||  // SHLD 
			 opcode == 0xC2 || 
			 opcode == 0xC4 || 
			 opcode == 0xC5 || 
			 opcode == 0xC6
			) 
		{ 
			func += 1; 
		} 
		else if((opcode & 0xF0) == 0x80) 
		{ 
			func += operandSize;   // Jcc -i 
		} 
	}
	
	return func-pOrigin;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
有技术含量啊. 怎么没有人关注?

不过第一种方法的代码编译出来 (vc6, O1) 的尺寸是 747 字节. 可能在尺寸上没有太多优势.
2009-8-17 11:02
0
雪    币: 558
活跃值: (43)
能力值: ( LV12,RANK:220 )
在线值:
发帖
回帖
粉丝
3
谢谢关注!
第一个是模拟CPU解码,不是一般的表查询,因为不附带表,可以用在一般的场合。

另一个问题是早几天才看了mlde32,才发现原来已经有了一个index-compressed优化的版本,不过和上面写的这个是不一样的。

附mlde32 mlde32.zip
上传的附件:
2009-8-17 12:06
0
游客
登录 | 注册 方可回帖
返回
//