首页
社区
课程
招聘
[原创]写了个反汇编的东西,分享出来
发表于: 2011-1-18 21:10 9208

[原创]写了个反汇编的东西,分享出来

2011-1-18 21:10
9208

原来写了个反汇编的函数,源代码好像也不太给力。

就大概说说原理吧:

源代码中自定义了许多表:

// 定义标志寄存器结构
typedef struct _INQUIRE_EFLAGS
{
DWORD dwUseField;      // 使用下列那些字段
DWORD dwTest;             // 要测试的标记,位1
DWORD dwModif;           // 会影响的32位标志寄存器,位2
DWORD dwDefine;         // 已定义的标记,位3
DWORD dwUndefine;     // 未定义的标记,这个标记还在考虑中,位4
DWORD dwFixSet;           // 确定会被置1的标记,位5
DWORD dwFixZro;           // 确定会被清0的标记,位6
} INQUIRE_EFLAGS, *LPINQUIRE_EFLAGS;

这个表,用于想要知道指令是否影响标记位的。

// ModR/M32表专用宏
#define MODRM32_MEM_FREG                0x1      // 全寄存器寻址
#define MODRM32_MEM_FREG_IMM1        0x2      // 全寄存器加立即数1寻址
#define MODRM32_MEM_FREG_IMM4        0x3      // 全寄存器加立即数4寻址
#define MODRM32_MEM_IMM4                0x4      // 立即数4寻址
#define MODRM32_REG                        0x5      // 寄存器作为操作数
#define MODRM32_SIB                        0x6      // 存在SIB

// ModR/M32表
typedef struct _TabModRM32
{
    BYTE  dwModRMMode;              // 寻址模式
    BYTE  dwMod;   
    BYTE  dwRegOp;
    BYTE  dwRM;
} TabModRM32;

这个表方便Mod如何解析的,反正就255种情况,我直接用程序生成这个表,直接查表,搞的现在我自己都忘了怎么解析Mod表,写的时候还知道。

// ModR/M16表专用宏
#define MODRM16_MEM_2REG           0x1 //   [bx + si], REG
#define MODRM16_MEM_1REG           0x2 //  [bx + si], REG
#define MODRM16_MEM_2REG_IMM1 0x3 //  [bx + si + IMM1], REG
#define MODRM16_MEM_1REG_IMM1 0x4 // [bx + si + IMM1], REG
#define MODRM16_MEM_2REG_IMM2 0x5 //[bx + si + IMM2], REG
#define MODRM16_MEM_1REG_IMM2 0x6 // [bx + si + IMM2], REG
#define MODRM16_MEM_IMM2           0x7 // [IMM2], REG
#define MODRM16_REG                      0x8 // Opcode REG, REG

typedef struct _TabModRM16
{
        BYTE  dwModRMMode;              // 寻址模式
        BYTE  dwMod;   
        BYTE  dwRegOp;
        BYTE  dwRM;
        BYTE  dwReg1;
        BYTE  dwReg2;
} TabModRM16;

同上,这个是16位的表

// SIB表
typedef struct _TabSib
{
BYTE   dwSibMode;              // 寻址模式
BYTE   dwScaleN;               // 比例因子
BYTE   dwIndex;             // 索引寄存器索引
BYTE   dwBase;              // 基址寄存器索引
} TabSib;

SIB也建表了

#define ADDR_BIT_1REG        BIT_4                // 地址中有1个寄存器
#define ADDR_BIT_2REG        (BIT_3 | BIT_4)        // 地址中有2个寄存器
#define ADDR_BIT_N        BIT_2                // 有比例因子
#define ADDR_BIT_IMM        BIT_1                // 有地址立即数

#define OPERAND_NULL 0x0        // 无操作数

// 最高位为1就是直接寻址,否则为间接寻址,直接寻址就是没有[]的
#define OPERAND_IMM (BIT_32 | ADDR_BIT_IMM)        // 立即数
#define OPERAND_REG (BIT_32 | ADDR_BIT_1REG)        // 寄存器

#define OPERAND_MEM_IMM        ADDR_BIT_IMM// 地址立即数
#define OPERAND_MEM_REG        ADDR_BIT_1REG        // 地址寄存器
#define OPERAND_MEM_REGIMM        (ADDR_BIT_1REG | ADDR_BIT_IMM)        // [REG + IMM]
#define OPERAND_MEM_2REG        ADDR_BIT_2REG// [REG1 + REG2]
#define OPERAND_MEM_2REGIMM        (ADDR_BIT_2REG | ADDR_BIT_IMM)        // [REG1 + REG2 + IMM]
#define OPERAND_MEM_1REGN        (ADDR_BIT_1REG | ADDR_BIT_N)        // [REG1 * N]
#define OPERAND_MEM_2REGN        (ADDR_BIT_2REG | ADDR_BIT_N)        // [REG1 + REG2 * N]
#define OPERAND_MEM_1REGNIMM (ADDR_BIT_1REG | ADDR_BIT_N | ADDR_BIT_IMM) // [REG1 * N + IMM]
#define OPERAND_MEM_2REGNIMM (ADDR_BIT_2REG | ADDR_BIT_N | ADDR_BIT_IMM)// [REG1 + REG2 * N + IMM]

// 其实2,4有符号数都是由1BYTE符号数扩展而来的
#define SIGN1IMM                0x1
#define SIGN2IMM                0x2
#define SIGN4IMM                0x3
#define UNSIGN1IMM                0x4
#define UNSIGN2IMM                0x5
#define UNSIGN4IMM                0x6

// 操作数结构
typedef struct  _UnImm
{
        BYTE ImmType;                                // 立即数类型,或地址立即数类型
        union                                               
        {
                CHAR  cImm;
                SHORT sImm;
                LONG  lImm;
                BYTE  Imm;
                WORD  wImm;
                DWORD dwImm;
        } AnyImm;

} UnImm;

// 操作数结构
typedef struct  _UnOperand
{
        DWORD AddrMode; // 表明本结构的意义和使用的字段
        BYTE Reg1;              // [base + index * n + IMM/1/4]
        BYTE Reg2;              //[Reg1 + Reg2 * n + IMM]
        BYTE N;                      // 比例因子,不存在就设置为1,也用于表示立即数的大小
        UnImm stImm;        // 立即数类型,或地址立即数类型

} UnOperand;

自己定义的一个操作数结构,用于解析指令的参数时好做判断

最后输出怎么一个结构。
typedef struct _InstructionFrame
{   
        DWORD        dwInstructionAddr;        // 指令地址
        DWORD        dwInstruction;        // 指令
        BYTE        dwInstructionLen;// 指令机器码长
        BYTE        arInstructionCode[INSTRUCTION_LEN]; // 机器码
       
        DWORD        dwGrp;        // 指令组
        DWORD        dwRing;  // 指令特权级     
        DWORD dwLock;        // 是否有锁前缀
        DWORD        dwRep;        // 是否有Rep前缀

        BYTE dwAddrSize; // 地址大小
        BYTE dwSegment;// 段前缀
        UnOperand stOpernd[3];        // 3个参数内容

        INQUIRE_EFLAGS        InquireEflags;        // 影响的标记位
} InstructionFrame;

把结构传入下面这个函数就可以返回指令的字符串,In_dwMnmicLen为对齐,就是质量和参数间的距离,In_dwlowerCase 为大写和小写。
DWORD Instruction(InstructionFrame *Out_InsFrame, TCHAR* Out_pMnemonic,  DWORD dwLen, DWORD In_dwMnmicLen = 6, DWORD In_dwlowerCase = 0);

原理其实好简单,就是不停的查表。

一共有:
1byte指令表
2byte指令表
扩展指令表
后缀指令表
前缀指令表
9b指令表----------------这个9b好像很特别,记得我用od和ida测试了好多次

总之第一次写,理解不够深刻吧,建了怎么多表

比如 查1byte指令表先,发现时0f就跳到2byte指令表去,mod中是扩展指令,就查扩展指令表,然后有的指令,不算2byte,存在扩展指令,而且后面一个字节又可以代表一个指令,所以就有了后缀指令表(而且是先查后缀,我没记错的话),前缀指令表就主要用于0F 38 如66 0f 38,什么66 67 f2 f3原来那么多用途,我还是第一次知道。

最后就定位到一个表,然后到其中去取得解析方式就ok了

有bug就告诉我吧!

望大虾提出意见,好提高一下,如果现在让我写,我可能还会设计成这样,只是细节的一些东西可能会做的更好。
代码中用了许多goto,好纠结这个goto。


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (9)
雪    币: 217
活跃值: (41)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
寒 估计没什么人研究这个东西。。想讨论下都没有
2011-1-19 15:46
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
顶一下
123
2011-1-19 21:53
0
雪    币: 209
活跃值: (83)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
看了源代码,无比强大,专研的很细,代码写了那么多。光建表就是个辛苦活。
向楼主学习。。。。
2011-1-21 15:27
0
雪    币: 142
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不懂,收藏先
2011-1-21 20:43
0
雪    币: 768
活跃值: (530)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
6
强大,占位膜拜~
2011-1-21 21:39
0
雪    币: 3227
活跃值: (2908)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
还没看mark一下,不知道能不能获取具体影响哪些寄存器?比XDE更详细?。。下载看下。thx  新年快乐
2011-2-4 10:16
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
8
要是按PE格式反汇编就更好了
2011-2-4 14:57
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
9
FishSeeWater大侠最近在研究什么啊
2011-2-4 14:58
0
雪    币: 27
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
mark一下
2011-2-7 04:18
0
游客
登录 | 注册 方可回帖
返回
//