能力值:
( LV3,RANK:35 )
|
-
-
2 楼
这不是用了我写的XAntiDebug么 https://github.com/strivexjun/XAntiDebug
|
能力值:
( LV9,RANK:270 )
|
-
-
3 楼
StriveXjun
这不是用了我写的XAntiDebug么
https://github.com/strivexjun/XAntiDebug
原来这样!不知这个CM谁写的,当时觉得第二次NtQueryInformationProcess Call有创意,学习了! 不过那个DLL被VM了,估计很多人不知道是哪里被检测到。
|
能力值:
( 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表,老师能指点下吗?
|
能力值:
( 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"。
奇怪的是,它没有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的两个帖子。后来看雪有人问过,不记得回在哪个帖子了。
|
能力值:
( LV3,RANK:35 )
|
-
-
6 楼
MistHill
请教就不敢了,大家一起讨论、共同进步。
VMP3出来这么久了,还真没研究过。这两天找了样本来看。
VMP2的时候,有4张CRC校验表,校验顺序依次是:
1. File C ...
太厉害了 ! 非常感谢老师回复,这些内容要慢慢消化了!
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
原来两位都是密界大佬元老,后辈们崇拜不已。
|
能力值:
( LV5,RANK:78 )
|
-
-
8 楼
MistHill
请教就不敢了,大家一起讨论、共同进步。
VMP3出来这么久了,还真没研究过。这两天找了样本来看。
VMP2的时候,有4张CRC校验表,校验顺序依次是:
1. File C ...
受教了.大佬不亏是大佬..真的厉害.希望有时间能能大佬一半厉害就好了..
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
这是什么原理啊,SOD都拿他没办法
|
能力值:
( 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的说法的,别误人子弟,谢谢.
|