首页
社区
课程
招聘
求教一个关于反汇编的问题
发表于: 2005-8-19 14:08 5132

求教一个关于反汇编的问题

2005-8-19 14:08
5132
在处理一段机器码的时候,反汇编工具是如何将其成一个一个的汇编指令的?也就是说,如何确定一条汇编指令的长度?比如55 89 E5 6A FF,反汇编工具是如何确定要像55/89 E5/6A FF这样断开,并得出push ebp/mov ebp,esp/push -1?希望高手能给出一个详细点的解答,最好是完整的方法。谢谢!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
因为55是单字节指令,没有55 xx等多字节指令的形式.
89/6A已经定义不是单字节指令,因此要取下一字节或更多字节组成一个指令.
如果学过huffman编码就能很好地理解.
2005-8-19 17:44
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
具体一下,如何确定一个值(如55)是单字节指令?是有一个固定的表吗?
2005-8-19 19:50
0
雪    币: 390
活跃值: (707)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
4
是的。
你可以参考Intel的指令手册,或者去看老罗的网站
2005-8-19 22:50
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
Intel指令集?还好,这个东东我有。但是还有一事不明:知道指令了,如何确定参数长度?
比如下面:
0F 47 /r          CMOVA r16, r/m16         Move if above (CF=0 and ZF=0)
0F 47 /r          CMOVA r32, r/m32         Move if above (CF=0 and ZF=0)
如何确定参数是16位还是32位?
2005-8-20 09:36
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Intel指令集?还好,这个东东我有。但是还有一事不明:知道指令了,如何确定参数长度?
比如下面:
0F 47 /r          CMOVA r16, r/m16         Move if above (CF=0 and ZF=0)
0F 47 /r          CMOVA r32, r/m32         Move if above (CF=0 and ZF=0)
如何确定参数是16位还是32位?
2005-8-20 09:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
Intel指令集?还好,这个东东我有。但是还有一事不明:知道指令了,如何确定参数长度?
比如下面:
0F 47 /r          CMOVA r16, r/m16         Move if above (CF=0 and ZF=0)
0F 47 /r          CMOVA r32, r/m32         Move if above (CF=0 and ZF=0)
如何确定参数是16位还是32位?
2005-8-20 09:47
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
0F是扩展指令集的前缀码,指令长度要参考后面的机器指令.
如0F 47,指令长度取决于后面的47.
2005-8-20 10:24
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢各位的指导,但看来要写成程序好像不是很够用。简单一点说,我的程序需要能在一段机器码中间按汇编断开,各位如果会作希望给出一点完整的方案,谢谢!
2005-8-21 08:21
0
雪    币: 217
活跃值: (99)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
送你一个函数,可以统计一段代码的指令数,当然包括断开指令的算法.
支持80386,FPU,PPro,MMX,3DNow!,SSE,SSE2,SSE3等指令集,自己研究去吧.

int instructionCount(unsigned char *func)
{
        int count = 0;

        while(*func != 0xCC)
        {
                // Skip prefixes F0h, F2h, F3h, 66h, 67h, D8h-DFh
                int operandSize = 4;
                int FPU = 0;
                while(*func == 0xF0 ||
                      *func == 0xF2 ||
                      *func == 0xF3 ||
                      (*func & 0xFE) == 0x66 ||
                      (*func & 0xF8) == 0xD8)
                {
                        if(*func == 0x66)
                        {
                                operandSize = 2;
                        }
                        else if((*func & 0xF8) == 0xD8)
                        {
                                FPU = *func++;
                                break;
                        }

                        func++;
                }

                // Skip two-byte opcode byte
                bool twoByte = false;
                if(*func == 0x0F)
                {
                        twoByte = true;
                        func++;
                }

                // Skip opcode byte
                unsigned char opcode = *func++;

                // Skip mod R/M byte, undo when not required
                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++;
                        }
                }

                // Skip SIB and displacement
                if((modRM & 0x07) == 0x04) func += 1;        // SIB
                if((modRM & 0xC5) == 0x05) func += 4;        // Dword displacement, no base
                if((modRM & 0xC0) == 0x40) func += 1;        // Byte displacement
                if((modRM & 0xC0) == 0x80) func += 4;        // Dword displacement

                // Skip immediate
                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 & 0xF8) == 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 & 0xF8) == 0xB8 ||
                                (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
                        }
                }

                count++;
        }

        return count;
}
2005-8-22 00:12
0
雪    币: 228
活跃值: (85)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
我也又找到一个
Micro Length-Disassembler Engine32
                ------------------------------------------
                ABOUT THE MICRO LENGTH-DISASSEMBLER ENGINE
                ------------------------------------------
    ----------
     OVERVIEW
    ----------

        A  length-disassembler engine is a piece of code that allows u to know
    the length of any x86 instruction. The mlde32 engine supports the ordinary 386
    opcode set, plus the extensions: fpu, mmx, cmov, sse, sse2 etc...

    It's usage is very simple here's the prototype:

         int __cdecl mlde32(void *codeptr);

         where:
         codeptr -> is a pointer to the opcode that u want to know the size.

        if  you have any  problem  using  the engine,  just take look in  some
        examples at the /examples (nothing more obvious).  That's  a very  simple  and
        powerful engine,and does not require too much system resources either,just 160
    bytes of stack space is needed. This engine is only code, and no fixed offsets
    were used so it can be permutaded/perverted at your own will.

    Obs: This engine is NOT a smaller version of Z0MBiE's LDE engine, Z0MBiE's lde
    is brilliant mine one is just awesome. :-)

附件:mlde32.zip
2005-8-22 00:27
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢各位的支持!不胜感激!
2005-8-22 08:01
0
游客
登录 | 注册 方可回帖
返回
//