Sunday, October 30, 2011

Disassembly Algorithms

As with any problem in computer science, there are many ways to solve the problem of disassembling executable code. I was wondering how IDA Pro disassembles executables. In general, disassembly can be performed as follows:

  1. We take the bytes one instruction at a time and look the instruction up in a lookup table we have prebuilt(which maps raw byte values to opcode mneumonics). Keep in mind that different architectures can have different instruction lengths and some instruction sets could have variable instruction lengths. In the case of variable instruction lengths, we have to use "context clues" such as reading bytes before/after this instruction to infer what this instruction could be.
  2. The lookup in the table will yield the opcode mneumonic for this instruction.
  3. While we still have more data, go back to step 1.

The actual disassembly process presented above might not be very complex, but the question arises "How do we traverse the executable?" As I presented in a previous blogpost, there are multiple sections within an executable, so one may be unsure about where in the executable to even start disassembling. According to "The IDA Pro Book: The Unofficial Guide" by Chris Eagle, there are 2 main executable traversal algorithms.

Linear Sweep Disassembly

In this algorithm, we start at the beginning of a section, and keep track of the length of each instruction we disassemble. Naturally, the next instruction's address can be computed as follow follows:

Next instruction address = Current instruction address + Current instruction size

As the name implies, this algorithm scans the executable linearly(it does not refer to the Asymptotic Complexity of this algorithm). When call or jmp instructions are encountered, they are decoded as regular instructions, and given no special consideration. Think of this algorithm as instruction-by-instruction decoding. Eagle also mentions that this algorithm is used by popular disassembly engines such as gdb, WinDbg and objdump.
  • Advantages: all the byes in the section is guaranteed to be decoded
  • Disadvantages: ALL the bytes in the section is guaranteed to be decoded(including non-executable data)

Recursive Descent Disassembly

In this algorithm, we use the basic approach in Linear Sweep Disassembly, except we are a little smarter about branching instructions. We decode each instruction that we see, but if we see a jmp, call, or other type of control-flow-manipulating instruction, we also add the target address operand of the instruction to a list for further processing. Once we are finished linearly processing all the instructions in the executable, we go back and repeat the same process starting at each address in the list we created which contains the target addresses of control flow manipulation instructions we passed. One noteworthy point is that addresses that are only known at execution time(such as an address stored in EAX) rather than known those hardcoded into the binary (and lend themselves to static analysis) cannot be added to the list for further processing, because the address is not known. The word "Recursive" in the name refers to the fact that we take both branches of eligible branching statements. If all possible execution paths are modeled as a tree, this would effectively be a Breadth-First-Traversal of the execution tree. Think about this algorithm as one that only processes bytes that the CPU processes. IDA Pro uses this algorithm.
  • Advantages: only disassembles bytes that the CPU encounters, and not extraneous bytes
  • Disadvantages: relatively complex, does not always disassemble the whole executable if there is code which is not called explicitly based on its address.

Tuesday, September 27, 2011

Reversing Stuxnet: 5 (Kernel Hooking)

In order to be executed by the Windows kernel, Stuxnet has to "hook" certain functions/handlers (aka register itself). As you might know, since a driver is running in kernel space, it has access to core parts of the kernel. Drivers have access to things such as the IDT(Interrupt Descriptor Table), SSDT(System Service Descriptor Table), and other drivers that are currently loaded into the kernel.

The SSDT is the table that holds addresses of different system call APIs. The entries of this table points to places where user land can call into the kernel. Below, I have dumped the SSDT, and as we can see, there is no SSDT hooking because all the entries of the table contain addresses that point inside the nt module (hence the nt! before each function name). If any entry of the SSDT was hooked by Stuxnet, we should see something like "mrxnet!" for that entry below:

kd> dds KiServiceTable L128
804fc624  8058391a nt!NtAcceptConnectPort
804fc628  8056b154 nt!NtAccessCheck
804fc62c  80560664 nt!NtAccessCheckAndAuditAlarm
804fc630  805b6323 nt!NtAccessCheckByType
804fc634  8055616d nt!NtAccessCheckByTypeAndAuditAlarm
804fc638  8060df58 nt!NtAccessCheckByTypeResultList
804fc63c  8060fed7 nt!NtAccessCheckByTypeResultListAndAuditAlarm
804fc640  8060ff14 nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle
804fc644  8055469c nt!NtAddAtom
804fc648  8061b93c nt!NtSetBootOptions
804fc64c  8060da54 nt!NtAdjustGroupsToken
804fc650  8055e764 nt!NtAdjustPrivilegesToken
804fc654  8060781d nt!NtAlertResumeThread
804fc658  80562f2c nt!NtAlertThread
804fc65c  8055fb3d nt!NtAllocateLocallyUniqueId
804fc660  8060110e nt!NtAllocateUserPhysicalPages
804fc664  8056085b nt!NtAllocateUuids
804fc668  8057df4b nt!NtAllocateVirtualMemory
804fc66c  8054ec3b nt!NtAreMappedFilesTheSame
804fc670  805b78cf nt!NtAssignProcessToJobObject
804fc674  8050c5fc nt!NtCallbackReturn
804fc678  8061b934 nt!NtCancelDeviceWakeupRequest
804fc67c  805b30bc nt!NtCancelIoFile
804fc680  804e1910 nt!NtCancelTimer
804fc684  8056decb nt!NtClearEvent
804fc688  805725c1 nt!NtClose
804fc68c  8055ff19 nt!NtCloseObjectAuditAlarm
804fc690  80620f33 nt!NtCompactKeys
804fc694  80610955 nt!NtCompareTokens
804fc698  80583d84 nt!NtCompleteConnectPort
804fc69c  8062115f nt!NtCompressKey
804fc6a0  80565287 nt!NtConnectPort
804fc6a4  804d8365 nt!NtContinue
804fc6a8  8062952b nt!NtCreateDebugObject
804fc6ac  8059d59a nt!NtCreateDirectoryObject
804fc6b0  805799e0 nt!NtCreateEvent
804fc6b4  8061be63 nt!NtCreateEventPair
804fc6b8  80578edf nt!NtCreateFile
804fc6bc  80555d7d nt!NtCreateIoCompletion
804fc6c0  805b7237 nt!NtCreateJobObject
804fc6c4  80607c3e nt!NtCreateJobSet
804fc6c8  80563030 nt!NtCreateKey
804fc6cc  80562111 nt!NtCreateMailslotFile
804fc6d0  80582a9f nt!NtCreateMutant
804fc6d4  8056ad3c nt!NtCreateNamedPipeFile
804fc6d8  80596e08 nt!NtCreatePagingFile
804fc6dc  80551dbe nt!NtCreatePort
804fc6e0  8059a61d nt!NtCreateProcess
804fc6e4  80580346 nt!NtCreateProcessEx
804fc6e8  8061c3a2 nt!NtCreateProfile
804fc6ec  805711d5 nt!NtCreateSection
804fc6f0  80553a81 nt!NtCreateSemaphore
804fc6f4  805b676e nt!NtCreateSymbolicLinkObject
804fc6f8  8057f298 nt!NtCreateThread
804fc6fc  80550e73 nt!NtCreateTimer
804fc700  8054e5dc nt!NtCreateToken
804fc704  805a4eca nt!NtCreateWaitablePort
804fc708  8062a616 nt!NtDebugActiveProcess
804fc70c  8062a757 nt!NtDebugContinue
804fc710  80571a83 nt!NtDelayExecution
804fc714  80554473 nt!NtDeleteAtom
804fc718  8061b934 nt!NtCancelDeviceWakeupRequest
804fc71c  805a4df4 nt!NtDeleteFile
804fc720  80563d14 nt!NtDeleteKey
804fc724  805becf1 nt!NtDeleteObjectAuditAlarm
804fc728  80563631 nt!NtDeleteValueKey
804fc72c  805863ad nt!NtDeviceIoControlFile
804fc730  8059668b nt!NtDisplayString
804fc734  80582614 nt!NtDuplicateObject
804fc738  8056b231 nt!NtDuplicateToken
804fc73c  8061b93c nt!NtSetBootOptions
804fc740  8056a5dc nt!NtEnumerateKey
804fc744  8061b92c nt!NtEnumerateSystemEnvironmentValuesEx
804fc748  80564a47 nt!NtEnumerateValueKey
804fc74c  8060002c nt!NtExtendSection
804fc750  805a0a01 nt!NtFilterToken
804fc754  805547de nt!NtFindAtom
804fc758  80563e23 nt!NtFlushBuffersFile
804fc75c  8057c60f nt!NtFlushInstructionCache
804fc760  8056172f nt!NtFlushKey
804fc764  8055137a nt!NtFlushVirtualMemory
804fc768  806019d5 nt!NtFlushWriteBuffer
804fc76c  806014ab nt!NtFreeUserPhysicalPages
804fc770  8057e36e nt!NtFreeVirtualMemory
804fc774  8057c130 nt!NtFsControlFile
804fc778  805a6880 nt!NtGetContextThread
804fc77c  80605081 nt!NtGetDevicePowerState
804fc780  8054c018 nt!NtGetPlugPlayEvent
804fc784  80527855 nt!NtGetWriteWatch
804fc788  8055735f nt!NtImpersonateAnonymousToken
804fc78c  80564477 nt!NtImpersonateClientOfPort
804fc790  8055f8ef nt!NtImpersonateThread
804fc794  805a34ad nt!NtInitializeRegistry
804fc798  80604e8a nt!NtInitiatePowerAction
804fc79c  80607b14 nt!NtIsProcessInJob
804fc7a0  80605073 nt!NtIsSystemResumeAutomatic
804fc7a4  805a31ae nt!NtListenPort
804fc7a8  805a74a9 nt!NtLoadDriver
804fc7ac  8059f701 nt!NtLoadKey
804fc7b0  8059f713 nt!NtLoadKey2
804fc7b4  8055f45e nt!NtLockFile
804fc7b8  805a0434 nt!NtLockProductActivationKeys
804fc7bc  8059cefc nt!NtLockRegistryKey
804fc7c0  805abb4b nt!NtLockVirtualMemory
804fc7c4  805b6da3 nt!NtMakePermanentObject
804fc7c8  805b6cc1 nt!NtMakeTemporaryObject
804fc7cc  80600438 nt!NtMapUserPhysicalPages
804fc7d0  806009d2 nt!NtMapUserPhysicalPagesScatter
804fc7d4  8057648d nt!NtMapViewOfSection
804fc7d8  8061b934 nt!NtCancelDeviceWakeupRequest
804fc7dc  8055fca7 nt!NtNotifyChangeDirectoryFile
804fc7e0  80557b10 nt!NtNotifyChangeKey
804fc7e4  80563aa0 nt!NtNotifyChangeMultipleKeys
804fc7e8  8057dbd7 nt!NtOpenDirectoryObject
804fc7ec  8056735c nt!NtOpenEvent
804fc7f0  8061bf35 nt!NtOpenEventPair
804fc7f4  80576449 nt!NtOpenFile
804fc7f8  805f5a37 nt!NtOpenIoCompletion
804fc7fc  805bcd82 nt!NtOpenJobObject
804fc800  80573055 nt!NtOpenKey
804fc804  80582952 nt!NtOpenMutant
804fc808  80561934 nt!NtOpenObjectAuditAlarm
804fc80c  80566e3a nt!NtOpenProcess
804fc810  8058147f nt!NtOpenProcessToken
804fc814  8057c770 nt!NtOpenProcessTokenEx
804fc818  8057b6b8 nt!NtOpenSection
804fc81c  805ac119 nt!NtOpenSemaphore
804fc820  80579b45 nt!NtOpenSymbolicLinkObject
804fc824  805563f7 nt!NtOpenThread
804fc828  805845b3 nt!NtOpenThreadToken
804fc82c  8057e9e2 nt!NtOpenThreadTokenEx
804fc830  805a5fe6 nt!NtOpenTimer
804fc834  80552aa9 nt!NtPlugPlayControl
804fc838  80556232 nt!NtPowerInformation
804fc83c  805536d9 nt!NtPrivilegeCheck
804fc840  8059c0e1 nt!NtPrivilegeObjectAuditAlarm
804fc844  805b0e95 nt!NtPrivilegedServiceAuditAlarm
804fc848  8057cc95 nt!NtProtectVirtualMemory
804fc84c  8056482d nt!NtPulseEvent
804fc850  8057cbae nt!NtQueryAttributesFile
804fc854  8061b93c nt!NtSetBootOptions
804fc858  8061b93c nt!NtSetBootOptions
804fc85c  804f5b66 nt!NtQueryDebugFilterState
804fc860  8057d1e3 nt!NtQueryDefaultLocale
804fc864  80580a70 nt!NtQueryDefaultUILanguage
804fc868  805841b5 nt!NtQueryDirectoryFile
804fc86c  80566b3b nt!NtQueryDirectoryObject
804fc870  805f5be3 nt!NtQueryEaFile
804fc874  8056d88e nt!NtQueryEvent
804fc878  8055f6d8 nt!NtQueryFullAttributesFile
804fc87c  80553c68 nt!NtQueryInformationAtom
804fc880  80576210 nt!NtQueryInformationFile
804fc884  80584b8c nt!NtQueryInformationJobObject
804fc888  805fdfa2 nt!NtQueryInformationPort
804fc88c  8057a6e8 nt!NtQueryInformationProcess
804fc890  805827e7 nt!NtQueryInformationThread
804fc894  8057eb20 nt!NtQueryInformationToken
804fc898  8056aa98 nt!NtQueryInstallUILanguage
804fc89c  8061c811 nt!NtQueryIntervalProfile
804fc8a0  805f5ada nt!NtQueryIoCompletion
804fc8a4  8055b86b nt!NtQueryKey
804fc8a8  80620abd nt!NtQueryMultipleValueKey
804fc8ac  8061c21f nt!NtQueryMutant
804fc8b0  80578c7b nt!NtQueryObject
804fc8b4  80620c90 nt!NtQueryOpenSubKeys
804fc8b8  80586703 nt!NtQueryPerformanceCounter
804fc8bc  805f6401 nt!NtQueryQuotaInformationFile
804fc8c0  8057d0e1 nt!NtQuerySection
804fc8c4  80555795 nt!NtQuerySecurityObject
804fc8c8  8061b48a nt!NtQuerySemaphore
804fc8cc  8057a874 nt!NtQuerySymbolicLinkObject
804fc8d0  8061b94c nt!NtQuerySystemEnvironmentValue
804fc8d4  8061b924 nt!NtQuerySystemEnvironmentValueEx
804fc8d8  8057a7ba nt!NtQuerySystemInformation
804fc8dc  80558ec1 nt!NtQuerySystemTime
804fc8e0  8055673c nt!NtQueryTimer
804fc8e4  80553b55 nt!NtQueryTimerResolution
804fc8e8  80575d81 nt!NtQueryValueKey
804fc8ec  8057d479 nt!NtQueryVirtualMemory
804fc8f0  8057a580 nt!NtQueryVolumeInformationFile
804fc8f4  80556082 nt!NtQueueApcThread
804fc8f8  804d83ad nt!NtRaiseException
804fc8fc  805bc4e4 nt!NtRaiseHardError
804fc900  8057c24f nt!NtReadFile
804fc904  80550518 nt!NtReadFileScatter
804fc908  80566a22 nt!NtReadRequestData
804fc90c  805849c5 nt!NtReadVirtualMemory
804fc910  80583835 nt!NtRegisterThreadTerminatePort
804fc914  80571ae9 nt!NtReleaseMutant
804fc918  80558f33 nt!NtReleaseSemaphore
804fc91c  8056dc7a nt!NtRemoveIoCompletion
804fc920  8062a6df nt!NtRemoveProcessDebug
804fc924  80620e01 nt!NtRenameKey
804fc928  806211df nt!NtReplaceKey
804fc92c  8056d3aa nt!NtReplyPort
804fc930  80580f92 nt!NtReplyWaitReceivePort
804fc934  80580bb4 nt!NtReplyWaitReceivePortEx
804fc938  805fe063 nt!NtReplyWaitReplyPort
804fc93c  8060500c nt!NtRequestDeviceWakeup
804fc940  805667ce nt!NtRequestPort
804fc944  80583120 nt!NtRequestWaitReplyPort
804fc948  80604e3a nt!NtRequestWakeupLatency
804fc94c  8054b145 nt!NtResetEvent
804fc950  80527d79 nt!NtResetWriteWatch
804fc954  806200e0 nt!NtRestoreKey
804fc958  806077ce nt!NtResumeProcess
804fc95c  8057f394 nt!NtResumeThread
804fc960  8062017a nt!NtSaveKey
804fc964  80620202 nt!NtSaveKeyEx
804fc968  806202c6 nt!NtSaveMergedKeys
804fc96c  8057b7a2 nt!NtSecureConnectPort
804fc970  8061b93c nt!NtSetBootOptions
804fc974  8061b93c nt!NtSetBootOptions
804fc978  80607f6a nt!NtSetContextThread
804fc97c  8062bd1b nt!NtSetDebugFilterState
804fc980  8059a92c nt!NtSetDefaultHardErrorPort
804fc984  8059d382 nt!NtSetDefaultLocale
804fc988  8059d358 nt!NtSetDefaultUILanguage
804fc98c  805f60eb nt!NtSetEaFile
804fc990  8056de41 nt!NtSetEvent
804fc994  8056dc23 nt!NtSetEventBoostPriority
804fc998  8061c1c3 nt!NtSetHighEventPair
804fc99c  8061c103 nt!NtSetHighWaitLowEventPair
804fc9a0  8062a0d0 nt!NtSetInformationDebugObject
804fc9a4  8058181d nt!NtSetInformationFile
804fc9a8  805b7482 nt!NtSetInformationJobObject
804fc9ac  8062069d nt!NtSetInformationKey
804fc9b0  805819c2 nt!NtSetInformationObject
804fc9b4  8057f45a nt!NtSetInformationProcess
804fc9b8  8058372d nt!NtSetInformationThread
804fc9bc  8054e1f9 nt!NtSetInformationToken
804fc9c0  8061c390 nt!NtSetIntervalProfile
804fc9c4  8056df13 nt!NtSetIoCompletion
804fc9c8  80606a63 nt!NtSetLdtEntries
804fc9cc  8061c167 nt!NtSetLowEventPair
804fc9d0  8061c09f nt!NtSetLowWaitHighEventPair
804fc9d4  805f63e7 nt!NtSetQuotaInformationFile
804fc9d8  80556354 nt!NtSetSecurityObject
804fc9dc  8061bbcb nt!NtSetSystemEnvironmentValue
804fc9e0  8061b924 nt!NtQuerySystemEnvironmentValueEx
804fc9e4  8056613e nt!NtSetSystemInformation
804fc9e8  8063874b nt!NtSetSystemPowerState
804fc9ec  805a4a3b nt!NtSetSystemTime
804fc9f0  805b6e63 nt!NtSetThreadExecutionState
804fc9f4  804e19bd nt!NtSetTimer
804fc9f8  805b2c51 nt!NtSetTimerResolution
804fc9fc  8059f55b nt!NtSetUuidSeed
804fca00  80563215 nt!NtSetValueKey
804fca04  805f68db nt!NtSetVolumeInformationFile
804fca08  8061ae18 nt!NtShutdownSystem
804fca0c  80528d95 nt!NtSignalAndWaitForSingleObject
804fca10  8061c5cb nt!NtStartProfile
804fca14  8061c76f nt!NtStopProfile
804fca18  8060777f nt!NtSuspendProcess
804fca1c  805abf08 nt!NtSuspendThread
804fca20  8061c89a nt!NtSystemDebugControl
804fca24  80607ee0 nt!NtTerminateJobObject
804fca28  8056c6dc nt!NtTerminateProcess
804fca2c  8056ce2e nt!NtTerminateThread
804fca30  8057f43d nt!NtTestAlert
804fca34  8052eeaa nt!NtTraceEvent
804fca38  8061b944 nt!NtTranslateFilePath
804fca3c  805f8709 nt!NtUnloadDriver
804fca40  80620379 nt!NtUnloadKey
804fca44  806204f0 nt!NtUnloadKeyEx
804fca48  8055f32c nt!NtUnlockFile
804fca4c  805b383d nt!NtUnlockVirtualMemory
804fca50  8056b931 nt!NtUnmapViewOfSection
804fca54  805b10b4 nt!NtVdmControl
804fca58  80629de3 nt!NtWaitForDebugEvent
804fca5c  80571f9d nt!NtWaitForMultipleObjects
804fca60  805718fb nt!NtWaitForSingleObject
804fca64  8061c043 nt!NtWaitHighEventPair
804fca68  8061bfe7 nt!NtWaitLowEventPair
804fca6c  8057d80a nt!NtWriteFile
804fca70  80550378 nt!NtWriteFileGather
804fca74  805647fc nt!NtWriteRequestData
804fca78  8057f7e6 nt!NtWriteVirtualMemory
804fca7c  804dfe07 nt!NtYieldExecution
804fca80  80588779 nt!NtCreateKeyedEvent
804fca84  80580654 nt!NtOpenKeyedEvent
804fca88  8061cc87 nt!NtReleaseKeyedEvent
804fca8c  8061cf0e nt!NtWaitForKeyedEvent
804fca90  80605e85 nt!NtQueryPortInformationProcess
804fca94  0000011c
804fca98  2c2c2018
804fca9c  44402c40
804fcaa0  1818080c
804fcaa4  0c040408
804fcaa8  08081810
804fcaac  0808040c
804fcab0  080c0404
804fcab4  2004040c
804fcab8  140c1008
804fcabc  0c102c0c
804fcac0  10201c0c

The IDT is the Interrupt Descriptor Table. Whenever the system gets an interrupt, this table is referenced to find the correct interrupt handler. For example, in the old days of Windows, the CPU would switch to kernel mode for a system call with the assembly instruction "Int 0x2E", which is why you see "nt!KiSystemService" at entry 2E in the table. Modern Windows uses the SYSENTER instruction, which is faster. Stuxnet could have modified the IDT to point to its own code, in which case we might have seen an entry below beginning with "mrxnet!". But since we don’t see that, it means that Stuxnet has not hooked this table either.

kd> !idt -a

Dumping IDT:

00:              804d59b2 nt!KiTrap00
01:              804d5b06 nt!KiTrap01
02:              Task Selector = 0x0058
03:              804d5e2e nt!KiTrap03
04:              804d5f96 nt!KiTrap04
05:              804d60de nt!KiTrap05
06:              804d6242 nt!KiTrap06
07:              804d681e nt!KiTrap07
08:              Task Selector = 0x0050
09:              804d6c41 nt!KiTrap09
0a:              804d6d49 nt!KiTrap0A
0b:              804d6e75 nt!KiTrap0B
0c:              804d7042 nt!KiTrap0C
0d:              804d7310 nt!KiTrap0D
0e:              804d79a4 nt!KiTrap0E
0f:               804d7d50 nt!KiTrap0F
10:              804d7e58 nt!KiTrap10
11:              804d7f78 nt!KiTrap11
12:              Task Selector = 0x00A0
13:              804d80c8 nt!KiTrap13
14:              804d7d50 nt!KiTrap0F
15:              804d7d50 nt!KiTrap0F
16:              804d7d50 nt!KiTrap0F
17:              804d7d50 nt!KiTrap0F
18:              804d7d50 nt!KiTrap0F
19:              804d7d50 nt!KiTrap0F
1a:              804d7d50 nt!KiTrap0F
1b:              804d7d50 nt!KiTrap0F
1c:              804d7d50 nt!KiTrap0F
1d:              804d7d50 nt!KiTrap0F
1e:              804d7d50 nt!KiTrap0F
1f:               804d7d50 nt!KiTrap0F
20:              00000000
21:              00000000
22:              00000000
23:              00000000
24:              00000000
25:              00000000
26:              00000000
27:              00000000
28:              00000000
29:              00000000
2a:              804d525e nt!KiGetTickCount
2b:              804d5354 nt!KiCallbackReturn
2c:              804d54c4 nt!KiSetLowWaitHighThread
2d:              804d5d1e nt!KiDebugService
2e:              804d4dcd nt!KiSystemService
2f:               804d7d50 nt!KiTrap0F
30:              806ba6e4 hal!HalpClockInterrupt
31:              8196946c i8042prt!I8042KeyboardInterruptService (KINTERRUPT 81969430)
32:              804d44c4 nt!KiUnexpectedInterrupt2
33:              804d44ce nt!KiUnexpectedInterrupt3
34:              804d44d8 nt!KiUnexpectedInterrupt4
35:              804d44e2 nt!KiUnexpectedInterrupt5
36:              804d44ec nt!KiUnexpectedInterrupt6
37:              804d44f6 nt!KiUnexpectedInterrupt7
38:              806b5160 hal!HalpProfileInterrupt
39:              81b9b6dc ACPI!ACPIInterruptServiceRoutine (KINTERRUPT 81b9b6a0)
                             portcls!CInterruptSync::Release+0x10 (KINTERRUPT 81a0d5a8)
3a:              81b91dd4 VBoxGuest+0xB60 (KINTERRUPT 81b91d98)
3b:              8196531c USBPORT!USBPORT_InterruptService (KINTERRUPT 819652e0)
3c:              81968044 i8042prt!I8042MouseInterruptService (KINTERRUPT 81968008)
3d:              804d4532 nt!KiUnexpectedInterrupt13
3e:              81b99044 atapi!IdePortInterrupt (KINTERRUPT 81b99008)
3f:               81b992cc atapi!IdePortInterrupt (KINTERRUPT 81b99290)
40:              804d4550 nt!KiUnexpectedInterrupt16
41:              804d455a nt!KiUnexpectedInterrupt17
42:              804d4564 nt!KiUnexpectedInterrupt18
43:              804d456e nt!KiUnexpectedInterrupt19
44:              804d4578 nt!KiUnexpectedInterrupt20
45:              804d4582 nt!KiUnexpectedInterrupt21
46:              804d458c nt!KiUnexpectedInterrupt22
47:              804d4596 nt!KiUnexpectedInterrupt23
48:              804d45a0 nt!KiUnexpectedInterrupt24
49:              804d45aa nt!KiUnexpectedInterrupt25
4a:              804d45b4 nt!KiUnexpectedInterrupt26
4b:              804d45be nt!KiUnexpectedInterrupt27
4c:              804d45c8 nt!KiUnexpectedInterrupt28
4d:              804d45d2 nt!KiUnexpectedInterrupt29
4e:              804d45dc nt!KiUnexpectedInterrupt30
4f:               804d45e6 nt!KiUnexpectedInterrupt31
50:              804d45f0 nt!KiUnexpectedInterrupt32
51:              804d45fa nt!KiUnexpectedInterrupt33
52:              804d4604 nt!KiUnexpectedInterrupt34
53:              804d460e nt!KiUnexpectedInterrupt35
54:              804d4618 nt!KiUnexpectedInterrupt36
55:              804d4622 nt!KiUnexpectedInterrupt37
56:              804d462c nt!KiUnexpectedInterrupt38
57:              804d4636 nt!KiUnexpectedInterrupt39
58:              804d4640 nt!KiUnexpectedInterrupt40
59:              804d464a nt!KiUnexpectedInterrupt41
5a:              804d4654 nt!KiUnexpectedInterrupt42
5b:              804d465e nt!KiUnexpectedInterrupt43
5c:              804d4668 nt!KiUnexpectedInterrupt44
5d:              804d4672 nt!KiUnexpectedInterrupt45
5e:              804d467c nt!KiUnexpectedInterrupt46
5f:               804d4686 nt!KiUnexpectedInterrupt47
60:              804d4690 nt!KiUnexpectedInterrupt48
61:              804d469a nt!KiUnexpectedInterrupt49
62:              804d46a4 nt!KiUnexpectedInterrupt50
63:              804d46ae nt!KiUnexpectedInterrupt51
64:              804d46b8 nt!KiUnexpectedInterrupt52
65:              804d46c2 nt!KiUnexpectedInterrupt53
66:              804d46cc nt!KiUnexpectedInterrupt54
67:              804d46d6 nt!KiUnexpectedInterrupt55
68:              804d46e0 nt!KiUnexpectedInterrupt56
69:              804d46ea nt!KiUnexpectedInterrupt57
6a:              804d46f4 nt!KiUnexpectedInterrupt58
6b:              804d46fe nt!KiUnexpectedInterrupt59
6c:              804d4708 nt!KiUnexpectedInterrupt60
6d:              804d4712 nt!KiUnexpectedInterrupt61
6e:              804d471c nt!KiUnexpectedInterrupt62
6f:               804d4726 nt!KiUnexpectedInterrupt63
70:              804d4730 nt!KiUnexpectedInterrupt64
71:              804d473a nt!KiUnexpectedInterrupt65
72:              804d4744 nt!KiUnexpectedInterrupt66
73:              804d474e nt!KiUnexpectedInterrupt67
74:              804d4758 nt!KiUnexpectedInterrupt68
75:              804d4762 nt!KiUnexpectedInterrupt69
76:              804d476c nt!KiUnexpectedInterrupt70
77:              804d4776 nt!KiUnexpectedInterrupt71
78:              804d4780 nt!KiUnexpectedInterrupt72
79:              804d478a nt!KiUnexpectedInterrupt73
7a:              804d4794 nt!KiUnexpectedInterrupt74
7b:              804d479e nt!KiUnexpectedInterrupt75
7c:              804d47a8 nt!KiUnexpectedInterrupt76
7d:              804d47b2 nt!KiUnexpectedInterrupt77
7e:              804d47bc nt!KiUnexpectedInterrupt78
7f:               804d47c6 nt!KiUnexpectedInterrupt79
80:              804d47d0 nt!KiUnexpectedInterrupt80
81:              804d47da nt!KiUnexpectedInterrupt81
82:              804d47e4 nt!KiUnexpectedInterrupt82
83:              804d47ee nt!KiUnexpectedInterrupt83
84:              804d47f8 nt!KiUnexpectedInterrupt84
85:              804d4802 nt!KiUnexpectedInterrupt85
86:              804d480c nt!KiUnexpectedInterrupt86
87:              804d4816 nt!KiUnexpectedInterrupt87
88:              804d4820 nt!KiUnexpectedInterrupt88
89:              804d482a nt!KiUnexpectedInterrupt89
8a:              804d4834 nt!KiUnexpectedInterrupt90
8b:              804d483e nt!KiUnexpectedInterrupt91
8c:              804d4848 nt!KiUnexpectedInterrupt92
8d:              804d4852 nt!KiUnexpectedInterrupt93
8e:              804d485c nt!KiUnexpectedInterrupt94
8f:               804d4866 nt!KiUnexpectedInterrupt95
90:              804d4870 nt!KiUnexpectedInterrupt96
91:              804d487a nt!KiUnexpectedInterrupt97
92:              804d4884 nt!KiUnexpectedInterrupt98
93:              804d488e nt!KiUnexpectedInterrupt99
94:              804d4898 nt!KiUnexpectedInterrupt100
95:              804d48a2 nt!KiUnexpectedInterrupt101
96:              804d48ac nt!KiUnexpectedInterrupt102
97:              804d48b6 nt!KiUnexpectedInterrupt103
98:              804d48c0 nt!KiUnexpectedInterrupt104
99:              804d48ca nt!KiUnexpectedInterrupt105
9a:              804d48d4 nt!KiUnexpectedInterrupt106
9b:              804d48de nt!KiUnexpectedInterrupt107
9c:              804d48e8 nt!KiUnexpectedInterrupt108
9d:              804d48f2 nt!KiUnexpectedInterrupt109
9e:              804d48fc nt!KiUnexpectedInterrupt110
9f:               804d4906 nt!KiUnexpectedInterrupt111
a0:              804d4910 nt!KiUnexpectedInterrupt112
a1:              804d491a nt!KiUnexpectedInterrupt113
a2:              804d4924 nt!KiUnexpectedInterrupt114
a3:              804d492e nt!KiUnexpectedInterrupt115
a4:              804d4938 nt!KiUnexpectedInterrupt116
a5:              804d4942 nt!KiUnexpectedInterrupt117
a6:              804d494c nt!KiUnexpectedInterrupt118
a7:              804d4956 nt!KiUnexpectedInterrupt119
a8:              804d4960 nt!KiUnexpectedInterrupt120
a9:              804d496a nt!KiUnexpectedInterrupt121
aa:               804d4974 nt!KiUnexpectedInterrupt122
ab:              804d497e nt!KiUnexpectedInterrupt123
ac:               804d4988 nt!KiUnexpectedInterrupt124
ad:              804d4992 nt!KiUnexpectedInterrupt125
ae:              804d499c nt!KiUnexpectedInterrupt126
af:               804d49a6 nt!KiUnexpectedInterrupt127
b0:              804d49b0 nt!KiUnexpectedInterrupt128
b1:              804d49ba nt!KiUnexpectedInterrupt129
b2:              804d49c4 nt!KiUnexpectedInterrupt130
b3:              804d49ce nt!KiUnexpectedInterrupt131
b4:              804d49d8 nt!KiUnexpectedInterrupt132
b5:              804d49e2 nt!KiUnexpectedInterrupt133
b6:              804d49ec nt!KiUnexpectedInterrupt134
b7:              804d49f6 nt!KiUnexpectedInterrupt135
b8:              804d4a00 nt!KiUnexpectedInterrupt136
b9:              804d4a0a nt!KiUnexpectedInterrupt137
ba:              804d4a14 nt!KiUnexpectedInterrupt138
bb:              804d4a1e nt!KiUnexpectedInterrupt139
bc:              804d4a28 nt!KiUnexpectedInterrupt140
bd:              804d4a32 nt!KiUnexpectedInterrupt141
be:              804d4a3c nt!KiUnexpectedInterrupt142
bf:               804d4a46 nt!KiUnexpectedInterrupt143
c0:              804d4a50 nt!KiUnexpectedInterrupt144
c1:              804d4a5a nt!KiUnexpectedInterrupt145
c2:              804d4a64 nt!KiUnexpectedInterrupt146
c3:              804d4a6e nt!KiUnexpectedInterrupt147
c4:              804d4a78 nt!KiUnexpectedInterrupt148
c5:              804d4a82 nt!KiUnexpectedInterrupt149
c6:              804d4a8c nt!KiUnexpectedInterrupt150
c7:              804d4a96 nt!KiUnexpectedInterrupt151
c8:              804d4aa0 nt!KiUnexpectedInterrupt152
c9:              804d4aaa nt!KiUnexpectedInterrupt153
ca:               804d4ab4 nt!KiUnexpectedInterrupt154
cb:              804d4abe nt!KiUnexpectedInterrupt155
cc:               804d4ac8 nt!KiUnexpectedInterrupt156
cd:              804d4ad2 nt!KiUnexpectedInterrupt157
ce:              804d4adc nt!KiUnexpectedInterrupt158
cf:               804d4ae6 nt!KiUnexpectedInterrupt159
d0:              804d4af0 nt!KiUnexpectedInterrupt160
d1:              804d4afa nt!KiUnexpectedInterrupt161
d2:              804d4b04 nt!KiUnexpectedInterrupt162
d3:              804d4b0e nt!KiUnexpectedInterrupt163
d4:              804d4b18 nt!KiUnexpectedInterrupt164
d5:              804d4b22 nt!KiUnexpectedInterrupt165
d6:              804d4b2c nt!KiUnexpectedInterrupt166
d7:              804d4b36 nt!KiUnexpectedInterrupt167
d8:              804d4b40 nt!KiUnexpectedInterrupt168
d9:              804d4b4a nt!KiUnexpectedInterrupt169
da:              804d4b54 nt!KiUnexpectedInterrupt170
db:              804d4b5e nt!KiUnexpectedInterrupt171
dc:              804d4b68 nt!KiUnexpectedInterrupt172
dd:              804d4b72 nt!KiUnexpectedInterrupt173
de:              804d4b7c nt!KiUnexpectedInterrupt174
df:               804d4b86 nt!KiUnexpectedInterrupt175
e0:              804d4b90 nt!KiUnexpectedInterrupt176
e1:              804d4b9a nt!KiUnexpectedInterrupt177
e2:              804d4ba4 nt!KiUnexpectedInterrupt178
e3:              804d4bae nt!KiUnexpectedInterrupt179
e4:              804d4bb8 nt!KiUnexpectedInterrupt180
e5:              804d4bc2 nt!KiUnexpectedInterrupt181
e6:              804d4bcc nt!KiUnexpectedInterrupt182
e7:              804d4bd6 nt!KiUnexpectedInterrupt183
e8:              804d4be0 nt!KiUnexpectedInterrupt184
e9:              804d4bea nt!KiUnexpectedInterrupt185
ea:              804d4bf4 nt!KiUnexpectedInterrupt186
eb:              804d4bfe nt!KiUnexpectedInterrupt187
ec:              804d4c08 nt!KiUnexpectedInterrupt188
ed:              804d4c12 nt!KiUnexpectedInterrupt189
ee:              804d4c19 nt!KiUnexpectedInterrupt190
ef:               804d4c20 nt!KiUnexpectedInterrupt191
f0:               804d4c27 nt!KiUnexpectedInterrupt192
f1:               804d4c2e nt!KiUnexpectedInterrupt193
f2:               804d4c35 nt!KiUnexpectedInterrupt194
f3:               804d4c3c nt!KiUnexpectedInterrupt195
f4:               804d4c43 nt!KiUnexpectedInterrupt196
f5:               804d4c4a nt!KiUnexpectedInterrupt197
f6:               804d4c51 nt!KiUnexpectedInterrupt198
f7:               804d4c58 nt!KiUnexpectedInterrupt199
f8:               804d4c5f nt!KiUnexpectedInterrupt200
f9:               804d4c66 nt!KiUnexpectedInterrupt201
fa:               804d4c6d nt!KiUnexpectedInterrupt202
fb:               804d4c74 nt!KiUnexpectedInterrupt203
fc:               804d4c7b nt!KiUnexpectedInterrupt204
fd:               804d4c82 nt!KiUnexpectedInterrupt205
fe:               804d4c89 nt!KiUnexpectedInterrupt206
ff:                804d4c90 nt!KiUnexpectedInterrupt207

Driver IRP handler Functions Tables:
Userland communicates with kernel device drivers through IRPs(I/O Request Packets). There are different kinds of IRPs that can be passed from userland to a driver. Some of these types of IRPs can be found here (, and in Greg Hoglund's Rootkits book(page 96). Rootkits can hook the IRP handler function tables of other drivers to get their own code to run upon certain IRP events. I found that Stuxnet actually does hook the IRP Function Table. In the below screenshot, we can see 2 code blocks. In the first code block, all 27 entries of the IRP function handler table are overwritten to point to a function that does nothing (hence I named it doNothing). The following block of code does the interesting stuff. It actually hooks 2 entries in the IRP function handler table (IRP_MJ_DEVICE_CONTROL and IRP_MJ_FILE_SYSTEM_CONTROL) and redirects those entries to 2 different functions.

After further thought, I realized why Stuxnet probably doesn’t hook SSDT or IDT. Never versions of Windows have a technology called "Patchguard" built into the kernel. Patch guard prevents exactly what I mentioned above: hooking IDT and SSDT ( Since Stuxnet was meant to run on all the newest versions of Windows, the authors had to abide by Patchguard rules. Obviously, Patchguard does not block IRP function handler hooking, which is a completely legitimate driver behavior, which is why Stuxnet is able to infect newer versions of windows.