首页
社区
课程
招聘
[原创]Themida VM 代码还原
发表于: 2009-2-17 22:17 34678

[原创]Themida VM 代码还原

2009-2-17 22:17
34678

【文章标题】: Themida VM 代码还原
【文章作者】: hawk
【作者邮箱】: hkp2000hk@sina.com
【作者主页】: http://localhost
【作者QQ号】: 99224775
【软件名称】: Themida.不知道
【下载地址】: 自己搜索下载
【保护方式】: 虚拟机
【使用工具】: 老三样
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  IDA分析目标发现虚拟机,应该是Themida CISC 版本及加密参数不详。
  
  虚拟机入口0x1EAE4,ContextBase 0x1E800 MethodTableSize 0xA8
  
  首先IDA手工修复代码,虚拟机主体为一函数,160+Method分别建立函数。
  
  把0x1EB4E主循环扒下来
  //----------------------------------------------------//
  lodsb
  xor     al, bl
  push    7BB9h
  mov     [esp], edx
  mov     dh, 28h
  jmp     loc_22604
  shl     dh, 6
  push    ebx
  mov     bl, 4Eh
  sub     bl, 11h
  sub     bl, 0EAh
  xor     dh, bl
  pop     ebx
  jmp     loc_1F55B
  xor     al, dh
  jmp     loc_23352
  mov     edx, [esp]
  add     esp, 4
  push    ecx
  jmp     loc_1FF5D
  push    ebx
  jmp     loc_1F06D
  mov     bh, 6Eh
  add     bh, 0DDh
  jmp     loc_20342
  neg     bh
  shl     bh, 2
  sub     bh, 1
  not     bh
  xor     bh, 0B3h
  mov     ch, bh
  pop     ebx
  jmp     loc_20878
  sub     al, ch
  mov     ecx, [esp]
  jmp     loc_20CB2
  add     esp, 4
  sub     bl, 7Eh
  sub     bl, 2Ah
  sub     bl, al
  jmp     loc_21116
  push    ecx
  mov     cl, 2Ah
  add     bl, cl
  jmp     loc_22287
  pop     ecx
  push    edx
  mov     dl, 0C3h
  xor     dl, 84h
  jmp     loc_22B10
  sub     dl, 0DBh
  jmp     loc_2273F
  sub     dl, 0F7h
  xor     dl, 0Bh
  jmp     loc_1F6D9
  add     bl, dl
  pop     edx
  movzx   eax, al
  jmp     dword ptr [edi+eax*4]
  //-------------------修复后的代码--------------------//
  LODSB
  XOR     AL, BL
  XOR        AL, 53H
  SUB        AL, 9FH
  SUB     BL, AL
  MOVZX   EAX, AL
  JMP     DWORD PTR [EDI+EAX*4]
  //---------------------------------------------------//
  VS2008 新建工程
  ref        class        _VM_Analyze
  {
  public:
          static        String^        GetHexString(UInt32 HexValue,Int32 Size);
          UInt32        ImageBase;
          array<Byte>        ^ImageData;
  
          UInt32        ContextBase;
          UInt32        ContextKey;
          UInt32        CodePointer;
  
          StringWriter        ^AnalyzeResult;
  
          Byte        ReadByte();
          UInt16        ReadWord();
          UInt32        ReadDword();
          Boolean        Decode();
          Void        LoadImage(String^ ImagePath);
          _VM_Analyze(UInt32 Key);
  };
  
  Boolean        _VM_Analyze::Decode()
  {
          /*
          LODSB
          XOR     AL, BL
          XOR     AL, 53H
          SUB     AL, 9FH
          SUB     BL, AL
          MOVZX   EAX, AL
          JMP     DWORD PTR [EDI+EAX*4]
          */
          Byte        Opcode=ReadByte();
          Byte        Key=ContextKey;
          Opcode=Opcode^Key;
          Opcode=Opcode^0x53;
          Opcode=Opcode-0x9F;
          Key=Key-Opcode;
          ContextKey=ContextKey&0xFFFFFF00|Key;
          switch (Opcode)
          {
          default:
                  {
                          UInt32        K=ContextKey;
                          UInt32        P=CodePointer;
                          String        ^s=AnalyzeResult->ToString();
                          throw        s;
                  }
          }
  }
  
  OllyICE 加载目标 下断MainLoop JumpMethodTable
  VS2008 F5 抛出异常 Opcode=0x?? ContextKey=0x????????
  OllyICE JumpMethodTable 条件断 AL==0x??
  对比ContextKey==EBX 恭喜清洗代码应该没有什么BUG
  
  按照Opcode==0x??拔下对应的Method代码
  清洗之
  一般都是
  LODS?
  (ADD|SUB|???) EAX, EBX
  (ADD|???????) EAX, 0x???????
  (ADD|???????) EAX, 0x???????
  (ADD|???????) EBX, EAX
  ????????
  ????????
  JMP MainLoop
  
  清洗后的代码贴到switch(Opcode)里面
          case        0x2E:
                  /*
                  LODSB
                  XOR     AL, BL
                  ADD     AL, 0CAH
                  ADD     AL, 1BH
                  ADD     BL, AL
                  MOVZX   EAX, AL
                  LEA     EAX, [EDI+EAX*4]
                  PUSH        EAX
                  */
                  {
                          Byte        arg1=ReadByte();
                          Byte        Key=ContextKey;
                          arg1=arg1^Key;
                          arg1=arg1+0xCA;
                          arg1=arg1+0x1B;
                          Key=Key+arg1;
                          ContextKey=ContextKey&0xFFFFFF00|Key;
                          AnalyzeResult->WriteLine(String::Format("PUSH\t{0}",GetHexString(ContextBase+arg1*4,4)));
                  }
                  return        true;
  扒掉取arg1和解码更新Key的代码
  剩下的代码原样输出
  本来160+的Method现在大概只要处理20-40个吧
  原先的VMCode经过处理之后就成功从CISC映射到了X86
  
  //-----------------------------映射过的代码---------------------------//
  PUSH        1E81CH
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E814H
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E800H
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E810H
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E80CH
  POP        EDX
  POP        DWORD PTR [EDX]
  MOV        BYTE PTR [1E828H], 1
  PUSH        1E80CH
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E808H
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E804H
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E818H
  POP        EDX
  POP        DWORD PTR [EDX]
  MOV        EDX, ESP
  PUSH        EDX
  PUSH        4
  POP        EAX
  ADD        [ESP], EAX
  POP        ESP
  PUSH        1E810H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        ESP
  PUSH        1E810H
  POP        EDX
  PUSH        EDX
  PUSH        1E804H
  PUSH        1E810H
  POP        EDX
  POP        EDX
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        ESP
  PUSH        14H
  POP        EAX
  SUB        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  POP        ESP
  PUSH        1E80CH
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        1E800H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        EDX
  PUSH        1E800H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EDX
  PUSH        1E80CH
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EDX
  POP        EDX
  PUSH        1E814H
  PUSH        1E818H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EDX
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        1E80CH
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        1E80CH
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        1E810H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        1E80CH
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EAX
  ADD        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  POP        EDX
  POP        EAX
  XOR        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  PUSH        1E80CH
  POP        EDX
  PUSH        EDX
  PUSH        EDX
  PUSH        4
  POP        EAX
  ADD        [ESP], EAX
  POP        EDX
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E818H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        1E818H
  PUSH        1E800H
  PUSH        1E814H
  POP        EDX
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EDX
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EAX
  XOR        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  PUSH        1E818H
  POP        EDX
  PUSH        EDX
  PUSH        SMALL 6B21H
  PUSH        1E808H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EDX
  PUSH        SMALL 9594H
  POP        EDX
  POP        EDX
  POP        DWORD PTR [EDX]
  PUSH        1E80CH
  POP        EDX
  PUSH        SMALL WORD PTR [EDX]
  PUSH        DWORD PTR [1E810H]
  POP        EDX
  PUSH        EDX
  PUSH        0FFFFFFF4H
  POP        EAX
  ADD        [ESP], EAX
  POP        EDX
  PUSH        EDX
  PUSH        1E804H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  PUSH        SMALL 6C0EH
  PUSH        SMALL 0D566H
  POP        EDX
  POP        EDX
  POP        EDX
  POP        SMALL WORD PTR [EDX]
  PUSH        DWORD PTR [1E810H]
  POP        EDX
  PUSH        EDX
  PUSH        0FFFFFFF6H
  POP        EAX
  ADD        [ESP], EAX
  PUSH        SMALL 8E94H
  PUSH        SMALL 5A8FH
  POP        EDX
  POP        EDX
  PUSH        EDX
  PUSH        EDX
  PUSH        1E810H
  PUSH        SMALL 0CE98H
  PUSH        SMALL 152DH
  POP        EDX
  POP        EDX
  POP        EDX
  PUSH        1E814H
  POP        EDX
  POP        DWORD PTR [EDX]
  MOV        EBX, 0
  PUSH        1E818H
  POP        EDX
  PUSH        EDX
  PUSH        1E818H
  POP        EDX
  PUSH        DWORD PTR [EDX]
  POP        EDX
  POP        EDX
  MOV        EBX, 0
  PUSH        DWORD PTR [EDX]
  MOV        EBX, 0
  PUSH        EDX
  PUSH        SMALL 0BD8FH
  PUSH        SMALL 0C90CH
  POP        EDX
  POP        EDX
  PUSH        DWORD PTR [1E814H]
  POP        EDX
  MOV        EBX, 0
  POP        DWORD PTR [EDX]
  PUSH        EDX
  PUSH        1E808H
  POP        EDX
  POP        EDX
  MOV        EBX, 0
  JXXX        3000011H
  JNX        23B6CH
  //-----------------------------------------------------------//
  Themida 的VMCode也是经过混淆的(该死的多态变形)
  一开始的代码大概意思就是
  POPF
  POP EDI
  POP ESI
  POP EBP
  POP ESP//VM 是堆栈机 不用ESP 再说了 POPA 也不改ESP
  POP EBX
  POP EDX
  POP ECX
  POP EAX
  
  搞定VM 寄存器 地址啦
  
  #define        R_EFLAG        "1E81CH"
  
  #define        R_EDI        "1E814H"
  #define        R_ESI        "1E800H"
  #define        R_EBP        "1E810H"
  #define        R_ESP        "1E80CH"
  #define        R_EBX        "1E80CH"
  #define        R_EDX        "1E808H"
  #define        R_ECX        "1E804H"
  #define        R_EAX        "1E818H"
  
  //------------------------------经过清洗的X86版虚拟代码--------------------//
  MOV        EDX, 1E81CH
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E814H
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E800H
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E810H
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E80CH
  POP        DWORD PTR [EDX]
  MOV        BYTE PTR [1E828H], 1
  MOV        EDX, 1E80CH
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E808H
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E804H
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E818H
  POP        DWORD PTR [EDX]
  MOV        EDX, ESP
  PUSH        EDX
  MOV        EAX, 4
  ADD        [ESP], EAX
  POP        ESP
  MOV        EDX, 1E810H
  PUSH        DWORD PTR [EDX]
  PUSH        ESP
  MOV        EDX, 1E810H
  POP        DWORD PTR [EDX]
  PUSH        ESP
  MOV        EAX, 14H
  SUB        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  POP        ESP
  MOV        EDX, 1E80CH
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E800H
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E814H
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E80CH
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E80CH
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E810H
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E80CH
  MOV        EAX, [EDX]
  ADD        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  POP        EDX
  POP        EAX
  XOR        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  PUSH        1E80CH
  PUSH        EDX
  MOV        EAX, 4
  ADD        [ESP], EAX
  POP        EDX
  POP        EDX
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E818H
  PUSH        DWORD PTR [EDX]
  MOV        EDX, 1E818H
  MOV        EAX, [EDX]
  XOR        [ESP], EAX
  PUSHF
  POP        DWORD PTR [1E81CH]
  PUSH        1E818H
  PUSH        SMALL 6B21H
  MOV        EDX, [1E808H]
  PUSH        SMALL 9594H
  POP        EDX
  POP        EDX
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E80CH
  PUSH        SMALL WORD PTR [EDX]
  PUSH        DWORD PTR [1E810H]
  MOV        EAX, 0FFFFFFF4H
  ADD        [ESP], EAX
  POP        EDX
  POP        SMALL WORD PTR [EDX]
  PUSH        DWORD PTR [1E810H]
  MOV        EAX, 0FFFFFFF6H
  ADD        [ESP], EAX
  MOV        EDX, 8E945A8FH
  MOV        EDX, 1E814H
  POP        DWORD PTR [EDX]
  MOV        EDX, 1E818H
  PUSH        DWORD PTR [EDX]
  MOV        EDX, [1E814H]
  POP        DWORD PTR [EDX]
  JXXX        3000011H
  JNX        23B6CH
  //---------------------------------------------------------------------------------//
  现在吧X86代码空间的虚拟代码在映射一把
  吧Register也映射回来
  //----------------------------------真正的X86版代码--------------------------------//
  POPF
  POP        EDI
  POP        ESI
  POP        EBP
  POP        EBX
  MOV        BYTE PTR [1E828H], 1
  POP        EBX
  POP        EDX
  POP        ECX
  POP        EAX
  PUSH        ESP
  ADD        DWORD PTR [ESP], 4
  POP        ESP
  PUSH        EBP
  PUSH        ESP
  POP        EBP
  PUSH        ESP
  SUB        DWORD PTR [ESP], 14H
  PUSHF
  POPF
  POP        ESP
  PUSH        EBX
  PUSH        ESI
  PUSH        EDI
  PUSH        EBX
  XOR        [ESP], EBX
  PUSHF
  POPF
  POP        EBX
  PUSH        EAX
  XOR        [ESP], EAX
  PUSHF
  POPF
  POP        EAX
  PUSH        BX
  POP        SMALL WORD PTR [EBP+0FFFFFFF4H]
  PUSH        EBP
  ADD        DWORD PTR [ESP], 0FFFFFFF6H
  POP        EDI
  PUSH        EAX
  POP        DWORD PTR [EDI]
  JXXX        3000011H
  JNX        23B6CH
  //-------------------------------------------------------------------------------------//
  再次清洗一边
  //-------------------------------------最终的成品面世啦--------------------------------//
  POPF
  POP        EDI
  POP        ESI
  POP        EBP
  POP        EBX
  MOV        BYTE PTR [1E828H], 1
  POP        EBX
  POP        EDX
  POP        ECX
  POP        EAX
  ADD    ESP, 4
  PUSH        EBP
  MOV    EBP, ESP
  SUB    ESP, 14H
  PUSH        EBX
  PUSH        ESI
  PUSH        EDI
  XOR    EBX, EBX
  XOR    EAX, EAX
  MOV        [EBP-0CH], BX
  LEA        EDI, [EBP-0AH]
  MOV    [EDI], EAX
  JXXX        3000011H
  JNX        23B6CH
  //-----------------------------------------------------------------------------------------------//
  
  至此全部工序就此结束
  
  //-----------------------------------------------------------------------------------------------//
  
  
--------------------------------------------------------------------------------
【经验总结】
  虚拟机的本质其实就是代码的多态变形,难点也就是对多态代码的归一化处理,从明文到密文是单向和确定的,
  但是从密文到明文却是多项和不确定的。规则复杂的吓人,盼望会玩太极的牛人快快写一工具出来救广大人民于水火。
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2009年02月17日 22:18:27


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

收藏
免费 7
支持
分享
最新回复 (49)
雪    币: 207
活跃值: (13)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
哈哈 沙发 不会吧,字数太少?
2009-2-17 22:18
0
雪    币: 485
活跃值: (12)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
3
强大,啥时候我也看看虚拟机什么样
2009-2-17 23:32
0
雪    币: 1657
活跃值: (291)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
4
恩不错~~~
2009-2-18 04:09
0
雪    币: 82
活跃值: (10)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
5
学习强文,对付虚拟机就用虚拟机的思路,能去花就OK了,不是非得还原到mov才能分析.
2009-2-18 05:39
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
6
这种事我也做过一次
还是觉得用途不大, 一样会累死人. 最后删之.
2009-2-18 08:18
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
7
5楼都学习了
我也要学习
楼主应该是kanxue特邀的
也不排除马甲的可能
和上次一样,这个版块要10贴以上才能发主题
但楼主直接能发,应该是kanxue先借了10个贴子吧
所以,楼主应该还会继续贴教程的
我们就排队学习吧
2009-2-18 08:53
0
雪    币: 362
活跃值: (25)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
强帖!学习。
2009-2-18 09:24
0
雪    币: 71
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
排队学习
2009-2-18 09:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
排队学习
2009-2-18 09:57
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
11
7楼正解。。。
2009-2-18 10:25
0
雪    币: 251
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
12
看雪ID:Brunhilde

为啥两个不一样的呢?
2009-2-18 10:32
0
雪    币: 251
活跃值: (25)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
13
大牛的分析能力很强啊
2009-2-18 10:33
0
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
14
隐藏者都是高手 呵呵 关系不一般啊
2009-2-18 11:35
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
15
5楼6楼7楼都在学习
我也要学习

现在的牛人都是一贴一精,太猛了
2009-2-18 11:53
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
16
膜拜人肉的时代
2009-2-18 12:35
0
雪    币: 2316
活跃值: (129)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
17
标记下,慢慢学习。
2009-2-18 13:06
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
18
我来膜拜的~~~
2009-2-18 15:12
0
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
19
天书一样,膜拜~!
2009-2-18 16:27
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
20
大家注意1楼。估计是马甲切换器出故障了。
2009-2-18 20:30
0
雪    币: 442
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
留个名吧
2009-2-18 21:47
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
22
排队学习~期待后续教程~~
2009-2-18 22:20
0
雪    币: 82
活跃值: (725)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
精华!学习!对于vmp我简直是文盲,需要恶补功课。
2009-2-19 01:00
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
24
跟着大牛一起排队学习
2009-2-19 08:33
0
雪    币: 2657
活跃值: (479)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
曾有类似想法,可惜精力有限
2009-2-19 13:15
0
游客
登录 | 注册 方可回帖
返回
//