上一篇文章指出了去混淆的重要性与去混淆的方法,没有可看过的可以看[原创]从0开始手撕64位vmp3.5壳(能撕但只能撕一点点)-逆向工程-看雪安全社区|专业技术交流与安全研究论坛
这一篇就讲解下如何识别handle。首先从VMinit开始 由于我们不是静态分析,我们通过工具能获取到每一步执行结果和堆栈,因此我将用最简单的方式不看加解密直接分析Handle(也是我目前唯一会的)。
我们只用在vminit中找到VMstrack 还有 VMEIP 就可以了,其实VEIP的作用也可以忽略不计,就是看个乐子,但是VMStrack要好好理解。
ok 接下来就开始看第一个handle
ok通过上面三个Handle 我们可以总结出 每次push ret 就是 Handle结尾
接下来讲堆栈,大家要认真理解。
首先来看vmHandle的堆栈,很简单,保存现场,然后提升堆栈


然后看看接下来的handle执行后


可以看到 接下来两个handle把之前push的堆栈存到了 当前rps+rdx 的位置中, 其中rdx 是从rdi中取得,对于目前的动态分析这都不重要。我只要知道使用rdx的时候是什么值就行,不用在意哪里来的。
看下图 是我截取的工具截图, 可以看到 当执行到mov [rsp + rdx], rcx 的时候 rdx =0x10。因此通过目前的堆栈就可以看出,就是把之前堆栈的值pop到新的栈里。前后关系要理清楚,是发现了它弹出了堆栈。所以叫vpop 而不是因为叫vpop 所以弹出了堆栈。


如上图左上角所示
接下来一系列handle都是vpop。那么就是把各种寄存器全部取出来放到rps+xx的堆栈中。
从handle1 -handle19都是Vpop 值得注意的是 pop不是顺序的,是乱序的。
下图就是各种push 大家记住 rsp+0xA8 是rax,后面有用


接下看handle20
从上面就能看出来 堆栈+8 还有写值 就是push 立即数 。 至于0是怎么算出来的,0代表了什么我还没有研究,目前不影响我们。
下面我们看handle21
0x28 我们在handle1写入的,当时写入的是 0x7ff507a40000 我们在看是否能对应的上。

如上图所示 r9 就是我们handle1写入的值, 当然你也可以从左边的handle列表里面看到,左侧的handle列表就是我编写的自动识别脚本识别出来的 脚本位置在开源项目的 scripts\split_handlers.lua。每一个handle都是人工识别后,编写lua脚本自动识别。当然工具也又ai接口,ai可以直接获取内容。但是最好人工看,AI还是容易掉坑里。
为了方便起见下面我们就尽量看左边的Handle简介,遇到特殊Handle再讲解
一定有人已经按耐不住了,讲了这么久 你加密前的汇编影子都没看到。
这是因为VMP要各种初始化,具体作用作者也是云里雾里不敢乱说。我们直接跳到逆向汇编的部分
如下所示是我加壳前的汇编 已经在第一章介绍过了
首先就是push rax 如下图所示 之前说过rsp+0xA8 就是RAX 那么Handle35行的意思就是 push rax,注意这个push是Vpush。不等于真实汇编的push。


看着上面的解释是不是一头雾水 实际就是把R8 也就是当前指针push到堆栈里 疑惑的话先接着往下看
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于 2026-9-11 09:49
被卑鄙兔编辑
,原因: