-
-
[原创]一个32位长度反汇编引擎以及对xfish LDE的进一步优化
-
发表于:
2009-8-10 23:08
8851
-
[原创]一个32位长度反汇编引擎以及对xfish LDE的进一步优化
这里有两个主题,不过都是关于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;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)