VMProtect完全解析之TLS

  • A+
所属分类:逆向工程

VMProtect完全解析之TLS

听朋友说程序加了VMProtect后,很难破解,今天我们就来看看这个保护有多难。首先先分析下VMProtect最早执行的部分–TLS。今天我们的样本就先看看VMProtect的主程序,我用的是VMProtect Ultimate v 2.12.3版本,网上搜一下就可以下载得到。

VMProtect主要实现了一个自己的虚拟机,通过解析执行来完成相关的工作,直接看他的引擎本文暂不描述,我自己写了个解析器。将TLS部分解析后如下:

           SetReg32 38
           GetImm32 9711ACF7
           Add32
           SetReg32 0C
           SetReg32 2C
           SetReg32 30
           SetReg32 20
           SetReg32 34
           SetReg32 24
           SetReg32 08
           SetReg32 14
           SetReg32 3C
           SetReg32 10
           SetReg32 18
           SetReg32 1C
           SetReg32 28
           GetImm32 45569F07
           GetImm16 0000
           GetImm32 01179B0A   ===================== cmp byte ptr [0x01179b0a], 0
           RmDs8
           GetEsp32
           RmSs8
           NNA8
           SetReg32 04
           Add8
           SetReg32 28
           GetEsp32
           RmSs8
           NNA8
           SetReg32 0C
           SetReg8 1C
           GetReg32 28
           GetReg32 28
           NNA32
           SetReg32 08
           GetImm32 FFFFF7EA
           NNA32
           SetReg32 3C
           GetReg32 0C
           GetReg32 0C
           NNA32
           SetReg32 3C
           GetImm32 00000815
           NNA32
           SetReg32 04
           Add32
           SetReg32 00
           SetReg32 04
           GetImm32 449A0010
           GetEsp32
           GetImm16 0004
           GetReg32 04
           GetImm32 FFFFFFBF
           NNA32
           SetReg32 28
           Shr32
           SetReg32 08
           Add32
           SetReg32 00
           RdSs32
           jne -> 449A0010:45569F07
           SetReg32 1C
           SetReg32 3C
           SetReg32 00
           GetReg32 1C
           SetReg32 00
           GetReg32 00
           GetEsp32
           RdSs32
           NNA32
           SetReg32 08
           GetImm32 BBBEF8A6
           NNA32
           SetReg32 3C
           GetReg32 00
           GetImm32 44410759
           NNA32
           SetReg32 08
           NNA32
           SetReg32 3C
           SetReg32 08
           GetReg32 2C
           GetReg32 18
           GetReg32 04
           GetReg32 20
           GetReg32 34
           GetReg32 18
           GetReg32 10
           GetReg32 24
           GetReg32 30
           GetReg32 00
           GetReg32 14
           GetImm32 68EE5309
           GetReg32 2C
           Add32
           SetReg32 0C
           GetReg32 38
           GetReg32 08
           SetEip

 首先检测 0x01179B0A 是否初始化,这个值关系着后面的流程,如果这个被置1,后面就不会检测入口的断点。我们接着看第二部分:

           ===================================================================
           ===== Jne 00DB0749 0117985E
           ===================================================================
           =====00DB0749 00DB0749
           SetReg32 24
           GetImm32 9711ACF7
           Add32
           SetReg32 04
           SetReg32 00
           SetReg32 1C
           SetReg32 38
           GetReg32 38
           GetReg32 38
           NNA32
           SetReg32 10
           GetImm32 BBBEF8A6
           NNA32
           SetReg32 08
           GetReg32 38
           GetImm32 44410759
           NNA32
           SetReg32 10
           NNA32
           SetReg32 18
           SetReg32 20
           SetReg32 04
           SetReg32 30
           SetReg32 34
           SetReg32 28
           SetReg32 10
           SetReg32 3C
           SetReg32 0C
           SetReg32 2C
           SetReg32 08
           GetReg32 0C
           GetReg32 30
           GetReg32 3C
           GetReg32 04
           GetReg32 1C
           GetReg32 10
           GetReg32 34
           GetImm32 55D02669
           GetImm32 01179B0A
           GetImm32 00400000     =============================Image base
           SetReg32 2C
           GetImm32 0000003C     =============================PeOffset
           GetReg32 2C
           Add32
           SetReg32 18
           RmDs32
           SetReg32 08
           GetReg32 2C
           GetReg32 08
           Add32
           SetReg32 30
           SetReg32 18           ==============================PeHead
           GetImm32 00000028     ==============================Pe Entry offset
           GetReg32 18
           Add32
           SetReg32 30
           RmDs32
           GetEsp32
           RdSs32
           SetReg32 34
           GetReg32 2C
           Add32
           SetReg32 08
           SetReg32 30
           GetImm16 00CC         ================================INT 3断点
           GetReg32 30
           RmDs8
           GetEsp32
           RmSs8
           NNA8
           SetReg32 18
           Add8
           SetReg32 34
           GetEsp32
           RmSs8
           NNA8
           SetReg32 18
           SetReg8 08
           GetReg32 34
           GetEsp32
           RdSs32
           NNA32
           SetReg32 20
           GetImm32 FFFFF7EA
           NNA32
           SetReg32 0C
           GetReg32 18
           GetEsp32
           RdSs32
           NNA32
           SetReg32 08
           GetImm32 00000815
           NNA32
           SetReg32 14
           Add32
           SetReg32 20
           SetReg32 14
           SetReg32 08
           GetImm32 55D026FC
           GetEsp32
           GetImm16 0004
           GetReg32 14
           GetImm32 FFFFFFBF
           NNA32
           SetReg32 3C
           Shr32
           SetReg32 20
           Add32
           SetReg32 3C
           RdSs32
           jne -> 55D026FC:55D02669
           SetReg32 3C
           SetReg32 38
           SetReg32 34
           GetReg32 3C
           SetReg32 34
           GetReg32 34
           GetEsp32
           RdSs32
           NNA32
           SetReg32 20
           GetImm32 AB37E0B8
           NNA32
           SetReg32 3C
           GetReg32 34
           GetImm32 54C81F47
           NNA32
           SetReg32 20
           NNA32
           SetReg32 20
           SetReg32 38
           GetReg32 2C
           GetReg32 10
           GetReg32 10
           GetReg32 28
           GetReg32 2C
           GetReg32 04
           GetReg32 14
           GetReg32 30
           GetReg32 28
           GetReg32 1C
           GetReg32 08
           GetReg32 00
           GetImm32 68EE5309
           Add32
           SetReg32 0C
           GetReg32 24
           GetReg32 38
           SetEip

 从上面的代码可以看出,VMProtect直接检测了入口的CC断点,因此,如果我们OD直接停在入口点的话将会被检测到。

           ===================================================================
           =====011839BB 011839BB
           SetReg32 3C
           GetImm32 9711ACF7
           Add32
           SetReg32 18
           SetReg32 20
           SetReg32 2C
           SetReg32 04
           SetReg32 08
           SetReg32 0C
           SetReg32 38
           SetReg32 00
           SetReg32 28
           SetReg32 34
           GetReg32 34
           GetReg32 34
           NNA32
           SetReg32 14
           GetImm32 AB37E0B8
           NNA32
           SetReg32 10
           GetImm32 54C81F47
           GetReg32 34
           NNA32
           SetReg32 24
           NNA32
           SetReg32 30
           SetReg32 14
           SetReg32 24
           SetReg32 10
           SetReg32 30
           GetImm16 0001                =======================如果检测到了就写入1
           GetImm32 00000001            =======================记录地址偏移1(0x01179b0a+1)
           GetReg32 2C
           Add32
           SetReg32 30
           WmDs8
           GetImm32 0000027B
           GetReg32 30
           GetReg32 24
           GetReg32 14
           SetReg32 18
           GetReg32 18
           GetEsp32
           RdSs32
           NNA32
           SetReg32 10
           GetImm32 AB37E0B8
           NNA32
           SetReg32 1C
           GetImm32 54C81F47
           GetReg32 18
           NNA32
           SetReg32 1C
           NNA32
           SetReg32 10
           GetReg32 28
           GetReg32 00
           GetReg32 38
           GetReg32 0C
           GetReg32 08
           GetReg32 04
           GetReg32 2C
           GetImm32 68EE5309
           GetReg32 20
           Add32
           SetReg32 30
           GetReg32 3C
           SetReg32 1C
           GetImm32 9711ACF7
           Add32
           SetReg32 3C
           SetReg32 34
           SetReg32 3C
           SetReg32 30
           SetReg32 10
           SetReg32 20
           SetReg32 04
           SetReg32 0C
           SetReg32 38
           SetReg32 28
           GetReg32 28
           GetEsp32
           RdSs32
           NNA32
           SetReg32 2C
           GetImm32 AB37E0B8
           NNA32
           SetReg32 18
           GetReg32 28
           GetImm32 54C81F47
           NNA32
           SetReg32 08
           NNA32
           SetReg32 08
           SetReg32 2C
           SetReg32 00
           SetReg32 24
           SetReg32 14
           SetReg32 14
           SetReg32 24
           SetReg32 00
           SetReg32 18
           SetReg32 30
           SetReg32 08
           SetReg32 38
           GetReg32 38
           GetReg32 38
           NNA32
           SetReg32 0C
           GetImm32 000008FF
           NNA32
           SetReg32 0C
           AddEsp4
           GetEsp32
           RdSs32
           GetEsp32
           GetImm32 00000010
           Add32
           SetReg32 0C
           WmSs32
           SetReg32 3C
           SetReg32 3C
           SetReg32 04
           GetReg32 10
           GetReg32 14
           GetReg32 38
           GetReg32 00
           GetReg32 2C
           GetReg32 08
           GetReg32 24
           GetReg32 30
           GetReg32 18
           GetReg32 0C
           GetReg32 0C

TLS中只是将检测结果保存起来,然后在入口点之后的代码里检测这个标志位,我们只要在入口点将这个值改成0,后面就不会显示检测到调试器,当然后面的检测还有,下次再分享,本文就不再描述。

总结:整个TLS的过程不复杂,复杂的是对VMProtect的引擎的解析,如果大家喜欢此类文章,后续我将继续发表相关文章。        

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: