Sunday, November 4, 2012

How To Check Export Functions Of Windows 8 NT Kernel By Using Windbg

How To Check Export Functions Of Windows 8 NT Kernel By Using Windbg

by cawan (cawan[at]

on 4/11/2012

In most of the time, PE viewer approach is the most well-known technique in listing the
export functions from the export directory of PE file. For windows kernel, it is common
to use those PE viewers to parse the header of ntoskrnl.exe or ntkrnlpa.exe in getting
the contents under export directory. However, it is really cumbersome when we designing
the shellcode in windbg and keep switching to PE viewer to refer the export function list.
It is getting more annoying when the base address is ASLRed... So, we need to find a way
do everything in windbg, because we are lazy...

First of all, let us parse the PE header of the windows kernel from windbg.

kd> !dh /f nt

           14C machine (i386)
              14 number of sections
5010ADF0 time date stamp Thu Jul 26 10:39:44 2012

          0 file pointer to symbol table
          0 number of symbols
       E0 size of optional header
     122 characteristics
               App can handle >2gb addresses
               32 bit word machine

           10B magic #
        10.10 linker version
    4B3E00 size of code
      CE200 size of initialized data
         2800 size of uninitialized data
     221310 address of entry point
         1000 base of code
         ----- new -----
 00400000 image base
         1000 section alignment
           200 file alignment
               1 subsystem (Native)
          6.02 operating system version
          6.02 image version
         6.02 subsystem version
    58E000 size of image
          800 size of headers
    550165 checksum
00040000 size of stack reserve
00002000 size of stack commit
00100000 size of heap reserve
00001000 size of heap commit
       0  DLL characteristics
   4BA000 [   134CA] address [size] of Export Directory
    20B394 [         DC] address [size] of Import Directory
    538000 [    31A50] address [size] of Resource Directory
              0 [             0] address [size] of Exception Directory
   54C200 [       20F0] address [size] of Security Directory
   56A000 [    23A14] address [size] of Base Relocation Directory
  1C4AA4 [          38] address [size] of Debug Directory
              0 [            0] address [size] of Description Directory
              0 [            0] address [size] of Special Directory
              0 [            0] address [size] of Thread Storage Directory
      14490 [          40] address [size] of Load Configuration Directory
              0 [            0] address [size] of Bound Import Directory
   20B000 [        394] address [size] of Import Address Table Directory
              0 [            0] address [size] of Delay Import Directory
              0 [            0] address [size] of COR20 Header Directory
              0 [            0] address [size] of Reserved Directory

Well, the export directory is at 4ba000 and the size of this structure is 134ca.
Let us check it further

kd> dd nt+4ba000
81327000  00000000 5010adf0 00000000 004bff76
81327010  00000001 00000989 00000987 004ba028
81327020  004bc64c 004bec68 0035e96d 000f7470
81327030  000bc0d2 000ba677 000b2047 000d4a00
81327040  0007b7fb 0007ba2e 000d6718 000d679f
81327050  000ba781 000cee95 00170874 00163eb9
81327060  001708c0 00170100 00163ea4 00163e8f
81327070  00163e71 0017011c 00163e5c 00170174

We need to get the list of export functions name, from PE specification, we have this

    public UInt32 Characteristics;
    public UInt32 TimeDateStamp;
    public UInt16 MajorVersion;
    public UInt16 MinorVersion;
    public UInt32 Name;
    public UInt32 Base;
    public UInt32 NumberOfFunctions;
    public UInt32 NumberOfNames;
    public UInt32 AddressOfFunctions;
    public UInt32 AddressOfNames;
    public UInt32 AddressOfNameOrdinals;

So, from IMAGE_EXPORT_DIRECTORY structure, AddressOfNames at offset 0x20 (32 in decimal)
has what we are looking for. Let us check address 0x004bc64c.

kd> dd nt+004bc64c
8132964c  004bff83 004bff95 004bffad 004bffcc
8132965c  004bffe0 004bfff3 004c0005 004c0012
8132966c  004c0031 004c003d 004c005b 004c0066
8132967c  004c0073 004c007f 004c008d 004c00a2
8132968c  004c00c6 004c00d3 004c00e2 004c00f2
8132969c  004c0104 004c0111 004c0123 004c0133
813296ac  004c014a 004c0169 004c018b 004c01a1
813296bc  004c01b7 004c01cc 004c01df 004c01f4

Those are pointers to the export functions name. Verify it.

kd> db nt+004bff83
8132cf83  41 6c 70 63 47 65 74 48-65 61 64 65 72 53 69 7a  AlpcGetHeaderSiz
8132cf93  65 00 41 6c 70 63 47 65-74 4d 65 73 73 61 67 65  e.AlpcGetMessage
8132cfa3  41 74 74 72 69 62 75 74-65 00 41 6c 70 63 49 6e  Attribute.AlpcIn
8132cfb3  69 74 69 61 6c 69 7a 65-4d 65 73 73 61 67 65 41  itializeMessageA
8132cfc3  74 74 72 69 62 75 74 65-00 42 67 6b 44 69 73 70  ttribute.BgkDisp
8132cfd3  6c 61 79 43 68 61 72 61-63 74 65 72 00 42 67 6b  layCharacter.Bgk
8132cfe3  47 65 74 43 6f 6e 73 6f-6c 65 53 74 61 74 65 00  GetConsoleState.
8132cff3  42 67 6b 47 65 74 43 75-72 73 6f 72 53 74 61 74  BgkGetCursorStat

There are a lot of strings starting from 004bff83. Check the first 2 items.

kd> da nt+004bff83
8132cf83  "AlpcGetHeaderSize"
kd> da nt+004bff95
8132cf95  "AlpcGetMessageAttribute"

By referring the IMAGE_EXPORT_DIRECTORY structure again, the NumberOfNames at offset 0x18
shows the number of export functions in the nt kernel. So, there are 987 export functions
in the nt kernel. We can write a script to dump all the exported functions now.

8132cf83  "AlpcGetHeaderSize"
8132cf95  "AlpcGetMessageAttribute"
8132cfad  "AlpcInitializeMessageAttribute"
8132cfcc  "BgkDisplayCharacter"
8132cfe0  "BgkGetConsoleState"
8132cff3  "BgkGetCursorState"
8132d005  "BgkSetCursor"
8132d012  "CcAddDirtyPagesToExternalCache"
8132d031  "CcCanIWrite"
8132d03d  "CcCoherencyFlushAndPurgeCache"
8132d05b  "CcCopyRead"
8132d066  "CcCopyReadEx"
8132d073  "CcCopyWrite"
8132d07f  "CcCopyWriteEx"
8132d08d  "CcCopyWriteWontFlush"
8132d0a2  "CcDeductDirtyPagesFromExternalCa"
8132d0c6  "CcDeferWrite"
8132d0d3  "CcFastCopyRead"
8132d0e2  "CcFastCopyWrite"
8132d0f2  "CcFastMdlReadWait"
8132d104  "CcFlushCache"
8132d111  "CcFlushCacheToLsn"
8132d123  "CcGetDirtyPages"
8132d133  "CcGetFileObjectFromBcb"
8132d14a  "CcGetFileObjectFromSectionPtrs"
8132d169  "CcGetFileObjectFromSectionPtrsRe"
8132d18b  "CcGetFlushedValidData"
8132d1a1  "CcGetLsnForFileObject"
8132d1b7  "CcInitializeCacheMap"
8132d1cc  "CcIsThereDirtyData"
8132d1df  "CcIsThereDirtyDataEx"
8132d1f4  "CcIsThereDirtyLoggedPages"
8132d20e  "CcMapData"
8132d218  "CcMdlRead"
8132d222  "CcMdlReadComplete"
8132d234  "CcMdlWriteAbort"
8132d244  "CcMdlWriteComplete"
8132d257  "CcPinMappedData"
8132d267  "CcPinRead"
8132d271  "CcPrepareMdlWrite"
8132d283  "CcPreparePinWrite"
8132d295  "CcPurgeCacheSection"
8132d2a9  "CcRegisterExternalCache"
8132d2c1  "CcRemapBcb"
8132d2cc  "CcRepinBcb"
8132d2d7  "CcScheduleReadAhead"
8132d2eb  "CcScheduleReadAheadEx"

How about if we need to know that an function name is included in the export functions list
or not ? Simple, let's say we need to know HalDispatchTable is in the export functions list
or not...

8132fed0  "HalDispatchTable"
.shell: Process exited

Yes, it is included. How about we want to dump the list of native api of windows 8 ? Simple.

81338eac  "ZwAccessCheckAndAuditAlarm"
81338ec7  "ZwAddBootEntry"
81338ed6  "ZwAddDriverEntry"
81338ee7  "ZwAdjustPrivilegesToken"
81338eff  "ZwAlertThread"
81338f0d  "ZwAllocateLocallyUniqueId"
81338f27  "ZwAllocateVirtualMemory"
81338f3f  "ZwAlpcAcceptConnectPort"
81338f57  "ZwAlpcCancelMessage"
81338f6b  "ZwAlpcConnectPort"
81338f7d  "ZwAlpcConnectPortEx"
81338f91  "ZwAlpcCreatePort"
81338fa2  "ZwAlpcCreatePortSection"
81338fba  "ZwAlpcCreateResourceReserve"
81338fd6  "ZwAlpcCreateSectionView"
81338fee  "ZwAlpcCreateSecurityContext"
8133900a  "ZwAlpcDeletePortSection"
81339022  "ZwAlpcDeleteResourceReserve"
8133903e  "ZwAlpcDeleteSectionView"
81339056  "ZwAlpcDeleteSecurityContext"
81339072  "ZwAlpcDisconnectPort"
81339087  "ZwAlpcQueryInformation"
8133909e  "ZwAlpcSendWaitReceivePort"
813390b8  "ZwAlpcSetInformation"
813390cd  "ZwAssignProcessToJobObject"
813390e8  "ZwCancelIoFile"
813390f7  "ZwCancelTimer"
81339105  "ZwClearEvent"
81339112  "ZwClose"
8133911a  "ZwCloseObjectAuditAlarm"
81339132  "ZwCommitComplete"
81339143  "ZwCommitEnlistment"
81339156  "ZwCommitTransaction"
8133916a  "ZwConnectPort"
81339178  "ZwCreateDirectoryObject"
81339190  "ZwCreateEnlistment"
813391a3  "ZwCreateEvent"
813391b1  "ZwCreateFile"
813391be  "ZwCreateIoCompletion"
813391d3  "ZwCreateJobObject"
813391e5  "ZwCreateKey"
813391f1  "ZwCreateKeyTransacted"
81339207  "ZwCreateResourceManager"
8133921f  "ZwCreateSection"
8133922f  "ZwCreateSymbolicLinkObject"
8133924a  "ZwCreateTimer"
81339258  "ZwCreateTransaction"
8133926c  "ZwCreateTransactionManager"
81339287  "ZwCreateWnfStateName"
8133929c  "ZwDeleteBootEntry"
813392ae  "ZwDeleteDriverEntry"
813392c2  "ZwDeleteFile"
813392cf  "ZwDeleteKey"
813392db  "ZwDeleteValueKey"
813392ec  "ZwDeleteWnfStateData"
81339301  "ZwDeleteWnfStateName"
81339316  "ZwDeviceIoControlFile"
8133932c  "ZwDisplayString"
8133933c  "ZwDuplicateObject"
8133934e  "ZwDuplicateToken"
8133935f  "ZwEnumerateBootEntries"
81339376  "ZwEnumerateDriverEntries"
8133938f  "ZwEnumerateKey"
8133939e  "ZwEnumerateTransactionObject"
813393bb  "ZwEnumerateValueKey"
813393cf  "ZwFlushBuffersFile"
813393e2  "ZwFlushBuffersFileEx"
813393f7  "ZwFlushInstructionCache"
8133940f  "ZwFlushKey"
8133941a  "ZwFlushVirtualMemory"
8133942f  "ZwFreeVirtualMemory"
81339443  "ZwFsControlFile"
81339453  "ZwGetNotificationResourceManager"
81339474  "ZwImpersonateAnonymousToken"
81339490  "ZwInitiatePowerAction"
813394a6  "ZwIsProcessInJob"
813394b7  "ZwLoadDriver"
813394c4  "ZwLoadKey"
813394ce  "ZwLoadKeyEx"
813394da  "ZwLockFile"
813394e5  "ZwLockProductActivationKeys"
81339501  "ZwMakeTemporaryObject"
81339517  "ZwMapViewOfSection"
8133952a  "ZwModifyBootEntry"
8133953c  "ZwModifyDriverEntry"
81339550  "ZwNotifyChangeKey"
81339562  "ZwNotifyChangeSession"
81339578  "ZwOpenDirectoryObject"
8133958e  "ZwOpenEnlistment"
8133959f  "ZwOpenEvent"
813395ab  "ZwOpenFile"
813395b6  "ZwOpenJobObject"
813395c6  "ZwOpenKey"
813395d0  "ZwOpenKeyEx"
813395dc  "ZwOpenKeyTransacted"
813395f0  "ZwOpenKeyTransactedEx"
81339606  "ZwOpenProcess"
81339614  "ZwOpenProcessToken"
81339627  "ZwOpenProcessTokenEx"
8133963c  "ZwOpenResourceManager"
81339652  "ZwOpenSection"
81339660  "ZwOpenSession"
8133966e  "ZwOpenSymbolicLinkObject"
81339687  "ZwOpenThread"
81339694  "ZwOpenThreadToken"
813396a6  "ZwOpenThreadTokenEx"
813396ba  "ZwOpenTimer"
813396c6  "ZwOpenTransaction"
813396d8  "ZwOpenTransactionManager"
813396f1  "ZwPowerInformation"
81339704  "ZwPrePrepareComplete"
81339719  "ZwPrePrepareEnlistment"
81339730  "ZwPrepareComplete"
81339742  "ZwPrepareEnlistment"
81339756  "ZwPropagationComplete"
8133976c  "ZwPropagationFailed"
81339780  "ZwPulseEvent"
8133978d  "ZwQueryBootEntryOrder"
813397a3  "ZwQueryBootOptions"
813397b6  "ZwQueryDefaultLocale"
813397cb  "ZwQueryDefaultUILanguage"
813397e4  "ZwQueryDirectoryFile"
813397f9  "ZwQueryDirectoryObject"
81339810  "ZwQueryDriverEntryOrder"
81339828  "ZwQueryEaFile"
81339836  "ZwQueryFullAttributesFile"
81339850  "ZwQueryInformationEnlistment"
8133986d  "ZwQueryInformationFile"
81339884  "ZwQueryInformationJobObject"
813398a0  "ZwQueryInformationProcess"
813398ba  "ZwQueryInformationResourceManage"
813398dc  "ZwQueryInformationThread"
813398f5  "ZwQueryInformationToken"
8133990d  "ZwQueryInformationTransaction"
8133992b  "ZwQueryInformationTransactionMan"
81339950  "ZwQueryInstallUILanguage"
81339969  "ZwQueryKey"
81339974  "ZwQueryLicenseValue"
81339988  "ZwQueryObject"
81339996  "ZwQueryQuotaInformationFile"
813399b2  "ZwQuerySection"
813399c1  "ZwQuerySecurityAttributesToken"
813399e0  "ZwQuerySecurityObject"
813399f6  "ZwQuerySymbolicLinkObject"
81339a10  "ZwQuerySystemEnvironmentValueEx"
81339a30  "ZwQuerySystemInformation"
81339a49  "ZwQueryValueKey"
81339a59  "ZwQueryVirtualMemory"
81339a6e  "ZwQueryVolumeInformationFile"
81339a8b  "ZwQueryWnfStateData"
81339a9f  "ZwQueryWnfStateNameInformation"
81339abe  "ZwReadFile"
81339ac9  "ZwReadOnlyEnlistment"
81339ade  "ZwRecoverEnlistment"
81339af2  "ZwRecoverResourceManager"
81339b0b  "ZwRecoverTransactionManager"
81339b27  "ZwRemoveIoCompletion"
81339b3c  "ZwRemoveIoCompletionEx"
81339b53  "ZwRenameKey"
81339b5f  "ZwReplaceKey"
81339b6c  "ZwRequestPort"
81339b7a  "ZwRequestWaitReplyPort"
81339b91  "ZwResetEvent"
81339b9e  "ZwRestoreKey"
81339bab  "ZwRollbackComplete"
81339bbe  "ZwRollbackEnlistment"
81339bd3  "ZwRollbackTransaction"
81339be9  "ZwSaveKey"
81339bf3  "ZwSaveKeyEx"
81339bff  "ZwSecureConnectPort"
81339c13  "ZwSetBootEntryOrder"
81339c27  "ZwSetBootOptions"
81339c38  "ZwSetCachedSigningLevel"
81339c50  "ZwSetDefaultLocale"
81339c63  "ZwSetDefaultUILanguage"
81339c7a  "ZwSetDriverEntryOrder"
81339c90  "ZwSetEaFile"
81339c9c  "ZwSetEvent"
81339ca7  "ZwSetInformationEnlistment"
81339cc2  "ZwSetInformationFile"
81339cd7  "ZwSetInformationJobObject"
81339cf1  "ZwSetInformationKey"
81339d05  "ZwSetInformationObject"
81339d1c  "ZwSetInformationProcess"
81339d34  "ZwSetInformationResourceManager"
81339d54  "ZwSetInformationThread"
81339d6b  "ZwSetInformationToken"
81339d81  "ZwSetInformationTransaction"
81339d9d  "ZwSetInformationVirtualMemory"
81339dbb  "ZwSetQuotaInformationFile"
81339dd5  "ZwSetSecurityObject"
81339de9  "ZwSetSystemEnvironmentValueEx"
81339e07  "ZwSetSystemInformation"
81339e1e  "ZwSetSystemTime"
81339e2e  "ZwSetTimer"
81339e39  "ZwSetTimerEx"
81339e46  "ZwSetValueKey"
81339e54  "ZwSetVolumeInformationFile"
81339e6f  "ZwTerminateJobObject"
81339e84  "ZwTerminateProcess"
81339e97  "ZwTraceEvent"
81339ea4  "ZwTranslateFilePath"
81339eb8  "ZwUnloadDriver"
81339ec7  "ZwUnloadKey"
81339ed3  "ZwUnloadKeyEx"
81339ee1  "ZwUnlockFile"
81339eee  "ZwUnlockVirtualMemory"
81339f04  "ZwUnmapViewOfSection"
81339f19  "ZwUpdateWnfStateData"
81339f2e  "ZwWaitForMultipleObjects"
81339f47  "ZwWaitForSingleObject"
81339f5d  "ZwWriteFile"
81339f69  "ZwYieldExecution"
.shell: Process exited

Yes, we get the complete list. This technique is really helpful when I did memory analysis
of kernel pool to build a kernel shellcode testing platform in windbg.

pdf version:

No comments:

Post a Comment