首页
社区
课程
招聘
[转帖]一个反调试有特色的CrackMe
发表于: 2018-5-2 09:14 10175

[转帖]一个反调试有特色的CrackMe

2018-5-2 09:14
10175

转自“吾爱破解”。

反调试有意思,可以杀掉绝大部分的OD;目标程序:无壳 无花 无VM  有反调试;程序会指定目标 修改这个目标即可成功

反调试有意思,可以杀掉绝大部分的OD;目标程序:无壳 无花 无VM  有反调试;程序会指定目标 修改这个目标即可成功

具有商业保护软件的基本特性:Shadow DLLs、内存DLL等。
VMProtect的Tag都写好了,只差加壳。
要废掉其中关键的反调试不难,能弄懂其原理就是收获。
具有商业保护软件的基本特性:Shadow DLLs、内存DLL等。
VMProtect的Tag都写好了,只差加壳。
要废掉其中关键的反调试不难,能弄懂其原理就是收获。

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

上传的附件:
收藏
免费 2
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  demoscene   +1.00 2018/08/17
最新回复 (9)
雪    币: 1036
活跃值: (1311)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
2
这不是用了我写的XAntiDebug么
https://github.com/strivexjun/XAntiDebug
2018-5-2 10:03
0
雪    币: 627
活跃值: (663)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
3
StriveXjun 这不是用了我写的XAntiDebug么 https://github.com/strivexjun/XAntiDebug
原来这样!不知这个CM谁写的,当时觉得第二次NtQueryInformationProcess  Call有创意,学习了!
不过那个DLL被VM了,估计很多人不知道是哪里被检测到。
2018-5-2 10:20
0
雪    币: 1036
活跃值: (1311)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
4
MistHill 原来这样!不知这个CM谁写的,当时觉得第二次NtQueryInformationProcess Call有创意,学习了! 不过那个DLL被VM了,估计很多人不知道是哪里被检测到。
MistHill老师,能请教个你VMP3的CRC问题么?
我的思路是这样的:
1.VMP有个hash的计算表,分别是  struct{RVA,Lenght,HASH},在handle计算的时候分别读取这3个数值解密,然后分段校验
2.我找到了计算hash的handle(这里他有多个,我选其中一个),我循环用跟踪直到下一次调用计算hash的handle,这其中的过程他必定会  使用  pushimm32  或者readmem32  取读取这个hash计算的内容来解密。
3.如果找到了这个hash表的话,我把这个表的所有内容,全部换成一组  RVA,Lengt,Hash,这样VMP读来读去只会校验一个分段,这样来过掉他的CRC校验。

可我现在按照这个思路,找遍了pushimm32  和  readmem32的handle  也没发现他读取  这个hash表,老师能指点下吗?
2018-5-2 10:35
0
雪    币: 627
活跃值: (663)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
5
StriveXjun MistHill老师,能请教个你VMP3的CRC问题么? 我的思路是这样的: 1.VMP有个hash的计算表,分别是 struct{RVA,Lenght,HASH},在handle计算的时候分别读 ...
请教就不敢了,大家一起讨论、共同进步。
VMP3出来这么久了,还真没研究过。这两天找了样本来看。

VMP2的时候,有4张CRC校验表,校验顺序依次是:
1. File Check
用API CreateFile, CreateFileMapping, and MapViewOfFile把自身映射到内存,进行校验。
表通常含4条记录,这个表本身不做校验,可随便改。
2. Memory Check #1
表的记录项有几十到数百不等,表自身有校验。如果改了其中的条目,需要修改表的CRC值。
这两个检查发生在用户代码、数据、资源段解密之前。
3. Memory Check #2
含有数百到数千条记录,校验在程序完全解压缩、解密后进行,对用户程序进行校验。这个表自身的CRC是VM中的一个立即数,不好改,通过修补vGetHash/vCheck("VMP分析插件v1.4"的术语)容易一些。
这三个校验位于vmp1中,即壳代码段。按VMProtect官方文档,一个代码段对应一个VM,所以用VMP保护的程序通常有两个VM:vmp1和vmp0。
4. Random Memory Check
如果在保护时,勾选了"VM integrity check",就会有这个检查。
位于vmp0中,表的结构与前三个有所不同,记录格式是{unsigned char *offsetRVA, unsigned char length, unsigned int neghash}。
其中只有offsetRVA是加密的,校验不过不会报“文件损坏”,程序会死掉。因为是:返回地址+hash+neghash,如果hash+neghash不为0,就不知道跑哪里去了。

"Memory Check #1"和"Memory Check #2"中的记录不总是有效的,如果offsetRVA解密后为-0x1,则这是一条结束记录。可利用这个特点,把这条记录放到第一条的位置,整个表就废了。只需要修表自身的CRC。

VMP3看了两个样本,前三个校验是类似的,最后一个没时间看,不知道是怎么个情况。
VMP3的三个表都有的,顺序有所不同:"Memory Check #1"、"File Check"、"Memory Check #2"。

第一个样本:Sound的“VMProtect Ultimate v3.0.1.465 Unpack me
奇怪的是,它没有vGetHash handler,而是一个GetHash函数,在0x005F5661处。
三张表的位置:
Memory#1   005FC85D
File       0060C99D
Memory#2   00527D41
三张表的位置:
Memory#1   005F2A9A
File       00793741
Memory#2   005C8601
VMP2的vGetHash只有一个,算法一直未变。其间可能有多个分支。
v301例子是一个函数,而v309例子有11个vGetHash!(以下的v301和v309仅针对这两个样本。)
这三个hash算法都不同,v309的非常象标准的CRC32算法。
v309的11个vGetHash handler入口:
         1) 005D8131
         2) 005DADF4    ; for Memory Check #2 #E6+1
         3) 005DC448
         4) 005DD26C
         5) 005DD62E
         6) 005DEFF4
         7) 005E06BF
         8) 005E29FF
         9) 005E4B60    ; for File Check #04
        10) 005E6771
        11) 005E6937    ; for Memory Check#1 #18+1
这11个vGetHash虽然入口不同,有意思的是,在length>1的情况下,都会跳到3)的出口。
VMP3不再像VMP2那样有一张加密的Handler入口表和Dispatcher,VMP3的每个handler前半部分是完成其功能,后半部分是解密下一个handler基于EDI的偏移。EDI在VMP2时是VM_CONTEXT,现在是上一个handler的入口。
这和Oreans的VM handler就非常相似了!handler数不再局限于Handler表265项的限制,通常VMP2合并相同的入口地址后,只剩下几十个hadnler。
Oreans的 Tiger VM 基本上有1000多个handler,相同功能的handler除了入口地址不同,解码算法也有差异。VMP2时,一个程序中VM0和VM1相同功能的handler除了入口地址不同,解码算法是一样的。
另外v309的handler代码是乱序的,跳来跳去,与 Tiger Black 相似。

这些表的offsetRVA、length和hash在VMP2时,解密算法有时会非常复杂、且各不相同,前三种校验需要找出9种算法。
VMP3好像简化了,从看过的这两个例子来讲,hash未加密。offsetRVA和length都是简单地异或一个IMM32常数:v301是0x29F04A81,v309是0x75695A20。
例如,"Memory Check #1"
v301(XOR 0x29F04A81):
        Table Addr   OffsetRVA   Lenght      Hash               Dec. Off        Dec. Len
        ----------   ---------   ------      ----               --------        --------
        005FC85D     29EF82E8    29F04BF5    1A686282   ->      001FC869        00000174
        005FC869     29D118CD    29F04A8D    40D9EDE3   ->      0021524C        0000000C
        005FC875     29F04BDD    29F04ABD    8FCCEB28   ->      0000015C        0000003C
        ...
v309(XOR 0x75695A20):
        Table Addr   OffsetRVA   Lenght      Hash               Dec. Off        Dec. Len
        ----------   ---------   ------      ----               --------        --------
        005F2A9A     75767086    75695B00    5AAE2075   ->      001F2AA6        00000120
        005F2AA6     75695A04    75695B30    766F7A15   ->      00000024        00000110
        005F2AB2     757648F4    75695A2C    5283700C   ->      001F12D4        0000000C
        ...

啰嗦这么多,回到您的问题。附件中"TraceHandlers.txt"记录的是样本v309两次vGetHash("Memory Check #1")之间所有的handler执行过程。
助记符同"VMP分析插件v1.4":pushimm32==vPushIMM4,readmem32==vReadMemDs4。
记录中按列从左至右依次是:序号、vEIP(ESI)、handler入口地址、助记符、关键数据。共4个单元块,由vJmp(vJcc)过渡。
第一个单元进行上一次vGetHash的hash比较,视结果跳不同的地址;接下来是下个vGetHash的数据准备过程。
重点在第三个单元,最初的Table地址005F2AA6这里没记录到出处,应该在前面有个vPushIMM4,保存在vReg中,现在直接从vReg读取。
然后vAdd的偏移04,08都是vPushIMM4,用vReadMemDs4读加密的OffsetRVA和Lenght。
这些应该和VMP2差不多,您说没找到pushimm32和readmem32,也许没找准,或具体情况不一样。
从记录看,这些handler的执行过程基本都是有效指令,VMP2有很多垃圾handler穿插其中。
还可以看到解密OffsetRVA和Lenght的一条汇编指令"XOR"需要4个vNand4 handler来模拟;汇编指令"BSWAP"就需要更多的handler来模拟了!

对这个话题感兴趣的人,如果不熟悉,可参阅我以前回在tuts4you关于VMP2的两个帖子。后来看雪有人问过,不记得回在哪个帖子了。
上传的附件:
2018-5-4 17:00
1
雪    币: 1036
活跃值: (1311)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
6
MistHill 请教就不敢了,大家一起讨论、共同进步。 VMP3出来这么久了,还真没研究过。这两天找了样本来看。 VMP2的时候,有4张CRC校验表,校验顺序依次是: 1. File C ...
太厉害了  !  非常感谢老师回复,这些内容要慢慢消化了!
2018-5-7 10:14
0
雪    币: 3277
活跃值: (1992)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
原来两位都是密界大佬元老,后辈们崇拜不已。
2018-5-7 13:01
0
雪    币: 783
活跃值: (1121)
能力值: ( LV5,RANK:78 )
在线值:
发帖
回帖
粉丝
8
MistHill 请教就不敢了,大家一起讨论、共同进步。 VMP3出来这么久了,还真没研究过。这两天找了样本来看。 VMP2的时候,有4张CRC校验表,校验顺序依次是: 1. File C ...
受教了.大佬不亏是大佬..真的厉害.希望有时间能能大佬一半厉害就好了..
2019-9-10 01:13
0
雪    币: 4713
活跃值: (3224)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这是什么原理啊,SOD都拿他没办法
2020-5-31 19:19
0
雪    币: 688
活跃值: (204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
原理好简单,就是"自制"SYSCALL调用,不通过NTDLL去调用SYSCALL,
一般的反反调试,都是通过HOOK NTDLL来实现FAKE.所以不通过NTDLL调用SYSCALL就行了.
这种人造SYSCALL调用,由于是动态调用的,没有一般情况下没有固定的地址,要在RING3拦截的话,只能通过特征搜索在其
调用之前找到它,这样处理太过于针对,通用性不强.
而最佳的做法就是在RING0处理了,因为它无论在任何位置调用CALL,最终RING0的入口只有一个.
而另外一个细节就是,其实同一个进程里面,是有2个版本的NTDLL的,分别是32位和64位的,一般情况下,
使用普通进程软件,枚举模块的话,只会看到对应版本的NTDLL,其实还有一个隐藏的NTDLL,
这个就是某人说的,假冒WOW64调用SYSCALL,其实这个并非是WOW64,
何为WOW64?64位进程跨进程访问32位,此32位对于那个64位来说,它是WOW64.
也就是说,对于自身来说,是没有WOW64的说法的,别误人子弟,谢谢.
2020-6-1 19:18
0
游客
登录 | 注册 方可回帖
返回
//