首页
社区
课程
招聘
tvm分析与还原
发表于: 2023-5-26 01:19 33404

tvm分析与还原

2023-5-26 01:19
33404

一句话概括就是腾讯自家的虚拟化加密壳。把腾讯的安全产品拉入 PE 工具,看到区段中有 .tvm0 那就没跑了。

这次还原用到的demo是前段时间 游戏安全技术竞赛的决赛附加题一个非常好的demo,驱动基本上全vm了。

还要特别感谢 这位大佬放出来的脱壳版,给我节省了许多验证还原效果的时间。

还原脚本项目地址:xx_tvm

文档我也只说明了一些明显的点,还是看代码更加清晰。

然后给你的idapython安装以下的库:

1.

可优化成:

直接特征识别即可,请参考idapython/TVMunicornTrace.py .tvmFunTask.mabe_1()

2.

可优化成:

直接特征识别即可,请参考idapython/TVMunicornTrace.py .tvmFunTask.mabe_2()

3.

可优化成:

直接特征识别即可,请参考idapython/TVMunicornTrace.py .tvmFunTask.mabe_3_4()

4.(类似 3)

可优化成:

直接特征识别即可,请参考idapython/TVMunicornTrace.py .tvmFunTask.mabe_3_4()

去混淆前:

去混淆后:

虚拟机的大致架构如下,非常标准。

实际上tvm有多个handle分发器和多张handleTable,但是它们的作用、内容完全一致,所以我就只画出一个handle分发器,下面也只讲解一张handleTable

使用unicorn 跟一次tvm入口到出口,脚本参考:idapython/TVMunicornTrace.py

初始rsp设置为 0x1800

入口:(已去混淆) 完整文件请查看trace_file/tvm入口到出口 去混淆.log

未去混淆的查看trace_file/tvm入口到出口 未去混淆.log

1400d2ffc1400d315f,tvm第一次保存进入虚拟机前的寄存器状态:

接下来是第二次保存进入虚拟机前的寄存器状态:

1400d31601400d30aa,保存状态如下:

接下来保存 虚拟机指令起始点和虚拟机寄存器的起始指针

结构如下:

14006024c这是当前函数的虚拟指令起始点,可以先记住,后面就知道为什么我这么说了。

接下来进入

进call,return地址入栈:

这个函数,它也会保存一下寄存器状态,但是没啥用:

保存的状态如下:

然后会把V_RIP换个位置;

接下来就开始处理虚拟指令了。先把栈空间的格式整理一下:(这个地方非常重要)

其实只需要记住 R10放着V_REG_P 和 [rbp+8] 放着 V_RIP 。

这是一段 tvmhandle的分发(tvmopcode的处理方式)

[rbp + 8] 是 V_RIP,放入r9,然后从[R9] 取出 tvmopcode 放入r8b 然后异或 0x5D,然后 r9 +1(上面是混淆过的,实际效果就是 + 1 )。

R8b - 1 如果大于0xC8,就跳转到1400D9954,说明这是未知的tvmopcode,出错。1400D9954是int3指令。

然后 handleTable 放入 R9,取表项 [R9 + R8 *8],即为这个handle的偏移,加上基址0x140000000,即为这个handle 的实际处理地址:1400d60f2,通过 jmp r8 跳转过去。

(可以看到 取得第一个 tvmopcode 是 0xe8 ,和上面图中的是一样的)

注意,tvm有多张handleTable,但是里面的内容都是一样的。所以拿到一张表就行了

tvmopcode^0x5d - 1 < 0xC8 可以推测一共有 0xc8 ( 0~0xc7 )个 tvmopcode,例:

现在我们知道,tvm的handleTable有0xc8个有效项,我们就可以遍历handleTable,并且静态跟踪出handle。看它是如何处理的:

导出handle代码(idapython/TVMHandleOut.py

补充:虽然handle有0xc8个有效项,但是很多是重复的,是留作拓展用的,真正有效的handle就 80个:

左边 是 handle处理地址,右边是 tvmopcode

并在在 当前文件夹/handleout 文件夹内,输出全部handle静态跟踪(运行脚本的同时会对handle去简单的混淆)

:(刚好80个不相同的handle,文件名用 tvmopcode)

一共有80个不同功能的tvmopcode,为节省篇幅,我这里挑一个常见的讲解,全部的handle分析,其余的全部放在(handle_out/

(那个特别多的是int3,应该是预留以后更新用的)

我静态跟踪handle是以 jnb 为结尾的(就是判断是否大于0xc8后的jnb),所以跟踪文件后半段有一些不用看。

我对 tvmAsm的命名规则:

我这里直接将全部tvmAsm展示出来:(参考 idapython/deTvm.py . tvmHandleTableInit()

解释:

TVMTABEL.append 第一个参数是我给tvmAsm取的名字,第二个参数就是 tvmopcode,第三个参数是:如果这个handle要取虚拟寄存器,就必须通过 这个值解密取得虚拟寄存器,就像是我上文中解释的:

这里再挑几个特殊说明一下:

把tvm的跟踪规则写好后,就可以跟踪导出这个函数的虚拟化控制流:跟踪参考

idapython/deTvm.py . traceTask.track()

这是我挑的一个短的函数:0x140001250 参考trace_file/sub_0x140001250.log

使用函数traceTask.track(0) + traceTask.traceOut(),输出如下

可能会好奇这些 PO_reg 怎么来的,其实这是我对 traceCode的优化:

正常的取 虚拟机寄存器 都是 [r10 + xxx],r10 就是 V_REG_P,前面说过了,看下面这一段(前面也出现过)。

例如 PO_r8 其实就是 [r10 + 0x48]

所以 tvmAsm对 PO_reg 操作 可以理解为对虚拟机外的真实寄存器操作。

这里我使用了 标记working + 赋值表记录 的方法,将所有有意义的 tvmAsm找出来。

先说哪种tvmAsm会被标记为 working:(标记为working表明至少可以还原出一条原始Asm)

只要标记好这几个点,就能还原出全部的Asm。参考(idapython/deTvm.py . traceTask.track()

那么我们标记好后,这段 tvm指令就如下:

箭头指着的就是标记为working的TraceCode。那么接下来要干嘛,就很清晰了,把相关的traceCode找出来(变量溯源)。

例子1:

这一句被标记为working,我们找他使用的参数的赋值语句,直到 找到 整数 或 PO_reg

我们把 [r10 + 0xa8]的赋值语句找出来(往上找):

这一句用到了 [r10 + 0xb8],找它的赋值语句:

又是 [r10 + 0xb8],再往上找:

用到 [r10 + 0xb0] 和 [r10 + 0xa0],往上找:

[r10 + 0xa0]找到尽头了,[r10 + 0xb0]还没找到尽头,继续网上找[ r10 + 0xa8 ]的赋值语句:

找到尽头,是将 PO_rsp 放入。我们把这些 traceCode放在一起:

参考 idapython/deTvm.py . traceTask.VRegRecord()

这样也有点不好看,用变量传播优化一下:

参考idapython/deTvm.py . tvmToAsm.optimize()

这一些 traceCode,就可以还原出一句 Asm:(以下我们对这一段可还原成Asm的TraceCode集合统称为一个 tvmToAsm 结构

于是这一段就可以还原成:

为什么是 sub rsp,0x28而不是 lea rsp,[rsp - 0x28]是有讲究的:

看traceCode中的一句 v_add_oregll_iregll_iregll_oregl,他是有输出 rflag的,并且放入的位置就是 PO_rf,说明这一句ASM是会影响标志位,而 lea 是不影响标志位的,所以将它还原成 sub

我们顺势对这个函数的所有被标记为working 的traceCode进行变量溯源+优化,那么最后就可以得到:tvmToAsmAll

一个函数内的所有 tvmToAsm 组成一个 tvmToAsmAll ,下图中一段一段的就是 tvmToAsm

看,真正有效的就这一些,其余的都可以看作花指令。所以这个函数的原始ASM就是:(手动还原)

上文说过,tvm不能模拟全部的Asm,所以有些Asm需要暂时退出虚拟机执行,然后再返回虚拟机:

我们到0x1400c7588,然后往下跟(中间是还原真实寄存器),

直到出现 mov rsp,[rsp] ,之后的下一句就是真实需要执行的ASM了。即为 call sub_140005E38。

接下来会重新进入虚拟机,步骤和上文进入虚拟机的步骤大致相同。

所以 v_jmp_ll 是最容易还原成 Asm 之一的 tvmAsm了。

参考idapython/deTvm.py . tvmToAsm.vjmp_handle()

关于如何找到workingTraceCode的相关traceCode,我的方案如下:(如果你有其他方案,可以不用看这一段)

把全部traceCode的赋值语句找出来,然后给相关虚拟机寄存器添加赋值记录,形成一张赋值表,例如:

我就可以得到这么一张表:

当需要检索这一句traceCode的相关traceCode时:

就可以直接查表,先找到[ r10 + 0xa8 ]的赋值记录栈traceTaskRegList,然后通过地址找到最近的一次赋值traceTaskReg,然后traceTaskReg记录了这一句traceCode,就可以找到了。

于是就找到了相关traceCode:

因为是将 PO_reg 赋值给它,所以到此检索完毕,如果不是,则按照相同的方法继续往上找。

相关代码参考:idapython/deTvm.py . traceTask.VRegRecord()

例如有两个连续的 tvmToAsm,导出的相关traceCode如下:

我们可以发现,有两段相关traceCode是相同的,这就出现问题了:

第一个tvmToAsm可以翻译成 xor edi,edi,那么第二个tvmToAsm能翻译成什么呢?

如果我们人为识别,就可以将其翻译成 mov ecx,edi,因为 [r10 + 450]在前面已经放入了 PO_rdi,下面又取它放入 PO_rcx

于是我们可以进行优化,如果 有一句 v_mov_iregx_iregx(PO_reg , xxxx)那么我们就可以将 xxxx的上一次赋值标记为PO_reg

还是以上面的那一段代码为例:

[r10 + 0x450]上一次赋值语句为:

我们可以将其标记为 PO_rdi,那么当其他的workingTraceCode向上进行查找赋值表的时候,就可以找到PO_rdi,于是就优化为了:

实现代码参考:idapython/deTvm.py . traceTask.VRegRecord()

push:

这是两个连续的 tvmToAsm,

如果按照一般的分析方式,那么这两句可以翻译为:

乍一看没什么问题,就是将 push r13分开成两句执行,可是如果是pop,那么情况就有点不同了:

pop:

如果按照一般的分析方式,那么这两句可以翻译为:

这就出问题了,这两句并不等于 pop r13 指令,那么问题出在哪呢,我们取消掉变量传播优化再看看:

问题就出在,这两句 workingTraceCode在进行变量溯源时,都找到了 0x14004dca7 这一句,

将 PO_rsp 放入虚拟机寄存器 [r10 + 0xa8],并且在第一句workingTraceCode中,又更改了 PO_rsp的值,所以导致出错。

幸运的是这种情况只会出现在 push 和 pop 中(参考idapython/deTvm.py . tvmToAsmAll.outerror()),

所以我们要对 push 和 pop 特殊处理,请参考:idapython/deTvm.py . tvmToAsmAll.findPushAndPop()

特殊处理,优化后的 push 和 pop:

push:

pop:

这就清晰很多了。

前置知识:

各个标志位的位置:

tvm巧妙的利用了and sub setz je 这四种指令模拟一个jcc,例如:

(v_je 的跳转是通过 加减 V_RIP 实现的,我这里直接优化成 绝对地址,省了我们去计算)

上面的代码,先保留 rflag 的zf位,然后再减去zf位,如果结果为0,那么 V_RIP 就变成 v_je 的第二个操作数 0x14003c274否则 V_RIP变为0x14003c1fe

于是,上面这段tvmasm可以翻译为:

第一个tvmToAsm:

如果 zf = sf = of = 0,则V_RIP = 0x1400369ec ,否则 V_RIP = 0x140036ac6 (其实就是下面那一段,因为优化了所以地址对不上)

第二个tvmToAsm:

如果 zf = 0 且 sf = of = 1,则V_RIP = 0x1400369ec,否则 VRIP = 0x1400368ef

于是,上面这段tvmasm可以翻译为:

JE 的特征 0x40 0x40 (看上图你就知道是什么特征了)

JG 的特征 0x8c0 0x0 0x8c0 0x880(看上图你就知道是什么特征了)

全部的jcc特征:(代码参考idapython/deTvm.py . tvmToAsm.vjcc_handle()

上面我说JBE JNA 的特征是0x41 0x1 0x41 0x40这其实是错误的:

因为 这只是 jmp if ZF != CF,真正的 JBE JNAjmp if CF = 1 or ZF = 1

对应的特征应该是 0x41 0x1 0x41 0x40 0x41 0x41,在这个版本的 tvm 中 ,它将 JBE JNA错误处理成了jmp if ZF != CF

我逆了较新版本的 tvm ,JBE JNA这里的bug就被修复了,就是0x41 0x1 0x41 0x40 0x41 0x41

(看来ACE部门用的tvm版本不够新啊)

参考idapython/deTvm.py . tvmToAsmAll.AllTvmAsmToAsm()

push 和 pop 在上文已经识别出来了,

jcc 在上文也识别出来了,

tvm没有模拟的Asm,也可以通过跟踪 v_jmp_ll 得到,上文也说了。

一些明显的 tvmAsm也可以直接识别原本的AsmOpcode:

如果tvmToAsm中的traceCode的tvmAsm含有以上的字符串,

那么可以直接将这个tvmtoAsm的AsmOpcode设置为对应项,例如:

可以直接将Asm的Opcode 设置成 xor,如果要翻译成Asm的话,就翻译成了 xor edx,edx

以上部分,参考代码:idapython/deTvm.py . tvmToAsm.setASMOpcode_1()

识别 lea mov add sub ,这部分比较复杂,如果是人为识别就简单。

我们先对每一个tvmToAsm内的traceCode再进行一次变量分析,列出一个赋值表,类似于上文赋值表的结构。

除此之外,我们还要对其进行标记设置,例如:

标记的结构:[handle,tvmPara,IsUseRflag],依次是处理手段、虚拟机寄存器、是否使用(输出)标志位

有了这些标记,再加上14004a507这一句指令,我们就可以识别这个tvmToAsm的AsmOpcode了:

有了这些标记,再加上14006280b这一句指令,我们就可以识别这个tvmToAsm的AsmOpcode了:

有了这些标记,再加上14004a82c这一句指令,我们就可以识别这个tvmToAsm的AsmOpcode了:

有了这些标记,再加上140062837这一句指令,我们就可以识别这个tvmToAsm的AsmOpcode了:

以上部分都只是一些简单例子,关于更加严格的 sub add lea mov 分类,参考代码:

idapython/deTvm.py . tvmToAsm.record_tage() 负责跟踪标记

idapython/deTvm.py . tvmToAsm.setASMOpcode_2()负责分类 sub add lea mov

到这里的时候,全部 tvmToAsm 的 AsmOpcode都已经全部识别。

首先介绍一个工具函数 :GetAsmPara可以将标记转换成Asm操作数的格式。

例子和上图是一样的。转换为标记如下:

看到140062837这一条workingTraceCode:

v_mov_iregb_iregb ( iregb :PO_rax ,iregb :[ r10 + 0x90 ] );

代码参考:idapython/deTvm.py . tvmToAsm.mov_handle()

例子和上图是一样的。转换为标记如下:

看到14004a82c这一条workingTraceCode:

v_mov_iregll_iregll ( iregll :PO_r8 ,iregll :[ r10 + 0xa0 ] );

代码参考:idapython/deTvm.py . tvmToAsm.lea_handle()

用上面add的例子,但是进行GetAsmPara的是红框框起来的这两个:(对于sub的处理是一样的)

对红框的两个参数进行GetAsmPara

代码参考:idapython/deTvm.py . tvmToAsm.add_sub_handle()

以下都是 对 红框框框起来的 tvmPara 进行GetAsmPara

代码参考:idapython/deTvm.py . tvmToAsm.push_handle()

代码参考:idapython/deTvm.py . tvmToAsm.pop_handle()

cmp:

test:

代码参考:idapython/deTvm.py . tvmToAsm.cmp_test_handle()

举例如果 opcode是 movzx

其余的一样,取 opcode 对应的 第二个参数,然后 workingTraceCode的第一个参数进行GetAsmPara

代码参考:idapython/deTvm.py . tvmToAsm.movzx_movsx_movsxd_handle()

取 tvmAsmOpcode内含有 "not"字符串的那一句traceCode,取第二个参数进行 GetAsmPara

代码参考:idapython/deTvm.py . tvmToAsm.not_handle()

取 tvmAsmOpcode含有 上述opcode 的traceCode,取第三个参数进行 GetAsmPara

取workingTraceCode的第一个参数进行GetAsmPara,以xor为例:

代码参考:idapython/deTvm.py . tvmToAsm.xxx_handle()

上面我们已经获取了 jcc的类型,和它的两个跳转地址,虽然都是 V_RIP,

我们对这两个V_RIP往下找第一个 workingTrace,它所在的 tvmToAsm 就是对应的跳转地址,

我们可以给这个地址的的Asm打上跳转目的地标签,例如:

可以翻译为:

参考代码:idapython/deTvm.py . tvmToAsm.jcc_handle()

这部分略,比较简单,就是通过keystone库函数将Asm编译成十六进制机器码,然后再创建一个段,把内存写进去。详情参考:idapython/deTvm.py . tvmToAsmAll.WriteHex()main0函数。

值得一提的是,我发现了keystone的一个bug,你们可以试一下:

输出的结果是:

将其转换成 ASM,是

这明显是错误的,0x1400ef00a+0x7+0x4000d250 != 0x14000d250

就能输出正确的字节码。

所以我采用的方法是一句一句将Asm转换成HEX,如果遇到 mov reg,qword ptr[xxx],

就把格式改成 mov reg,qword ptr[rip + yyy],详情参考代码:

idapython/deTvm.py . Asm.AsmToHex()

main0是对全部ida识别的函数进行特征分析,如果符合tvm函数特征,就对它进行还原。

可以算是一键还原全部tvm函数了,有可能有些tvm函数不符合特征,你也可以手动添加还原函数。

例如:

你知道一个函数0x140001250它是被vm的,那么你这么写,脚本就会自动特征识别V_RIP。

如果你这个被vm的函数不符合我写的特征,但它确实是tvm的函数,那么可以这么写,自己设置V_RIP:

traceOut(0)输出的结果如下:( 基本没做处理)

如果想看 对标记working的traceCode进行变量溯源的结果,你可以这么写:

输出:

如果想进一步的进行变量传播优化还有 push、pop 优化,可以这么写:

输出:

如果想看还原成 ASM是什么样的,可以这样写:

输出:

如果想看 tvmToAsm和Asm对应起来的输出,可以这样写:

输出:

总所周知 ACE-BASE.sys 的DriverUnload函数是被vm了的,那么我们就用它来看看还原效果:

不错,很符合我对DriverUnload的想象。

左边 命名为 icxxx 的函数均为还原成功的函数。

还原脚本项目地址:xx_tvm

这个脚本只适用于这个版本的 tvm (ACE用的版本)。

新一点的tvm,虽然用的是同一套虚拟化指令集,但它会对整数进行加密,读取时进行简单的xor解密,并且新增了一些 虚拟指令。

而且 进入虚拟机的特征也有点不一样,不过对脚本进行简单的修改即可兼容。

ACE你快用新版的tvm,你现在用的版本是有bug的(JBE JNA的模拟是错的)。

 
 
 
 
import capstone
import keystone
import copy
import unicorn
import capstone
import keystone
import copy
import unicorn
1400d302c : not     r10                               ,R10 <-- ffffffffffffffff 
1400d302f : xchg    rax, r10                          ,RAX <-- ffffffffffffffff  ,R10 <-- 0 
1400d3031 : mov     [rbp+var_s8], r10                
1400d3035 : not     rax                               ,RAX <-- 0 
1400d3038 : xchg    rax, r10
1400d302c : not     r10                               ,R10 <-- ffffffffffffffff 
1400d302f : xchg    rax, r10                          ,RAX <-- ffffffffffffffff  ,R10 <-- 0 
1400d3031 : mov     [rbp+var_s8], r10                
1400d3035 : not     rax                               ,RAX <-- 0 
1400d3038 : xchg    rax, r10
1400d3031 : mov     [rbp+var_s8], rax
1400d3031 : mov     [rbp+var_s8], rax
 
1400d5b36 : xchg    rax, r11                          ,RAX <-- 14006024c  ,R11 <-- 0 
1400d5b38 : mov     rax, [rbp+98h]                   
1400d5b3f : not     rax                               ,RAX <-- fffffffebff9fdb3 
1400d9148 : xchg    rax, r11                          ,RAX <-- 0  ,R11 <-- fffffffebff9fdb3 
1400d914a : not     r11                               ,R11 <-- 14006024c
1400d5b36 : xchg    rax, r11                          ,RAX <-- 14006024c  ,R11 <-- 0 
1400d5b38 : mov     rax, [rbp+98h]                   
1400d5b3f : not     rax                               ,RAX <-- fffffffebff9fdb3 
1400d9148 : xchg    rax, r11                          ,RAX <-- 0  ,R11 <-- fffffffebff9fdb3 
1400d914a : not     r11                               ,R11 <-- 14006024c
1400d5b38 : mov     r11, [rbp+98h]
1400d5b38 : mov     r11, [rbp+98h]
 
1400d9156 : push    r10                               ,RSP <-- 1500 
1400d9158 : lea     r10, loc_1400E1D70+2              ,R10 <-- 1400e1d72 
1400d915f : lea     r10, [r10-0A812h]                 ,R10 <-- 1400d7560 
1400d9166 : jmp     r10                              
 
1400d7560 : pop     r10                               ,RSP <-- 1508  ,R10 <-- 0
1400d9156 : push    r10                               ,RSP <-- 1500 
1400d9158 : lea     r10, loc_1400E1D70+2              ,R10 <-- 1400e1d72 
1400d915f : lea     r10, [r10-0A812h]                 ,R10 <-- 1400d7560 
1400d9166 : jmp     r10                              
 
1400d7560 : pop     r10                               ,RSP <-- 1508  ,R10 <-- 0
1400d9156 : jmp     1400d7560
 
1400d7560 : nop
1400d9156 : jmp     1400d7560
 
1400d7560 : nop
 
1400d7240 : push    r10                               ,RSP <-- 1500 
1400d7242 : mov     r10, 14011A470h                   ,R10 <-- 14011a470 
1400d724c : pushfq                                    ,RSP <-- 14f8 
1400d724d : add     r10, 0FFFFFFFFFFFBF569h           ,R10 <-- 1400d99d9  ,RF <-- 3 
1400d7254 : popfq                                     ,RSP <-- 1500  ,RF <-- 12 
1400d7255 : jmp     r10                              
 
1400d99d9 : pop     r10                               ,RSP <-- 1508  ,R10 <-- 1638
1400d7240 : push    r10                               ,RSP <-- 1500 
1400d7242 : mov     r10, 14011A470h                   ,R10 <-- 14011a470 
1400d724c : pushfq                                    ,RSP <-- 14f8 
1400d724d : add     r10, 0FFFFFFFFFFFBF569h           ,R10 <-- 1400d99d9  ,RF <-- 3 
1400d7254 : popfq                                     ,RSP <-- 1500  ,RF <-- 12 
1400d7255 : jmp     r10                              
 
1400d99d9 : pop     r10                               ,RSP <-- 1508  ,R10 <-- 1638
1400d7240 : jmp 1400d99d9
 
1400d99d9 : nop
1400d7240 : jmp 1400d99d9
 
1400d99d9 : nop
 
 
 
 
 
 
 
 
 
 
140086efa : call    sub_1400085E8                     ,RSP <-- 17f8  //这个函数被vm
1400085e8 : jmp     sub_1400D2FF4                    
1400d2ff4 : lea     rsp, [rsp-248h]                   ,RSP <-- 15b0  //开辟虚拟机栈空间
1400d2ffc : mov     [rsp+10h], rbp                    //保存进入虚拟机时的寄存器状态
1400d3001 : mov     rbp, rsp                          ,RBP <-- 15b0 
1400d3004 : pushfq                                    ,RSP <-- 15a8 
1400d3005 : pop     [rbp+0h]                            ,RSP <-- 15b0 
1400d3008 : mov     [rbp+78h], r14               
1400d3012 : mov     [rbp+30h], rdx               
1400d3022 : mov     [rbp+50h], r9                
1400d3031 : mov     [rbp+8h], rax                
1400d303f : mov     [rbp+60h], r11               
1400d3043 : jmp     short loc_1400D3054              
1400d305a : mov     [rbp+18h], rbx                   
1400d305e : mov     [rbp+40h], rsp                   
1400d3062 : mov     [rbp+28h], rdi                   
1400d3066 : mov     [rbp+70h], r13                   
1400d306f : mov     [rbp+48h], r8                    
1400d3078 : mov     [rbp+80h], r15                   
1400d3085 : mov     [rbp+58h], r10                   
1400d308f : mov     [rbp+38h], rsi                   
1400d3093 : mov     [rbp+68h], r12                   
1400d3097 : jmp     loc_1400D3145                    
1400d314c : mov     [rbp+20h], rcx                   
1400d3156 : pushfq                                    ,RSP <-- 15a8 
1400d3157 : add     qword ptr [rbp+40h], 248h         #恢复成原来的栈顶
1400d315f : popfq                                     ,RSP <-- 15b0 
1400d3160 : lea     r11, [rbp+90h]                    ,R11 <-- 1640 
1400d3167 : push    qword ptr [rbp+8]                 ,RSP <-- 15a8 
1400d316a : pop     qword ptr [r11]                   ,RSP <-- 15b0 
1400d316d : push    qword ptr [rbp+18h]               ,RSP <-- 15a8 
1400d3170 : pop     qword ptr [r11+8]                 ,RSP <-- 15b0 
1400d3174 : push    qword ptr [rbp+20h]               ,RSP <-- 15a8 
1400d3177 : pop     qword ptr [r11+10h]               ,RSP <-- 15b0 
1400d317b : push    qword ptr [rbp+30h]               ,RSP <-- 15a8 
1400d317e : pop     qword ptr [r11+18h]               ,RSP <-- 15b0 
1400d3182 : push    qword ptr [rbp+40h]               ,RSP <-- 15a8 
1400d3185 : pop     qword ptr [r11+20h]               ,RSP <-- 15b0 
1400d3189 : push    qword ptr [rbp+10h]               ,RSP <-- 15a8 
1400d318c : jmp     loc_1400D30DC                    
1400d30dd : pop     qword ptr [r11+28h]               ,RSP <-- 15b0 
1400d30e1 : push    qword ptr [rbp+38h]               ,RSP <-- 15a8 
1400d30e4 : pop     qword ptr [r11+30h]               ,RSP <-- 15b0 
1400d30e8 : push    qword ptr [rbp+28h]               ,RSP <-- 15a8 
1400d30eb : pop     qword ptr [r11+38h]               ,RSP <-- 15b0 
1400d30ef : push    qword ptr [rbp+48h]               ,RSP <-- 15a8 
1400d30f2 : pop     qword ptr [r11+40h]               ,RSP <-- 15b0 
1400d30f6 : push    qword ptr [rbp+50h]               ,RSP <-- 15a8 
1400d30f9 : pop     qword ptr [r11+48h]               ,RSP <-- 15b0 
1400d30fd : push    qword ptr [rbp+58h]               ,RSP <-- 15a8 
1400d3100 : pop     qword ptr [r11+50h]               ,RSP <-- 15b0 
1400d3104 : push    qword ptr [rbp+60h]               ,RSP <-- 15a8 
1400d3107 : pop     qword ptr [r11+58h]               ,RSP <-- 15b0 
1400d310b : push    qword ptr [rbp+68h]               ,RSP <-- 15a8 
1400d310e : pop     qword ptr [r11+60h]               ,RSP <-- 15b0 
1400d3112 : push    qword ptr [rbp+70h]               ,RSP <-- 15a8 
1400d3115 : pop     qword ptr [r11+68h]               ,RSP <-- 15b0 
1400d3119 : push    qword ptr [rbp+78h]               ,RSP <-- 15a8 
1400d311c : pop     qword ptr [r11+70h]               ,RSP <-- 15b0 
1400d3120 : push    qword ptr [rbp+80h]               ,RSP <-- 15a8 
1400d3126 : pop     qword ptr [r11+78h]               ,RSP <-- 15b0 
1400d312a : push    qword ptr [rbp+0]                 ,RSP <-- 15a8 
1400d312d : jmp     loc_1400D30A8                    
1400d30aa : pop     qword ptr [r11+80h]               ,RSP <-- 15b0 
1400d30b1 : lea     r11, byte_14006024B+1             ,R11 <-- 14006024c 
1400d30b8 : lea     r10, [rbp+88h]                    ,R10 <-- 1638 
1400d30bf : lea     rsp, [rsp-8]                      ,RSP <-- 15a8 
1400d30c4 : mov     [rsp], r10                       
1400d30c8 : lea     rsp, [rsp-8]                      ,RSP <-- 15a0 
1400d30cd : mov     [rsp], r11                       
1400d30d1 : call    sub_1400D5B02                     ,RSP <-- 1598 
1400d5b02 : lea     rsp, [rsp-8]                      ,RSP <-- 1590 
1400d5b07 : mov     [rsp+8+var_8], rbx               
1400d5b0b : lea     rsp, [rsp-8]                      ,RSP <-- 1588 
1400d5b10 : mov     [rsp+10h+var_10], rsi            
1400d5b14 : lea     rsp, [rsp-8]                      ,RSP <-- 1580 
1400d5b19 : mov     [rsp+18h+var_18], rdi            
1400d5b1d : lea     rsp, [rsp-8]                      ,RSP <-- 1578 
1400d5b22 : mov     [rsp+20h+var_20], rbp            
1400d5b26 : lea     rsp, [rsp-8]                      ,RSP <-- 1570 
1400d5b2b : mov     [rsp+28h+var_28], r15            
1400d5b2f : sub     rsp, 68h                          ,RSP <-- 1508  ,RF <-- 12 
1400d5b33 : mov     rbp, rsp                          ,RBP <-- 1508 
1400d5b38 : mov     r11, [rbp+98h]                    ,R11 <-- V_RIP
1400d5b42 : jmp     loc_1400D9146                    
1400d914f : mov     r10, [rbp+0A0h]                   ,R10 <-- V_REG_p
1400d9156 : jmp     loc_1400D7560                    
1400d756a : call    loc_1400DA21F                     ,RSP <-- 1500 
1400da21f : lea     rsp, [rsp+8]                      ,RSP <-- 1508 
1400da224 : lea     r9, loc_1400E47B0                 ,R9 <-- 1400e47b0 
1400da22e : jmp     loc_1400D8689                    
1400d868e : mov     [rbp+0], r9                      
1400d8695 : jmp     loc_1400DB455                    
1400db45f : mov     [rbp+8], r11
140086efa : call    sub_1400085E8                     ,RSP <-- 17f8  //这个函数被vm
1400085e8 : jmp     sub_1400D2FF4                    
1400d2ff4 : lea     rsp, [rsp-248h]                   ,RSP <-- 15b0  //开辟虚拟机栈空间
1400d2ffc : mov     [rsp+10h], rbp                    //保存进入虚拟机时的寄存器状态
1400d3001 : mov     rbp, rsp                          ,RBP <-- 15b0 
1400d3004 : pushfq                                    ,RSP <-- 15a8 
1400d3005 : pop     [rbp+0h]                            ,RSP <-- 15b0 
1400d3008 : mov     [rbp+78h], r14               
1400d3012 : mov     [rbp+30h], rdx               
1400d3022 : mov     [rbp+50h], r9                
1400d3031 : mov     [rbp+8h], rax                
1400d303f : mov     [rbp+60h], r11               
1400d3043 : jmp     short loc_1400D3054              
1400d305a : mov     [rbp+18h], rbx                   
1400d305e : mov     [rbp+40h], rsp                   
1400d3062 : mov     [rbp+28h], rdi                   
1400d3066 : mov     [rbp+70h], r13                   
1400d306f : mov     [rbp+48h], r8                    
1400d3078 : mov     [rbp+80h], r15                   
1400d3085 : mov     [rbp+58h], r10                   
1400d308f : mov     [rbp+38h], rsi                   
1400d3093 : mov     [rbp+68h], r12                   
1400d3097 : jmp     loc_1400D3145                    
1400d314c : mov     [rbp+20h], rcx                   
1400d3156 : pushfq                                    ,RSP <-- 15a8 
1400d3157 : add     qword ptr [rbp+40h], 248h         #恢复成原来的栈顶
1400d315f : popfq                                     ,RSP <-- 15b0 
1400d3160 : lea     r11, [rbp+90h]                    ,R11 <-- 1640 
1400d3167 : push    qword ptr [rbp+8]                 ,RSP <-- 15a8 
1400d316a : pop     qword ptr [r11]                   ,RSP <-- 15b0 
1400d316d : push    qword ptr [rbp+18h]               ,RSP <-- 15a8 
1400d3170 : pop     qword ptr [r11+8]                 ,RSP <-- 15b0 
1400d3174 : push    qword ptr [rbp+20h]               ,RSP <-- 15a8 
1400d3177 : pop     qword ptr [r11+10h]               ,RSP <-- 15b0 
1400d317b : push    qword ptr [rbp+30h]               ,RSP <-- 15a8 
1400d317e : pop     qword ptr [r11+18h]               ,RSP <-- 15b0 
1400d3182 : push    qword ptr [rbp+40h]               ,RSP <-- 15a8 
1400d3185 : pop     qword ptr [r11+20h]               ,RSP <-- 15b0 
1400d3189 : push    qword ptr [rbp+10h]               ,RSP <-- 15a8 
1400d318c : jmp     loc_1400D30DC                    
1400d30dd : pop     qword ptr [r11+28h]               ,RSP <-- 15b0 
1400d30e1 : push    qword ptr [rbp+38h]               ,RSP <-- 15a8 
1400d30e4 : pop     qword ptr [r11+30h]               ,RSP <-- 15b0 
1400d30e8 : push    qword ptr [rbp+28h]               ,RSP <-- 15a8 
1400d30eb : pop     qword ptr [r11+38h]               ,RSP <-- 15b0 
1400d30ef : push    qword ptr [rbp+48h]               ,RSP <-- 15a8 
1400d30f2 : pop     qword ptr [r11+40h]               ,RSP <-- 15b0 
1400d30f6 : push    qword ptr [rbp+50h]               ,RSP <-- 15a8 
1400d30f9 : pop     qword ptr [r11+48h]               ,RSP <-- 15b0 
1400d30fd : push    qword ptr [rbp+58h]               ,RSP <-- 15a8 
1400d3100 : pop     qword ptr [r11+50h]               ,RSP <-- 15b0 
1400d3104 : push    qword ptr [rbp+60h]               ,RSP <-- 15a8 
1400d3107 : pop     qword ptr [r11+58h]               ,RSP <-- 15b0 
1400d310b : push    qword ptr [rbp+68h]               ,RSP <-- 15a8 
1400d310e : pop     qword ptr [r11+60h]               ,RSP <-- 15b0 
1400d3112 : push    qword ptr [rbp+70h]               ,RSP <-- 15a8 
1400d3115 : pop     qword ptr [r11+68h]               ,RSP <-- 15b0 
1400d3119 : push    qword ptr [rbp+78h]               ,RSP <-- 15a8 
1400d311c : pop     qword ptr [r11+70h]               ,RSP <-- 15b0 
1400d3120 : push    qword ptr [rbp+80h]               ,RSP <-- 15a8 
1400d3126 : pop     qword ptr [r11+78h]               ,RSP <-- 15b0 
1400d312a : push    qword ptr [rbp+0]                 ,RSP <-- 15a8 
1400d312d : jmp     loc_1400D30A8                    
1400d30aa : pop     qword ptr [r11+80h]               ,RSP <-- 15b0 
1400d30b1 : lea     r11, byte_14006024B+1             ,R11 <-- 14006024c 
1400d30b8 : lea     r10, [rbp+88h]                    ,R10 <-- 1638 
1400d30bf : lea     rsp, [rsp-8]                      ,RSP <-- 15a8 
1400d30c4 : mov     [rsp], r10                       
1400d30c8 : lea     rsp, [rsp-8]                      ,RSP <-- 15a0 
1400d30cd : mov     [rsp], r11                       
1400d30d1 : call    sub_1400D5B02                     ,RSP <-- 1598 
1400d5b02 : lea     rsp, [rsp-8]                      ,RSP <-- 1590 
1400d5b07 : mov     [rsp+8+var_8], rbx               
1400d5b0b : lea     rsp, [rsp-8]                      ,RSP <-- 1588 
1400d5b10 : mov     [rsp+10h+var_10], rsi            
1400d5b14 : lea     rsp, [rsp-8]                      ,RSP <-- 1580 
1400d5b19 : mov     [rsp+18h+var_18], rdi            
1400d5b1d : lea     rsp, [rsp-8]                      ,RSP <-- 1578 
1400d5b22 : mov     [rsp+20h+var_20], rbp            
1400d5b26 : lea     rsp, [rsp-8]                      ,RSP <-- 1570 
1400d5b2b : mov     [rsp+28h+var_28], r15            
1400d5b2f : sub     rsp, 68h                          ,RSP <-- 1508  ,RF <-- 12 
1400d5b33 : mov     rbp, rsp                          ,RBP <-- 1508 
1400d5b38 : mov     r11, [rbp+98h]                    ,R11 <-- V_RIP
1400d5b42 : jmp     loc_1400D9146                    
1400d914f : mov     r10, [rbp+0A0h]                   ,R10 <-- V_REG_p
1400d9156 : jmp     loc_1400D7560                    
1400d756a : call    loc_1400DA21F                     ,RSP <-- 1500 
1400da21f : lea     rsp, [rsp+8]                      ,RSP <-- 1508 
1400da224 : lea     r9, loc_1400E47B0                 ,R9 <-- 1400e47b0 
1400da22e : jmp     loc_1400D8689                    
1400d868e : mov     [rbp+0], r9                      
1400d8695 : jmp     loc_1400DB455                    
1400db45f : mov     [rbp+8], r11
rsp = rbp = 15b0
[15b0](rbp+0)    rflag                           
[15b8](rbp+8)    rax
[15c0](rbp+10)    rbp        (原来的栈底)
[15c8](rbp+18)    rbx
[15d0](rbp+20)    rcx
[15d8](rbp+28)    rdi
[15e0](rbp+30)    rdx
[15e8](rbp+38)    rsi
[15f0](rbp+40)    rsp     (原来的栈顶)
[15f8](rbp+48)    r8
[1600](rbp+50)    r9
[1608](rbp+58)    r10
[1610](rbp+60)    r11
[1618](rbp+68)    r12
[1620](rbp+70)    r13
[1628](rbp+78)    r14
[1630](rbp+80)    r15
rsp = rbp = 15b0
[15b0](rbp+0)    rflag                           
[15b8](rbp+8)    rax
[15c0](rbp+10)    rbp        (原来的栈底)
[15c8](rbp+18)    rbx
[15d0](rbp+20)    rcx
[15d8](rbp+28)    rdi
[15e0](rbp+30)    rdx
[15e8](rbp+38)    rsi
[15f0](rbp+40)    rsp     (原来的栈顶)
[15f8](rbp+48)    r8
[1600](rbp+50)    r9
[1608](rbp+58)    r10
[1610](rbp+60)    r11
[1618](rbp+68)    r12
[1620](rbp+70)    r13
[1628](rbp+78)    r14
[1630](rbp+80)    r15
1400d3160 : lea     r11, [rbp+90h]                    ,R11 <-- 1640  #接着往栈上保存原始寄存器状态
1400d3160 : lea     r11, [rbp+90h]                    ,R11 <-- 1640  #接着往栈上保存原始寄存器状态
[1640](r11+0)    rax
[1648](r11+8)    rbx
[1650](r11+10)    rcx
[1658](r11+18)    rdx
[1660](r11+20)    rsp
[1668](r11+28)    rbp
[1670](r11+30)    rsi
[1678](r11+38)    rdi
[1680](r11+40)    r8
[1688](r11+48)    r9
[1690](r11+50)    r10
[1698](r11+58)    r11
[16a0](r11+60)    r12
[16a8](r11+68)    r13
[16b0](r11+70)    r14
[16b8](r11+78)    r15
[16c0](r11+80)    rflag
[1640](r11+0)    rax
[1648](r11+8)    rbx
[1650](r11+10)    rcx
[1658](r11+18)    rdx
[1660](r11+20)    rsp
[1668](r11+28)    rbp
[1670](r11+30)    rsi
[1678](r11+38)    rdi
[1680](r11+40)    r8
[1688](r11+48)    r9
[1690](r11+50)    r10
[1698](r11+58)    r11
[16a0](r11+60)    r12
[16a8](r11+68)    r13
[16b0](r11+70)    r14
[16b8](r11+78)    r15
[16c0](r11+80)    rflag
1400d30b1 : lea     r11, byte_14006024B+1             ,R11 <-- 14006024c  //这个是V_RIP (即虚拟指令起始点)
1400d30b8 : lea     r10, [rbp+88h]                    ,R10 <-- 1638        //这个是 V_REG_P
1400d30bf : lea     rsp, [rsp-8]                      ,RSP <-- 15a8 
1400d30c4 : mov     [rsp], r10                       
1400d30c8 : lea     rsp, [rsp-8]                      ,RSP <-- 15a0 
1400d30cd : mov     [rsp], r11
1400d30b1 : lea     r11, byte_14006024B+1             ,R11 <-- 14006024c  //这个是V_RIP (即虚拟指令起始点)
1400d30b8 : lea     r10, [rbp+88h]                    ,R10 <-- 1638        //这个是 V_REG_P
1400d30bf : lea     rsp, [rsp-8]                      ,RSP <-- 15a8 
1400d30c4 : mov     [rsp], r10                       
1400d30c8 : lea     rsp, [rsp-8]                      ,RSP <-- 15a0 
1400d30cd : mov     [rsp], r11
[15a0]    V_RIP                            虚拟指令起始点
[15a8]    V_REG_P                            1638(虚拟机寄存器)
[15a0]    V_RIP                            虚拟指令起始点
[15a8]    V_REG_P                            1638(虚拟机寄存器)
 
 
1400d30d1 : call    sub_1400D5B02                     ,RSP <-- 1598
1400d30d1 : call    sub_1400D5B02                     ,RSP <-- 1598
[1598] = return add(call    sub_1400D5B02 下一行的地址 是int3)
[1598] = return add(call    sub_1400D5B02 下一行的地址 是int3)
1400d5b02 : lea     rsp, [rsp-8]                      ,RSP <-- 1590 
1400d5b07 : mov     [rsp+8+var_8], rbx               
1400d5b0b : lea     rsp, [rsp-8]                      ,RSP <-- 1588 
1400d5b10 : mov     [rsp+10h+var_10], rsi            
1400d5b14 : lea     rsp, [rsp-8]                      ,RSP <-- 1580 
1400d5b19 : mov     [rsp+18h+var_18], rdi            
1400d5b1d : lea     rsp, [rsp-8]                      ,RSP <-- 1578 
1400d5b22 : mov     [rsp+20h+var_20], rbp            
1400d5b26 : lea     rsp, [rsp-8]                      ,RSP <-- 1570 
1400d5b2b : mov     [rsp+28h+var_28], r15
1400d5b02 : lea     rsp, [rsp-8]                      ,RSP <-- 1590 
1400d5b07 : mov     [rsp+8+var_8], rbx               
1400d5b0b : lea     rsp, [rsp-8]                      ,RSP <-- 1588 
1400d5b10 : mov     [rsp+10h+var_10], rsi            
1400d5b14 : lea     rsp, [rsp-8]                      ,RSP <-- 1580 
1400d5b19 : mov     [rsp+18h+var_18], rdi            
1400d5b1d : lea     rsp, [rsp-8]                      ,RSP <-- 1578 
1400d5b22 : mov     [rsp+20h+var_20], rbp            
1400d5b26 : lea     rsp, [rsp-8]                      ,RSP <-- 1570 
1400d5b2b : mov     [rsp+28h+var_28], r15
[1570]  r15                                rbp = 15b0
[1578]  rbp
[1580]  rdi
[1588]  rsi
[1590]  rbx
[1570]  r15                                rbp = 15b0
[1578]  rbp
[1580]  rdi
[1588]  rsi
[1590]  rbx
1400d5b2f : sub     rsp, 68h                          ,RSP <-- 1508  ,RF <-- 12 
1400d5b33 : mov     rbp, rsp                          ,RBP <-- 1508 
1400d5b38 : mov     r11, [rbp+98h]                    ,R11 <-- V_RIP
1400d5b42 : jmp     loc_1400D9146                    
1400d914f : mov     r10, [rbp+0A0h]                   ,R10 <-- V_REG_p
1400d9156 : jmp     loc_1400D7560                    
1400d756a : call    loc_1400DA21F                     ,RSP <-- 1500 
1400da21f : lea     rsp, [rsp+8]                      ,RSP <-- 1508  //进call又rsp+8,假装是jmp
1400da224 : lea     r9, loc_1400E47B0                 ,R9 <-- 1400e47b0  //这是int3 指令的地址
1400da22e : jmp     loc_1400D8689                    
1400d868e : mov     [rbp+0], r9                      
1400d8695 : jmp     loc_1400DB455                    
1400db45f : mov     [rbp+8], r11                      V_RIP 放到 [1510]
1400d5b2f : sub     rsp, 68h                          ,RSP <-- 1508  ,RF <-- 12 
1400d5b33 : mov     rbp, rsp                          ,RBP <-- 1508 
1400d5b38 : mov     r11, [rbp+98h]                    ,R11 <-- V_RIP
1400d5b42 : jmp     loc_1400D9146                    
1400d914f : mov     r10, [rbp+0A0h]                   ,R10 <-- V_REG_p
1400d9156 : jmp     loc_1400D7560                    
1400d756a : call    loc_1400DA21F                     ,RSP <-- 1500 
1400da21f : lea     rsp, [rsp+8]                      ,RSP <-- 1508  //进call又rsp+8,假装是jmp
1400da224 : lea     r9, loc_1400E47B0                 ,R9 <-- 1400e47b0  //这是int3 指令的地址
1400da22e : jmp     loc_1400D8689                    
1400d868e : mov     [rbp+0], r9                      
1400d8695 : jmp     loc_1400DB455                    
1400db45f : mov     [rbp+8], r11                      V_RIP 放到 [1510]
虚拟机内RBP = RSP = 1508 ,R10 = V_REG_P
[1508] int3指令指针
[1510] V_RIP                                    //当前执行到的位置
.....
 
[1570]  r15                                rbp = 15b0
[1578]  rbp
[1580]  rdi
[1588]  rsi
[1590]  rbx
[1598] = return add(sub_1400D5B02 下一行的地址 是int3)
 
[15a0]    V_RIP                                    //虚拟指令起始点,这是不会变的
[15a8]    V_REG_P                                    //1638(虚拟机寄存器),这是不会变的
 
[15b0](rbp+0)    rflag                            //这里以下是进入虚拟机前的寄存器状态
[15b8](rbp+8)    rax
[15c0](rbp+10)    rbp        (原来的栈底)
[15c8](rbp+18)    rbx
[15d0](rbp+20)    rcx
[15d8](rbp+28)    rdi
[15e0](rbp+30)    rdx
[15e8](rbp+38)    rsi
[15f0](rbp+40)    rsp     (原来的栈顶)
[15f8](rbp+48)    r8
[1600](rbp+50)    r9
[1608](rbp+58)    r10
[1610](rbp+60)    r11
[1618](rbp+68)    r12
[1620](rbp+70)    r13
[1628](rbp+78)    r14
[1630](rbp+80)    r15
 
[1638]    UnKnow                V_REG_P = r10 = 1638 //虚拟机的虚拟寄存器从 1638 开始往下都是
[1640](r11+0)    rax                                //这里以下是进入虚拟机前的寄存器状态
[1648](r11+8)    rbx
[1650](r11+10)    rcx
[1658](r11+18)    rdx
[1660](r11+20)    rsp
[1668](r11+28)    rbp
[1670](r11+30)    rsi
[1678](r11+38)    rdi
[1680](r11+40)    r8
[1688](r11+48)    r9
[1690](r11+50)    r10
[1698](r11+58)    r11
[16a0](r11+60)    r12
[16a8](r11+68)    r13
[16b0](r11+70)    r14
[16b8](r11+78)    r15
[16c0](r11+80)    rflag
虚拟机内RBP = RSP = 1508 ,R10 = V_REG_P
[1508] int3指令指针
[1510] V_RIP                                    //当前执行到的位置
.....
 
[1570]  r15                                rbp = 15b0
[1578]  rbp
[1580]  rdi
[1588]  rsi
[1590]  rbx
[1598] = return add(sub_1400D5B02 下一行的地址 是int3)
 
[15a0]    V_RIP                                    //虚拟指令起始点,这是不会变的
[15a8]    V_REG_P                                    //1638(虚拟机寄存器),这是不会变的
 
[15b0](rbp+0)    rflag                            //这里以下是进入虚拟机前的寄存器状态
[15b8](rbp+8)    rax
[15c0](rbp+10)    rbp        (原来的栈底)
[15c8](rbp+18)    rbx
[15d0](rbp+20)    rcx
[15d8](rbp+28)    rdi
[15e0](rbp+30)    rdx
[15e8](rbp+38)    rsi
[15f0](rbp+40)    rsp     (原来的栈顶)
[15f8](rbp+48)    r8
[1600](rbp+50)    r9
[1608](rbp+58)    r10
[1610](rbp+60)    r11
[1618](rbp+68)    r12
[1620](rbp+70)    r13
[1628](rbp+78)    r14
[1630](rbp+80)    r15
 
[1638]    UnKnow                V_REG_P = r10 = 1638 //虚拟机的虚拟寄存器从 1638 开始往下都是
[1640](r11+0)    rax                                //这里以下是进入虚拟机前的寄存器状态
[1648](r11+8)    rbx
[1650](r11+10)    rcx
[1658](r11+18)    rdx
[1660](r11+20)    rsp
[1668](r11+28)    rbp
[1670](r11+30)    rsi
[1678](r11+38)    rdi
[1680](r11+40)    r8
[1688](r11+48)    r9
[1690](r11+50)    r10
[1698](r11+58)    r11
[16a0](r11+60)    r12
[16a8](r11+68)    r13
[16b0](r11+70)    r14
[16b8](r11+78)    r15
[16c0](r11+80)    rflag
1400d7234 : mov     r9, [rbp+8]                       ,R9 <-- 14006024c 
1400d7240 : jmp     loc_1400D99D9                    
1400d99db : mov     r8b, [r9]                         ,R8 <-- e8 
1400d99de : xor     r8b, 5Dh                          ,R8 <-- b5  ,RF <-- 82 
1400d99e2 : mov     rdx, 25E9ECA9BDE22AEAh            ,RDX <-- 25e9eca9bde22aea 
1400d99ec : not     rdx                               ,RDX <-- da161356421dd515 
1400d99ef : lea     rdx, [r9+rdx]                     ,RDX <-- da1613578223d761 
1400d99f3 : jmp     loc_1400D86A6                    
1400d86a8 : mov     r9, 0DA161356421DD513h            ,R9 <-- da161356421dd513 
1400d86b2 : not     r9                                ,R9 <-- 25e9eca9bde22aec 
1400d86b5 : lea     r9, [rdx+r9]                      ,R9 <-- 14006024d 
1400d86bf : mov     [rbp+8], r9                      
1400d86c9 : movzx   r8, r8b                          
1400d86cd : sub     r8, 1                             ,R8 <-- b4  ,RF <-- 6 
1400d86d1 : jmp     loc_1400D7E10                    
1400d7e11 : cmp     r8, 0C8h                          ,RF <-- 93 
1400d7e18 : jnb     loc_1400D9954                    
1400d7e1e : lea     r9, word_1400DB5AA                ,R9 <-- 1400db5aa 
1400d7e25 : mov     r8, [r9+r8*8]                     ,R8 <-- d60f2 
1400d7e29 : lea     r9, cs:140000000h                 ,R9 <-- 140000000 
1400d7e30 : jmp     loc_1400D6558                    
1400d6559 : add     r8, r9                            ,R8 <-- 1400d60f2  ,RF <-- 2 
1400d655c : jmp     r8                                //进入handle
1400d7234 : mov     r9, [rbp+8]                       ,R9 <-- 14006024c 
1400d7240 : jmp     loc_1400D99D9                    
1400d99db : mov     r8b, [r9]                         ,R8 <-- e8 
1400d99de : xor     r8b, 5Dh                          ,R8 <-- b5  ,RF <-- 82 
1400d99e2 : mov     rdx, 25E9ECA9BDE22AEAh            ,RDX <-- 25e9eca9bde22aea 
1400d99ec : not     rdx                               ,RDX <-- da161356421dd515 
1400d99ef : lea     rdx, [r9+rdx]                     ,RDX <-- da1613578223d761 
1400d99f3 : jmp     loc_1400D86A6                    
1400d86a8 : mov     r9, 0DA161356421DD513h            ,R9 <-- da161356421dd513 
1400d86b2 : not     r9                                ,R9 <-- 25e9eca9bde22aec 
1400d86b5 : lea     r9, [rdx+r9]                      ,R9 <-- 14006024d 
1400d86bf : mov     [rbp+8], r9                      
1400d86c9 : movzx   r8, r8b                          
1400d86cd : sub     r8, 1                             ,R8 <-- b4  ,RF <-- 6 
1400d86d1 : jmp     loc_1400D7E10                    
1400d7e11 : cmp     r8, 0C8h                          ,RF <-- 93 
1400d7e18 : jnb     loc_1400D9954                    
1400d7e1e : lea     r9, word_1400DB5AA                ,R9 <-- 1400db5aa 
1400d7e25 : mov     r8, [r9+r8*8]                     ,R8 <-- d60f2 
1400d7e29 : lea     r9, cs:140000000h                 ,R9 <-- 140000000 
1400d7e30 : jmp     loc_1400D6558                    
1400d6559 : add     r8, r9                            ,R8 <-- 1400d60f2  ,RF <-- 2 
1400d655c : jmp     r8                                //进入handle
 
 
 
handleTableBase = 0x1400db5aa
Dllbase = 0x140000000
handle = Dllbase + qword[(tvmopcode^0x5d - 1)*8 + handleTableBase]
handleTableBase = 0x1400db5aa
Dllbase = 0x140000000
handle = Dllbase + qword[(tvmopcode^0x5d - 1)*8 + handleTableBase]
 
handleTable的第 0x00 项: tvmopcode = (0x00 + 1) ^ 0x5d = 0x5c
......
handleTable的第 0x3c 项: tvmopcode = (0x3c + 1) ^ 0x5d = 0x60
......
handleTable的第 0xc7 项: tvmopcode = (0xc7 + 1) ^ 0x5d = 0x95
handleTable的第 0x00 项: tvmopcode = (0x00 + 1) ^ 0x5d = 0x5c
......
handleTable的第 0x3c 项: tvmopcode = (0x3c + 1) ^ 0x5d = 0x60
......
handleTable的第 0xc7 项: tvmopcode = (0xc7 + 1) ^ 0x5d = 0x95
 
 
 
1400d9954 : 9a  9b  98  99  9c  9d  e2  e3  e0  e1  e6  e7  e4  eb  ec  ed  f2  f3  f0  f1  f6  f7  f5  fa  fb  f9  fe  ff  c2  c0  c1  c6  c7  c4  c5  c8  ce  cf  cc  cd  db  d8  de  df  dc  dd  23  26  27  24  2a  28  2e  2c  2d  32  33  30  31  36  37  34  35  3a  3b  38  39  3e  3f  3d  02  03  00  07  04  05  0a  0b  08  0e  0f  0d  12  13  10  17  14  15  1a  1b  18  1e  1f  1c  63  61  66  67  64  6b  69  6f  6c  71  76  77  74  7b  79  7e  7f  7c  53  50  55  5b  58  59  5e  5f  5c
1400d8eb1 : 5a
1400d5b5a : 54
1400d5cd8 : 57
1400db3d3 : 56
1400d761b : 51
1400da3e5 : 52
1400dabb0 : 4d
1400d8196 : 4c
1400d6c8c : 4f
1400d82fa : 4e
1400d6e7d : 49
1400d7172 : 48
1400d9374 : 4b
1400daa8e : 4a
1400db0f9 : 45
1400dae51 : 44
1400d8be2 : 47
1400d946b : 46
1400d995a : 41
1400daf90 : 40
1400d7a8a : 43
1400d5e10 : 42
1400d7258 : 7d
1400daecb : 78
1400d5d02 : 7a
1400d974c : 75
1400d7f26 : 70
1400d8e1b : 73
1400d8dbf : 72
1400d8362 : 6d
1400d6fc9 : 6e
1400d7c1f : 68
1400d63cd : 6a
1400d9abb : 65
1400d8431 : 60
1400d7797 : 62
1400da161 : 1d
1400d7313 : 19
1400d92b0 : 16
1400d9c5c : 11
1400dab1e : 0c
1400d86e2 : 09
1400d7352 : 06
1400dad5e : 01
1400d9524 : 3c
1400dad2c : 2f
1400d8b8d : 29
1400d7d39 : 2b
1400d8f7b : 25
1400d696f : 21
1400d71f5 : 20
1400d71b3 : 22
1400d770e : d9
1400da48c : da
1400d74d2 : d5
1400d70ee : d4
1400d95ad : d7
1400d6f6c : d6
1400d84d0 : d1
1400da357 : d0
1400d78f9 : d3
1400d7998 : d2
1400d8561 : c9
1400d624c : cb
1400d9169 : ca
1400d64ac : c3
1400d5c7b : fd
1400d9dd5 : fc
1400d6913 : f8
1400dafcf : f4
1400d7bc7 : ef
1400d7fc4 : ee
1400d9446 : e9
1400d60f2 : e8
1400d69e8 : ea
1400d9584 : e5
1400da10c : 9f
1400d8e89 : 9e
1400d8cdd : 95
1400d9954 : 9a  9b  98  99  9c  9d  e2  e3  e0  e1  e6  e7  e4  eb  ec  ed  f2  f3  f0  f1  f6  f7  f5  fa  fb  f9  fe  ff  c2  c0  c1  c6  c7  c4  c5  c8  ce  cf  cc  cd  db  d8  de  df  dc  dd  23  26  27  24  2a  28  2e  2c  2d  32  33  30  31  36  37  34  35  3a  3b  38  39  3e  3f  3d  02  03  00  07  04  05  0a  0b  08  0e  0f  0d  12  13  10  17  14  15  1a  1b  18  1e  1f  1c  63  61  66  67  64  6b  69  6f  6c  71  76  77  74  7b  79  7e  7f  7c  53  50  55  5b  58  59  5e  5f  5c
1400d8eb1 : 5a
1400d5b5a : 54
1400d5cd8 : 57
1400db3d3 : 56
1400d761b : 51
1400da3e5 : 52
1400dabb0 : 4d
1400d8196 : 4c
1400d6c8c : 4f
1400d82fa : 4e
1400d6e7d : 49
1400d7172 : 48
1400d9374 : 4b
1400daa8e : 4a
1400db0f9 : 45
1400dae51 : 44
1400d8be2 : 47
1400d946b : 46
1400d995a : 41
1400daf90 : 40
1400d7a8a : 43
1400d5e10 : 42
1400d7258 : 7d
1400daecb : 78
1400d5d02 : 7a
1400d974c : 75
1400d7f26 : 70
1400d8e1b : 73
1400d8dbf : 72
1400d8362 : 6d
1400d6fc9 : 6e
1400d7c1f : 68
1400d63cd : 6a
1400d9abb : 65
1400d8431 : 60
1400d7797 : 62
1400da161 : 1d
1400d7313 : 19
1400d92b0 : 16
1400d9c5c : 11
1400dab1e : 0c
1400d86e2 : 09
1400d7352 : 06
1400dad5e : 01
1400d9524 : 3c
1400dad2c : 2f
1400d8b8d : 29
1400d7d39 : 2b
1400d8f7b : 25
1400d696f : 21
1400d71f5 : 20
1400d71b3 : 22
1400d770e : d9
1400da48c : da
1400d74d2 : d5
1400d70ee : d4
1400d95ad : d7
1400d6f6c : d6
1400d84d0 : d1
1400da357 : d0
1400d78f9 : d3
1400d7998 : d2
1400d8561 : c9
1400d624c : cb
1400d9169 : ca
1400d64ac : c3
1400d5c7b : fd
1400d9dd5 : fc
1400d6913 : f8
1400dafcf : f4
1400d7bc7 : ef
1400d7fc4 : ee
1400d9446 : e9
1400d60f2 : e8
1400d69e8 : ea
1400d9584 : e5
1400da10c : 9f
1400d8e89 : 9e
1400d8cdd : 95
 
 
 
 
 
0xe8 p_a b_ULONG64
 
0x3F26
 
*(PULONG64)p_a = b_ULONG64;
 
v_mov_iregll_ll
----------------------------------------//虚线以上是分析出来的
 
0x1400d60f5 : mov     r9, [rbp+8]                    
0x1400d6102 : mov     r8w, [r9]                       这里取2字节 (取虚拟寄存器都是取2字节)
0x1400d6106 : xor     r8w, 3F26h                      异或 3F26(不同的handl异或的值不同) 得到 a,
0x1400d610c : mov     rdx, 0F84A86395161A270h         所以就是取虚拟机寄存器  V_REG_P + a
0x1400d6116 : not     rdx                            
0x1400d6119 : jmp     loc_1400D9077                  
0x1400d9078 : lea     rdx, [r10+rdx]                 
0x1400d907c : movzx   r8, r8w                        
0x1400d9080 : mov     rcx, 7B579C6AE9E5D8Eh          
0x1400d908a : not     rcx                            
0x1400d908d : add     r8, rcx                        
0x1400d9090 : lea     r8, [rdx+r8]                    p_a = r8 = V_REG_P + a
0x1400d9094 : lea     r9, [r9+2]                      V_RIP+=2
0x1400d909b : mov     rdx, [r9]                       b_ULONG64  从tvm指令表中取8字节
0x1400d909e : jmp     loc_1400DA2DD                  
0x1400da2ed : mov     [r8], rdx                       放入 [r8],即放入 p_a
0x1400da2f0 : jmp     loc_1400DA9AC                  
0x1400da9b4 : lea     r9, [r9+8]                      V_RIP+=8
0x1400da9be : mov     [rbp+8], r9                     V_RIP放回[rbp+8]
0x1400da9c8 : jmp     loc_1400DAC79                  
0x1400dac7c : mov     r9, [rbp+8]                     这里以下属于下一个handle分发,不用看
0x1400dac89 : mov     r8b, [r9]                      
0x1400dac8c : xor     r8b, 5Dh                       
0x1400dac90 : mov     rdx, 0D3676A56DAFF3C65h        
0x1400dac9a : jmp     loc_1400D7763                  
0x1400d7764 : not     rdx                            
0x1400d7767 : lea     rdx, [r9+rdx]                  
0x1400d776b : mov     r9, 2C9895A92500C398h          
0x1400d7775 : not     r9                             
0x1400d7778 : lea     r9, [rdx+r9]                   
0x1400d777f : jmp     loc_1400D5B91                  
0x1400d5b95 : mov     [rbp+8], r9                    
0x1400d5b9e : movzx   r8, r8b                        
0x1400d5ba2 : sub     r8, 1; switch 200 cases        
0x1400d5ba6 : jmp     loc_1400D98A8                  
0x1400d98aa : cmp     r8, 0C8h                       
0x1400d98b1 : jnb     def_1400D655C;
0xe8 p_a b_ULONG64
 
0x3F26
 
*(PULONG64)p_a = b_ULONG64;
 
v_mov_iregll_ll
----------------------------------------//虚线以上是分析出来的
 
0x1400d60f5 : mov     r9, [rbp+8]                    
0x1400d6102 : mov     r8w, [r9]                       这里取2字节 (取虚拟寄存器都是取2字节)
0x1400d6106 : xor     r8w, 3F26h                      异或 3F26(不同的handl异或的值不同) 得到 a,
0x1400d610c : mov     rdx, 0F84A86395161A270h         所以就是取虚拟机寄存器  V_REG_P + a
0x1400d6116 : not     rdx                            
0x1400d6119 : jmp     loc_1400D9077                  
0x1400d9078 : lea     rdx, [r10+rdx]                 
0x1400d907c : movzx   r8, r8w                        
0x1400d9080 : mov     rcx, 7B579C6AE9E5D8Eh          
0x1400d908a : not     rcx                            
0x1400d908d : add     r8, rcx                        
0x1400d9090 : lea     r8, [rdx+r8]                    p_a = r8 = V_REG_P + a
0x1400d9094 : lea     r9, [r9+2]                      V_RIP+=2
0x1400d909b : mov     rdx, [r9]                       b_ULONG64  从tvm指令表中取8字节
0x1400d909e : jmp     loc_1400DA2DD                  
0x1400da2ed : mov     [r8], rdx                       放入 [r8],即放入 p_a
0x1400da2f0 : jmp     loc_1400DA9AC                  
0x1400da9b4 : lea     r9, [r9+8]                      V_RIP+=8

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2023-5-30 15:15 被icey_编辑 ,原因:
收藏
免费 37
支持
分享
打赏 + 5.00雪花
打赏次数 1 雪花 + 5.00
 
赞赏  orz1ruo   +5.00 2023/06/02 原创内容~
最新回复 (50)
雪    币: 3297
活跃值: (5395)
能力值: ( LV6,RANK:92 )
在线值:
发帖
回帖
粉丝
2
@南山区法院
2023-5-26 01:50
3
雪    币: 14
活跃值: (454)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
@南山必胜客
2023-5-26 02:23
1
雪    币: 1282
活跃值: (4555)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
前排支持!!!!!!
2023-5-26 02:27
1
雪    币: 45
活跃值: (2480)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
坏了 出个题比赛 被偷家了
2023-5-26 05:18
2
雪    币: 996
活跃值: (1443)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
这是哪位大将报上名来
2023-5-26 07:52
1
雪    币: 548
活跃值: (60)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
2023-5-26 08:39
1
雪    币: 6533
活跃值: (4331)
能力值: ( LV10,RANK:163 )
在线值:
发帖
回帖
粉丝
8
牛逼,牛逼
2023-5-26 08:53
1
雪    币: 3059
活跃值: (30876)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
tql
2023-5-26 09:10
2
雪    币: 1641
活跃值: (3601)
能力值: (RANK:15 )
在线值:
发帖
回帖
粉丝
10
坏了 出个题比赛 被偷家了
2023-5-26 09:21
1
雪    币: 4061
活跃值: (3452)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
牛逼
2023-5-26 09:24
1
雪    币: 1671
活跃值: (215832)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
12
tql
2023-5-26 09:30
1
雪    币: 10960
活跃值: (2920)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
13
无法学习,只能膜拜
2023-5-26 09:41
1
雪    币: 3163
活跃值: (3137)
能力值: ( LV7,RANK:111 )
在线值:
发帖
回帖
粉丝
14
很黄,很暴力,做保护的都怕楼主这种
2023-5-26 10:14
1
雪    币: 1392
活跃值: (5172)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
15
律师函警告
2023-5-26 10:43
2
雪    币: 458
活跃值: (1882)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
ORZ啊啊啊啊啊
2023-5-26 12:03
1
雪    币: 3565
活跃值: (3950)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
厉害了,只能膜拜。
2023-5-26 12:42
1
雪    币: 8447
活跃值: (5041)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
18
强的要死
2023-5-26 13:02
1
雪    币: 2155
活跃值: (2587)
能力值: ( LV12,RANK:667 )
在线值:
发帖
回帖
粉丝
19
本来只想出个题,结果被偷家(
2023-5-26 13:48
1
雪    币: 948
活跃值: (1924)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
20
tql
2023-5-26 13:50
1
雪    币: 2335
活跃值: (1319)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
21
一出手就非同凡响
2023-5-26 14:20
1
雪    币: 4734
活跃值: (4281)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
实际上vmp目前也已经扛不住了
2023-5-26 14:26
1
雪    币: 183
活跃值: (2427)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
23
坏了 出个题比赛 被偷家了
2023-5-26 14:54
1
雪    币: 698
活跃值: (4564)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
真的6
2023-5-26 15:14
1
雪    币: 246
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
坏了 出个题比赛 被偷家了
2023-5-26 15:22
1
游客
登录 | 注册 方可回帖
返回
//