How to disable Windows to create an automatic restore point when installing my kernel driver?

284 Views Asked by At

I developed a NDIS 6.x LWF kernel driver and wrapped it into an installer using NSIS 2.46. I found that after its installation, Windows will automatically create a system restore point named Device Driver Package Install: Nmap Project Network Service.

However, in fact it turns out that this restore point created by Windows is not good. I tried rolling back to that restore point, and my software is still there, including the driver .sys file and other modifications to the system (like creating an adapter such as Windows Loopback Adapter).

This is understandable because my installer indeed does some modifications before installing the driver, while Windows only takes the snapshot right when the driver is being installed. So my changes prior to the driver installation is not included.

So I decided to create a restore point by myself (using SysRestore provided by NSIS) before all actual installation steps of the installer.

And I want to disable Windows to automatically create the restore point for my driver. What's the best to do this? Thanks!

3

There are 3 best solutions below

2
On BEST ANSWER

The SysRestore plug-in calls SRSetRestorePoint with BEGIN_SYSTEM_CHANGE but according to MSDN you can call it with BEGIN_NESTED_SYSTEM_CHANGE to only create one restore point. I don't know if this just applies to a single process or if it also applies to any child process you might be using to install the driver but it is perhaps worth a try. The code might look something like this:

!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 $1 0 "" +2 +2
    System::Call '*$SRSTATUS(${STATEMGRSTATUS})(0)' ; Make sure nStatus is ERROR_SUCCESS
System::Free $0
DetailPrint "SRSetRestorePoint(BEGIN_NESTED_SYSTEM_CHANGE) returned $1"


; TODO: Install driver here


System::Call '*$SRSTATUS(${STATEMGRSTATUS})(.r0,.r1)' ; Extract nStatus and llSequenceNumber
IntCmpU $0 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 $0
    DetailPrint "SRSetRestorePoint(END_NESTED_SYSTEM_CHANGE) returned $1"
norpt:
System::Free $SRSTATUS
SectionEnd
1
On

I don't know whether it's the best way, but you could always stop the System Restore service. In my opinion, this is a delicate issue and probably a bigger intervention than a user would expect from a driver installer.

In any case, you should communicate this to your users in advance and (re)start the service on completion.

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

Edit: a previous version of this answer described how to disable the ServiceRestore service

0
On

There's a few alternatives to WSR that do the same functionality (i.e. Comodo Time Machine, Shadow Defender, RollbackRx, etc) you may be better off using those to take a snapshot as I'm sure they aren't witheld by the same restrictions.