-
-
[旧帖] [原创]new blue pill在Intel系列CPU上无法卸载问题 0.00雪花
-
发表于: 2014-9-13 15:31 1408
-
实验环境win7 sp1 x64,newbluepill-0.32,VS2013,WDK8.1
NewBluePill源代码编译后,使用InstDrv成功载入生成的两个驱动:dbgclient.sys和newbp.sys。通过bpknock.exe查看运行结果,成功安装了bluepill。
但卸载时出了问题,dbgclient.sys驱动可以成功卸载,但newbp.sys已卸载系统就停下不动了。
目的是基于newbluepill做实验,但这很不方便,不能每次修改完代码都重启一次吧。不是什么高难度的工作,只是没找到有人告诉如何做,分享一下。
下面进入正文:
查阅相关资料在书《NewBluePill深入理解硬件虚拟机》的第90页中看到了解释。书中说默认情况下NewBluePill在Intel平台上是不能正常关闭的,并分析了不能关闭的原因。
按照书中分析的原因,对代码进行了一些修改,成功实现了卸载,不能卸载的具体原因,可参照书上的描述,就不重复了,下面只给出修复思路和代码。
书中分析后得出的结论是:驱动卸载函数会为每个CPU调用编号为NBP_HYPERCALL_UNLOAD的VMCALL,不能成功卸载的原因是没有对该VMMCALL进行处理。并给出了bluepill中另一个可以卸载虚拟机的函数,Hvm->ArchShutdown。
所以修复思路就是将编号为NBP_HYPERCALL_UNLOAD的VMCALL注册为处理函数为Hvm->ArchShutdown。
Bluepill中为各个VMM Exit事件注册处理函数的函数是VmxRegisterTraps。
原有代码中为VMCALL注册处理函数的过程为:
1. 定义一个数组:
TableOfVmxExits[]= {
EXIT_REASON_VMCALL,
EXIT_REASON_VMCALL,
EXIT_REASON_VMLAUNCH,
EXIT_REASON_VMRESUME,
EXIT_REASON_VMPTRLD,
EXIT_REASON_VMPTRST,
EXIT_REASON_VMREAD,
EXIT_REASON_VMWRITE,
EXIT_REASON_VMXON,
EXIT_REASON_VMXOFF
};
2. 在之后为数组中的每一项注册处理函数:
for(i = 0; i < sizeof (TableOfVmxExits) / sizeof (ULONG32); i++) {
if (!NT_SUCCESS (Status =TrInitializeGeneralTrap (Cpu, TableOfVmxExits[i], 0, // length of the instruction, 0 meanslength need to be get from vmcs later.
VmxDispatchVmxInstrDummy, &Trap))) {
_KdPrint (("VmxRegisterTraps():Failed to register VmxDispatchVmon with status 0x%08hX\n", Status));
return Status;
}
TrRegisterTrap (Cpu, Trap);
}
但注册的处理函数为VmxDispatchVmxInstrDummy。
进行的修改是:
将两个EXIT_REASON_VMCALL冲上述数组中删除。
在下面单独为其注册处理函数:
if(!NT_SUCCESS(Status = TrInitializeGeneralTrap(Cpu, EXIT_REASON_VMCALL, 0, //length of the instruction, 0 means length need to be get from vmcs later.
Hvm->ArchShutdown, &Trap))) {
_KdPrint(("VmxRegisterTraps(): Failed to register VmxDispatchCpuidwith status 0x%08hX\n", Status));
return Status;
}
TrRegisterTrap(Cpu, Trap);
如此就可以成功卸载了。
NewBluePill源代码编译后,使用InstDrv成功载入生成的两个驱动:dbgclient.sys和newbp.sys。通过bpknock.exe查看运行结果,成功安装了bluepill。
但卸载时出了问题,dbgclient.sys驱动可以成功卸载,但newbp.sys已卸载系统就停下不动了。
目的是基于newbluepill做实验,但这很不方便,不能每次修改完代码都重启一次吧。不是什么高难度的工作,只是没找到有人告诉如何做,分享一下。
下面进入正文:
查阅相关资料在书《NewBluePill深入理解硬件虚拟机》的第90页中看到了解释。书中说默认情况下NewBluePill在Intel平台上是不能正常关闭的,并分析了不能关闭的原因。
按照书中分析的原因,对代码进行了一些修改,成功实现了卸载,不能卸载的具体原因,可参照书上的描述,就不重复了,下面只给出修复思路和代码。
书中分析后得出的结论是:驱动卸载函数会为每个CPU调用编号为NBP_HYPERCALL_UNLOAD的VMCALL,不能成功卸载的原因是没有对该VMMCALL进行处理。并给出了bluepill中另一个可以卸载虚拟机的函数,Hvm->ArchShutdown。
所以修复思路就是将编号为NBP_HYPERCALL_UNLOAD的VMCALL注册为处理函数为Hvm->ArchShutdown。
Bluepill中为各个VMM Exit事件注册处理函数的函数是VmxRegisterTraps。
原有代码中为VMCALL注册处理函数的过程为:
1. 定义一个数组:
TableOfVmxExits[]= {
EXIT_REASON_VMCALL,
EXIT_REASON_VMCALL,
EXIT_REASON_VMLAUNCH,
EXIT_REASON_VMRESUME,
EXIT_REASON_VMPTRLD,
EXIT_REASON_VMPTRST,
EXIT_REASON_VMREAD,
EXIT_REASON_VMWRITE,
EXIT_REASON_VMXON,
EXIT_REASON_VMXOFF
};
2. 在之后为数组中的每一项注册处理函数:
for(i = 0; i < sizeof (TableOfVmxExits) / sizeof (ULONG32); i++) {
if (!NT_SUCCESS (Status =TrInitializeGeneralTrap (Cpu, TableOfVmxExits[i], 0, // length of the instruction, 0 meanslength need to be get from vmcs later.
VmxDispatchVmxInstrDummy, &Trap))) {
_KdPrint (("VmxRegisterTraps():Failed to register VmxDispatchVmon with status 0x%08hX\n", Status));
return Status;
}
TrRegisterTrap (Cpu, Trap);
}
但注册的处理函数为VmxDispatchVmxInstrDummy。
进行的修改是:
将两个EXIT_REASON_VMCALL冲上述数组中删除。
在下面单独为其注册处理函数:
if(!NT_SUCCESS(Status = TrInitializeGeneralTrap(Cpu, EXIT_REASON_VMCALL, 0, //length of the instruction, 0 means length need to be get from vmcs later.
Hvm->ArchShutdown, &Trap))) {
_KdPrint(("VmxRegisterTraps(): Failed to register VmxDispatchCpuidwith status 0x%08hX\n", Status));
return Status;
}
TrRegisterTrap(Cpu, Trap);
如此就可以成功卸载了。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
看原图
赞赏
雪币:
留言: