Occasionally, you may find yourself in a situation where you need to “un-patch” the kernel in order to make forward progress with investigating a problem. This has often been the case with me and certain unnamed anti-virus programs that have the misguided intention to prevent the computer administrator from administering their computer, by denying everyone access to certain protected processes.
Normally, this is done by the use of a kernel driver that hooks various kernel system calls and prevents usermode from being able to access a protected process. While this may be done in the name of preventing malware from interfering with anti-virus software, it also has the unfortunate side effect of preventing legitimate troubleshooting of software issues.
Fortunately, with WinDbg installed and a little knowledge of the debugger, it is easy to reverse these abusive kernel patches that undermine the ability of a system administrator to do his or her job.
Now, normally, you might think that one would be stuck reverse engineering large sections of code in order to disable such kinds of protection mechanisms. However, in the vast majority of cases like these, you can simply have the kernel debugger perform a comparison of the kernel memory image with the image retrieved from the symbol server, and fix up any differences (accounting for relocations). This may be done with the !chkimg -f nt command. Using !chkimg in this fashion allows you to quickly remove unwanted kernel patches without having to dig through third party code that has injected itself into the system.
If you are feeling particularly adventurerous, you can even do this in local kernel debugger mode on Windows XP or later, without having to boot the system with /DEBUG. Be warned that this does carry an inherent race condition, though very unlikely in most cases with system service patching, that you might crash the system if someone makes a call to one of the regions of the kernel that you are unpatching while the kernel is being restored to its pristine state.
You should also be aware that depending on how the third party software that has patched the kernel is written, removing the patches out from under it may have varying negative side effects; be careful. As a result, if you are working on a critical or production system, you may want to pick a different approach. If you are just working on a throw-away repro environment in a VM, though, this can be a good quick-n-dirty way to get the job done.
Despite these potential problems, I’ve successfully used this trick in a pinch several times successfully. If you are running into a brick wall with debugging malfunctioning anti-virus software interactions with your product because of anti-debug protection mechanisms, you might give this technique a try.
Hi Skywing.
I had problems using this method. First i check a shadow
copy of the SDT with current system.(using command from your article about KAV)
Then, !chkimg -f nt, which detects errors, but is unable to fix them.
How can i resolve this?
thanks in advance & keep digging!
Kevin
Microsoft (R) Windows Debugger Version 6.5.0003.7
Copyright (c) Microsoft Corporation. All rights reserved.
Unable to read head of debugger data list
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Symbol search path is: G:\WINDOWS\Symbols
Executable search path is: G:\WINDOWS;G:\WINDOWS\system32
*******************************************************************************
WARNING: Local kernel debugging requires booting with /debug to work optimally.
*******************************************************************************
Windows XP Kernel Version 2600 (Service Pack 2) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp2_rtm.040803-2158
Kernel base = 0x80800000 PsLoadedModuleList = 0x8087c1a0
Debug session time: Fri Nov 10 15:04:27.375 2006 (GMT+0)
System Uptime: 0 days 0:01:07.968
lkd> dps poi ( nt!KeServiceDescriptorTableShadow ) l dwo ( nt!KeServiceDescriptorTableShadow + 8 )
8082a030 808c149a nt!NtAcceptConnectPort
8082a034 8090e666 nt!NtAccessCheck
8082a038 80911ec4 nt!NtAccessCheckAndAuditAlarm
8082a03c 8090e698 nt!NtAccessCheckByType
8082a040 80911efe nt!NtAccessCheckByTypeAndAuditAlarm
8082a044 8090e6ce nt!NtAccessCheckByTypeResultList
8082a048 80911f42 nt!NtAccessCheckByTypeResultListAndAuditAlarm
8082a04c 80911f86 nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle
8082a050 809335da nt!NtAddAtom
8082a054 8093484e nt!NtQueryBootOptions
8082a058 80909a08 nt!NtAdjustGroupsToken
8082a05c 80909660 nt!NtAdjustPrivilegesToken
8082a060 808f2684 nt!NtAlertResumeThread
8082a064 808f2634 nt!NtAlertThread
8082a068 80933c00 nt!NtAllocateLocallyUniqueId
8082a06c 808d3088 nt!NtAllocateUserPhysicalPages
8082a070 80933218 nt!NtAllocateUuids
8082a074 808c5910 nt!NtAllocateVirtualMemory
8082a078 808cd4da nt!NtAreMappedFilesTheSame
8082a07c 808f4162 nt!NtAssignProcessToJobObject
8082a080 80827d04 nt!NtCallbackReturn
8082a084 808e5e0e nt!NtModifyBootEntry
8082a088 80893be6 nt!NtCancelIoFile
8082a08c 8085d1dc nt!NtCancelTimer
8082a090 8092c8ea nt!NtClearEvent
8082a094 808d9714 nt!NtClose
8082a098 809123fe nt!NtCloseObjectAuditAlarm
8082a09c 809417a2 nt!NtCompactKeys
8082a0a0 809168f0 nt!NtCompareTokens
8082a0a4 808c1b88 nt!NtCompleteConnectPort
8082a0a8 809419f6 nt!NtCompressKey
8082a0ac 808c143a nt!NtConnectPort
8082a0b0 80868fd0 nt!NtContinue
8082a0b4 8095f9e8 nt!NtCreateDebugObject
8082a0b8 808db610 nt!NtCreateDirectoryObject
8082a0bc 8092c93a nt!NtCreateEvent
8082a0c0 80934b94 nt!NtCreateEventPair
8082a0c4 8089614c nt!NtCreateFile
8082a0c8 808949de nt!NtCreateIoCompletion
8082a0cc 808f3126 nt!NtCreateJobObject
8082a0d0 808f2e5e nt!NtCreateJobSet
8082a0d4 b9edbc04
8082a0d8 8089625a nt!NtCreateMailslotFile
8082a0dc 80934f8c nt!NtCreateMutant
8082a0e0 80896186 nt!NtCreateNamedPipeFile
8082a0e4 808c88fa nt!NtCreatePagingFile
8082a0e8 808c1f56 nt!NtCreatePort
8082a0ec 808eece8 nt!NtCreateProcess
8082a0f0 808eec32 nt!NtCreateProcessEx
8082a0f4 809353ac nt!NtCreateProfile
8082a0f8 808c823e nt!NtCreateSection
8082a0fc 80932936 nt!NtCreateSemaphore
8082a100 808e2410 nt!NtCreateSymbolicLinkObject
8082a104 808eead0 nt!NtCreateThread
8082a108 8093485c nt!NtCreateTimer
8082a10c 80916c98 nt!NtCreateToken
8082a110 808c1f7a nt!NtCreateWaitablePort
8082a114 80960ac4 nt!NtDebugActiveProcess
8082a118 80960c14 nt!NtDebugContinue
8082a11c 8093426e nt!NtDelayExecution
8082a120 80933a90 nt!NtDeleteAtom
8082a124 808e5e0e nt!NtModifyBootEntry
8082a128 80893d2c nt!NtDeleteFile
8082a12c 80942062 nt!NtDeleteKey
8082a130 8091250a nt!NtDeleteObjectAuditAlarm
8082a134 80942232 nt!NtDeleteValueKey
8082a138 80896312 nt!NtDeviceIoControlFile
8082a13c 809308aa nt!NtDisplayString
8082a140 808db1f0 nt!NtDuplicateObject
8082a144 8090a8a6 nt!NtDuplicateToken
8082a148 8093484e nt!NtQueryBootOptions
8082a14c b9edbd48
8082a150 80934310 nt!NtEnumerateSystemEnvironmentValuesEx
8082a154 b9edc0c0
8082a158 808d0c00 nt!NtExtendSection
8082a15c 8090aa52 nt!NtFilterToken
8082a160 80933844 nt!NtFindAtom
8082a164 80893df8 nt!NtFlushBuffersFile
8082a168 808d3912 nt!NtFlushInstructionCache
8082a16c 809428e6 nt!NtFlushKey
8082a170 808c960a nt!NtFlushVirtualMemory
8082a174 808d38b4 nt!NtFlushWriteBuffer
8082a178 808d3424 nt!NtFreeUserPhysicalPages
8082a17c 808cfeda nt!NtFreeVirtualMemory
8082a180 80896346 nt!NtFsControlFile
8082a184 808eefe2 nt!NtGetContextThread
8082a188 808e5e30 nt!NtGetDevicePowerState
8082a18c 808b631e nt!NtGetPlugPlayEvent
8082a190 80845c4e nt!NtGetWriteWatch
8082a194 809165e4 nt!NtImpersonateAnonymousToken
8082a198 808c1fe4 nt!NtImpersonateClientOfPort
8082a19c 808f52fa nt!NtImpersonateThread
8082a1a0 8093fbaa nt!NtInitializeRegistry
8082a1a4 808e5c08 nt!NtInitiatePowerAction
8082a1a8 808f2d22 nt!NtIsProcessInJob
8082a1ac 808e5e1c nt!NtIsSystemResumeAutomatic
8082a1b0 808c21f0 nt!NtListenPort
8082a1b4 808a132a nt!NtLoadDriver
8082a1b8 80943902 nt!NtLoadKey
8082a1bc 8094354c nt!NtLoadKey2
8082a1c0 8089637a nt!NtLockFile
8082a1c4 80930e0c nt!NtLockProductActivationKeys
8082a1c8 80941aa2 nt!NtLockRegistryKey
8082a1cc 808d3a1a nt!NtLockVirtualMemory
8082a1d0 808dca90 nt!NtMakePermanentObject
8082a1d4 808d97b8 nt!NtMakeTemporaryObject
8082a1d8 808d237c nt!NtMapUserPhysicalPages
8082a1dc 808d2954 nt!NtMapUserPhysicalPagesScatter
8082a1e0 808cef5a nt!NtMapViewOfSection
8082a1e4 808e5e0e nt!NtModifyBootEntry
8082a1e8 80896faa nt!NtNotifyChangeDirectoryFile
8082a1ec 809438cc nt!NtNotifyChangeKey
8082a1f0 809429e8 nt!NtNotifyChangeMultipleKeys
8082a1f4 808db6e2 nt!NtOpenDirectoryObject
8082a1f8 8092ca3a nt!NtOpenEvent
8082a1fc 80934c6c nt!NtOpenEventPair
8082a200 8089726a nt!NtOpenFile
8082a204 80894ab6 nt!NtOpenIoCompletion
8082a208 808f32ac nt!NtOpenJobObject
8082a20c b9edbae2
8082a210 80935064 nt!NtOpenMutant
8082a214 80911fcc nt!NtOpenObjectAuditAlarm
8082a218 808e8b78 nt!NtOpenProcess
8082a21c 8090b29e nt!NtOpenProcessToken
8082a220 8090aea4 nt!NtOpenProcessTokenEx
8082a224 808c7274 nt!NtOpenSection
8082a228 80932a30 nt!NtOpenSemaphore
8082a22c 808e25f6 nt!NtOpenSymbolicLinkObject
8082a230 808e8e04 nt!NtOpenThread
8082a234 8090b2bc nt!NtOpenThreadToken
8082a238 8090b014 nt!NtOpenThreadTokenEx
8082a23c 8093497e nt!NtOpenTimer
8082a240 80962cb6 nt!NtPlugPlayControl
8082a244 808e6c64 nt!NtPowerInformation
8082a248 80915696 nt!NtPrivilegeCheck
8082a24c 809112de nt!NtPrivilegeObjectAuditAlarm
8082a250 809114ca nt!NtPrivilegedServiceAuditAlarm
8082a254 808d54e2 nt!NtProtectVirtualMemory
8082a258 8092caf2 nt!NtPulseEvent
8082a25c 80893fde nt!NtQueryAttributesFile
8082a260 8093484e nt!NtQueryBootOptions
8082a264 8093484e nt!NtQueryBootOptions
8082a268 80864206 nt!NtQueryDebugFilterState
8082a26c 8092e65e nt!NtQueryDefaultLocale
8082a270 8092f2be nt!NtQueryDefaultUILanguage
8082a274 80896f44 nt!NtQueryDirectoryFile
8082a278 808db782 nt!NtQueryDirectoryObject
8082a27c 8089729a nt!NtQueryEaFile
8082a280 8092cbba nt!NtQueryEvent
8082a284 80894116 nt!NtQueryFullAttributesFile
8082a288 80933ab8 nt!NtQueryInformationAtom
8082a28c 80897b16 nt!NtQueryInformationFile
8082a290 808f377e nt!NtQueryInformationJobObject
8082a294 808c224e nt!NtQueryInformationPort
8082a298 808ea4de nt!NtQueryInformationProcess
8082a29c 808e90aa nt!NtQueryInformationThread
8082a2a0 8090b39c nt!NtQueryInformationToken
8082a2a4 8092ea5c nt!NtQueryInstallUILanguage
8082a2a8 8093582e nt!NtQueryIntervalProfile
8082a2ac 80894b5e nt!NtQueryIoCompletion
8082a2b0 b9edc18a
8082a2b4 80940da0 nt!NtQueryMultipleValueKey
8082a2b8 8093510c nt!NtQueryMutant
8082a2bc 808e1ad8 nt!NtQueryObject
8082a2c0 80941406 nt!NtQueryOpenSubKeys
8082a2c4 809358bc nt!NtQueryPerformanceCounter
8082a2c8 80898960 nt!NtQueryQuotaInformationFile
8082a2cc 808d56a4 nt!NtQuerySection
8082a2d0 808dd45c nt!NtQuerySecurityObject
8082a2d4 80932ae8 nt!NtQuerySemaphore
8082a2d8 808e2696 nt!NtQuerySymbolicLinkObject
8082a2dc 8093432c nt!NtQuerySystemEnvironmentValue
8082a2e0 80934302 nt!NtSetSystemEnvironmentValueEx
8082a2e4 8092f33e nt!NtQuerySystemInformation
8082a2e8 809311c0 nt!NtQuerySystemTime
8082a2ec 80934a36 nt!NtQueryTimer
8082a2f0 80930a78 nt!NtQueryTimerResolution
8082a2f4 b9edc022
8082a2f8 808d5d2a nt!NtQueryVirtualMemory
8082a2fc 80898e50 nt!NtQueryVolumeInformationFile
8082a300 808eed2e nt!NtQueueApcThread
8082a304 80869018 nt!NtRaiseException
8082a308 8093275a nt!NtRaiseHardError
8082a30c 80899618 nt!NtReadFile
8082a310 80899ba6 nt!NtReadFileScatter
8082a314 808c2cd6 nt!NtReadRequestData
8082a318 808d11ec nt!NtReadVirtualMemory
8082a31c 808f027e nt!NtRegisterThreadTerminatePort
8082a320 80935244 nt!NtReleaseMutant
8082a324 80932c18 nt!NtReleaseSemaphore
8082a328 80894e56 nt!NtRemoveIoCompletion
8082a32c 80960b94 nt!NtRemoveProcessDebug
8082a330 809415f8 nt!NtRenameKey
8082a334 809437b2 nt!NtReplaceKey
8082a338 808c2356 nt!NtReplyPort
8082a33c 808c331e nt!NtReplyWaitReceivePort
8082a340 808c2d26 nt!NtReplyWaitReceivePortEx
8082a344 808c2640 nt!NtReplyWaitReplyPort
8082a348 808e5da0 nt!NtRequestDeviceWakeup
8082a34c 808bf8b4 nt!NtRequestPort
8082a350 808bfbe0 nt!NtRequestWaitReplyPort
8082a354 808e5bae nt!NtRequestWakeupLatency
8082a358 8092cccc nt!NtResetEvent
8082a35c 8084612e nt!NtResetWriteWatch
8082a360 8093ffda nt!NtRestoreKey
8082a364 808f25de nt!NtResumeProcess
8082a368 808f24c0 nt!NtResumeThread
8082a36c 8094007c nt!NtSaveKey
8082a370 8094010c nt!NtSaveKeyEx
8082a374 809401d8 nt!NtSaveMergedKeys
8082a378 808c0bce nt!NtSecureConnectPort
8082a37c 8093484e nt!NtQueryBootOptions
8082a380 8093484e nt!NtQueryBootOptions
8082a384 808ef1f2 nt!NtSetContextThread
8082a388 8096384c nt!NtSetDebugFilterState
8082a38c 80932604 nt!NtSetDefaultHardErrorPort
8082a390 8092e7ae nt!NtSetDefaultLocale
8082a394 8092f020 nt!NtSetDefaultUILanguage
8082a398 808977b6 nt!NtSetEaFile
8082a39c 8092cd8c nt!NtSetEvent
8082a3a0 8092ce56 nt!NtSetEventBoostPriority
8082a3a4 80934f28 nt!NtSetHighEventPair
8082a3a8 80934e58 nt!NtSetHighWaitLowEventPair
8082a3ac 8096055e nt!NtSetInformationDebugObject
8082a3b0 8089811a nt!NtSetInformationFile
8082a3b4 808f448e nt!NtSetInformationJobObject
8082a3b8 8094096c nt!NtSetInformationKey
8082a3bc 808e0f1c nt!NtSetInformationObject
8082a3c0 808eb636 nt!NtSetInformationProcess
8082a3c4 808e95f6 nt!NtSetInformationThread
8082a3c8 80917a12 nt!NtSetInformationToken
8082a3cc 80935390 nt!NtSetIntervalProfile
8082a3d0 80894df4 nt!NtSetIoCompletion
8082a3d4 808f140a nt!NtSetLdtEntries
8082a3d8 80934ec4 nt!NtSetLowEventPair
8082a3dc 80934dec nt!NtSetLowWaitHighEventPair
8082a3e0 8089893e nt!NtSetQuotaInformationFile
8082a3e4 808dd390 nt!NtSetSecurityObject
8082a3e8 809345b0 nt!NtSetSystemEnvironmentValue
8082a3ec 80934302 nt!NtSetSystemEnvironmentValueEx
8082a3f0 8092d68c nt!NtSetSystemInformation
8082a3f4 8096fde8 nt!NtSetSystemPowerState
8082a3f8 80931d80 nt!NtSetSystemTime
8082a3fc 808e5ac2 nt!NtSetThreadExecutionState
8082a400 8085d318 nt!NtSetTimer
8082a404 80931252 nt!NtSetTimerResolution
8082a408 809330ce nt!NtSetUuidSeed
8082a40c b9edc212
8082a410 80899274 nt!NtSetVolumeInformationFile
8082a414 8093086e nt!NtShutdownSystem
8082a418 8084aed6 nt!NtSignalAndWaitForSingleObject
8082a41c 809355da nt!NtStartProfile
8082a420 80935784 nt!NtStopProfile
8082a424 808f2588 nt!NtSuspendProcess
8082a428 808f23fa nt!NtSuspendThread
8082a42c 809359a8 nt!NtSystemDebugControl
8082a430 808f4ff8 nt!NtTerminateJobObject
8082a434 808f04c8 nt!NtTerminateProcess
8082a438 808f06c2 nt!NtTerminateThread
8082a43c 808f2748 nt!NtTestAlert
8082a440 808599e4 nt!NtTraceEvent
8082a444 8093431e nt!NtTranslateFilePath
8082a448 808a14be nt!NtUnloadDriver
8082a44c 8094055a nt!NtUnloadKey
8082a450 80940748 nt!NtUnloadKeyEx
8082a454 80896726 nt!NtUnlockFile
8082a458 808d3fa8 nt!NtUnlockVirtualMemory
8082a45c 808cfd70 nt!NtUnmapViewOfSection
8082a460 80918dca nt!NtVdmControl
8082a464 809602c6 nt!NtWaitForDebugEvent
8082a468 808ddac8 nt!NtWaitForMultipleObjects
8082a46c 808dd9de nt!NtWaitForSingleObject
8082a470 80934d88 nt!NtWaitHighEventPair
8082a474 80934d24 nt!NtWaitLowEventPair
8082a478 8089a0b6 nt!NtWriteFile
8082a47c 8089a6c6 nt!NtWriteFileGather
8082a480 808c2cfe nt!NtWriteRequestData
8082a484 808d12f6 nt!NtWriteVirtualMemory
8082a488 8082a6d0 nt!NtYieldExecution
8082a48c 80935e00 nt!NtCreateKeyedEvent
8082a490 80935eea nt!NtOpenKeyedEvent
8082a494 80935f9c nt!NtReleaseKeyedEvent
8082a498 80936228 nt!NtWaitForKeyedEvent
8082a49c 808e907a nt!NtQueryPortInformationProcess
lkd> !chkimg -f nt
Warning: Any detected errors will be fixed to what we expect!
Unable to write expected value at: 8082a0d4
Unable to write expected value at: 8082a0d5
Unable to write expected value at: 8082a0d6
Unable to write expected value at: 8082a0d7
Unable to write expected value at: 8082a14c
Unable to write expected value at: 8082a14d
Unable to write expected value at: 8082a14e
Unable to write expected value at: 8082a14f
Unable to write expected value at: 8082a154
Unable to write expected value at: 8082a155
Unable to write expected value at: 8082a156
Unable to write expected value at: 8082a157
Unable to write expected value at: 8082a20c
Unable to write expected value at: 8082a20d
Unable to write expected value at: 8082a20e
Unable to write expected value at: 8082a20f
Unable to write expected value at: 8082a2b0
Unable to write expected value at: 8082a2b1
Unable to write expected value at: 8082a2b2
Unable to write expected value at: 8082a2b3
Unable to write expected value at: 8082a2f4
Unable to write expected value at: 8082a2f5
Unable to write expected value at: 8082a2f6
Unable to write expected value at: 8082a2f7
Unable to write expected value at: 8082a40c
Unable to write expected value at: 8082a40d
Unable to write expected value at: 8082a40e
Unable to write expected value at: 8082a40f
28 errors (fixed): nt (8082a0d4-8082a40f)