如何在安装我的内核驱动程序时禁用 Windows 创建自动还原点?
How to disable Windows to create an automatic restore point when installing my kernel driver?
我开发了一个 NDIS 6.x LWF 内核驱动程序并使用 NSIS 2.46 将其包装到安装程序中。我发现安装后Windows会自动创建一个名为Device Driver Package Install: Nmap Project Network Service
.
的系统还原点
然而,事实证明Windows创建的这个还原点并不好。我尝试回滚到那个还原点,但我的软件仍然存在,包括驱动程序 .sys
文件和对系统的其他修改(例如创建适配器 Windows Loopback Adapter
)。
这是可以理解的,因为我的安装程序确实在安装驱动程序之前做了一些修改,而Windows只是在安装驱动程序时才拍摄快照。所以不包括我在安装驱动程序之前所做的更改。
所以我决定在安装程序的所有实际安装步骤之前自己创建一个还原点(使用 SysRestore
由 NSIS 提供)。
并且我想禁用Windows 自动为我的驱动程序创建还原点。最好的做法是什么?谢谢!
我不知道这是否是最好的方法,但您可以随时停止系统还原服务。在我看来,这是一个微妙的问题,可能比用户对驱动程序安装程序的预期干预更大。
在任何情况下,您都应该提前将此告知您的用户,并在完成后(重新)启动服务。
Section
# Stop the service
nsExec::Exec 'net.exe STOP "srservice"'
# Install kernel driver
SectionEnd
# Restore original setting
Function startSysRestore
nsExec::Exec 'net.exe START "srservice"'
FunctionEnd
# Things go right
Function .onInstSuccess
Call startSysRestore
FunctionEnd
# Things might go wrong
Function .onUserAbort
Call startSysRestore
FunctionEnd
Function .onInstFailed
Call startSysRestore
FunctionEnd
编辑:此答案的先前版本描述了如何禁用 ServiceRestore 服务
SysRestore plug-in calls SRSetRestorePoint
with BEGIN_SYSTEM_CHANGE
but according to MSDN 你可以用 BEGIN_NESTED_SYSTEM_CHANGE
调用它来只创建一个还原点。我不知道这是否只适用于单个进程,或者它是否也适用于您可能用来安装驱动程序的任何子进程,但也许值得一试。代码可能如下所示:
!define MAX_DESC 64
!define MAX_DESC_W 256
!define STATEMGRSTATUS i,l
!define RESTOREPOINTINFOA i,i,l,&m${MAX_DESC}
!define RESTOREPOINTINFOW i,i,l,&w${MAX_DESC_W}
!if "${NSIS_CHAR_SIZE}" <= 1
!define RESTOREPOINTINFO "${RESTOREPOINTINFOA}"
!else
!define RESTOREPOINTINFO "${RESTOREPOINTINFOW}"
!endif
!define BEGIN_NESTED_SYSTEM_CHANGE 102
!define END_NESTED_SYSTEM_CHANGE 103
!define DEVICE_DRIVER_INSTALL 10
Section
System::Call 'KERNEL32::LoadLibrary(t "$SysDir\SrClient.dll")'
Var /Global SRSTATUS
System::Call '*(${STATEMGRSTATUS})i.s'
Pop $SRSTATUS
System::Call '*(${RESTOREPOINTINFO})(${BEGIN_NESTED_SYSTEM_CHANGE},${DEVICE_DRIVER_INSTALL},0,&t${MAX_DESC} "Installed driver XYZ")i.r0'
System::Call 'SrClient::SRSetRestorePoint(ir0,i$SRSTATUS)i.r1'
IntCmpU 0 "" +2 +2
System::Call '*$SRSTATUS(${STATEMGRSTATUS})(0)' ; Make sure nStatus is ERROR_SUCCESS
System::Free [=10=]
DetailPrint "SRSetRestorePoint(BEGIN_NESTED_SYSTEM_CHANGE) returned "
; TODO: Install driver here
System::Call '*$SRSTATUS(${STATEMGRSTATUS})(.r0,.r1)' ; Extract nStatus and llSequenceNumber
IntCmpU [=10=] 0 "" norpt norpt ; Did the first call to SRSetRestorePoint succeed?
System::Call '*(${RESTOREPOINTINFO})(${END_NESTED_SYSTEM_CHANGE},${DEVICE_DRIVER_INSTALL},r1)i.r0'
System::Call 'SrClient::SRSetRestorePoint(ir0,i$SRSTATUS)i.r1'
System::Free [=10=]
DetailPrint "SRSetRestorePoint(END_NESTED_SYSTEM_CHANGE) returned "
norpt:
System::Free $SRSTATUS
SectionEnd
有一些 WSR 的替代品可以实现相同的功能(例如 Comodo Time Machine、Shadow Defender、RollbackRx 等),您最好使用它们来拍摄快照,因为我相信它们不会被遗弃受到同样的限制。
我开发了一个 NDIS 6.x LWF 内核驱动程序并使用 NSIS 2.46 将其包装到安装程序中。我发现安装后Windows会自动创建一个名为Device Driver Package Install: Nmap Project Network Service
.
然而,事实证明Windows创建的这个还原点并不好。我尝试回滚到那个还原点,但我的软件仍然存在,包括驱动程序 .sys
文件和对系统的其他修改(例如创建适配器 Windows Loopback Adapter
)。
这是可以理解的,因为我的安装程序确实在安装驱动程序之前做了一些修改,而Windows只是在安装驱动程序时才拍摄快照。所以不包括我在安装驱动程序之前所做的更改。
所以我决定在安装程序的所有实际安装步骤之前自己创建一个还原点(使用 SysRestore
由 NSIS 提供)。
并且我想禁用Windows 自动为我的驱动程序创建还原点。最好的做法是什么?谢谢!
我不知道这是否是最好的方法,但您可以随时停止系统还原服务。在我看来,这是一个微妙的问题,可能比用户对驱动程序安装程序的预期干预更大。
在任何情况下,您都应该提前将此告知您的用户,并在完成后(重新)启动服务。
Section
# Stop the service
nsExec::Exec 'net.exe STOP "srservice"'
# Install kernel driver
SectionEnd
# Restore original setting
Function startSysRestore
nsExec::Exec 'net.exe START "srservice"'
FunctionEnd
# Things go right
Function .onInstSuccess
Call startSysRestore
FunctionEnd
# Things might go wrong
Function .onUserAbort
Call startSysRestore
FunctionEnd
Function .onInstFailed
Call startSysRestore
FunctionEnd
编辑:此答案的先前版本描述了如何禁用 ServiceRestore 服务
SysRestore plug-in calls SRSetRestorePoint
with BEGIN_SYSTEM_CHANGE
but according to MSDN 你可以用 BEGIN_NESTED_SYSTEM_CHANGE
调用它来只创建一个还原点。我不知道这是否只适用于单个进程,或者它是否也适用于您可能用来安装驱动程序的任何子进程,但也许值得一试。代码可能如下所示:
!define MAX_DESC 64
!define MAX_DESC_W 256
!define STATEMGRSTATUS i,l
!define RESTOREPOINTINFOA i,i,l,&m${MAX_DESC}
!define RESTOREPOINTINFOW i,i,l,&w${MAX_DESC_W}
!if "${NSIS_CHAR_SIZE}" <= 1
!define RESTOREPOINTINFO "${RESTOREPOINTINFOA}"
!else
!define RESTOREPOINTINFO "${RESTOREPOINTINFOW}"
!endif
!define BEGIN_NESTED_SYSTEM_CHANGE 102
!define END_NESTED_SYSTEM_CHANGE 103
!define DEVICE_DRIVER_INSTALL 10
Section
System::Call 'KERNEL32::LoadLibrary(t "$SysDir\SrClient.dll")'
Var /Global SRSTATUS
System::Call '*(${STATEMGRSTATUS})i.s'
Pop $SRSTATUS
System::Call '*(${RESTOREPOINTINFO})(${BEGIN_NESTED_SYSTEM_CHANGE},${DEVICE_DRIVER_INSTALL},0,&t${MAX_DESC} "Installed driver XYZ")i.r0'
System::Call 'SrClient::SRSetRestorePoint(ir0,i$SRSTATUS)i.r1'
IntCmpU 0 "" +2 +2
System::Call '*$SRSTATUS(${STATEMGRSTATUS})(0)' ; Make sure nStatus is ERROR_SUCCESS
System::Free [=10=]
DetailPrint "SRSetRestorePoint(BEGIN_NESTED_SYSTEM_CHANGE) returned "
; TODO: Install driver here
System::Call '*$SRSTATUS(${STATEMGRSTATUS})(.r0,.r1)' ; Extract nStatus and llSequenceNumber
IntCmpU [=10=] 0 "" norpt norpt ; Did the first call to SRSetRestorePoint succeed?
System::Call '*(${RESTOREPOINTINFO})(${END_NESTED_SYSTEM_CHANGE},${DEVICE_DRIVER_INSTALL},r1)i.r0'
System::Call 'SrClient::SRSetRestorePoint(ir0,i$SRSTATUS)i.r1'
System::Free [=10=]
DetailPrint "SRSetRestorePoint(END_NESTED_SYSTEM_CHANGE) returned "
norpt:
System::Free $SRSTATUS
SectionEnd
有一些 WSR 的替代品可以实现相同的功能(例如 Comodo Time Machine、Shadow Defender、RollbackRx 等),您最好使用它们来拍摄快照,因为我相信它们不会被遗弃受到同样的限制。