Quantcast
Channel: windows deep internals
Viewing all 265 articles
Browse latest View live

afd endpoints owner

$
0
0
Alex as usually made perfect work to bypass even paranoid EDRs
The main problem is detection of duplicated sockets. There is a hint however:
all ownership of the socket still belongs to the original creator – even when the creator exists (and actually, because Netio.sys is still referencing the original EPROCESS, the creator and the PID become “zombies” and leak resources).
o`k, reason is true, but reference holds by afd.sys. Lets see why
We need disasm 2 functions to write simple script. First - we need back offset from afd!AfdEndpointListHead to read endpoint. It can be extracted from AfdIsAddressInUse:
  mov     [rsp+arg_0], rbx
  mov     [rsp+arg_8], rbp
  mov     [rsp+arg_10], rsi
  push    rdi
  sub     rsp, 30h
  mov     rsi, rcx
  xor     ebx, ebx
  mov     rcx, cs:AfdGlobalData
  call    cs:__imp_ExEnterCriticalRegionAndAcquireResourceShared
  nop     dword ptr [rax+rax+00h]
  mov     rdi, cs:AfdEndpointListHead
  lea     rbp, AfdEndpointListHead
  jmp     short loc_1C003C0D3
; ---------------------------------------------------------------------------

loc_1C003C054:                          ; CODE XREF: AfdIsAddressInUse+BE
  lea     rdx, [rdi-120h]
...
loc_1C003C0D3
  cmp     rdi, rbp
  jnz     loc_1C003C054


Then we need offset to EPROCESS - it can be extracted for example from AfdFreeEndpointResources:

  mov     rcx, [rbx+28h]
  mov     edx, 200h
  call    cs:__imp_PsReturnPoolQuota
  nop     dword ptr [rax+rax+00h]
  mov     rcx, [rbx+28h]  ; Object
  call    cs:__imp_ObfDereferenceObject


Now we have all parts of this puzzle. Let`s see what we can do in windbg


kd> ? afd!AfdEndpointListHead
Evaluate expression: -8772979362448 = fffff805`61ae7570
kd> r $t0 =  0xfffff805`61ae7570; .for( r $t1 = poi(@$t0) ;  (@$t1 != @$t0) ; r $t1 = poi(@$t1) ) { !process poi(@$t1-120+28) 0 }

PROCESS ffffe50f664e0080
    SessionId: 1  Cid: 0bf4    Peb: 8c93382000  ParentCid: 02d8
    DirBase: 6ceb6000  ObjectTable: ffff818ffd8744c0  HandleCount:
    Image: SkypeApp.exe

...

kernel pte in windows 10 64bit

$
0
0
Quarantine is a good time to re-read some old but useful papers and check if you can catch trick with making KUSER_SHARED_DATA writable againSo lets see what we need:
  • some logic to extract PTE base from MiGetPteAddress
  • primitive to check if some address is valid - I used MmIsAddressValid
  • primitive to read page from kernel memory
Start with some system info:
pSystemRangeStart: FFFF800000000000
PTE base address: FFFF880000000000
PTE mask: 7FFFFFFFF8
PTE shift: 9

Do some calculation
function to get offset to PTE looks like:
return (address >> 9) & 0x7FFFFFFFF8;

for pSystemRangeStart PTE will be
4000000000 + pte_base = FFFF884000000000
You may notice that this address located above pte_base

for last available address in system FFFFFFFFFFFFFFFF PTE will be
7FFFFFFFF8 + pte_base = FFFF887FFFFFFFF8

Also we need some inverse function to convert from PTE to page address. First we need sub pte_base, then divide on sizeof(MMPTE_HARDWARE) and then multiply to size of page. And add some base address. Try to calculate this base for example for PTE of pSystemRangeStart FFFF884000000000:
(FFFF884000000000 - FFFF880000000000) / sizeof(MMPTE_HARDWARE) * 0x1000 = 800000000000

Our base is FFFF800000000000 (value of pSystemRangeStart) - 800000000000 = FFFF000000000000

Notice that this base does not match with pSystemRangeStart
So our inverse function may looks like:
return 0xFFFF000000000000 + (ptr_addr - pte_base) / sizeof(MMPTE_HARDWARE) * 0x1000;

Ok, it seems that we have all puzzle pieces and can scan all PTE from FFFF884000000000 to FFFF887FFFFFFFF8. Yes, all 0x4000000000 bytes - 256Gb. Sure, we can wait for results before retirement

Lets think if there are some ways to reduce amount of memory for scanning
You may notice that all of PTE not nailed in the middle of nothing but occupy some memory. And this memory also must have some valid PTE - lets call it secondary PTE. And if some page for this secondary PTE is not valid we can skip 512 * 0x1000 = 0x200000 PTE. So I just wrote some code to check first this secondary PTE and load only PTE located in valid memory


Results

On my work machine it tooks only several seconds to scan all PTE.
Readed C75 pages for secondary PTE
183843 pages for PTE
0 BSODs

Good news - yes, you can detect writable KUSER_SHARED_DATA. You could do it with reading of just 8 bytes if you know PTE base, mask and shift

Bad news - there are lots of writable pages without NX bit. On clear windows 10 build 19624 with 2Gb of RAM there are 4760 such pages and only 2 mapped to some drivers:
 [352] FFFFF80274360000 NX 0 -> \SystemRoot\System32\drivers\E1G6032E.sys
 [383] FFFFF8027437F000 NX 0 -> \SystemRoot\System32\drivers\E1G6032E.sys


On my work machines with 32Gb of RAM there are already 130698 such pages. I don`t know who allocated them and for what, but their very presence makes a threats detection virtually impossibly

COMPlus_ETWEnabled

$
0
0
There is nice trick to hide that your .NET assemblies does not have ETW logging
Lets see if we can detect this not from environment vars
ETW logging inited in mscorwks.dll!CEtwTracer::Register:


 lea     rcx, aEtwenabled               ; "ETWEnabled"
 mov     [rsp+168h+var_148], 0
 lea     r9d, [rdx+1]
 lea     r8d, [rdx+7]
 call    ?GetConfigDWORD@EEConfig@@SAKPEBGKKHW4ConfigSearch@1@@Z
 test    eax, eax
 jz      loc_6427F59447D ; skip

loc_6427F5943B8:
 lea     rcx, aAdvapi32_dll_3           ; "advapi32.dll"
 call    cs:__imp_GetModuleHandleW
 test    rax, rax
 mov     cs:?m_hModule@CEtwTracer@@0PEAUHINSTANCE__@@EA, rax ; HINSTANCE__ * CEtwTracer::m_hModule
 jz      loc_6427F594473
 lea     rdx, aRegistertraceg           ; "RegisterTraceGuidsW"
 mov     rcx, rax                       ; hModule
 call    cs:__imp_GetProcAddress
 mov     rcx, cs:?m_hModule@CEtwTracer@@0PEAUHINSTANCE__@@EA ; hModule
 lea     rdx, aUnregistertrac           ; "UnregisterTraceGuids"
 mov     cs:?g_pufnRegisterTraceGuids@@3P6AKP6AKW4WMIDPREQUESTCODE@@PEAXPEAK1@Z1PEBU_GUID@@KPEAU_TRACE_GUID_REGISTRATION@@PEBG6PEA_K@ZEA, rax ; ulong (*g_pufnRegisterTraceGuids)(ulong (*)(WMIDPREQUESTCODE,void *,ulong *,void *),void *,_GUID const *,ulong,_TRACE_GUID_REGISTRATION *,ushort const *,ushort const *,unsigned __int64 *)
 call    cs:__imp_GetProcAddress
 mov     rcx, cs:?m_hModule@CEtwTracer@@0PEAUHINSTANCE__@@EA ; hModule
 lea     rdx, aGettracelogger           ; "GetTraceLoggerHandle"
 mov     cs:?g_pufnUnregisterTraceGuids@@3P6AK_K@ZEA, rax ; ulong (*g_pufnUnregisterTraceGuids)(unsigned __int64)
 call    cs:__imp_GetProcAddress
 mov     rcx, cs:?m_hModule@CEtwTracer@@0PEAUHINSTANCE__@@EA ; hModule
 lea     rdx, aGettraceenable           ; "GetTraceEnableLevel"
 mov     cs:?g_pufnGetTraceLoggerHandle@@3P6A_KPEAX@ZEA, rax ; unsigned __int64 (*g_pufnGetTraceLoggerHandle)(void *)
 call    cs:__imp_GetProcAddress
 mov     rcx, cs:?m_hModule@CEtwTracer@@0PEAUHINSTANCE__@@EA ; hModule
 lea     rdx, aGettraceenab_1           ; "GetTraceEnableFlags"
 mov     cs:?g_pufnGetTraceEnableLevel@@3P6AE_K@ZEA, rax ; uchar (*g_pufnGetTraceEnableLevel)(unsigned __int64)
 call    cs:__imp_GetProcAddress
 mov     rcx, cs:?m_hModule@CEtwTracer@@0PEAUHINSTANCE__@@EA ; hModule
 lea     rdx, aTraceevent               ; "TraceEvent"
 mov     cs:?g_pufnGetTraceEnableFlags@@3P6AK_K@ZEA, rax ; ulong (*g_pufnGetTraceEnableFlags)(unsigned __int64)
 call    cs:__imp_GetProcAddress
 mov     cs:?g_pufnTraceEvent@@3P6AK_KPEAU_EVENT_TRACE_HEADER@@@ZEA, rax ; ulong (*g_pufnTraceEvent)(unsigned __int64,_EVENT_TRACE_HEADER *)


as you can see if ETW logging was disables all related ETW pfns will not be inited. So it`s enough to check in debugger values of
  • g_pufnUnregisterTraceGuids
  • g_pufnGetTraceEnableLevel
  • g_pufnTraceEvent
  • g_pufnGetTraceEnableFlags
  • g_pufnGetTraceLoggerHandle
  • g_pufnRegisterTraceGuids
If they contains NULL or some trash not from advapi32.dll - logging does not work

undocumented env vars in mscorwks.dll

$
0
0
There are lots of env vars with prefix COMPlus_
So lets see only not presented in this document

Main function constructing name of env var is ?EnvGetString@REGUTIL@@SAPEAGPEBGH@Z called from:
  • ?UnsafeGetConfigDWORD@@YAKPEBGK@Z
  • ?GetConfigDWORD@EEConfig@@SAKPEBGKKHW4ConfigSearch@1@@Z
  • ?GetConfigString@EEConfig@@SAJPEBGPEAPEAGHW4ConfigSearch@1@@Z
  • ?init@ConfigDWORD@@AEAAXPEAGK@Z
  • ?GetConfigString@REGUTIL@@SAPEAGPEBGHW4CORConfigLevel@1@@Z
  • ?GetConfigDWORD@REGUTIL@@SAKPEBGKW4CORConfigLevel@1@H@Z

and perhaps from several thousand more places so I wrote some script to collect names and filter out known. Final list is:
  • AllowStrongNameBypass - DWORD
  • AssemblyUsageLogImpersonateUser - DWORD
  • BBSweep - DWORD
  • BreakOnAV - DWORD
  • bypassTrustedAppStrongNames - DWORD
  • Cor_Enable_Profiling - DWORD
  • DbgJITDebugLaunchSetting - DWORD
  • DbgManagedDebugger - string
  • DbgThreadCreateOption - DWORD
  • DisableDoubleMapping - DWORD
  • DisableSecurityTransparency - DWORD
  • EagerWatsonBuckets - DWORD
  • EHGolden - DWORD
  • JumpStubReserve - DWORD
  • legacyAssemblyProvidedEvidence - DWORD
  • legacyHMACWarning - DWORD
  • legacyMyComputerZone - DWORD
  • legacyV1CASPolicy - DWORD
  • LOPFriendlyFrames - DWORD
  • MD_TrackColDesMisses - DWORD
  • MemoryReport - DWORD
  • MemoryReportBreakOnContext - string
  • MemoryReportOutput - string
  • MemoryReportStackFrames - DWORD
  • MemoryReportSweepInterval - DWORD
  • MultiDomainHostGAC - DWORD
  • NGenAllowMsiInstall - DWORD
  • PrecodeInCodeHeap - DWORD
  • ReaderWriterLock_UseFixedIdGeneration - DWORD
  • ShowMetaDataAccess - DWORD
  • StressLoadThreadCount - DWORD
  • useEnUSLcidWithComInvoke - DWORD
  • UseFileMappingForByteArrays - DWORD
  • UseMethodDataCacheInFindDispatchImpl - DWORD
  • UsePcRel32Calls - DWORD

arm64 pc-relative literals

$
0
0
Lets see for example non-exported function function SepInitializeCodeIntegrity from arm64 kernel:
  STP             X19, X20, [SP,#-0x20+var_10]!
  STP             X21, X22, [SP,#0x10+var_s0]
  STR             X23, [SP,#0x10+var_s10]
  STP             X29, X30, [SP,#0x10+var_20]!
  MOV             X29, SP
  ADRP            X8, #SeCiCallbacks@PAGE
  ADD             X20, X8, #SeCiCallbacks@PAGEOFF
  ADD             X8, X20, #4
  MOV             W21, #6
  ADD             X9, X8, #0xC0

loc_1406A9C90                           ; CODE XREF: SepInitializeCodeIntegrity+30 j
  STP             XZR, XZR, [X8],#0x10
  CMP             X8, X9
  B.NE            loc_1406A9C90
  STR             WZR, [X8]
  MOV             W9, #0xD0
  LDR             X8, =0xA000007

qword_1406A9D30 DCQ 0xA000007


As you can see all DWORD constants under arm64 stored in some place after function, so you sure can find address 1406A9D30 but how to find function which using this constant? Instruction ldr can be located in range of 1Mb from this address

Right answer - we can use .pdata section. Under arm64 data in this section looks like:
struct pdata_item
{
  DWORD off;
  DWORD seh_off;
};

and they already sorted by offset, so we can use some kind of binary search - for example I used std::lower_bound
So algo for search by constants in arm64 code is simple:
  • find address of some constant in desired section
  • find address of function from .pdata section
  • disasm this function
  • PROFIT

sve/sve2 instructions for arm64

$
0
0
Today I finished adding of sve/sve2 instructions to my pet-project armpatched
I used as reference ISA_A64_xml_futureA-2019-09_OPT.pdf
Sure code is full of bugs, incomplete and has terrible style - all what you can expect from 7KLOC on plain C
Known problems:
  • since my main goal was code analysis disasm strings looks not very good - for example I totally emit register size suffixes (although size storing in op_reg.sz)
  • I don`t know for what used "fields" so they filled in voluntary random order
Zx registers marked as floating point with op_reg.fp == 2 and Px registers with op_reg.fp == 3
Code was tested on all possible instructions and looks like it does not crash. Bcs it seems that some instructions use floating point you must use KeSaveFloatingPointState/KeRestoreFloatingPointState in case of kernel mode

search references in arm64 code

$
0
0
Let's assume that you want to find address of non-exported CrashdmpCallTable in kernel. Usual old school way is to find unicode string "\SystemRoot\System32\Drivers\crashdmp.sys" and then to find reference to in .text section - if you are lucky enough this will be somewhere in middle of function IopLoadCrashdumpDriver. But on arm64 loading of address splitted in pair of instructions and even worse - values depends from address of instruction. Let`s see how it looks:

.text:00000001401AF700 6A 01 00 90     ADRP  X10, #aSystemrootSy_0@PAGE ; "\\SystemRoot\\System32\\Drivers\\crashd"...
.text:00000001401AF704 48 C1 09 91     ADD   X8, X10, #aSystemrootSy_0@PAGEOFF ; "\\SystemRoot\\System32\\Drivers\\crashd"...


Output from cmdline disasm for each of opcodes:
armpatched.exe 6A010090
Disassembled: adrp x10, 2c000

        This instruction is AD_INSTR_ADRP and is part of group AD_G_DataProcessingImmediate
        This instruction has 4 decode fields (from left to right):
                0x1, 0, 0xb, 0xa
        This instruction has 2 operands (from left to right):
                This operand is of type AD_OP_REG
                        Register: x10 size 40
                This operand is of type AD_OP_IMM
                        Immediate type: AD_IMM_ULONG
                        Value: 0x2c000

and
armpatched.exe 48C10991
Disassembled: add x8, x10, #0x270

        This instruction is AD_INSTR_ADD and is part of group AD_G_DataProcessingImmediate
        This instruction has 7 decode fields (from left to right):
                0x1, 0, 0, 0, 0x270, 0xa, 0x8
        This instruction has 3 operands (from left to right):
                This operand is of type AD_OP_REG
                        Register: x8 size 40
                This operand is of type AD_OP_REG
                        Register: x10 size 40
                This operand is of type AD_OP_IMM
                        Immediate type: AD_IMM_ULONG
                        Value: 0x270


What are the options?

Sure you can try to disasm whole .text section and hope that sooner or later the right piece of code will be found
Or perhaps add some optimization. First thing to notice is that you always know address of instruction in arm64. So next thing is to check if some instruction is ADRP or ADD - you can use some bitmasks magic for this (see file aarch64-tbl.h from GNU binutils). And only when you have the right instructions you can use disassembler to extract immediate values. So algo looks like
  • make array of addresses for each RXX register with NULL as initial value
  • check with bitmask for adrp or add current opcode
  • disasm instruction
  • store for ADRP address using register as index
  • for ADD check if previous ADRP was not too far - bcs it can be in some previous function, so I add check for 40 bytes
  • if address from ADRP + current imm value from ADD == your reference - stop
I commited today this logic in my armpatched GitHub - see class xref_finder in file hack.h

Some results. Reference to string was found at offset 1AE704 from start of .text section - this is 0x6B9C1 opcodes. Disasm was called only 0xB3C1 times - 0x273C for ADRP and 0x7C3B for ADD

what`s wrong with Etw

$
0
0
Disclaimer: as I am aware that the given code examples can be dangerous for Etw-based EDR products - all code was made for least popular version of windows - for arm64

Let's assume that we have some application that wants to hide its activity from trace logs - not necessary evil or malicious, for example just to hide used algos or bit paranoid like crypto-wallet. Lets see how can it achieve this (I have no desire to consider trivial cases like removing records from eventlog)

Semiofficial ways

  1. Sure all you readed about COMPlus_ETWEnabled but there is also promising COMPlus_ETWFlags 
  2. You can switch off etw tracing for services.exe with registry key TracingDisabled in Software\Microsoft\Windows NT\CurrentVersion\Tracing\SCM\Regular
  3. And the same for rpcrt4.dll with registry key ExtErrorInformation in HKLM\Software\Policies\Microsoft\Windows NT\Rpc
Actually there are virtually countless ways to do it. And many perhaps not documented bcs was written in Ms by some poor intern who was kicked out in the cold after another review 10+ years ago. I struggled with temptation to make clickbait caption like "99% of windows dlls can disable etw logs" but it`s close to the truth

Patching

  1. Yes, good old IAT hijacking for functions like EtwEventWrite works fine even though they can be easily detected
  2. Splicing of Etw functions. Almost same as above
  3. Some more sophisticated patching of internal wpp structures. For example you can find Etw handles and zero them. Or zero trace level. Or EventsEnableBits. PoC to find etw handles in rpcrt4.dll

Kernel mode

Who immediately remembered InfinityHook? Btw Ms removed pfn GetCpuClock from WMI_LOGGER_CONTEXT since est. build 18963
There are much more kernel sensors. PoC to find CmpTraceRoutine - and suddenly etw events from registry stop generating. Sure it`s not big problem if your product has some code registered with CmRegisterCallback

Conclusion

Etw is unreasonably complex and fragile technology and can easily be broken in too many places

_TlgProvider_t

$
0
0
let's continue to dissect ETW and consider one of the many usermode tracing structures - _TlgProvider_t. It is even officially documented in platform sdk in header TraceLoggingProvider.h (sample of using):
struct _TlgProvider_t
{
    UINT32 LevelPlus1;
    UINT16 const UNALIGNED* ProviderMetadataPtr; // Points to the RemainingSize member of provider metadata.
    ULONGLONG KeywordAny;
    ULONGLONG KeywordAll;
    REGHANDLE RegHandle;
    TLG_PENABLECALLBACK EnableCallback;
    PVOID CallbackContext;
};


purpose of the fields is pretty obvious except RegHandle - it's not real HANDLE but some structure with address to ETW_REGISTRATION_ENTRY.

How we can find it? Field ProviderMetadataPtr is pointer to _TlgProviderMetadata_t:
struct _TlgProviderMetadata_t
{
    UINT8 Type; // = _TlgBlobProvider3
    GUID ProviderId;
#define _TLG_PROVIDER_METADATA_PREAMBLE 16 // = sizeof(ProviderId)
    UINT16 RemainingSize; // = sizeof(RemainingSize + ProviderName)
    /*
    char ProviderName[sizeof("providerName")]; // UTF-8 nul-terminated provider name
    for each additional chunk of metadata {
        UINT16 ChunkSize;
        UINT8 ChunkType;
        UINT8 ChunkData[ChunkSize - 3];
    }
    */
};

actually it points to _TlgProviderMetadata_t.RemainingSize. Algo is simple - if you know provider GUID you can locate _TlgProviderMetadata_t.ProviderId by signature (usually located in .text or .rdata sections) and then find in .data section _TlgProvider_t whose ProviderMetadataPtr points to _TlgProviderMetadata_t.RemainingSize. I made simple PoC for arm64

How we can abuse it? Let`s see how this structures used for example in combase.dll:

  cmp     _Tlgg_hCombaseTraceLoggingProviderProv.LevelPlus1, 5
  jbe     skip_logging
  push    useTimer                      ; keyword
  push    useTimer                      ; hProvider
  call    __TlgKeywordOn@12             ; _TlgKeywordOn(x,x,x)
  test    al, al
  jz      skip_logging


One obvious way is just zero LevelPlus1. Lets see inside TlgKeywordOn:
BOOLEAN _TlgKeywordOn(
    TraceLoggingHProvider _In_ hProvider,
    ULONGLONG keyword)
    TLG_NOEXCEPT
{
    return keyword == 0 || (
        (keyword & hProvider->KeywordAny) &&
        (keyword & hProvider->KeywordAll) == hProvider->KeywordAll);
}


So perhaps we can also zero any of KeywordAll/KeywordAll fields. And finally we can just zero RegHandle. So if you have enough rights (or driver) you can disable tracing in any running process (for example services.exe, lsass, RPC Service, DCom Server etc)

etw tracing handles in kernel

$
0
0
let's continue to dissect ETW (part 1& 2). This time consider how tracing is implemented in the kernel itself. I made PoC to find all tracing handles in arm64 kernel and now give short explanation of what each of them is used for

EtwpEventTracingProvRegHandle

GUID B675EC37-BDB6-4648-BC92-F3FDC74D3CA2 (EventTracingProvGuid). Used in lots of internal etw related functions like EtwpTraceStackWalk, EtwpWriteUserEvent, EtwpFailLogging, NtTraceEvent, WmiTraceMessage, EtwWriteEx, EtwWrite etc

EtwKernelProvRegHandle

GUID A68CA8B7-004F-D7B6-A698-07E2DE0F1F5D (KernelProvGuid). Used for kernel tracing in functions like SeLogAccessFailure, CmpReorganizeHive, SepSetTokenUserAndGroups, EtwTraceSystemTimeChange, EtwTraceTimeZoneInformationRefresh etc

EtwpPsProvRegHandle

GUID 22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716 (PsProvGuid). Used for tracing processes subsystem activity in functions like PsImpersonateContainerOfThread, PspRevertContainerImpersonation, PspSetJobIoRateControl, PspSetJobIoAttribution, EtwTraceFreezeThawProcess etc

EtwpNetProvRegHandle

GUID 7DD42A49-5329-4832-8DFD-43D979153A88 (NetProvGuid). Used only in function EtwpTraceNetwork which assigning as callback in WmiSetNetworkNotify


EtwpDiskProvRegHandle

GUID C7BDE69A-E1E0-4177-B6EF-283AD1525271 (DiskProvGuid). Used in function EtwpTraceIo which assigning as callback in EtwpDiskIoNotifyRoutines

EtwpFileProvRegHandle

GUID EDD08927-9CC4-4E65-B970-C2560FB5C289 (FileProvGuid). Used in function EtwpTraceFileName which assigning as callback in array EtwpTraceFileName

EtwpRegTraceHandle

GUID 70EB4F03-C1DE-4F73-A051-33D13D5413BD (RegistryProvGuid). Seems that this handle was introduced in build 20170. Used in lots of registry related functions like CmpTraceHiveMountStop, CmpTraceHiveLoadStart, CmpTraceHiveMountBaseFileMounted etc

EtwpMemoryProvRegHandle

GUID D1D93EF7-E1F2-4F45-9943-03D245FE6C00 (MemoryProvGuid). Used in memory related functions like MiAllocatePagesForMdl, MiAllocateContiguousMemory etc

EtwAppCompatProvRegHandle

GUID 16A1ADC1-9B7F-4CD9-94B3-D8296AB1B130 (MS_Windows_Kernel_AppCompat_Provider). Used only in function CmpPublishEventForPcaResolver and perhaps related with AppCompat

EtwApiCallsProvRegHandle

GUID E02A841C-75A3-4FA7-AFC8-AE09CF9B7F23 (KernelAuditApiCallsGuid). Used in some API functions like PsOpenProcess, PsOpenThread, NtCreateSymbolicLinkObject etc. Very interesting trace results

EtwCVEAuditProvRegHandle

GUID 85A62A0D-7E17-485F-9D4F-749A287193A6 (CVEAuditProviderGuid). Used in exported function SeEtwWriteKMCveEvent and perhaps intended for 3rd party drivers. For now imported only by win32kfull.sys


EtwThreatIntProvRegHandle & EtwSecurityMitigationsRegHandle

See detailed description in my post

EtwLpacProvRegHandle

GUID 45EEC9E5-4A1B-5446-7AD8-A4AB1313C437 (MS_Windows_Security_LPAC_Provider). Used in function EtwTraceLpacAccessFailure -> SepLogLpacAccessFailure -> SeAccessCheckWithHintWithAdminlessChecks

EtwAdminlessProvRegHandle

GUID EA216962-877B-5B73-F7C5-8AEF5375959E (MS_Windows_Security_Adminless_Provider). Used in function EtwTraceAdminlessAccessFailure ->NtQueryInformationToken

What are all this handles?

They are just pointers to ETW_REG_ENTRY. In turn, this structure has a pointer to ETW_GUID_ENTRY and here the story becomes much more interesting. ETW_GUID_ENTRY has field TRACE_ENABLE_INFO:
struct _TRACE_ENABLE_INFO {
  // static data ------------------------------------
  // non-static data --------------------------------
  /**/ /*|0x4|*/ unsigned long IsEnabled;
  /**/ /*|0x1|*/ unsigned char Level;
  /**/ /*|0x1|*/ unsigned char Reserved1;
  /**/ /*|0x2|*/ unsigned short LoggerId;
  /**/ /*|0x4|*/ unsigned long EnableProperty;
  /**/ /*|0x4|*/ unsigned long Reserved2;
  /**/ /*|0x8|*/ unsigned __int64 MatchAnyKeyword;
  /**/ /*|0x8|*/ unsigned __int64 MatchAllKeyword; 


So knowing offsets of ETW_REG_ENTRY.GuidEntry and ETW_GUID_ENTRY.ProviderEnableInfo fields you can dynamically disable kernel ETW tracing. Very ironic that you can find this offsets with disassembling exported function EtwEventEnabled:
EtwEventEnabled proc near
 sub     rsp, 28h
 mov     r8, rcx
 test    rcx, rcx
 jz      short loc_140076F70
 mov     rax, [rcx+20h]        ; ETW_REG_ENTRY.GuidEntry
 mov     r9, [rdx+8]
 add     rax, 50h              ; ETW_GUID_ENTRY.ProviderEnableInfo
 cmp     dword ptr [rax], 0


But perhaps there is even more interesting thing - in theory you can just replace ETW_REG_ENTRY.GuidEntry to your own ETW_GUID_ENTRY and so hijaq kernel tracing to your own (and even usermode) logger!

etw part 4: _TlgProvider_t in kernel

$
0
0
let's continue to dissect ETW (parts 1,2& 3)
Basically structure _TlgProvider_t in kernel almost the same as in user mode but field RegHandle points to ETW_REG_ENTRY. You can easily find them using simple search for known guids - I made PoC for arm64 (and for ndis.sys too)

kernel contains following tlg providers:
  • Microsoft.Windows.TlgAggregateInternal, GUID 703FCC13-B66F-5868-DDD9-E2DB7F381FFB
  • KernelExecutive, GUID 8944A53C-A561-4E53-A0C6-D565414745FC
  • Microsoft.Windows.Kernel.BootEnvironment, GUID 23B76A75-CE4F-56EF-F903-C3A2D6AE3F6B
  • MSTelCov, GUID 1DD9B8C9-E078-4075-B9DE-4E5125071A18
  • KernelProcess, GUID 2839FF94-8F12-4E1B-82E3-AF7AF77A450F
  • KernelGeneral, GUID 7614521C-4D0B-4341-BFC9-873082C0F1D3
  • Microsoft-Windows-Kernel-Vm, GUID B7FBD4E0-FA8F-4C58-B0FB-3CC227B86ED6. Located in section ALMOSTRO
  • Microsoft.Windows.Kernel.Security, GUID 09A69A38-2680-4BFA-AD01-792AD63A4FF2
  • Microsoft.Windows.Security.Capabilities, GUID 27A8FDF4-9B77-575B-BE3B-E7163EF159BB
  • Microsoft.Windows.Kernel.ProcessSubsystem, GUID C59673D8-B796-58DF-FBF8-A70BAD656DCA
  • Microsoft.Windows.Kernel.Ttm, GUID 5E753E4D-2B0D-4451-B8F9-0F1253CA0B44. Located in section PAGEDATA
  • Microsoft.Windows.Kernel.Power.PowerTransitions, GUID 050BF899-DA06-4852-A63A-81E6B9A1C74F
  • Microsoft.Windows.Kernel.Power.DirectedDrips, GUID 0D2ED727-38A0-4B2B-9F7E-EC79B5EC4AA5. Located in section PAGEDATA
  • Microsoft.Windows.Kernel.Power, GUID 63BCA7A1-77EC-4EA7-95D0-98D3F0C0EBF7
  • Microsoft.Windows.Kernel.Power.DiagFxAccounting, GUID 57D04B7B-550A-49A2-ABCC-A7FA15598A30
  • Microsoft.Windows.Kernel.ObjectManager, GUID F39412D1-C9FD-5E79-8A82-9C9CBD8CA809
  • Microsoft-Windows-Kernel-Mm, GUID 7E9E8B9C-406C-5D73-E566-0F50EA3ADE3E
  • Microsoft.Windows.Kernel.Kernel, GUID 061C37C3-1363-5C1B-B8ED-F3D8F74633CE
  • Microsoft.Windows.Kernel.PnP, GUID 6C0EBBBB-C292-457D-9675-DFCC1C0D58B0
  • Microsoft.Windows.Kernel.DeviceConfig, GUID C8BDE9FF-F31F-59DC-6C27-CA37C516ADA5
  • Microsoft.Windows.Kernel.SysEnv, GUID A9FDF37B-D72D-4051-A3CD-D422103CE079
  • Microsoft.Windows.Kernel.LiveDump, GUID A4D16FC5-D1CF-4D72-A055-25F3EB02A70E
  • Microsoft.Windows.Kernel.Dump, GUID A51EE86B-8EA5-454C-9A7D-37B6655A535D
  • IumTelemetryProvider, GUID 73A33AB2-1966-4999-8ADD-868C41415269
  • Microsoft.Windows.Containers.RegistryVirtualization, GUID 252D9ECC-1C9F-4917-8760-F872A83BF018
  • Microsoft.Windows.Kernel.FeatureConfigurationManager, GUID F7E83426-2B81-58F9-C5D4-F2DB6D0AD473
  • Microsoft.Windows.Kernel.Registry, GUID E9EAF418-0C07-464C-AD14-A7F353349A00
  • Microsoft.Windows.FileSystem.Cache, GUID 74093E1D-DBE3-4019-B97D-54EDCB02CFED
  • Microsoft.Windows.Kernel.HAL, GUID 0F51C5A7-0E76-47A5-BEDE-7CF62C5822F6

So what bad guys can do knowing addresses of this _TlgProvider_t?

  • as in user mode they could zero field LevelPlus1
  • they could hijaq ETW_REG_ENTRY to some custom etw provider
  • they can patch TRACE_ENABLE_INFO in ETW_REG_ENTRY.GuidEntry and so disable tracing
  • and much better - do you see field EnableCallback? By default it set to function TlgAggregateInternalRegisteredProviderEtwCallback with prototype
    void TlgAggregateInternalRegisteredProviderEtwCallback(struct _GUID const *, unsigned long, unsigned char, unsigned __int64, unsigned __int64, struct _EVENT_FILTER_DESCRIPTOR *, void *)
    so perhaps hooking it you could have real-time notification when someone want to turn-on logging for your system (and perhaps clear all your hooks until better times) 

Mitigations

To ensure than you ETW-based EDR still not blind you could
  1. find _TlgProvider_t in kernel and drivers
  2. check field LevelPlus1
  3. check hook for EnableCallback
  4. check that field RegHandle points to right ETW_REG_ENTRY
  5. which in turn points to right ETW_GUID_ENTRY
  6. and check that this ETW_GUID_ENTRY was not disabled
Btw this is exactly what my new tool I'm working on does - so lets see sample of output:
 [1] Microsoft.Windows.Kernel.Registry at FFFFF80328202198
  LevelPlus1: 100
  KeywordAny: 800000000000
  KeywordAll: 0
  RegHandle:  FFFFBC0F1A88D190
  EnableCallback: FFFFF80327E02BF0 \SystemRoot\system32\ntoskrnl.exe
  GuidEntry: FFFFBC0F19F59DE0
 
and ETW_GUID_ENTRY from ETW_SILODRIVERSTATE.EtwpGuidHashTable:
 KEtw10[33.23]: RefCount 1 IsEnabled 0 level 0 at FFFFBC0F19F59DE0 (E9EAF418-0C07-464C-AD14-A7F353349A00) Microsoft.Windows.Kernel.Registry

as you can see this ETW_GUID_ENTRY was disabled and no tracing for registry events happens

IMAGE_LOAD_CONFIG_DIRECTORY from sdk 20190

$
0
0
just as illustration to paper about XFG
size is 0xB8 for 32 bit and 0x130 for 64 bit



typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32 {
    DWORD   Size;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   GlobalFlagsClear;
    DWORD   GlobalFlagsSet;
    DWORD   CriticalSectionDefaultTimeout;
    DWORD   DeCommitFreeBlockThreshold;
    DWORD   DeCommitTotalFreeThreshold;
    DWORD   LockPrefixTable;                // VA
    DWORD   MaximumAllocationSize;
    DWORD   VirtualMemoryThreshold;
    DWORD   ProcessHeapFlags;
    DWORD   ProcessAffinityMask;
    WORD    CSDVersion;
    WORD    DependentLoadFlags;
    DWORD   EditList;                       // VA
    DWORD   SecurityCookie;                 // VA
    DWORD   SEHandlerTable;                 // VA
    DWORD   SEHandlerCount;
    DWORD   GuardCFCheckFunctionPointer;    // VA
    DWORD   GuardCFDispatchFunctionPointer; // VA
    DWORD   GuardCFFunctionTable;           // VA
    DWORD   GuardCFFunctionCount;
    DWORD   GuardFlags;
    IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
    DWORD   GuardAddressTakenIatEntryTable; // VA
    DWORD   GuardAddressTakenIatEntryCount;
    DWORD   GuardLongJumpTargetTable;       // VA
    DWORD   GuardLongJumpTargetCount;
    DWORD   DynamicValueRelocTable;         // VA
    DWORD   CHPEMetadataPointer;
    DWORD   GuardRFFailureRoutine;          // VA
    DWORD   GuardRFFailureRoutineFunctionPointer; // VA
    DWORD   DynamicValueRelocTableOffset;
    WORD    DynamicValueRelocTableSection;
    WORD    Reserved2;
    DWORD   GuardRFVerifyStackPointerFunctionPointer; // VA
    DWORD   HotPatchTableOffset;
    DWORD   Reserved3;
    DWORD   EnclaveConfigurationPointer;    // VA
    DWORD   VolatileMetadataPointer;        // VA
    DWORD   GuardEHContinuationTable;       // VA
    DWORD   GuardEHContinuationCount;
    DWORD   GuardXFGCheckFunctionPointer;    // VA
    DWORD   GuardXFGDispatchFunctionPointer; // VA
    DWORD   GuardXFGTableDispatchFunctionPointer; // VA
} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;


typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 {
    DWORD      Size;
    DWORD      TimeDateStamp;
    WORD       MajorVersion;
    WORD       MinorVersion;
    DWORD      GlobalFlagsClear;
    DWORD      GlobalFlagsSet;
    DWORD      CriticalSectionDefaultTimeout;
    ULONGLONG  DeCommitFreeBlockThreshold;
    ULONGLONG  DeCommitTotalFreeThreshold;
    ULONGLONG  LockPrefixTable;                // VA
    ULONGLONG  MaximumAllocationSize;
    ULONGLONG  VirtualMemoryThreshold;
    ULONGLONG  ProcessAffinityMask;
    DWORD      ProcessHeapFlags;
    WORD       CSDVersion;
    WORD       DependentLoadFlags;
    ULONGLONG  EditList;                       // VA
    ULONGLONG  SecurityCookie;                 // VA
    ULONGLONG  SEHandlerTable;                 // VA
    ULONGLONG  SEHandlerCount;
    ULONGLONG  GuardCFCheckFunctionPointer;    // VA
    ULONGLONG  GuardCFDispatchFunctionPointer; // VA
    ULONGLONG  GuardCFFunctionTable;           // VA
    ULONGLONG  GuardCFFunctionCount;
    DWORD      GuardFlags;
    IMAGE_LOAD_CONFIG_CODE_INTEGRITY CodeIntegrity;
    ULONGLONG  GuardAddressTakenIatEntryTable; // VA
    ULONGLONG  GuardAddressTakenIatEntryCount;
    ULONGLONG  GuardLongJumpTargetTable;       // VA
    ULONGLONG  GuardLongJumpTargetCount;
    ULONGLONG  DynamicValueRelocTable;         // VA
    ULONGLONG  CHPEMetadataPointer;            // VA
    ULONGLONG  GuardRFFailureRoutine;          // VA
    ULONGLONG  GuardRFFailureRoutineFunctionPointer; // VA
    DWORD      DynamicValueRelocTableOffset;
    WORD       DynamicValueRelocTableSection;
    WORD       Reserved2;
    ULONGLONG  GuardRFVerifyStackPointerFunctionPointer; // VA
    DWORD      HotPatchTableOffset;
    DWORD      Reserved3;
    ULONGLONG  EnclaveConfigurationPointer;     // VA
    ULONGLONG  VolatileMetadataPointer;         // VA
    ULONGLONG  GuardEHContinuationTable;        // VA
    ULONGLONG  GuardEHContinuationCount;
    ULONGLONG  GuardXFGCheckFunctionPointer;    // VA
    ULONGLONG  GuardXFGDispatchFunctionPointer; // VA
    ULONGLONG  GuardXFGTableDispatchFunctionPointer; // VA
} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;

etw part 4½: MCGEN_TRACE_CONTEXT

$
0
0
let's continue to dissect ETW (parts 1,2, 3 & 4)
Now consider structures generated with mc.exe (Windows Message Compiler). It seems that this is very old technology - some .mc files in official Microsoft github repository have copyrights from 1992! Despite this they are still supported for example in MSBuild - see rule for MessageCompile

This generated with mc structure has name MCGEN_TRACE_CONTEXT and looks like:
typedef struct _MCGEN_TRACE_CONTEXT
{
    HANDLE                 RegistrationHandle;
    HANDLE                 Logger;
    ULONGLONG              MatchAnyKeyword;
    ULONGLONG              MatchAllKeyword;
    ULONG                  Flags;
    ULONG                  IsEnabled;
    UCHAR                  Level; 
    UCHAR                  Reserve;
    USHORT                 EnableBitsCount;
    PULONG                 EnableBitMask;
    const ULONGLONG*       EnableKeyWords;
    const UCHAR*           EnableLevel;
} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT;

Looks very similar to _TlgProvider_t. Unfortunately they cannot be found with some simple signatures scan - you need to use some disasm magic. I wrote simple PoC to find them in arm64 windows kernel
Let`s see where you can encounter this ancient variant of ETW

Kernel

kernel contains following mc generated providers:
  • MS_KernelCc_Provider_Context, GUID MS_KernelCc_Provider (A2D34BF1-70AB-5B21-C819-5A0DD42748FD)
  • MS_StorageTiering_Provider_Context. GUID MS_StorageTiering_Provider (990C55FC-2662-47F6-B7D7-EB3C027CB13F)
  • IoMgrProvider_Context, GUID IoMgrProvider (ABF1F586-2E50-4BA8-928D-49044E6F0DB7)
  • MS_KernelPnP_Provider_Context, GUID MS_KernelPnP_Provider (9C205A39-1250-487D-ABD7-E831C6290539)
Field RegistrationHandle in kernel mode points to ETW_REG_ENTRY (same as RegHandle in _TlgProvider_t)

Drivers 

This is not comprehensive list - just some samples
  • ndis.sys - NDIS_PROVIDER_ID_Context & SLEEPSTUDY_ETW_PROVIDER_Context
  • tcpip.sys - EQOS_EVENT_PROVIDER_Context & MICROSOFT_TCPIP_PROVIDER_Context
  • winnat.sys - MICROSOFT_WINNAT_ETW_PROVIDER_Context
  • ntfs.sys - NtfsGeneralEventProvider_Context
Lets see how they looks for example for tcpip.sys:

MCGEN_TRACE_CONTEXTs for tcpip.sys:
 [0] EQOS_EVENT_PROVIDER_Context at FFFFF80144CFC100
 RegistrationHandle: FFFF940A69586E90
  GuidEntry: FFFF940A690CF520
 Logger: 0000000000000000
 Flags: 0
 IsEnabled: 1
 Level: 255
 EnableBitsCount: 4
 [1] MICROSOFT_TCPIP_PROVIDER_Context at FFFFF80144CFA6D0
 RegistrationHandle: FFFF940A69586710
  GuidEntry: FFFF940A690CC7A0
 Logger: 0000000000000000
 Flags: 0
 IsEnabled: 1
 Level: 255
 EnableBitsCount: 7A

Usermode .dlls

Just like in _TlgProvider_t field RegistrationHandle is not real HANDLE but some structure with address to ETW_REGISTRATION_ENTRY. Again this is not comprehensive list - just some samples:
  • dnsrslvr.dll - MS_VPN_PLGN_PLATFORM_Operational_Context
  • rpcrt4.dll - RpcEtwGuid_Context & RpcLegacyEvents_Context
  • ole32.dll/combase.dll - COM_PERFORMANCE_PROVIDER_Context, ASYNCHRONOUS_CAUSALITY_PROVIDER_Context, WINRT_ERROR_PROVIDER_Context, RUNDOWN_INSTRUMENTATION_PROVIDER_Context
So as you can see these structures are ubiquitous and need to be checked against ETW attacks

IDCFuncs in ida pro 7.x

$
0
0

Let's assume what we want to have some normal programming language inside ida pro (not strange looking pile of spaces). Or just to made RPC interface so you can use several instances of ida from external processeses. In previous versions (since 4.x - I can be wrong) we had IDCFuncs which I used for example to embed perl. But since 7.x this symbol is no longer exported (obviously to make users' lives even more unbearable). Sure this small problem can`t stop me. So there are at least two ways to find IDCFuncs in any ida pro 7.x

signature search

strictly speaking this method allows you to find IDCFuncs->funcs. Name of first function in this array of ext_idcfunc_t always is "____" (yes, some undocumented function with name of four underscores). So you first must search for it in .text section (in ida.dll/ida64.dll) and then find address in .data - this will be first ext_idcfunc_t:

struct ext_idcfunc_t
{  const char *name;             ///< Name of function  
   idc_func_t *fptr;             ///< Pointer to the Function
   const char *args;             ///< Type of arguments. Terminated with 0.        
   const idc_value_t *defvals;   ///< Default argument values.
   int ndefvals;                 ///< Number of default values.     
   int flags;                    ///< \ref EXTFUN_
};

some disasm magic

It`s very ironic that in the disassembler you have to use another disassembler to find what you want. Lets see which exported functions use IDCFuncs
find_idc_func - contrary to expectations, it does not return any functions, prototype looks like:

idaman THREAD_SAFE bool ida_export find_idc_func(
        qstring *out,
        const char *prefix,
        int n=0);

ok, lets use ida pro to see some guts of ida pro:
find_idc_func   proc near               ; DATA XREF: .text:off_100037A8 o
                                        ; .text:000000001034C40C o

var_38          = qword ptr -38h
arg_0           = qword ptr  8
arg_8           = qword ptr  10h
arg_10          = qword ptr  18h
arg_18          = qword ptr  20h

                push    rdi
                push    r12
                push    r13
                push    r14
                push    r15
                sub     rsp, 30h
                mov     [rsp+58h+var_38], 0FFFFFFFFFFFFFFFEh
                mov     [rsp+58h+arg_0], rbx
                mov     [rsp+58h+arg_8], rbp
                mov     [rsp+58h+arg_10], rsi
                mov     r15d, r8d
                mov     r12, rdx
                mov     r13, rcx
                mov     rbx, cs:qword_10362658
                mov     [rsp+58h+arg_18], rbx
                mov     rcx, rbx

loc_100B886E:                           ; DATA XREF: .text:stru_102A80A8 o
                call    qmutex_lock ; exported function
                nop
                mov     rdi, 0FFFFFFFFFFFFFFFFh
                mov     rsi, rdi
                xchg    ax, ax

loc_100B8880:                           ; CODE XREF: find_idc_func+58 j
                inc     rsi
                cmp     byte ptr [r12+rsi], 0
                jnz     short loc_100B8880
                xor     ebp, ebp
                cmp     cs:IDCFuncs, rbp

Easy can be resolved with simple state machine - first cmp [memory in .data section] after qmutex_lock call

(semi)auto building of state machine

$
0
0

Several days ago I made PoC to extract addresses of WSK data from windows 10 arm64 afd.sys - specifically AfdWskClientListHead and lock AfdWskClientSpinLock. Nothing special except fact that afd.sys has no exported functions. So you must find some rare constant, then find functions which use it and only then do some disasm applying state machine to each code block (see lambda passed to traverse_simple_state_graph)

While I was writing this code, I was not left with a question whether it is possible to employ computer to build such state machines. And now I know that this is possible (at least for code on plain C for RISC-like asm with predictable addresses of instructions etc etc)

Lets see how such algo can be arranged:

1) you must find all cross-refs to desired variable and collect list of functions which use it (exactly what deriv_hack::find_xrefs method does)

2) then you must disasm each such function and try to get some primitives - like loading of constants, calling imported/exported functions etc - see deriv_hack::make_path method. Sure set of this primitives will be different for each processor and perhaps will depends from your tasks

Results for afd.sys!AfdWskClientListHead:

found at 00002698
 load
 call_imp KeAcquireInStackQueuedSpinLock
 load
found at 00004B30
 const 43444661 count 1
 call_imp ExAllocatePoolWithTag
 call_imp KeInitializeSpinLock
 load
 call_imp KeAcquireInStackQueuedSpinLock
 load
found at 000078C4
 load
 call_imp KeAcquireInStackQueuedSpinLock
 load
found at 0000D8B0
 load
 call_imp ExEnterCriticalRegionAndAcquireResourceExclusive
 load
 call_imp KeAcquireInStackQueuedSpinLock
 load
found at 0000D9F0
 load
 call_imp KeAcquireInStackQueuedSpinLock
 load
found at 00015BD8
 load
 load
 call_imp KeAcquireInStackQueuedSpinLock
 load
found at 000988D0
 load

Function at RVA 4B30 is AfdWskNotifyAttachClient and my manually written state machine does the same:
  1. wait for loading of constant 0x43444661
  2. then wait for ExAllocatePoolWithTag call
  3. then wait for KeAcquireInStackQueuedSpinLock
  4. and first loading in this state is AfdWskClientListHead
Very good results IMHO. You can play with this algo using -der option, first argument is filename to disasm and second RVA for symbol to find. For example to find KiInitialProcess in kernel (RVA 4A7080) run

ldr.exe -der D:\work\kernel\w10\18362\arm\ntoskrnl.exe 4A7080

Btw best candidate is exported KeQueryPriorityThread


efficiency of auto-derived state machines

$
0
0

It`s time to measure how effective this state-machines. I made today simple perl script to measure how much symbols (located in sections .data, ALMOSTRO and PAGEDATA) can be found for arm64 windows kernel. The conditions for success are

  • found function is exported
  • or found function use some unique constant which is used no more than 3 times
Result on kernel build 18346:
total: 3493 symbols, found 1466

Simple state machine with states containing only loading/storing, call import/export and loading of some constant is able to retrieve almost 42% of symbols

PS: for adf.sys (which has no exported functions at all) results even better:
total: 164 symbols, found 73
44.5%

using of auto-derived state machines

$
0
0

Let`s see what we can do with our auto-derivedstate-machines. All source code in my github repo

Simple case: KdLocalDebugEnabled

Assume that we want to find address of KdLocalDebugEnabled. On kernel 18345 RVA is 37CC18 and it located in section .data. Run
ldr.exe -se -t 8 -der D:\work\kernel\w10\18346\arm\ntoskrnl.exe 37CC18
to build rules. Option -t sets number of threads. Results:

found at 0076D850 - KdSystemDebugControl
 ldrb exorted KdDebuggerEnabled
 ldrb
apply return 37CC18, must_be 37CC18

This rule say that we must find exported function KdSystemDebugControl, wait for loading of exported symbol KdDebuggerEnabled and next loading operation will give us address of KdLocalDebugEnabled
Now apply this rule for kernel RTM 2004 (with option -T you can specify files on which to test rules):
ldr.exe -se -t 8 -der D:\work\kernel\w10\18346\arm\ntoskrnl.exe 37CC18 -T d:\work\kernel\w10\rtm\2004\arm\ntoskrnl.exe
 ldrb exorted KdDebuggerEnabled
 ldrb
Test[0]: C3F639

Lets check this address
// pubsym <rva 0xc3f639> KdLocalDebugEnabled

Second case: CmpTraceRoutine

IDA Pro shows 106 xrefs on kernel 18345, RVA is 8A8008. Lets see if rule for finding this address can be derived automatically:
Run
ldr.exe -se -t 8 -der D:\work\kernel\w10\18346\arm\ntoskrnl.exe 8A8008

Results:
found at 004E4800 - NtClose
 load exported PsInitialSystemProcess
 call_exp RtlMapGenericMask
 load
apply return 8A8008, must_be 8A8008

found at 005F8BE0 in section PAGE
 call_exp memset
 load exported CmKeyObjectType
 const 2001F count 38
 call_exp ObOpenObjectByName
 load exported CmKeyObjectType
 call_exp ObReferenceObjectByHandle
 call_exp ZwClose
 const 70684D43 count 1
 call_exp ExAllocatePoolWithTag
 load
apply return 8A8008, must_be 8A8008

This time we have two rules - one for exported function NtClose and second for some non-exported function at RVA 5F8BE0 - this is CmpLinkHiveToMaster (I think it was chosen because it contains unique constant 0x70684D43). Apply all this rules for kernel RTM 2004:

ldr.exe -se -t 8 -der D:\work\kernel\w10\18346\arm\ntoskrnl.exe 8A8008 -T d:\work\kernel\w10\rtm\2004\arm\ntoskrnl.exe

found at 005F8BE0 in section PAGE
 call_exp memset
 load exported CmKeyObjectType
 const 2001F count 38
 call_exp ObOpenObjectByName
 load exported CmKeyObjectType
 call_exp ObReferenceObjectByHandle
 call_exp ZwClose
 const 70684D43 count 1
 call_exp ExAllocatePoolWithTag
 load
Test[0]: 1030008

Second rule worked, check in pdbdump:
// pubsym <rva 0x1030008> CmpTraceRoutine

W32pServiceTable from windows 10 build 20292 64bit

$
0
0

 It seems that MS cut off whole apfnSimpleCall dispatching - no more functions

  • NtUserCallHwndParamLock
  • NtUserCallHwndParam
  • NtUserCallHwndLockSafe
  • NtUserCallHwndParamLockSafe
  • NtUserCallHwndLock
  • NtUserCallHwnd
  • NtUserCallNoParam
  • NtUserCallTwoParam
  • NtUserCallOneParam
  • NtUserCallHwndSafe
  • NtUserCallHwndOpt
Instead all functions from apfnSimpleCall now exported and contained in W32pServiceTable. Like (just to name few):
  • CreateMenu -> NtUserCreateMenu
  • CreatePopupMenu -> NtUserCreatePopupMenu
  • AllowForegroundActivation -> NtUserAllowForegroundActivation
etc etc
content of W32pServiceTable (W32pServiceLimit .eq. 0x5AA):

NtUserGetThreadState
NtUserPeekMessage
NtUserGetKeyState
NtUserInvalidateRect
NtUserGetMessage
NtUserMessageCall
NtGdiBitBlt
NtGdiGetCharSet
NtUserGetDC
NtGdiSelectBitmap
NtUserWaitMessage
NtUserTranslateMessage
NtUserGetProp
NtUserPostMessage
NtUserQueryWindow
NtUserTranslateAccelerator
NtGdiFlush
NtUserRedrawWindow
NtUserWindowFromPoint
NtUserCallMsgFilter
NtUserValidateTimerCallback
NtUserBeginPaint
NtUserSetTimer
NtUserEndPaint
NtUserSetCursor
NtUserKillTimer
NtUserBuildHwndList
NtUserSelectPalette
NtUserCallNextHookEx
NtUserHideCaret
NtGdiIntersectClipRect
NtUserGetProcessWindowStation
NtGdiDeleteObjectApp
NtUserSetWindowPos
NtUserShowCaret
NtUserEndDeferWindowPosEx
NtUserVkKeyScanEx
NtGdiSetDIBitsToDeviceInternal
NtGdiGetRandomRgn
NtUserCopyAcceleratorTable
NtUserNotifyWinEvent
NtGdiExtSelectClipRgn
NtUserIsClipboardFormatAvailable
NtUserSetScrollInfo
NtGdiStretchBlt
NtUserCreateCaret
NtGdiRectVisible
NtGdiCombineRgn
NtGdiGetDCObject
NtUserDispatchMessage
NtUserRegisterWindowMessage
NtGdiExtTextOutW
NtGdiSelectFont
NtGdiRestoreDC
NtGdiSaveDC
NtUserGetForegroundWindow
NtUserShowScrollBar
NtUserFindExistingCursorIcon
NtGdiGetDCDword
NtGdiGetRegionData
NtGdiLineTo
NtUserSystemParametersInfo
NtGdiGetAppClipBox
NtUserGetAsyncKeyState
NtUserGetCPD
NtUserRemoveProp
NtGdiDoPalette
NtGdiPolyPolyDraw
NtUserSetCapture
NtUserEnumDisplayMonitors
NtGdiCreateCompatibleBitmap
NtUserSetProp
NtGdiGetTextCharsetInfo
NtUserSBGetParms
NtUserGetIconInfo
NtUserExcludeUpdateRgn
NtUserSetFocus
NtGdiExtGetObjectW
NtUserGetUpdateRect
NtGdiCreateCompatibleDC
NtUserGetClipboardSequenceNumber
NtGdiCreatePen
NtUserShowWindow
NtUserGetKeyboardLayoutList
NtGdiPatBlt
NtUserMapVirtualKeyEx
NtUserSetWindowLong
NtGdiHfontCreate
NtUserMoveWindow
NtUserPostThreadMessage
NtUserDrawIconEx
NtUserGetSystemMenu
NtGdiDrawStream
NtUserInternalGetWindowText
NtUserGetWindowDC
NtGdiInvertRgn
NtGdiGetRgnBox
NtGdiGetAndSetDCDword
NtGdiMaskBlt
NtGdiGetWidthTable
NtUserScrollDC
NtUserGetObjectInformation
NtGdiCreateBitmap
NtUserFindWindowEx
NtGdiPolyPatBlt
NtUserUnhookWindowsHookEx
NtGdiGetNearestColor
NtGdiTransformPoints
NtGdiGetDCPoint
NtGdiCreateDIBBrush
NtGdiGetTextMetricsW
NtUserCreateWindowEx
NtUserSetParent
NtUserGetKeyboardState
NtUserToUnicodeEx
NtUserGetControlBrush
NtUserGetClassName
NtGdiAlphaBlend
NtGdiOffsetRgn
NtUserDefSetText
NtGdiGetTextFaceW
NtGdiStretchDIBitsInternal
NtUserSendInput
NtUserGetThreadDesktop
NtGdiCreateRectRgn
NtGdiGetDIBitsInternal
NtUserGetUpdateRgn
NtGdiDeleteClientObj
NtUserGetIconSize
NtUserFillWindow
NtGdiExtCreateRegion
NtGdiComputeXformCoefficients
NtUserSetWindowsHookEx
NtUserNotifyProcessCreate
NtGdiUnrealizeObject
NtUserGetTitleBarInfo
NtGdiRectangle
NtUserSetThreadDesktop
NtUserGetDCEx
NtUserGetScrollBarInfo
NtGdiGetTextExtent
NtUserSetWindowFNID
NtGdiSetLayout
NtUserCalcMenuBar
NtUserThunkedMenuItemInfo
NtGdiExcludeClipRect
NtGdiCreateDIBSection
NtGdiGetDCforBitmap
NtUserDestroyCursor
NtUserDestroyWindow
NtGdiCreateDIBitmapInternal
NtUserOpenWindowStation
NtUserSetCursorIconData
NtUserCloseDesktop
NtUserOpenDesktop
NtUserSetProcessWindowStation
NtUserGetAtomName
NtGdiExtCreatePen
NtGdiCreatePaletteInternal
NtGdiSetBrushOrg
NtUserBuildNameList
NtGdiSetPixel
NtUserRegisterClassExWOW
NtGdiCreatePatternBrushInternal
NtUserGetAncestor
NtGdiGetOutlineTextMetricsInternalW
NtGdiSetBitmapBits
NtUserCloseWindowStation
NtUserGetDoubleClickTime
NtUserEnableScrollBar
NtGdiCreateSolidBrush
NtUserGetClassInfoEx
NtGdiCreateClientObj
NtUserUnregisterClass
NtUserDeleteMenu
NtGdiRectInRegion
NtUserScrollWindowEx
NtGdiGetPixel
NtUserSetClassLong
NtUserGetMenuBarInfo
NtGdiGetNearestPaletteIndex
NtGdiGetCharWidthW
NtUserInvalidateRgn
NtUserGetClipboardOwner
NtUserSetWindowRgn
NtUserBitBltSysBmp
NtGdiGetCharWidthInfo
NtUserValidateRect
NtUserCloseClipboard
NtUserOpenClipboard
NtUserSetClipboardData
NtUserEnableMenuItem
NtUserAlterWindowStyle
NtGdiFillRgn
NtUserGetWindowPlacement
NtGdiModifyWorldTransform
NtGdiGetFontData
NtUserGetOpenClipboardWindow
NtUserSetThreadState
NtGdiOpenDCW
NtUserTrackMouseEvent
NtGdiGetTransform
NtUserDestroyMenu
NtGdiGetBitmapBits
NtUserConsoleControl
NtUserSetActiveWindow
NtUserSetInformationThread
NtUserSetWindowPlacement
NtUserGetControlColor
NtGdiSetMetaRgn
NtGdiSetMiterLimit
NtGdiSetVirtualResolution
NtGdiGetRasterizerCaps
NtUserSetWindowWord
NtUserGetClipboardFormatName
NtUserRealInternalGetMessage
NtUserCreateLocalMemHandle
NtUserAttachThreadInput
NtGdiCreateHalftonePalette
NtUserPaintMenuBar
NtUserSetKeyboardState
NtGdiCombineTransform
NtUserCreateAcceleratorTable
NtUserGetCursorFrameInfo
NtUserGetAltTabInfo
NtUserGetCaretBlinkTime
NtGdiQueryFontAssocInfo
NtUserProcessConnect
NtUserEnumDisplayDevices
NtUserEmptyClipboard
NtUserGetClipboardData
NtUserRemoveMenu
NtGdiSetBoundsRect
NtGdiGetBitmapDimension
NtUserConvertMemHandle
NtUserDestroyAcceleratorTable
NtUserGetGUIThreadInfo
NtGdiCloseFigure
NtUserSetWindowsHookAW
NtUserSetMenuDefaultItem
NtUserCheckMenuItem
NtUserSetWinEventHook
NtUserUnhookWinEvent
NtUserLockWindowUpdate
NtUserSetSystemMenu
NtUserThunkedMenuInfo
NtGdiBeginPath
NtGdiEndPath
NtGdiFillPath
NtUserDdeInitialize
NtUserModifyUserStartupInfoFlags
NtUserCountClipboardFormats
NtGdiAddFontMemResourceEx
NtGdiEqualRgn
NtGdiGetSystemPaletteUse
NtGdiRemoveFontMemResourceEx
NtUserEnumDisplaySettings
NtUserPaintDesktop
NtGdiExtEscape
NtGdiSetBitmapDimension
NtGdiSetFontEnumeration
NtUserChangeClipboardChain
NtUserSetClipboardViewer
NtUserShowWindowAsync
NtGdiCreateColorSpace
NtGdiDeleteColorSpace
NtUserActivateKeyboardLayout
NtBindCompositionSurface
NtCloseCompositionInputSink
NtCompositionInputThread
NtCompositionSetDropTarget
NtCompositorNotifyExitWindows
NtConfigureInputSpace
NtCreateCompositionInputSink
NtCreateCompositionSurfaceHandle
NtCreateImplicitCompositionInputSink
NtDCompositionAddCrossDeviceVisualChild
NtDCompositionBeginFrame
NtDCompositionBoostCompositorClock
NtDCompositionCommitChannel
NtDCompositionCommitSynchronizationObject
NtDCompositionConfirmFrame
NtDCompositionConnectPipe
NtDCompositionCreateAndBindSharedSection
NtDCompositionCreateChannel
NtDCompositionCreateConnection
NtDCompositionCreateDwmChannel
NtDCompositionCreateSharedResourceHandle
NtDCompositionCreateSynchronizationObject
NtDCompositionDestroyChannel
NtDCompositionDestroyConnection
NtDCompositionDuplicateHandleToProcess
NtDCompositionDuplicateSwapchainHandleToDwm
NtDCompositionEnableMMCSS
NtDCompositionGetBatchId
NtDCompositionGetChannels
NtDCompositionGetConnectionBatch
NtDCompositionGetDeletedResources
NtDCompositionGetFrameLegacyTokens
NtDCompositionGetFrameStatistics
NtDCompositionGetFrameSurfaceUpdates
NtDCompositionGetMaterialProperty
NtDCompositionGetTargetStatistics
NtDCompositionProcessChannelBatchBuffer
NtDCompositionReferenceSharedResourceOnDwmChannel
NtDCompositionRegisterThumbnailVisual
NtDCompositionRegisterVirtualDesktopVisual
NtDCompositionReleaseAllResources
NtDCompositionRemoveCrossDeviceVisualChild
NtDCompositionSetChannelCommitCompletionEvent
NtDCompositionSetChannelConnectionId
NtDCompositionSetChildRootVisual
NtDCompositionSetDebugCounter
NtDCompositionSetMaterialProperty
NtDCompositionSubmitDWMBatch
NtDCompositionSuspendAnimations
NtDCompositionSynchronize
NtDCompositionTelemetryAnimationScenarioBegin
NtDCompositionTelemetryAnimationScenarioReference
NtDCompositionTelemetryAnimationScenarioUnreference
NtDCompositionTelemetrySetApplicationId
NtDCompositionTelemetryTouchInteractionBegin
NtDCompositionTelemetryTouchInteractionEnd
NtDCompositionTelemetryTouchInteractionUpdate
NtDCompositionUpdatePointerCapture
NtDCompositionWaitForChannel
NtDCompositionWaitForCompositorClock
NtDesktopCaptureBits
NtDuplicateCompositionInputSink
NtDxgkCancelPresents
NtDxgkCheckSinglePlaneForMultiPlaneOverlaySupport
NtDxgkCreateTrackedWorkload
NtDxgkDestroyTrackedWorkload
NtDxgkDispMgrOperation
NtDxgkDisplayPortOperation
NtDxgkDuplicateHandle
NtDxgkEnumAdapters3
NtDxgkGetAvailableTrackedWorkloadIndex
NtDxgkGetProcessList
NtDxgkGetProperties
NtDxgkGetTrackedWorkloadStatistics
NtDxgkOutputDuplPresentToHwQueue
NtDxgkPinResources
NtDxgkRegisterVailProcess
NtDxgkResetTrackedWorkloadStatistics
NtDxgkSetProperties
NtDxgkSubmitPresentBltToHwQueue
NtDxgkSubmitPresentToHwQueue
NtDxgkUnpinResources
NtDxgkUpdateTrackedWorkload
NtDxgkVailConnect
NtDxgkVailDisconnect
NtDxgkVailPromoteCompositionSurface
NtEnableOneCoreTransformMode
NtFlipObjectAddContent
NtFlipObjectAddPoolBuffer
NtFlipObjectConsumerAcquirePresent
NtFlipObjectConsumerAdjustUsageReference
NtFlipObjectConsumerBeginProcessPresent
NtFlipObjectConsumerEndProcessPresent
NtFlipObjectConsumerPostMessage
NtFlipObjectConsumerQueryBufferInfo
NtFlipObjectCreate
NtFlipObjectDisconnectEndpoint
NtFlipObjectEnablePresentStatisticsType
NtFlipObjectOpen
NtFlipObjectPresentCancel
NtFlipObjectQueryBufferAvailableEvent
NtFlipObjectQueryEndpointConnected
NtFlipObjectQueryLostEvent
NtFlipObjectQueryNextMessageToProducer
NtFlipObjectReadNextMessageToProducer
NtFlipObjectRemoveContent
NtFlipObjectRemovePoolBuffer
NtFlipObjectSetContent
NtGdiAbortDoc
NtGdiAbortPath
NtGdiAddEmbFontToDC
NtGdiAddFontResourceW
NtGdiAddInitialFonts
NtGdiAddRemoteFontToDC
NtGdiAddRemoteMMInstanceToDC
NtGdiAngleArc
NtGdiAnyLinkedFonts
NtGdiArcInternal
NtGdiBRUSHOBJ_DeleteRbrush
NtGdiBRUSHOBJ_hGetColorTransform
NtGdiBRUSHOBJ_pvAllocRbrush
NtGdiBRUSHOBJ_pvGetRbrush
NtGdiBRUSHOBJ_ulGetBrushColor
NtGdiBeginGdiRendering
NtGdiCLIPOBJ_bEnum
NtGdiCLIPOBJ_cEnumStart
NtGdiCLIPOBJ_ppoGetPath
NtGdiCancelDC
NtGdiChangeGhostFont
NtGdiCheckBitmapBits
NtGdiClearBitmapAttributes
NtGdiClearBrushAttributes
NtGdiColorCorrectPalette
NtGdiConfigureOPMProtectedOutput
NtGdiConvertMetafileRect
NtGdiCreateBitmapFromDxSurface
NtGdiCreateBitmapFromDxSurface2
NtGdiCreateColorTransform
NtGdiCreateEllipticRgn
NtGdiCreateHatchBrushInternal
NtGdiCreateMetafileDC
NtGdiCreateOPMProtectedOutput
NtGdiCreateOPMProtectedOutputs
NtGdiCreateRoundRectRgn
NtGdiCreateServerMetaFile
NtGdiCreateSessionMappedDIBSection
NtGdiDDCCIGetCapabilitiesString
NtGdiDDCCIGetCapabilitiesStringLength
NtGdiDDCCIGetTimingReport
NtGdiDDCCIGetVCPFeature
NtGdiDDCCISaveCurrentSettings
NtGdiDDCCISetVCPFeature
NtGdiDdCreateFullscreenSprite
NtGdiDdDDIAbandonSwapChain
NtGdiDdDDIAcquireKeyedMutex
NtGdiDdDDIAcquireKeyedMutex2
NtGdiDdDDIAcquireSwapChain
NtGdiDdDDIAddSurfaceToSwapChain
NtGdiDdDDIAdjustFullscreenGamma
NtGdiDdDDICacheHybridQueryValue
NtGdiDdDDIChangeVideoMemoryReservation
NtGdiDdDDICheckExclusiveOwnership
NtGdiDdDDICheckMonitorPowerState
NtGdiDdDDICheckMultiPlaneOverlaySupport
NtGdiDdDDICheckMultiPlaneOverlaySupport2
NtGdiDdDDICheckMultiPlaneOverlaySupport3
NtGdiDdDDICheckOcclusion
NtGdiDdDDICheckSharedResourceAccess
NtGdiDdDDICheckVidPnExclusiveOwnership
NtGdiDdDDICloseAdapter
NtGdiDdDDIConfigureSharedResource
NtGdiDdDDICreateAllocation
NtGdiDdDDICreateBundleObject
NtGdiDdDDICreateContext
NtGdiDdDDICreateContextVirtual
NtGdiDdDDICreateDCFromMemory
NtGdiDdDDICreateDevice
NtGdiDdDDICreateHwContext
NtGdiDdDDICreateHwQueue
NtGdiDdDDICreateKeyedMutex
NtGdiDdDDICreateKeyedMutex2
NtGdiDdDDICreateOutputDupl
NtGdiDdDDICreateOverlay
NtGdiDdDDICreatePagingQueue
NtGdiDdDDICreateProtectedSession
NtGdiDdDDICreateSwapChain
NtGdiDdDDICreateSynchronizationObject
NtGdiDdDDIDDisplayEnum
NtGdiDdDDIDestroyAllocation
NtGdiDdDDIDestroyAllocation2
NtGdiDdDDIDestroyContext
NtGdiDdDDIDestroyDCFromMemory
NtGdiDdDDIDestroyDevice
NtGdiDdDDIDestroyHwContext
NtGdiDdDDIDestroyHwQueue
NtGdiDdDDIDestroyKeyedMutex
NtGdiDdDDIDestroyOutputDupl
NtGdiDdDDIDestroyOverlay
NtGdiDdDDIDestroyPagingQueue
NtGdiDdDDIDestroyProtectedSession
NtGdiDdDDIDestroySynchronizationObject
NtGdiDdDDIDispMgrCreate
NtGdiDdDDIDispMgrSourceOperation
NtGdiDdDDIDispMgrTargetOperation
NtGdiDdDDIEnumAdapters
NtGdiDdDDIEnumAdapters2
NtGdiDdDDIEscape
NtGdiDdDDIEvict
NtGdiDdDDIExtractBundleObject
NtGdiDdDDIFlipOverlay
NtGdiDdDDIFlushHeapTransitions
NtGdiDdDDIFreeGpuVirtualAddress
NtGdiDdDDIGetAllocationPriority
NtGdiDdDDIGetCachedHybridQueryValue
NtGdiDdDDIGetContextInProcessSchedulingPriority
NtGdiDdDDIGetContextSchedulingPriority
NtGdiDdDDIGetDWMVerticalBlankEvent
NtGdiDdDDIGetDeviceState
NtGdiDdDDIGetDisplayModeList
NtGdiDdDDIGetMemoryBudgetTarget
NtGdiDdDDIGetMultiPlaneOverlayCaps
NtGdiDdDDIGetMultisampleMethodList
NtGdiDdDDIGetOverlayState
NtGdiDdDDIGetPostCompositionCaps
NtGdiDdDDIGetPresentHistory
NtGdiDdDDIGetPresentQueueEvent
NtGdiDdDDIGetProcessDeviceRemovalSupport
NtGdiDdDDIGetProcessSchedulingPriorityBand
NtGdiDdDDIGetProcessSchedulingPriorityClass
NtGdiDdDDIGetResourcePresentPrivateDriverData
NtGdiDdDDIGetRuntimeData
NtGdiDdDDIGetScanLine
NtGdiDdDDIGetSetSwapChainMetadata
NtGdiDdDDIGetSharedPrimaryHandle
NtGdiDdDDIGetSharedResourceAdapterLuid
NtGdiDdDDIGetSharedResourceAdapterLuidFlipManager
NtGdiDdDDIGetSwapChainSurfacePhysicalAddress
NtGdiDdDDIGetYieldPercentage
NtGdiDdDDIInvalidateActiveVidPn
NtGdiDdDDIInvalidateCache
NtGdiDdDDILock
NtGdiDdDDILock2
NtGdiDdDDIMakeResident
NtGdiDdDDIMapGpuVirtualAddress
NtGdiDdDDIMarkDeviceAsError
NtGdiDdDDINetDispGetNextChunkInfo
NtGdiDdDDINetDispQueryMiracastDisplayDeviceStatus
NtGdiDdDDINetDispQueryMiracastDisplayDeviceSupport
NtGdiDdDDINetDispStartMiracastDisplayDevice
NtGdiDdDDINetDispStopMiracastDisplayDevice
NtGdiDdDDIOfferAllocations
NtGdiDdDDIOpenAdapterFromDeviceName
NtGdiDdDDIOpenAdapterFromHdc
NtGdiDdDDIOpenAdapterFromLuid
NtGdiDdDDIOpenBundleObjectNtHandleFromName
NtGdiDdDDIOpenKeyedMutex
NtGdiDdDDIOpenKeyedMutex2
NtGdiDdDDIOpenKeyedMutexFromNtHandle
NtGdiDdDDIOpenNtHandleFromName
NtGdiDdDDIOpenProtectedSessionFromNtHandle
NtGdiDdDDIOpenResource
NtGdiDdDDIOpenResourceFromNtHandle
NtGdiDdDDIOpenSwapChain
NtGdiDdDDIOpenSyncObjectFromNtHandle
NtGdiDdDDIOpenSyncObjectFromNtHandle2
NtGdiDdDDIOpenSyncObjectNtHandleFromName
NtGdiDdDDIOpenSynchronizationObject
NtGdiDdDDIOutputDuplGetFrameInfo
NtGdiDdDDIOutputDuplGetMetaData
NtGdiDdDDIOutputDuplGetPointerShapeData
NtGdiDdDDIOutputDuplPresent
NtGdiDdDDIOutputDuplReleaseFrame
NtGdiDdDDIPollDisplayChildren
NtGdiDdDDIPresent
NtGdiDdDDIPresentMultiPlaneOverlay
NtGdiDdDDIPresentMultiPlaneOverlay2
NtGdiDdDDIPresentMultiPlaneOverlay3
NtGdiDdDDIPresentRedirected
NtGdiDdDDIQueryAdapterInfo
NtGdiDdDDIQueryAllocationResidency
NtGdiDdDDIQueryClockCalibration
NtGdiDdDDIQueryFSEBlock
NtGdiDdDDIQueryProcessOfferInfo
NtGdiDdDDIQueryProtectedSessionInfoFromNtHandle
NtGdiDdDDIQueryProtectedSessionStatus
NtGdiDdDDIQueryRemoteVidPnSourceFromGdiDisplayName
NtGdiDdDDIQueryResourceInfo
NtGdiDdDDIQueryResourceInfoFromNtHandle
NtGdiDdDDIQueryStatistics
NtGdiDdDDIQueryVidPnExclusiveOwnership
NtGdiDdDDIQueryVideoMemoryInfo
NtGdiDdDDIReclaimAllocations
NtGdiDdDDIReclaimAllocations2
NtGdiDdDDIReleaseKeyedMutex
NtGdiDdDDIReleaseKeyedMutex2
NtGdiDdDDIReleaseProcessVidPnSourceOwners
NtGdiDdDDIReleaseSwapChain
NtGdiDdDDIRemoveSurfaceFromSwapChain
NtGdiDdDDIRender
NtGdiDdDDIReserveGpuVirtualAddress
NtGdiDdDDISetAllocationPriority
NtGdiDdDDISetContextInProcessSchedulingPriority
NtGdiDdDDISetContextSchedulingPriority
NtGdiDdDDISetDisplayMode
NtGdiDdDDISetDodIndirectSwapchain
NtGdiDdDDISetFSEBlock
NtGdiDdDDISetGammaRamp
NtGdiDdDDISetHwProtectionTeardownRecovery
NtGdiDdDDISetMemoryBudgetTarget
NtGdiDdDDISetMonitorColorSpaceTransform
NtGdiDdDDISetProcessDeviceRemovalSupport
NtGdiDdDDISetProcessSchedulingPriorityBand
NtGdiDdDDISetProcessSchedulingPriorityClass
NtGdiDdDDISetQueuedLimit
NtGdiDdDDISetStablePowerState
NtGdiDdDDISetStereoEnabled
NtGdiDdDDISetSyncRefreshCountWaitTarget
NtGdiDdDDISetVidPnSourceHwProtection
NtGdiDdDDISetVidPnSourceOwner
NtGdiDdDDISetYieldPercentage
NtGdiDdDDIShareObjects
NtGdiDdDDISharedPrimaryLockNotification
NtGdiDdDDISharedPrimaryUnLockNotification
NtGdiDdDDISignalSynchronizationObject
NtGdiDdDDISignalSynchronizationObjectFromCpu
NtGdiDdDDISignalSynchronizationObjectFromGpu
NtGdiDdDDISignalSynchronizationObjectFromGpu2
NtGdiDdDDISubmitCommand
NtGdiDdDDISubmitCommandToHwQueue
NtGdiDdDDISubmitSignalSyncObjectsToHwQueue
NtGdiDdDDISubmitWaitForSyncObjectsToHwQueue
NtGdiDdDDITrimProcessCommitment
NtGdiDdDDIUnOrderedPresentSwapChain
NtGdiDdDDIUnlock
NtGdiDdDDIUnlock2
NtGdiDdDDIUpdateAllocationProperty
NtGdiDdDDIUpdateGpuVirtualAddress
NtGdiDdDDIUpdateOverlay
NtGdiDdDDIWaitForIdle
NtGdiDdDDIWaitForSynchronizationObject
NtGdiDdDDIWaitForSynchronizationObjectFromCpu
NtGdiDdDDIWaitForSynchronizationObjectFromGpu
NtGdiDdDDIWaitForVerticalBlankEvent
NtGdiDdDDIWaitForVerticalBlankEvent2
NtGdiDdDestroyFullscreenSprite
NtGdiDdNotifyFullscreenSpriteUpdate
NtGdiDdQueryVisRgnUniqueness
NtGdiDeleteColorTransform
NtGdiDescribePixelFormat
NtGdiDestroyOPMProtectedOutput
NtGdiDestroyPhysicalMonitor
NtGdiDoBanding
NtGdiDrawEscape
NtGdiDwmCreatedBitmapRemotingOutput
NtGdiEllipse
NtGdiEnableEudc
NtGdiEndDoc
NtGdiEndGdiRendering
NtGdiEndPage
NtGdiEngAlphaBlend
NtGdiEngAssociateSurface
NtGdiEngBitBlt
NtGdiEngCheckAbort
NtGdiEngComputeGlyphSet
NtGdiEngCopyBits
NtGdiEngCreateBitmap
NtGdiEngCreateClip
NtGdiEngCreateDeviceBitmap
NtGdiEngCreateDeviceSurface
NtGdiEngCreatePalette
NtGdiEngDeleteClip
NtGdiEngDeletePalette
NtGdiEngDeletePath
NtGdiEngDeleteSurface
NtGdiEngEraseSurface
NtGdiEngFillPath
NtGdiEngGradientFill
NtGdiEngLineTo
NtGdiEngLockSurface
NtGdiEngMarkBandingSurface
NtGdiEngPaint
NtGdiEngPlgBlt
NtGdiEngStretchBlt
NtGdiEngStretchBltROP
NtGdiEngStrokeAndFillPath
NtGdiEngStrokePath
NtGdiEngTextOut
NtGdiEngTransparentBlt
NtGdiEngUnlockSurface
NtGdiEnsureDpiDepDefaultGuiFontForPlateau
NtGdiEnumFonts
NtGdiEnumObjects
NtGdiEudcLoadUnloadLink
NtGdiExtFloodFill
NtGdiFONTOBJ_cGetAllGlyphHandles
NtGdiFONTOBJ_cGetGlyphs
NtGdiFONTOBJ_pQueryGlyphAttrs
NtGdiFONTOBJ_pfdg
NtGdiFONTOBJ_pifi
NtGdiFONTOBJ_pvTrueTypeFontFile
NtGdiFONTOBJ_pxoGetXform
NtGdiFONTOBJ_vGetInfo
NtGdiFlattenPath
NtGdiFontIsLinked
NtGdiForceUFIMapping
NtGdiFrameRgn
NtGdiFullscreenControl
NtGdiGetBitmapDpiScaleValue
NtGdiGetBoundsRect
NtGdiGetCOPPCompatibleOPMInformation
NtGdiGetCertificate
NtGdiGetCertificateByHandle
NtGdiGetCertificateSize
NtGdiGetCertificateSizeByHandle
NtGdiGetCharABCWidthsW
NtGdiGetCharacterPlacementW
NtGdiGetColorAdjustment
NtGdiGetColorSpaceforBitmap
NtGdiGetCurrentDpiInfo
NtGdiGetDCDpiScaleValue
NtGdiGetDeviceCaps
NtGdiGetDeviceCapsAll
NtGdiGetDeviceWidth
NtGdiGetDhpdev
NtGdiGetETM
NtGdiGetEmbUFI
NtGdiGetEmbedFonts
NtGdiGetEntry
NtGdiGetEudcTimeStampEx
NtGdiGetFontFileData
NtGdiGetFontFileInfo
NtGdiGetFontResourceInfoInternalW
NtGdiGetFontUnicodeRanges
NtGdiGetGlyphIndicesW
NtGdiGetGlyphIndicesWInternal
NtGdiGetGlyphOutline
NtGdiGetKerningPairs
NtGdiGetLinkedUFIs
NtGdiGetMiterLimit
NtGdiGetMonitorID
NtGdiGetNumberOfPhysicalMonitors
NtGdiGetOPMInformation
NtGdiGetOPMRandomNumber
NtGdiGetObjectBitmapHandle
NtGdiGetPath
NtGdiGetPerBandInfo
NtGdiGetPhysicalMonitorDescription
NtGdiGetPhysicalMonitors
NtGdiGetProcessSessionFonts
NtGdiGetPublicFontTableChangeCookie
NtGdiGetRealizationInfo
NtGdiGetServerMetaFileBits
NtGdiGetSpoolMessage
NtGdiGetStats
NtGdiGetStringBitmapW
NtGdiGetSuggestedOPMProtectedOutputArraySize
NtGdiGetTextExtentExW
NtGdiGetUFI
NtGdiGetUFIPathname
NtGdiGradientFill
NtGdiHLSurfGetInformation
NtGdiHLSurfSetInformation
NtGdiHT_Get8BPPFormatPalette
NtGdiHT_Get8BPPMaskPalette
NtGdiIcmBrushInfo
NtGdiInit
NtGdiInitSpool
NtGdiMakeFontDir
NtGdiMakeInfoDC
NtGdiMakeObjectUnXferable
NtGdiMakeObjectXferable
NtGdiMirrorWindowOrg
NtGdiMonoBitmap
NtGdiMoveTo
NtGdiOffsetClipRgn
NtGdiPATHOBJ_bEnum
NtGdiPATHOBJ_bEnumClipLines
NtGdiPATHOBJ_vEnumStart
NtGdiPATHOBJ_vEnumStartClipLines
NtGdiPATHOBJ_vGetBounds
NtGdiPathToRegion
NtGdiPlgBlt
NtGdiPolyDraw
NtGdiPolyTextOutW
NtGdiPtInRegion
NtGdiPtVisible
NtGdiQueryFonts
NtGdiRemoveFontResourceW
NtGdiRemoveMergeFont
NtGdiResetDC
NtGdiResizePalette
NtGdiRoundRect
NtGdiSTROBJ_bEnum
NtGdiSTROBJ_bEnumPositionsOnly
NtGdiSTROBJ_bGetAdvanceWidths
NtGdiSTROBJ_dwGetCodePage
NtGdiSTROBJ_vEnumStart
NtGdiScaleRgn
NtGdiScaleValues
NtGdiScaleViewportExtEx
NtGdiScaleWindowExtEx
NtGdiSelectBrush
NtGdiSelectClipPath
NtGdiSelectPen
NtGdiSetBitmapAttributes
NtGdiSetBrushAttributes
NtGdiSetColorAdjustment
NtGdiSetColorSpace
NtGdiSetFontXform
NtGdiSetIcmMode
NtGdiSetLinkedUFIs
NtGdiSetMagicColors
NtGdiSetOPMSigningKeyAndSequenceNumbers
NtGdiSetPUMPDOBJ
NtGdiSetPixelFormat
NtGdiSetRectRgn
NtGdiSetSizeDevice
NtGdiSetSystemPaletteUse
NtGdiSetTextJustification
NtGdiSetUMPDSandboxState
NtGdiStartDoc
NtGdiStartPage
NtGdiStrokeAndFillPath
NtGdiStrokePath
NtGdiSwapBuffers
NtGdiTransparentBlt
NtGdiUMPDEngFreeUserMem
NtGdiUnloadPrinterDriver
NtGdiUnmapMemFont
NtGdiUpdateColors
NtGdiUpdateTransform
NtGdiWidenPath
NtGdiXFORMOBJ_bApplyXform
NtGdiXFORMOBJ_iGetXform
NtGdiXLATEOBJ_cGetPalette
NtGdiXLATEOBJ_hGetColorTransform
NtGdiXLATEOBJ_iXlate
NtHWCursorUpdatePointer
NtInputSpaceRegionFromPoint
NtUserGetOwnerTransformedMonitorRect
NtIsOneCoreTransformMode
NtKSTInitialize
NtKSTWait
NtMITAccessibilityTimerNotification
NtMITActivateInputProcessing
NtMITConfigureVirtualTouchpad
NtMITCoreMsgKOpenConnectionTo
NtMITDeactivateInputProcessing
NtMITDisableMouseIntercept
NtMITDispatchCompletion
NtMITEnableMouseIntercept
NtMITGetCursorUpdateHandle
NtMITInitMinuserThread
NtMITMinuserSetInputTransformOffset
NtMITMinuserWindowDestroyed
NtMITPostMouseInputMessage
NtMITPostThreadEventMessage
NtMITPostWindowEventMessage
NtMITPrepareReceiveInputMessage
NtMITPrepareSendInputMessage
NtMITProcessDelegateCapturedPointers
NtMITSetInputCallbacks
NtMITSetInputDelegationMode
NtMITSetInputObservationState
NtMITSetKeyboardInputRoutingPolicy
NtMITSetKeyboardOverriderState
NtMITSetLastInputRecipient
NtMITSynthesizeKeyboardInput
NtMITSynthesizeMouseInput
NtMITSynthesizeTouchInput
NtMITUninitMinuserThread
NtMITUpdateInputGlobals
NtMapVisualRelativePoints
NtMinGetInputTransform
NtMinInteropCoreMessagingWithInput
NtMinQPeekForInput
NtMinQSuspendInputProcessing
NtMinQUpdateWakeMask
NtModerncoreBeginLayoutUpdate
NtModerncoreCreateDCompositionHwndTarget
NtModerncoreCreateGDIHwndTarget
NtModerncoreDestroyDCompositionHwndTarget
NtModerncoreDestroyGDIHwndTarget
NtModerncoreEnableResizeLayoutSynchronization
NtModerncoreGetNavigationWindowVisual
NtModerncoreGetResizeDCompositionSynchronizationObject
NtModerncoreGetWindowContentVisual
NtModerncoreIdleTimerThread
NtModerncoreIsResizeLayoutSynchronizationEnabled
NtModerncoreProcessConnect
NtModerncoreRegisterEnhancedNavigationWindowHandle
NtModerncoreRegisterNavigationWindowHandle
NtModerncoreSetNavigationServiceSid
NtModerncoreUnregisterNavigationWindowHandle
NtNotifyPresentToCompositionSurface
NtOpenCompositionSurfaceDirtyRegion
NtOpenCompositionSurfaceSectionInfo
NtOpenCompositionSurfaceSwapChainHandleInfo
NtQueryCompositionInputIsImplicit
NtQueryCompositionInputQueueAndTransform
NtQueryCompositionInputSink
NtQueryCompositionInputSinkLuid
NtQueryCompositionInputSinkViewId
NtQueryCompositionSurfaceBinding
NtQueryCompositionSurfaceFrameRate
NtQueryCompositionSurfaceHDRMetaData
NtQueryCompositionSurfaceRenderingRealization
NtQueryCompositionSurfaceStatistics
NtRIMAddInputObserver
NtRIMAreSiblingDevices
NtRIMDeviceIoControl
NtRIMEnableMonitorMappingForDevice
NtRIMFreeInputBuffer
NtRIMGetDevicePreparsedData
NtRIMGetDevicePreparsedDataLockfree
NtRIMGetDeviceProperties
NtRIMGetDevicePropertiesLockfree
NtRIMGetPhysicalDeviceRect
NtRIMGetSourceProcessId
NtRIMObserveNextInput
NtRIMOnAsyncPnpWorkNotification
NtRIMOnPnpNotification
NtRIMOnTimerNotification
NtRIMQueryDevicePath
NtRIMReadInput
NtRIMRegisterForInputEx
NtRIMRemoveInputObserver
NtRIMSetDeadzoneRotation
NtRIMSetExtendedDeviceProperty
NtRIMSetTestModeStatus
NtRIMUnregisterForInput
NtRIMUpdateInputObserverRegistration
NtSetCompositionSurfaceAnalogExclusive
NtSetCompositionSurfaceBufferUsage
NtSetCompositionSurfaceDirectFlipState
NtSetCompositionSurfaceIndependentFlipInfo
NtSetCompositionSurfaceStatistics
NtSetCursorInputSpace
NtSetPointerDeviceInputSpace
NtSetShellCursorState
NtTokenManagerConfirmOutstandingAnalogToken
NtTokenManagerCreateCompositionTokenHandle
NtTokenManagerCreateFlipObjectReturnTokenHandle
NtTokenManagerCreateFlipObjectTokenHandle
NtTokenManagerGetAnalogExclusiveSurfaceUpdates
NtTokenManagerGetAnalogExclusiveTokenEvent
NtTokenManagerOpenSectionAndEvents
NtTokenManagerThread
NtUnBindCompositionSurface
NtUpdateInputSinkTransforms
NtUserAcquireIAMKey
NtUserAcquireInteractiveControlBackgroundAccess
NtUserAddClipboardFormatListener
NtUserAddVisualIdentifier
NtUserAllowForegroundActivation
NtUserAllowSetForegroundWindow
NtUserArrangeIconicWindows
NtUserAssociateInputContext
NtUserAutoPromoteMouseInPointer
NtUserAutoRotateScreen
NtUserBeginDeferWindowPos
NtUserBeginLayoutUpdate
NtUserBlockInput
NtUserBroadcastImeShowStatusChange
NtUserBroadcastThemeChangeEvent
NtUserBuildHimcList
NtUserBuildPropList
NtUserCalculatePopupWindowPosition
NtUserCanBrokerForceForeground
NtUserCancelQueueEventCompletionPacket
NtUserChangeDisplaySettings
NtUserChangeWindowMessageFilter
NtUserChangeWindowMessageFilterEx
NtUserCheckAccessForIntegrityLevel
NtUserCheckImeShowStatusInThread
NtUserCheckProcessForClipboardAccess
NtUserCheckProcessSession
NtUserCheckWindowThreadDesktop
NtUserChildWindowFromPointEx
NtUserCitSetInfo
NtUserClearForeground
NtUserClearRunWakeBit
NtUserClearWakeMask
NtUserClearWindowState
NtUserClipCursor
NtUserCompositionInputSinkLuidFromPoint
NtUserCompositionInputSinkViewInstanceIdFromPoint
NtUserConfigureActivationObject
NtUserConfigureProcessGroupedForegroundPriorityBoost
NtUserConfirmResizeCommit
NtUserCreateActivationObject
NtUserCreateBaseWindow
NtUserCreateDCompositionHwndTarget
NtUserCreateDesktopEx
NtUserCreateEmptyCursorObject
NtUserCreateInputContext
NtUserCreateMenu
NtUserCreatePalmRejectionDelayZone
NtUserCreatePopupMenu
NtUserCreateSystemThreads
NtUserCreateWindowStation
NtUserCsDdeUninitialize
NtUserCtxDisplayIOCtl
NtUserDWP_GetEnabledPopupOffset
NtUserDeferWindowDpiChanges
NtUserDeferWindowPosAndBand
NtUserDeferredDesktopRotation
NtUserDelegateCapturePointers
NtUserDelegateInput
NtUserDeregisterShellHookWindow
NtUserDestroyActivationObject
NtUserDestroyCaret
NtUserDestroyDCompositionHwndTarget
NtUserDestroyInputContext
NtUserDestroyPalmRejectionDelayZone
NtUserDirectedYield
NtUserDisableImmersiveOwner
NtUserDisableProcessWindowFiltering
NtUserDisableProcessWindowsGhosting
NtUserDisableThreadIme
NtUserDiscardPointerFrameMessages
NtUserDisplayConfigGetDeviceInfo
NtUserDisplayConfigSetDeviceInfo
NtUserDoInitMessagePumpHook
NtUserDoSoundConnect
NtUserDoSoundDisconnect
NtUserDoUninitMessagePumpHook
NtUserDownlevelTouchpad
NtUserDragDetect
NtUserDragObject
NtUserDrainThreadCoreMessagingCompletions
NtUserDrawAnimatedRects
NtUserDrawCaption
NtUserDrawCaptionTemp
NtUserDrawMenuBar
NtUserDrawMenuBarTemp
NtUserDwmGetRemoteSessionOcclusionEvent
NtUserDwmGetRemoteSessionOcclusionState
NtUserDwmKernelShutdown
NtUserDwmKernelStartup
NtUserDwmLockScreenUpdates
NtUserDwmValidateWindow
NtUserEnableChildWindowDpiMessage
NtUserEnableIAMAccess
NtUserEnableModernAppWindowKeyboardIntercept
NtUserEnableMouseInPointer
NtUserEnableMouseInPointerForThread
NtUserEnableMouseInPointerForWindow
NtUserEnableMouseInputForCursorSuppression
NtUserEnableNonClientDpiScaling
NtUserEnableResizeLayoutSynchronization
NtUserEnableSessionForMMCSS
NtUserEnableShellWindowManagementBehavior
NtUserEnableSoftwareCursorForScreenCapture
NtUserEnableTouchPad
NtUserEnableWindow
NtUserEnableWindowGDIScaledDpiMessage
NtUserEnableWindowResizeOptimization
NtUserEndMenu
NtUserEnsureDpiDepSysMetCacheForPlateau
NtUserEnumClipboardFormats
NtUserEvent
NtUserFlashWindowEx
NtUserForceEnableNumpadTranslation
NtUserForceWindowToDpiForTest
NtUserFrostCrashedWindow
NtUserFunctionalizeDisplayConfig
NtUserGetActiveProcessesDpis
NtUserSetSensorPresence
NtUserGetAppImeLevel
NtUserGetAutoRotationState
NtUserGetCIMSSM
NtUserGetCaretPos
NtUserGetClassIcoCur
NtUserGetClipCursor
NtUserGetClipboardAccessToken
NtUserGetClipboardViewer
NtUserGetComboBoxInfo
NtUserGetCurrentDpiInfoForWindow
NtUserGetCurrentInputMessageSource
NtUserGetCursor
NtUserGetCursorInfo
NtUserGetCursorPos
NtUserGetDCompositionHwndBitmap
NtUserGetDManipHookInitFunction
NtUserGetDesktopID
NtUserGetDesktopVisualTransform
NtUserGetDeviceChangeInfo
NtUserGetDisplayAutoRotationPreferences
NtUserGetDisplayAutoRotationPreferencesByProcessId
NtUserGetDisplayConfigBufferSizes
NtUserGetDpiForCurrentProcess
NtUserGetDpiForMonitor
NtUserGetExtendedPointerDeviceProperty
NtUserGetGestureConfig
NtUserGetGestureExtArgs
NtUserGetGestureInfo
NtUserGetGuiResources
NtUserGetHDevName
NtUserGetHimetricScaleFactorFromPixelLocation
NtUserGetIMEShowStatus
NtUserGetImeHotKey
NtUserGetImeInfoEx
NtUserGetInputContainerId
NtUserGetInputDesktop
NtUserGetInputEvent
NtUserGetInputLocaleInfo
NtUserGetInteractiveControlDeviceInfo
NtUserGetInteractiveControlInfo
NtUserGetInteractiveCtrlSupportedWaveforms
NtUserGetInternalWindowPos
NtUserGetKeyNameText
NtUserGetKeyboardLayout
NtUserGetKeyboardLayoutName
NtUserGetKeyboardType
NtUserGetLayeredWindowAttributes
NtUserGetListBoxInfo
NtUserGetMenuIndex
NtUserGetMenuItemRect
NtUserGetMessagePos
NtUserGetMinuserIdForBaseWindow
NtUserGetModernAppWindow
NtUserGetMouseMovePointsEx
NtUserGetOemBitmapSize
NtUserGetPhysicalDeviceRect
NtUserGetPointerCursorId
NtUserGetPointerDevice
NtUserGetPointerDeviceCursors
NtUserGetPointerDeviceInputSpace
NtUserGetPointerDeviceOrientation
NtUserGetPointerDeviceProperties
NtUserGetPointerDeviceRects
NtUserGetPointerDevices
NtUserGetPointerFrameTimes
NtUserGetPointerInfoList
NtUserGetPointerInputTransform
NtUserGetPointerProprietaryId
NtUserGetPointerType
NtUserGetPrecisionTouchPadConfiguration
NtUserGetPriorityClipboardFormat
NtUserGetProcessDefaultLayout
NtUserGetProcessDpiAwarenessContext
NtUserGetProcessUIContextInformation
NtUserGetQueueIocp
NtUserGetQueueStatus
NtUserGetQueueStatusReadonly
NtUserGetRawInputBuffer
NtUserGetRawInputData
NtUserGetRawInputDeviceInfo
NtUserGetRawInputDeviceList
NtUserGetRawPointerDeviceData
NtUserGetRegisteredRawInputDevices
NtUserGetRequiredCursorSizes
NtUserGetResizeDCompositionSynchronizationObject
NtUserGetSendMessageReceiver
NtUserGetSharedWindowData
NtUserGetSysMenuOffset
NtUserYieldTask
NtUserGetSystemContentRects
NtUserGetSystemDpiForProcess
NtUserGetTopLevelWindow
NtUserGetTouchInputInfo
NtUserGetTouchValidationStatus
NtUserGetUniformSpaceMapping
NtUserGetUnpredictedMessagePos
NtUserGetUpdatedClipboardFormats
NtUserGetWOWClass
NtUserGetWinStationInfo
NtUserGetWindowBand
NtUserGetWindowCompositionAttribute
NtUserGetWindowCompositionInfo
NtUserGetWindowContextHelpId
NtUserGetWindowDisplayAffinity
NtUserGetWindowFeedbackSetting
NtUserGetWindowMinimizeRect
NtUserGetWindowProcessHandle
NtUserGetWindowRgnEx
NtUserGetWindowThreadProcessId
NtUserGetWindowTrackInfoAsync
NtUserGhostWindowFromHungWindow
NtUserHandleDelegatedInput
NtUserHandleSystemThreadCreationFailure
NtUserHardErrorControl
NtUserHideCursorNoCapture
NtUserHidePointerContactVisualization
NtUserHiliteMenuItem
NtUserHungWindowFromGhostWindow
NtUserHwndQueryRedirectionInfo
NtUserHwndSetRedirectionInfo
NtUserImpersonateDdeClientWindow
NtUserInheritWindowMonitor
NtUserInitAnsiOem
NtUserInitRunThread
NtUserInitTask
NtUserInitThreadCoreMessagingIocp
NtUserInitialize
NtUserInitializeClientPfnArrays
NtUserInitializeGenericHidInjection
NtUserInitializeInputDeviceInjection
NtUserInitializePointerDeviceInjection
NtUserInitializePointerDeviceInjectionEx
NtUserInitializeTouchInjection
NtUserInjectDeviceInput
NtUserInjectGenericHidInput
NtUserInjectGesture
NtUserInjectKeyboardInput
NtUserInjectMouseInput
NtUserInjectPointerInput
NtUserInjectTouchInput
NtUserInteractiveControlQueryUsage
NtUserInternalGetWindowIcon
NtUserInternalToUnicode
NtUserIsChildWindowDpiMessageEnabled
NtUserIsMouseInPointerEnabled
NtUserIsMouseInputEnabled
NtUserIsNonClientDpiScalingEnabled
NtUserIsQueueAttached
NtUserIsResizeLayoutSynchronizationEnabled
NtUserIsTopLevelWindow
NtUserIsTouchWindow
NtUserIsWindowBroadcastingDpiToChildren
NtUserIsWindowGDIScaledDpiMessageEnabled
NtUserKillSystemTimer
NtUserLW_LoadFonts
NtUserLayoutCompleted
NtUserLinkDpiCursor
NtUserLoadCursorsAndIcons
NtUserLoadKeyboardLayoutEx
NtUserLoadUserApiHook
NtUserLockCursor
NtUserLockSetForegroundWindow
NtUserLockWindowStation
NtUserLockWorkStation
NtUserLogicalToPerMonitorDPIPhysicalPoint
NtUserLogicalToPhysicalDpiPointForWindow
NtUserLogicalToPhysicalPoint
NtUserMNDragLeave
NtUserMNDragOver
NtUserMagControl
NtUserMagGetContextInformation
NtUserMagSetContextInformation
NtUserMapDesktopObject
NtUserMapPointsByVisualIdentifier
NtUserMarkWindowForRawMouse
NtUserMenuItemFromPoint
NtUserMessageBeep
NtUserMinInitialize
NtUserMinMaximize
NtUserModifyWindowTouchCapability
NtUserMsgWaitForMultipleObjectsEx
NtUserNavigateFocus
NtUserNlsKbdSendIMENotification
NtUserNotifyIMEStatus
NtUserNotifyOverlayWindow
NtUserOpenInputDesktop
NtUserOpenThreadDesktop
NtUserPaintMonitor
NtUserPerMonitorDPIPhysicalToLogicalPoint
NtUserPhysicalToLogicalDpiPointForWindow
NtUserPhysicalToLogicalPoint
NtUserPlayEventSound
NtUserPostKeyboardInputMessage
NtUserPostQuitMessage
NtUserPrepareForLogoff
NtUserPrintWindow
NtUserProcessInkFeedbackCommand
NtUserPromoteMouseInPointer
NtUserPromotePointer
NtUserQueryBSDRWindow
NtUserQueryDisplayConfig
NtUserQueryInformationThread
NtUserQueryInputContext
NtUserQuerySendMessage
NtUserRealChildWindowFromPoint
NtUserRealWaitMessageEx
NtUserRealizePalette
NtUserReassociateQueueEventCompletionPacket
NtUserRedrawFrame
NtUserRedrawFrameAndHook
NtUserRedrawTitle
NtUserRegisterBSDRWindow
NtUserRegisterDManipHook
NtUserRegisterEdgy
NtUserRegisterErrorReportingDialog
NtUserRegisterGhostWindow
NtUserRegisterHotKey
NtUserRegisterLPK
NtUserRegisterLogonProcess
NtUserRegisterManipulationThread
NtUserRegisterPointerDeviceNotifications
NtUserRegisterPointerInputTarget
NtUserRegisterRawInputDevices
NtUserRegisterServicesProcess
NtUserRegisterSessionPort
NtUserRegisterShellHookWindow
NtUserRegisterShellPTPListener
NtUserRegisterSiblingFrostWindow
NtUserRegisterSystemThread
NtUserRegisterTasklist
NtUserRegisterTouchHitTestingWindow
NtUserRegisterTouchPadCapable
NtUserRegisterUserApiHook
NtUserRegisterUserHungAppHandlers
NtUserRegisterWindowArrangementCallout
NtUserReleaseCapture
NtUserReleaseDC
NtUserReleaseDwmHitTestWaiters
NtUserRemoteConnect
NtUserRemoteConnectState
NtUserRemoteConsoleShadowStop
NtUserRemoteDisconnect
NtUserRemoteNotify
NtUserRemotePassthruDisable
NtUserRemotePassthruEnable
NtUserRemoteReconnect
NtUserRemoteRedrawRectangle
NtUserRemoteRedrawScreen
NtUserRemoteShadowCleanup
NtUserRemoteShadowSetup
NtUserRemoteShadowStart
NtUserRemoteShadowStop
NtUserRemoteStopScreenUpdates
NtUserRemoteThinwireStats
NtUserRemoveClipboardFormatListener
NtUserRemoveInjectionDevice
NtUserRemoveQueueCompletion
NtUserRemoveVisualIdentifier
NtUserReplyMessage
NtUserReportInertia
NtUserResetDblClk
NtUserResolveDesktopForWOW
NtUserRestoreWindowDpiChanges
NtUserScaleSystemMetricForDPIWithoutCache
NtUserScheduleDispatchNotification
NtUserSendEventMessage
NtUserSendInteractiveControlHapticsReport
NtUserSetActivationFilter
NtUserSetActiveProcessForMonitor
NtUserSetAppImeLevel
NtUserSetAutoRotation
NtUserSetBridgeWindowChild
NtUserSetBrokeredForeground
NtUserSetCalibrationData
NtUserSetCancelRotationDelayHintWindow
NtUserSetCaretBlinkTime
NtUserSetCaretPos
NtUserSetChildWindowNoActivate
NtUserSetClassWord
NtUserSetCoreWindow
NtUserSetCoreWindowPartner
NtUserSetCursorContents
NtUserSetCursorPos
NtUserSetDesktopColorTransform
NtUserSetDesktopVisualInputSink
NtUserSetDialogControlDpiChangeBehavior
NtUserSetDialogPointer
NtUserSetDialogSystemMenu
NtUserSetDisplayAutoRotationPreferences
NtUserSetDisplayConfig
NtUserSetDisplayMapping
NtUserSetDoubleClickTime
NtUserSetDpiForWindow
NtUserSetFallbackForeground
NtUserSetFeatureReportResponse
NtUserSetForegroundRedirectionForActivationObject
NtUserSetForegroundWindow
NtUserSetForegroundWindowForApplication
NtUserSetFullscreenMagnifierOffsetsDWMUpdated
NtUserSetGestureConfig
NtUserSetImeHotKey
NtUserSetImeInfoEx
NtUserSetImeOwnerWindow
NtUserSetInputServiceState
NtUserSetInteractiveControlFocus
NtUserSetInteractiveCtrlRotationAngle
NtUserSetInternalWindowPos
NtUserSetLayeredWindowAttributes
NtUserSetMagnificationDesktopMagnifierOffsetsDWMUpdated
NtUserSetManipulationInputTarget
NtUserSetMenu
NtUserSetMenuContextHelpId
NtUserSetMenuFlagRtoL
NtUserSetMessageExtraInfo
NtUserSetMirrorRendering
NtUserSetModernAppWindow
NtUserSetMonitorWorkArea
NtUserSetMouseInputRateLimitingTimer
NtUserSetMsgBox
NtUserSetObjectInformation
NtUserSetPrecisionTouchPadConfiguration
NtUserSetProcessDefaultLayout
NtUserSetProcessDpiAwarenessContext
NtUserSetProcessInteractionFlags
NtUserSetProcessLaunchForegroundPolicy
NtUserSetProcessMousewheelRoutingMode
NtUserSetProcessRestrictionExemption
NtUserSetProcessUIAccessZorder
NtUserSetProgmanWindow
NtUserSetSharedWindowData
NtUserSetShellChangeNotifyHWND
NtUserSetShellWindowEx
NtUserSetSysColors
NtUserSetSysMenu
NtUserSetSystemContentRects
NtUserSetSystemCursor
NtUserSetSystemTimer
NtUserSetTSFEventState
NtUserSetTargetForResourceBrokering
NtUserSetTaskmanWindow
NtUserSetThreadInputBlocked
NtUserSetThreadLayoutHandles
NtUserSetThreadQueueMergeSetting
NtUserSetVisible
NtUserSetWaitForQueueAttach
NtUserSetWatermarkStrings
NtUserSetWindowBand
NtUserSetWindowCompositionAttribute
NtUserSetWindowCompositionTransition
NtUserSetWindowContextHelpId
NtUserSetWindowDisplayAffinity
NtUserSetWindowFeedbackSetting
NtUserSetWindowRgnEx
NtUserSetWindowShowState
NtUserSetWindowState
NtUserSetWindowStationUser
NtUserShellSetWindowPos
NtUserShowCursor
NtUserShowOwnedPopups
NtUserShowStartGlass
NtUserShowSystemCursor
NtUserShutdownBlockReasonCreate
NtUserShutdownBlockReasonQuery
NtUserShutdownReasonDestroy
NtUserSignalRedirectionStartComplete
NtUserSlicerControl
NtUserSoundSentry
NtUserStopAndEndInertia
NtUserSwapMouseButton
NtUserSwitchDesktop
NtUserSwitchToThisWindow
NtUserSystemParametersInfoForDpi
NtUserTestForInteractiveUser
NtUserThreadMessageQueueAttached
NtUserTraceLoggingSendMixedModeTelemetry
NtUserTrackPopupMenuEx
NtUserTransformPoint
NtUserTransformRect
NtUserUndelegateInput
NtUserUnhookWindowsHook
NtUserUnloadKeyboardLayout
NtUserUnlockWindowStation
NtUserUnregisterHotKey
NtUserUnregisterSessionPort
NtUserUnregisterUserApiHook
NtUserUpdateClientRect
NtUserUpdateDefaultDesktopThumbnail
NtUserUpdateInputContext
NtUserUpdateInstance
NtUserUpdateLayeredWindow
NtUserUpdatePerUserImmEnabling
NtUserUpdatePerUserSystemParameters
NtUserUpdateWindow
NtUserUpdateWindowInputSinkHints
NtUserUpdateWindowTrackingInfo
NtUserUpdateWindows
NtUserUserHandleGrantAccess
NtUserUserPowerCalloutWorker
NtUserValidateHandleSecure
NtUserValidateRgn
NtUserWOWCleanup
NtUserWOWModuleUnload
NtUserWaitAvailableMessageEx
NtUserWaitForInputIdle
NtUserWaitForMsgAndEvent
NtUserWaitForRedirectionStartComplete
NtUserWakeRITForShutdown
NtUserWindowFromDC
NtUserWindowFromPhysicalPoint
NtUserZapActiveAndFocus
NtValidateCompositionSurfaceHandle
NtVisualCaptureBits
NtUserSetClassLongPtr
NtUserSetWindowLongPtr

auto-derived FSM for usermode dlls

$
0
0

As expected results of auto-derived FSM for usermode dlls are much worse - for example on rpcrt4.dll can be found only 76 symbols from 228. It's because code in usermode contains much fewer unique constants (like NTSTATUS or allocation tags in kernel). So we need to use some additional data to make edges more distinguishable. Lets consider several candidates

load_config

Contains addresses of SecurityCookie and ptrs to GuardCFCheckFunctionPointer & GuardCFDispatchFunctionPointer. At least knowing SecurityCookie we can distinguish loading of some address in .data section from loading of cookies in prolog/epilogue of functions. But results are almost the same - 78 from 228

delayed import

New source of data missing in kernel mode. So I added new state to FSM - call_dimp, almost the same as call_imp but for delayed IAT. As expected results have grown - 109 from 228

constants in .rdata section

arm64 code can use not only ldr from constant pool but regular const data in .rdata section - for example strings for GetProcAddress etc. Lets see how looks such code:

 ADRP            X8, #aFeclientinitia@PAGE ; "FeClientInitialize"
 ADD             X1, X8, #aFeclientinitia@PAGEOFF ; "FeClientInitialize"
 ADRP            X9, #__imp_GetProcAddress@PAGE
 ADD             X8, X9, #__imp_GetProcAddress@PAGEOFF
 LDAR            X9, [X8]
 BLR             X9

For each add instruction we must check if address located in .rdata. But what length of constant? Well, bcs I build very simple FSM without typization - I can`t detect type of constant. So I decided just to use first 8 bytes. Then as with constant pool counting the number of these 8-byte constants in .rdata section and selected least common. Results - 131 found symbols from 228 - 57%. I think this is perfect results for dumb FSM with only 13 states

fsm rules syntax

$
0
0

I added saving and loading of FSM rules in file - so now you can edit them (or perhaps even write new manually) and then apply with new tool afsm. So lets see how it works

  1. We must make functions distinguishable. Functions must be either exported or contain loading of some constant - from constant pool or from .rdata section
  2. Then this functions disassembling and FSM rules applied to code-flow graph. There may be several results, so I added global storage - it can be accessed by index from any rules (but sure this storage belongs to each processed file). Storage logic cannot be auto-derived so you should write such rules manually - storing states must have "stg" prefix with index
Each rule starts with "section" keyword - it is section where located address which you want to find (you can use comments starting with '#'). Then you must pick function. If functions is exported it`s easy - "func" export_name, if not - just pick section where this function located with "fsection" section_name
Then follow one or more states of FSM:
  • load - loading from "section". Can have prefix stg N to remember this address
  • store - storing to "section". Can have prefix stg N to remember this address
  • ldrb - like "load" but for 1 byte
  • ldrh - like "load" but for 2 bytes
  • strb - like "store" but for 1 byte
  • strh - like "store" but for 2 byte
  • gload index - load address from storage with index
  • gstore index - store to address from storage with index
  • const - load some constant from constant pool
  • rdata - load some 8 byte constant from .rdata section
  • guid - load 16 byte guid from .rdata section. Actually rdata and guid could be one state with variable size but I am too lazy
  • call_imp - call some imported function from IAT
  • call_dimp - call some function from delayed IAT
  • call_exp - call exported function
  • call - just some call, perhaps located in specific section. Can have prefix stg N to remember this address
  • gcall index - call function with address in storage

Lets see example - say we want to find MCGEN_TRACE_CONTEXTs in kernel - registered with non-exported function McGenEventRegister_EtwRegister, There are 3 functions where this call occurs:
  • FsRtlpHeatRegisterVolume
  • IoInitSystemPreDrivers
  • PnpDiagInitialize
none of them are exported. Try write rules for them
# FsRtlpHeatRegisterVolume - located in PAGE section
section .data
fsection PAGE
call_exp ExAcquireResourceExclusiveLite
# MS_StorageTiering_Provider_Context - store in index 2
stg2 load
# MS_StorageTiering_Provider
guid FC 55 0C 99 62 26 F6 47 B7 D7 EB 3C 02 7C B1 3F
stg1 call

# IoInitSystemPreDrivers - located in INIT section
section .data
fsection INIT
call_imp ExpInitializeStateSeparationPhase0
# IoTraceHandle - store in index 3
stg3 load
# IoTraceProvider
guid BD CA 03 A1 42 82 93 4A 8D F5 1C DF 3B 3F 26 A6
call_exp EtwRegister
# IoMgrProvider_Context - store in index 4
stg4 load
# IoMgrProvider
guid 86 F5 F1 AB 50 2E A8 4B 92 8D 49 04 4E 6F 0D B7
# call to MS_StorageTiering_Provider - stored in first rule with index 1
gcall 1

# PnpDiagInitialize - located in INIT section
section .data
fsection INIT
# MS_KernelPnP_Provider_Context - store in index 5
stg5 load
# MS_KernelPnP_Provider
guid 39 5A 20 9C 50 12 7D 48 AB D7 E8 31 C6 29 05 39
# call to MS_StorageTiering_Provider - stored in first rule with index 1
gcall 1

As you can see I just store address of McGenEventRegister_EtwRegister in first rule with index 1 and then use gcall 1 as last state - just to be sure if this function really was called. Remaining indexes described in comments. Apply this rules to kernel 20251:
afsm.exe -a D:\src\armpatched\Release\mc.fsm D:\work\kernel\w10\20251\arm\ntoskrnl.exe
[0] D:\work\kernel\w10\20251\arm\ntoskrnl.exe: found at 0
 1 - 399238
 2 - C0DBE0
[0] D:\work\kernel\w10\20251\arm\ntoskrnl.exe: found at 0
 1 - 399238
 2 - C0DBE0
 3 - C4A5D8
 4 - C0A280
[0] D:\work\kernel\w10\20251\arm\ntoskrnl.exe: found at 0
 1 - 399238
 2 - C0DBE0
 3 - C4A5D8
 4 - C0A280
 5 - C04780

Result are in storage - for example C0DBE0 - RVA of MS_StorageTiering_Provider_Context bcs it was stored with index 2 etc. 
Now run this rules on kernel 18362:
afsm.exe -a D:\src\armpatched\Release\mc.fsm D:\work\kernel\w10\18362\arm\ntoskrnl.exe
[0] D:\work\kernel\w10\18362\arm\ntoskrnl.exe: found at 0
 1 - 1942A8
 2 - 3561A0
[0] D:\work\kernel\w10\18362\arm\ntoskrnl.exe: found at 0
 1 - 1942A8
 2 - 3561A0
 5 - 352E20

Second rules has no match - it`s bcs IoMgrTraceHandle registered with EtwRegister on old versions of kernel, so lets add new rule:
# IoInitSystemPreDrivers on old kernel
section .data
fsection INIT
call_imp ExpInitializeStateSeparationPhase0
stg3 load
guid BD CA 03 A1 42 82 93 4A 8D F5 1C DF 3B 3F 26 A6
call_exp EtwRegister
# IoMgrTraceHandle - store in index 6
stg6 load
guid 86 F5 F1 AB 50 2E A8 4B 92 8D 49 04 4E 6F 0D B7
call_exp EtwRegister

You can ask me - wait, function IoInitSystemPreDrivers is so long, why first state which you want is call imported ExpInitializeStateSeparationPhase0? Bcs I don`t care about other used variables - I want only build FSM to extract addresses of IoTraceHandle & IoMgrProvider_Context
Viewing all 265 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>