首页
社区
课程
招聘
[原创]32位反汇编引擎开发笔记:Step.6_引擎核心-函数封装
发表于: 2020-10-13 17:41 4494

[原创]32位反汇编引擎开发笔记:Step.6_引擎核心-函数封装

2020-10-13 17:41
4494

Step.1_引擎大纲

Step.2_框架搭建

Step.3_经典定长指令的解析

Step.4_变长指令复习1

Step.5_变长指令复习2 - 指令前缀

Step.6_引擎核心->函数封装

在前面5章中,我们完成了定长指令的解析也学习了变长指令的解析方法,在开始变长指令解析代码编写前,我们观察一下我们在Step3中所写的代码,大量冗余代码,如果要进行扩展,需要更改每一个函数,因此,本章我们不进行变长指令的解析,我们进行一下代码的优化

Step3代码中,我们看到了很多类似这样的代码:

大量的重复代码会使我们接下来的开发和维护变得异常困难,因此我们将这些代码进行整合提取,封装成一个函数buildStr,合并后的代码如下:

可以看到代码明显减少,而且层次分明了许多,具体合并代码不贴了,上传在附件里,大家可以自行下载阅读

我只在这里说一下我封装后的函数:buildStr的参数说明

如下是buildStr的函数声明:

我将目前能考虑到的所有情况全部封装成一个函数,这样不管什么汇编指令,只要传入的参数正确,我就可以正确的解析出一条指令,下面我将具体说明下每个参数的含义和作用

Opcode首地址,代表了当前解析的硬编码开始地址,这个地址不应该包含前缀,如: E8 12 34 56 78,则pOpcode代表E8的地址

此参数不可为空

整条硬编码的字节长度,不包含前缀,如 66 50 ,因为66是前缀,所以此参数应传递1

此参数不可为空

操作数1类型 ,0为寄存器 ,1为内存 ,2为单立即数操作 ,-1为单指令如nop retn

当指令类似 MOV EAX,0X12345678时,EAX我将其称之为操作数1,后面的12345678我将其称之为操作数2

操作数1应当满足以下几种情况中的一种:

操作数2类型, 0为寄存器 ,1为内存 ,2为立即数 ,3为段寄存器 ,-1为单寄存器操作 , -2为舍弃

当指令类似 MOV EAX,0X12345678时,EAX我将其称之为操作数1,后面的12345678我将其称之为操作数2

操作数2应当满足以下几种情况中的一种:

很尴尬,这是我上周写的函数,当时忘了是咋回事来着,我发现单寄存器操作满足不了我的需求,又加了一个类型为舍弃,我也忘了我当时写这俩啥区别了 淦....

操作数宽度,此参数代表整行指令出现MOV类的赋值语句时,需要指定当前操作的数据宽度是多少(和立即数大小无关,这点请注意),如 MOV EAX,[0x12346578],我们都知道这条指令操作的是4字节的内存,所以此参数传入4,若不是MOV语句,则此参数必须传入4

常量数宽度,也是立即数宽度,代表整行指令出现的立即数的字节数是多少

如 : PUSH 0x1234,向堆栈压入0x1234,则此参数应传入4(为啥不是2,请自行百度内存对齐相关知识)

如: MOV AL,0x12 ,则此参数传入1

如: MOV byte ptr ds:[EAX+0x1234],AL 则此参数传入4

如: MOV byte ptr ds:[EAX+0x12],AL 则此参数传入1

如: RETN 0x1234 则此参数传入2

没有常量数时,此参数传入0

指令名字字符串,宽字符,代表当前指令的指令是什么,类似MOV JMP PUSH DEC INC RETN的其中一个

寄存器1名字,如果操作数1为寄存器或包含寄存器,则此参数传入寄存器名字

如: MOV AL,0x12 ,则此参数传入AL

如: MOV byte ptr ds:[EAX+0x1234],AL 则此参数传入EAX

如 : PUSH 0x1234 ,则此参数传入""(空,不能传0,会空指针异常)

寄存器2名字,如果操作数2为寄存器或包含寄存器,则此参数传入寄存器名字

如: MOV byte ptr ds:[EAX+0x1234],AL 则此参数传入AL

如 : PUSH 0x1234 ,则此参数传入""(空,不能传0,会空指针异常)

如: MOV AL,0x12 ,则此参数传入""(空,不能传0,会空指针异常)

此条指令是否需要计算偏移

JCC系列 CALL修改EIP的指令,都需要进行偏移的计算,这时此参数传入1,不需要计算则传0

代码就上传附件了,这章没啥东西,就是封装了一个函数

感谢各位阅读

 
 
 
 
 
 
/*
       0F80~0F8F的解析
   */
   void Translate_0F80_0F8F() {
       switch (codeList[index + 1])
       {
       case 0x80:
       {
           //取出跳转后面的四字节偏移
           DWORD im = *((DWORD*)(codeList + index + 2));
           //计算跳转实际位置
           im = im + 6 + baseAddr + index;
           TCHAR* tt = (TCHAR*)malloc(256);
           memset(tt, 0, 256);
           BYTE b1 = *((BYTE*)(codeList + index + 3));
           BYTE b2 = *((BYTE*)(codeList + index + 4));
           BYTE b3 = *((BYTE*)(codeList + index + 5));
           BYTE b4 = *((BYTE*)(codeList + index + 6));
           _stprintf(tt, L"0F80%02X%02X%02X%02X\t\tJO %08X\r\n", b1, b2, b3, b4, im);
           append(tt);
           free(tt);
           break;
       }
       case 0x81:
       {
           //取出跳转后面的四字节偏移
           DWORD im = *((DWORD*)(codeList + index + 2));
           //计算跳转实际位置
           im = im + 6 + baseAddr + index;
           TCHAR* tt = (TCHAR*)malloc(256);
           memset(tt, 0, 256);
           BYTE b1 = *((BYTE*)(codeList + index + 2));
           BYTE b2 = *((BYTE*)(codeList + index + 3));
           BYTE b3 = *((BYTE*)(codeList + index + 4));
           BYTE b4 = *((BYTE*)(codeList + index + 5));
           _stprintf(tt, L"0F81 %02X%02X%02X%02X\tJNO %08X\r\n", b1, b2, b3, b4, im);
           append(tt);
           free(tt);
           break;
       }
/*
       0F80~0F8F的解析
   */
   void Translate_0F80_0F8F() {
       switch (codeList[index + 1])
       {
       case 0x80:
       {
           //取出跳转后面的四字节偏移
           DWORD im = *((DWORD*)(codeList + index + 2));
           //计算跳转实际位置
           im = im + 6 + baseAddr + index;
           TCHAR* tt = (TCHAR*)malloc(256);
           memset(tt, 0, 256);
           BYTE b1 = *((BYTE*)(codeList + index + 3));
           BYTE b2 = *((BYTE*)(codeList + index + 4));
           BYTE b3 = *((BYTE*)(codeList + index + 5));
           BYTE b4 = *((BYTE*)(codeList + index + 6));
           _stprintf(tt, L"0F80%02X%02X%02X%02X\t\tJO %08X\r\n", b1, b2, b3, b4, im);
           append(tt);
           free(tt);
           break;
       }
       case 0x81:
       {
           //取出跳转后面的四字节偏移
           DWORD im = *((DWORD*)(codeList + index + 2));
           //计算跳转实际位置
           im = im + 6 + baseAddr + index;
           TCHAR* tt = (TCHAR*)malloc(256);
           memset(tt, 0, 256);
           BYTE b1 = *((BYTE*)(codeList + index + 2));
           BYTE b2 = *((BYTE*)(codeList + index + 3));
           BYTE b3 = *((BYTE*)(codeList + index + 4));
           BYTE b4 = *((BYTE*)(codeList + index + 5));
           _stprintf(tt, L"0F81 %02X%02X%02X%02X\tJNO %08X\r\n", b1, b2, b3, b4, im);
           append(tt);
           free(tt);
           break;
       }
/*
        90~97的解析
    */
    void Translate_90_97() {
        switch (codeList[index])
        {
        case 0x90:
            append(buildStr((char*)(codeList + index), 1, -1, -2, 4, 0, (TCHAR*)(L"NOP"), (TCHAR*)(L""), 0, 0));
            break;
        case 0x91:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"ECX"), 0));
            break;
        case 0x92:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EDX"), 0));
            break;
        case 0x93:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EBX"), 0));
            break;
        case 0x94:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"ESP"), 0));
            break;
        case 0x95:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EBP"), 0));
            break;
        case 0x96:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"ESI"), 0));
            break;
        case 0x97:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EDI"), 0));
            break;
        }
        //解析完成后索引+1,之所以加一,是因为90~97全部是一字节的定长指令
        index++;
    }
 
/*
        B0~BF的解析
    */
    void Translate_B0_BF() {
        switch (codeList[index])
        {
        case 0xB0:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"AL"), 0, 0));
            break;
        }
        case 0xB1:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"CL"), 0, 0));
            break;
        }
        case 0xB2:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"DL"), 0, 0));
            break;
        }
        case 0xB3:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"BL"), 0, 0));
            break;
        }
        case 0xB4:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"AH"), 0, 0));
            break;
        }
        case 0xB5:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"CH"), 0, 0));
            break;
        }
        case 0xB6:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"DH"), 0, 0));
            break;
        }
        case 0xB7:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"BH"), 0, 0));
            break;
        }
        case 0xB8:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"EAX"), 0, 0));
            break;
        }
        case 0xB9:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"ECX"), 0, 0));
            break;
        }
        case 0xBA:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"EDX"), 0, 0));
            break;
        }
        case 0xBB:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"EBX"), 0, 0));
            break;
        }
        case 0xBC:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"ESP"), 0, 0));
            break;
        }
        case 0xBD:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"EBP"), 0, 0));
            break;
        }
        case 0xBE:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"ESI"), 0, 0));
            break;
        }
        case 0xBF:
        {
            append(buildStr((char*)(codeList + index), 5, 0, 2, 4, 4, (TCHAR*)(L"MOV"), (TCHAR*)(L"EDI"), 0, 0));
            break;
        }
        }
        if (codeList[index]<0xB8)
        {
            index += 2;
        }
        else {
            index += 5;
        }
    }
/*
        90~97的解析
    */
    void Translate_90_97() {
        switch (codeList[index])
        {
        case 0x90:
            append(buildStr((char*)(codeList + index), 1, -1, -2, 4, 0, (TCHAR*)(L"NOP"), (TCHAR*)(L""), 0, 0));
            break;
        case 0x91:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"ECX"), 0));
            break;
        case 0x92:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EDX"), 0));
            break;
        case 0x93:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EBX"), 0));
            break;
        case 0x94:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"ESP"), 0));
            break;
        case 0x95:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EBP"), 0));
            break;
        case 0x96:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"ESI"), 0));
            break;
        case 0x97:
            append(buildStr((char*)(codeList + index), 1, 0, 0, 4, 0, (TCHAR*)(L"XCHG"), (TCHAR*)(L"EAX"), (TCHAR*)(L"EDI"), 0));
            break;
        }
        //解析完成后索引+1,之所以加一,是因为90~97全部是一字节的定长指令
        index++;
    }
 
/*
        B0~BF的解析
    */
    void Translate_B0_BF() {
        switch (codeList[index])
        {
        case 0xB0:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"AL"), 0, 0));
            break;
        }
        case 0xB1:
        {
            append(buildStr((char*)(codeList + index), 2, 0, 2, 1, 1, (TCHAR*)(L"MOV"), (TCHAR*)(L"CL"), 0, 0));
            break;
        }
        case 0xB2:

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
支持
分享
最新回复 (3)
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
强。下次参考你的代码实现一把。
2020-11-23 10:05
0
雪    币: 2674
活跃值: (2304)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
感谢分享!
收藏起来慢慢研究!
2020-11-23 11:40
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
理好了
2021-3-11 17:51
0
游客
登录 | 注册 方可回帖
返回
//