<em id="pzl9c"></em>
      <dl id="pzl9c"><ins id="pzl9c"></ins></dl>
      <dfn id="pzl9c"></dfn>

        <progress id="pzl9c"></progress>
        <div id="pzl9c"><ol id="pzl9c"></ol></div>
          <div id="pzl9c"><tr id="pzl9c"></tr></div>

          <em id="pzl9c"></em>

            <em id="pzl9c"><ins id="pzl9c"><mark id="pzl9c"></mark></ins></em>
            <dl id="pzl9c"></dl>

            <dl id="pzl9c"></dl>

              <div id="pzl9c"></div>
              <dl id="pzl9c"><ins id="pzl9c"></ins></dl>

              <dfn id="pzl9c"></dfn>
              <sup id="pzl9c"><ins id="pzl9c"></ins></sup>

                <dl id="pzl9c"></dl>

                飘云阁(PYG官方论坛)

                 找回密码
                 加入论坛

                QQ登录

                只需一步£¬快速开始

                扫一扫£¬访问微社区

                返回列表
                查看: 4830|回复: 56
                打印 上一主题 下一主题

                [原创] 谈谈vmp的还原(3)

                    [复制链接]
              1. TA的每?#25307;?#24773;
                擦汗
                2016-4-19 21:35
              2. 签到天数: 3 天

                [LV.2]偶尔看看I

                跳转到指定楼层
                楼主
                发表于 2018-4-14 19:24:16 | 只看该作者 |只?#21019;?#22270; 回帖奖励 |倒序浏览 |阅读模式
                本帖最后由 wai1216 于 2018-4-15 18:25 编辑

                0x00 前言
                写在5.4之前

                vs2010£¬代码放在了github:vmp

                0x01 寄存器
                ?#20154;µcontext
                init初始化context分两种情况

                那么第二种,就是随机生成了

                关于pushad pushfd的保存

                如何选取空闲的context
                代码如下:
                1. int n = 0, k = 0;
                2. char cpu[16] = {0};

                3. int _getContextIndex( int type)
                4. {
                5.         if( tpye - 1 >= 2)
                6.         {
                7.                 switch(type)
                8.                 {
                9.                         case 0:
                10.                         case 4:
                11.                                 return dis->reg[0];
                12.                         case 1:
                13.                         case 5:
                14.                                 return dis->reg[1];
                15.                         case 2:
                16.                         case 6:
                17.                                 return dis->reg[2];
                18.                         case 3:
                19.                         case 7:
                20.                                 return dis->reg[3];                        
                21.                         case 9:
                22.                         case 0xD:
                23.                                 return dis->reg[9];               
                24.                         default:
                25.                                 return 0;                                                                                                
                26.                 }
                27.         }
                28.         else
                29.         {
                30.                 switch(type)
                31.                 {
                32.                 case 0:
                33.                 case 1:
                34.                 case 2:
                35.                 case 3:
                36.                 case 5:
                37.                 case 6:
                38.                 case 7:
                39.                 case 8:
                40.                 case 9:
                41.                 case 0xa:
                42.                         return dis->reg[_type];
                43.                 case 4:
                44.                         return -1;
                45.                 default:
                46.                         return 0;
                47.                 }
                48.         }
                49. }

                50. for( int i = 0; i < 16; i++)
                51. {
                52.         if( dis->reg[i] < 0xff)
                53.         {
                54.                         cpu[ dis->reg[i]] = 1;
                55.         }
                56. }
                57. i = 0;
                58. while( cpu[i] || rand()%2 != 1)
                59. {
                60.         i++;
                61.         return _getContextIndex(tpye);
                62. }
                63. dis->reg[k] = n;
                64. return _getContextIndex(tpye);
                复制代码
                这里说下£¬看到这部分实现的时候£¬脑子里的想法是当成树结构£¬用dfs去识别判断£¬因为以为是真轮转¡£记得£¬还给校长说£¬?#29992;?#19982;解密那个目录处理的方法好像是图算法¡£
                再注意到a2/v13 == 2, 才会去get context, 随意看一个调用

                关系到lval
                那么其他的情况在只是return context£¬那么就好办了£¬因为可以得到£¬并不是真轮转

                0x10 变形
                下面这个东西£¬也是?#26131;?#20329;服vmp作者的地方£¬因为就这点东西£¬就可以做很多事情了¡£


                首先这个函数£¬我也不知道怎么命名好£¬所以就当成fixed吧£¬可能叫plasmodium比较好

                1. _BOOL1 __fastcall CHECK_POP_ESP_OR_CONTEXT(struct_esi *a1)
                2. {
                3.   return a1->_var1_vm_interpreter_mnemonic == 2
                4.       && a1->_var2_addressing_mode == 2
                5.       && (!a1->_var3_lval_type_byte_word_dword_or_vm_displacement || a1->_reg_index != 4);
                6. }

                7. _BOOL1 __fastcall Check_PUSH_ESP_OR_CONTEXT(struct_esi *a1, char a2, char a3)
                8. {
                9.   return a1->_var1_vm_interpreter_mnemonic == 1
                10.       && a1->_var2_addressing_mode == 2
                11.       && a2 == a1->_var3_lval_type_byte_word_dword_or_vm_displacement
                12.       && a3 == a1->_reg_index;
                13. }

                14. _BOOL1 __fastcall CHECK_POP_AX(struct_esi *a1)
                15. {
                16.   return a1->_var1_vm_interpreter_mnemonic == 2 && a1->_var2_addressing_mode == 1;
                17. }

                18. //函数倒叙判断
                19. _BOOL1 __usercall [email protected]<al>(int *[email protected]<eax>, char [email protected]<dl>, int a3)
                20. {
                21.   bool _ret = 0;

                22.   if ( *_index >= 2 )
                23.   {
                24.     _cur_index = *_index;
                25.     _struct_cur = getStruct_1(*(a3 - 4), *_index);
                26.         //判断当前vm_mnemonic是否为0x4,0xf6
                27.     if ( _struct_cur->_var1_vm_interpreter_mnemonic != 4
                28.                 && _struct_cur->_var1_vm_interpreter_mnemonic != 0xF6
                29.                 || _struct_cur->_var3_lval_type_byte_word_dword_or_vm_displacement != __var3_lval_type_byte_word_dword_or_vm_displacement )// ?
                30.     {
                31.                 //为其他mnemonic 高于0x2e
                32.       if ( _struct_cur->_var1_vm_interpreter_mnemonic  >= 0x2A )
                33.       {
                34.         if ( CHECK_POP_ESP_OR_CONTEXT(_struct_cur) && getlen(*(a3 - 4)) - 1 > _cur_index )
                35.         {
                36.           if ( Check_PUSH_ESP_OR_CONTEXT(_struct_next,_struct_cur->_var3_lval_type_byte_word_dword_or_vm_displacement,_struct_cur->_reg_index)
                37.                                 && System::__linkproc__ RandInt(2) == 1 )
                38.           {
                39.             _struct_next->_reg_index = 4;
                40.             _struct_next->_var3_lval_type_byte_word_dword_or_vm_displacement = 2;
                41.             _struct_next->_other |= 4u;
                42.             _struct_new = (*(**(a3 - 4) + 16))();
                43.             _struct_new->_var1_vm_interpreter_mnemonic = 1;
                44.             _struct_new->_var2_addressing_mode = 3;
                45.             _struct_new->_var4_index = 3;
                46.             _struct_new->_var3_lval_type_byte_word_dword_or_vm_displacement = _struct_cur->_var3_lval_type_byte_word_dword_or_vm_displacement;
                47.             _struct_new->_other |= 4u;
                48.             _mov_var2_to_var3(*(a3 - 4), _struct_new, _struct_cur);
                49.             _mov_var2_to_var3(*(a3 - 4), _final, _struct_new);// add_to_list
                50.           }
                51.         }
                52.         else if ( CHECK_POP_AX(_struct_cur) )          // _fix var2 == 2 && var3 == 1
                53.         {
                54.           _next = _cur_index + 1;
                55.           _size = getlen(*(a3 - 4)) - 1;
                56.                   __ = __OFSUB__(_size,_next);
                57.           _len = _size - _next;
                58.           if ( !((_len < 0) ^ __) )
                59.           {
                60.             _pos = _len + 1;
                61.             _next = _next;
                62.             do
                63.             {
                64.               _struct_next = getStruct_1(*(a3 - 4), _next);
                65.               if ( !CHECK_POP_ESP_OR_CONTEXT(_struct_next)
                66.                                   || CHECK_POP_ESP(_struct_next)
                67.                                   || _struct_next->_var3_lval_type_byte_word_dword_or_vm_displacement != _struct_cur->_var3_lval_type_byte_word_dword_or_vm_displacement )
                68.               {
                69.                 break;
                70.               }
                71.               if ( System::__linkproc__ RandInt(2) == 1 )
                72.               {
                73.                 _struct_cur->_var2_addressing_mode = 2;
                74.                 _struct_cur->_reg_index = _struct_next->_reg_index;
                75.                 _struct_cur->_other |= 4u;
                76.                 return _ret;
                77.               }
                78.               ++_next;
                79.               --_pos;
                80.             }
                81.             while ( _pos );
                82.           }
                83.         }
                84.       }//0x1d之前 basic....
                85.       else if ( _struct_cur->_var3_lval_type_byte_word_dword_or_vm_displacement == __var3_lval_type_byte_word_dword_or_vm_displacement )//?
                86.       {
                87.         _struct_prev_prev = getStruct_1(*(a3 - 4), _cur_index - 2);
                88.         _struct_prev = getStruct_1(*(a3 - 4), _cur_index - 1);
                89.         if ( CHECK_LODSW_PUSH_AX(_struct_prev_prev, 1) && CHECK_LODS_PUSH_CONTEXT(_struct_prev, __var3_lval_type_byte_word_dword_or_vm_displacement) )
                90.         {
                91.           _cur_index -= 2;//移动到_prev_prev,指针
                92.           if ( !_struct_prev_prev->_rand_switch && !_struct_prev->_rand_switch )
                93.           {
                94.             _ret = !(_cur->_other & 1) && !CHECK_POP_ESP(_struct_prev);
                95.           }
                96.         }
                97.       }
                98.     }
                99.     else
                100.     {
                101.       _struct_prev_prev = getStruct_1(*(a3 - 4), _cur_index - 2);
                102.       _struct_prev = getStruct_1(*(a3 - 4), _cur_index - 1);
                103.       if ( CHECK_LODS_PUSH_CONTEXT(_struct_prev_prev, __var3_lval_type_byte_word_dword_or_vm_displacement) && CHECK_LODS_PUSH_CONTEXT(_struct_prev, __var3_lval_type_byte_word_dword_or_vm_displacement) )
                104.       {
                105.         _cur_index -= 2;
                106.         if ( _struct_prev_prev->_rand_switch || _struct_prev->_rand_switch || System::__linkproc__ RandInt(2) != 1 )
                107.         {
                108.           v10 = !CHECK_POP_ESP(_struct_prev_prev) && !CHECK_POP_ESP(_struct_prev);
                109.           _ret = v10;
                110.         }
                111.         else
                112.         {
                113.           if ( CHECK_POP_ESP(_struct_prev_prev) )
                114.           {
                115.             if ( _struct_prev->_var2_addressing_mode == 1 )
                116.               *_struct_prev->_Displacement_Immediate += 4;
                117.           }
                118.           else if ( CHECK_POP_ESP(_struct_prev) )
                119.           {
                120.             if ( _struct_prev_prev->_var2_addressing_mode == 1 )
                121.               *_struct_prev_prev->_Displacement_Immediate -= 4;
                122.           }
                123.           else
                124.           {
                125.             _ret = 1;
                126.           }
                127.           if ( _struct_prev->_var2_addressing_mode != 2
                128.             || _struct_prev_prev->_var2_addressing_mode != 2
                129.             || _struct_prev_prev->_reg_index != _struct_prev->_reg_index )
                130.           {
                131.             _struct_prev_prev->_other |= 4u;
                132.             _struct_prev->_other |= 4u;
                133.             _ExchangePos(*(a3 - 4), _struct_prev, _struct_prev_prev);// ?#25442;?#24403;前的前两个
                134.           }
                135.           else
                136.           {
                137.             _struct_prev->_reg_index = 4;            // fix
                138.             _struct_prev->_var3_lval_type_byte_word_dword_or_vm_displacement = 2;
                139.             _struct_prev->_other |= 4u;
                140.             _struct_new = (*(**(a3 - 4) + 16))();
                141.             _struct_new->_var1_vm_interpreter_mnemonic = 1;// push [imm]...
                142.             _struct_new->_var2_addressing_mode = 3;
                143.             _struct_new->_var4_index = 3;
                144.             _struct_new->_var3_lval_type_byte_word_dword_or_vm_displacement = _first->_var3_lval_type_byte_word_dword_or_vm_displacement;
                145.             _struct_new->_other |= 4u;
                146.             _mov_var2_to_var3(*(a3 - 4), _struct_end, _struct_cur);
                147.           }
                148.         }
                149.       }
                150.       else
                151.       {
                152.         if ( CHECK_LODS_PUSH_CONTEXT(_struct_prev, __var3_lval_type_byte_word_dword_or_vm_displacement) )
                153.         {
                154.           --_cur;//指针-1
                155.           if ( CHECK_POP_ESP(_struct_prev) )
                156.             return _ret;
                157.           _prev = _cur - 1;
                158.           if ( Vmp_Fixed(&_prev, __var3_lval_type_byte_word_dword_or_vm_displacement, a3) == 0 )// 递归调用,这时候就体现出第3个的用处了
                159.             return _ret;
                160.           *v3 = _prev;
                161.           _prev = _prev;
                162.           _ret = 1;
                163.         }
                164.         else
                165.         {
                166.           _prev = _cur - 1;
                167.           if ( Vmp_Fixed(&_prev, __var3_lval_type_byte_word_dword_or_vm_displacement, a3) )
                168.           {
                169.             _index = _prev;
                170.             _struct_prev_prev = getStruct_1(*(a3 - 4), _prev - 1);
                171.             _struct_prev = getStruct_1(*(a3 - 4), _prev);
                172.             if ( CHECK_LODS_PUSH_CONTEXT(_struct_prev_prev, __var3_lval_type_byte_word_dword_or_vm_displacement) )
                173.             {
                174.               --_cur;
                175.               if ( CHECK_POP_ESP(_struct_prev_prev) )
                176.                 return _ret;
                177.               _prev__ = _cur;
                178.               _ret = 1;
                179.             }
                180.             else
                181.             {
                182.               _prev = *v3 - 1;
                183.               if ( Vmp_Fixed(&_prev, __var3_lval_type_byte_word_dword_or_vm_displacement, a3) )
                184.               {
                185.                 *v3 = _prev;
                186.                 _prev = _prev;
                187.                 _ret = 1;
                188.               }
                189.             }
                190.           }
                191.         }
                192.         if ( _ret != 0 && rand()%2 == 1 )
                193.         {
                194.           _prev_index = _retn_index(_struct_prev);
                195.           _cur_index = _retn_index(_cur);
                196.           _flag = _prev - _prev_index == _prev_index - _cur_index;// len
                197.           if ( _prev__ - _prev_index == _prev_index - _cur_index && _cur_index - 1 >= _prev_index )
                198.           {
                199.             int dis = _cur_index - _prev_index;
                200.             while ( 1 )
                201.             {
                202.               _success = sub_48AF88(_prev_index, _prev_index + _prev__ - _prev_index, v13, a3);// 直到找到不同的
                203.               v13 = v16;
                204.               if ( !v15 )
                205.                 break;
                206.               ++v38;
                207.               if ( !--v14 )
                208.                 goto LABEL_45;
                209.             }
                210.             _flag = 0;
                211.           }
                212. LABEL_45:
                213.           if ( _flag != 0 )
                214.           {
                215.             _struct_prev = getStruct_1(*(a3 - 4), _prev_index);
                216.             _struct_prev->_var1_vm_interpreter_mnemonic = 1;
                217.             _struct_prev->_var2_addressing_mode = 2;
                218.             _struct_prev->_reg_index = 4;
                219.             _struct_prev->_var3_lval_type_byte_word_dword_or_vm_displacement = 2;
                220.             _struct_prev->_other |= 4u;
                221.             _struct_cur = getStruct_1(*(a3 - 4), _prev_index + 1);
                222.             _struct_cur->_var1_vm_interpreter_mnemonic = 1;
                223.             _struct_cur->_var2_addressing_mode = 3;
                224.             _struct_cur->_var4_index = 3;
                225.             _struct_cur->_var3_lval_type_byte_word_dword_or_vm_displacement = __var3_lval_type_byte_word_dword_or_vm_displacement;
                226.             _struct_cur->_other |= 4u;
                227.             if ( _prev_index + 2 <= _cur_index - 1 )
                228.             {
                229.               v19 = _prev_index + 2 - _cur_index;
                230.               _prev_index = _cur_index - 1;
                231.               do
                232.               {
                233.                 (*(**(a3 - 4) + 12))(*(a3 - 4), v39--);
                234.                 ++v19;
                235.               }
                236.               while ( v19 );
                237.             }
                238.           }
                239.           else
                240.           {
                241.             if ( _cur_index - 1 >= _prev_index )
                242.             {
                243.               v20 = _cur_index - _prev_index;
                244.               v40 = _prev_index;
                245.               do
                246.               {
                247.                 v21 = getStruct_1(*(a3 - 4), v40);
                248.                 v21->_other |= 4u;
                249.                 ++v40;
                250.                 --v20;
                251.               }
                252.               while ( v20 );
                253.             }
                254.             if ( _cur_index - 1 >= _prev_index )
                255.             {
                256.               v22 = _cur_index - _prev_index;
                257.               v41 = _prev_index;
                258.               do
                259.               {
                260.                 sub_47FB0C(*(a3 - 4), v41, v41 + _prev__ - _prev_index);//exchange
                261.                 ++v41;
                262.                 --v22;
                263.               }
                264.               while ( v22 );
                265.             }
                266.           }
                267.         }
                268.       }
                269.       if ( _ret )
                270.         _ret = (_cur->_other & 1) == 0;
                271.     }
                272.   }
                273.   return _ret;
                274. }
                复制代码
                当我看到这里的时候£¬真的£¬如果不是语言不在同一个频道£¬可能就膜拜了¡£
                随意的£¬举个例子¡£这里可能会需要一些数据结构的知识
                注意是倒叙进行判断的

                记当前结构为一个_cur_node
                记当?#21543;?#19968;个节点为_prev_node
                记当前下一个节点为_next_node

                假定
                1. _cur_node: LODS BYTE PTR DS:[ESI]  POP DWORD PTR DS:[EDI+EAX*4]
                2. _next_node: LODS BYTE PTR DS:[ESI] PUSH DWORD PTR DS:[EDI+EAX*4]
                复制代码
                这?#25945;?#22312;操作什么£¬很明显£¬可以看出vmp不是没有一些组合的
                那么可能会出现下面的情况
                _next_node变成PUSH ESP
                new node£¬生成一个新的节点£¬记为_tmp_node
                1. _tmp_node: POP EAX PUSH DWORD PTR ES:[EAX]
                复制代码
                之后在插入
                Before:
                1. LODS BYTE PTRDS:[ESI]  POP DWORD PTR DS:[EDI+EAX*4]
                2. LODS BYTE PTR DS:[ESI]  PUSH DWORD PTR DS:[EDI+EAX*4]
                复制代码
                After:
                1. LODS BYTE PTRDS:[ESI]  POP DWORD PTR DS:[EDI+EAX*4]
                2. PUSH ESP
                3. POP EAX PUSH DWORDPTR ES:[EAX]
                复制代码

                注意到eax一致£¬然后明白这个函数了吗£¿
                好像就这些了£¬我大概想阐述的东西,就这些¡£
                0x11 说下我还原的思路
                在我逆的过程中£¬一直在猜想vmp作者的构造思路¡£
                最开始的时候£¬我的想法?#21069;Ñesi看成vmp_encodes£¬那么asm有套opcode的构造手册£¬vmp作者也应该有一套这样的手册£¬当然也不是说像intel手册那种¡£但我一直从各个角?#28909;?#24605;考£¬都想不出£¬vmp作者是怎么构造出这些精彩的东西的¡£有兴趣的£¬可以尝试一下£¬如果是大一大二£¬我可能就这样继续下去了
                之后我想?#28909;?#30693;道了规则£¬可能不同版本£¬会有一些变化£¬但大致框架如此¡£
                而不同的是£¬我所想的是£¬是还原为encodes£¬而不是asm£¬这点也重要£¬因为即使trace£¬或者使用插件£¬是的£¬你人工可能可以识别£¬那?#21019;?#30721;认识么£¬当然可以写成分析树或写个虚拟引擎自?#21495;Ü£?#20294;我想£¬这也是vmp作者愿意看到的情况
                那么?#28909;?#24819;还原成encodes£¬先解析esi£¬之后只要规则到位£¬那?#27425;?#20204;可以得到disp,imm,sib,modrm,prefix¡£还需要确认的£¬就只剩下opcode了£¬所幸的是£¬相同mnemonic所对应的opcode并?#27426;à£?#23601;大致解决了类型?#27426;?#31561;的情况了¡£

                评分

                参与人数 2威望 +3 飘云币 +3 收起 理由
                windxp + 1 + 1 ?#34892;?#20998;享£¡
                ems0000 + 2 + 2

                查看全部评分

                本帖被以下淘专辑推荐:

                分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
                收藏收藏12 转播转播 分享分享 分享淘帖2 顶1 踩 扫码赞助 微信分享
              3. TA的每?#25307;?#24773;
                无聊
                2018-7-6 21:46
              4. 签到天数: 165 天

                [LV.7]常住?#29992;ñIII

                沙发
                发表于 2018-4-15 00:02:56 | 只看该作者
                ?#34892;»£?#32673;慕在学校就已这么厉害了  
                ps£º另外冒昧能问一下在哪所大学 £¿这么厉害 ¡£
                回复 支持 反对

                使用道具 举报

              5. TA的每?#25307;?#24773;
                开心
                2018-6-24 22:00
              6. 签到天数: 13 天

                [LV.3]偶尔看看II

                板凳
                发表于 2018-4-21 13:51:38 | 只看该作者
                又免费学了一课£¬也?#34892;?#27004;主费心写这么多话出来
                回复 支持 反对

                使用道具 举报

              7. TA的每?#25307;?#24773;
                开心
                2018-4-21 14:13
              8. 签到天数: 1 天

                [LV.1]初来乍到

                报纸
                发表于 2018-4-21 14:15:50 | 只看该作者
                ?#39336;ô£?#35874;谢分享
                回复 支持 反对

                使用道具 举报

                该用户?#28216;?#31614;到

                地板
                发表于 2018-4-23 20:14:51 | 只看该作者
                学习下,表示没看懂
                回复 支持 反对

                使用道具 举报

              9. TA的每?#25307;?#24773;
                开心
                2018-5-3 21:43
              10. 签到天数: 3 天

                [LV.2]偶尔看看I

                7#
                发表于 2018-5-2 11:02:06 | 只看该作者
                菜鸟表示看?#27426;®£?#20381;然?#34892;?/td>
                回复 支持 反对

                使用道具 举报

              11. TA的每?#25307;?#24773;
                开心
                2018-8-3 20:31
              12. 签到天数: 3 天

                [LV.2]偶尔看看I

                8#
                发表于 2018-5-8 18:28:34 | 只看该作者
                非常?#34892;?#20998;享£¬给力
                回复 支持 反对

                使用道具 举报

              13. TA的每?#25307;?#24773;
                开心
                昨天 17:00
              14. 签到天数: 19 天

                [LV.4]偶尔看看III

                9#
                发表于 2018-5-8 20:30:44 | 只看该作者
                膜拜下大牛 支持£¡
                回复 支持 反对

                使用道具 举报

              15. TA的每?#25307;?#24773;

                2018-6-16 05:03
              16. 签到天数: 23 天

                [LV.4]偶尔看看III

                10#
                发表于 2018-5-8 22:26:28 | 只看该作者
                这应该是博士生科研用的£¬我们幼儿园小朋友完全看?#27426;®¡?/td>
                回复 支持 反对

                使用道具 举报

                您需要登录后才可以回帖 登录 | 加入论坛

                本版积分规则

                关闭

                站长推荐上一条 /1 下一条

                快速回复 返回顶部 返回列表
                11Ñ¡5Öн±±¨µÀ