среда, 9 августа 2017 г.

wincheck rc8.58

  • add support of numerous versions of windows 10 insider preview - up to 16257
  • add -j option to dump jobs
  • add -dwf option to dump win32k filtering bitmaps
  • add support of DelegatedNtdll
  • add dumping of kprocess.LdtBaseAddress &LdtTableLength (based on this paper)

четверг, 13 июля 2017 г.

win32k calls filtering on w10

Lets see on some functions from W32pServiceTableFilter on w10 build 16215:
  push    ebp
  mov     ebp, esp
  push    2 ; call index
  call    _IsWin32KSyscallFiltered@4    ; IsWin32KSyscallFiltered(x)
  test    al, al
  jz      short loc_1361D
  lea     ecx, aNtusersetsenso          ; "NtUserSetSensorPresence"
  mov     edx, 2
  call    @NtUserWin32kSysCallFilterStub@8 ; NtUserWin32kSysCallFilterStub(x,x)
  call    _PsIsWin32KFilterEnabled@0    ; PsIsWin32KFilterEnabled()
  test    al, al
  jz      short loc_1361D
  lea     edx, _W32pServiceTableFilter
  mov     ecx, cs:_W32pServiceLimitFilter
  mov     eax, 2 ; call index
  lea     edx, [edx+ecx*4]
  movsx   eax, byte ptr [eax+edx]
  or      eax, eax
  jle     short loc_13619
  mov     eax, 0C000001Ch ;
  mov     esp, ebp
  pop     ebp
loc_1361D: ; call original function
  mov     esp, ebp
  pop     ebp
  jmp     _NtUserSetSensorPresence@4    ; NtUserSetSensorPresence(x)

In some case this stub just pass control to original function (NtUserSetSensorPresence in this case) if IsWin32KSyscallFiltered or PsIsWin32KFilterEnabled returned 0, returns STATUS_INVALID_SYSTEM_SERVICE or just do nothing. Last condition depends from byte stored with call index behind W32pServiceTableFilter, so we can write simple idc script to dump all functions which will return STATUS_INVALID_SYSTEM_SERVICE:

static main(void)
  auto  cnt, addr, tab, ftab, i, fp, name;
  addr = LocByName("_W32pServiceLimitFilter");
  if ( addr == BADADDR )
    Warn("Cannot find W32pServiceLimitFilter");
  cnt = Dword(addr);
  tab = LocByName("_W32pServiceTableFilter");
  if ( tab == BADADDR )
    Warn("Cannot find W32pServiceTableFilter");
  ftab = cnt * 4 + tab;
  fp = fopen("wf32.dmp", "w");
  for ( i = 0; i < cnt; i++, tab = tab + 4, ftab = ftab + 1 )
    if ( Byte(ftab) )
      addr = Dword(tab);
      name = Name(addr);
      fprintf(fp, "[%d] \"%s\",\n", i, name);

четверг, 6 июля 2017 г.


It seems that since est. w10 build 15007 you can have more than one loaded 32bit ntdll.dll
Function LdrpLoadDelegatedNtdll query key DelegatedNtdll via LdrQueryImageFileKeyOption then appends this value to \\SystemRoot\\system32\\ and loads it. Sure this required changes in callbacks propagation logic

There is table LdrpDelegatedNtdllExports which just hold pairs of exported symbol and offset to it "delegated" ptr:
  • LdrInitializeThunk -> LdrDelegatedLdrInitializeThunk
  • RtlUserThreadStart -> LdrDelegatedRtlUserThreadStart
  • RtlDispatchAPC -> LdrDelegatedRtlDispatchAPC
  • KiUserExceptionDispatcher -> LdrDelegatedKiUserExceptionDispatcher
  • KiUserApcDispatcher -> LdrDelegatedKiUserApcDispatcher
  • KiUserCallbackDispatcher -> LdrDelegatedKiUserCallbackDispatcher
  • KiRaiseUserExceptionDispatcher -> LdrDelegatedKiRaiseUserExceptionDispatcher
  • LdrSystemDllInitBlock -> LdrDelegatedSystemDllInitBlock
  • LdrpChildNtdll -> LdrpChildNtdllPointer
  • LdrParentInterlockedPopEntrySList -> LdrpParentInterlockedPopEntrySListPointer
  • LdrParentRtlInitializeNtUserPfn -> LdrpParentRtlInitializeNtUserPfnPointer
  • LdrParentRtlResetNtUserPfn -> LdrpParentRtlResetNtUserPfnPointer
  • LdrParentRtlRetrieveNtUserPfn -> LdrpParentRtlRetrieveNtUserPfnPointer

Lets see how this "delegated" pfns works

пятница, 16 июня 2017 г.

EPROCESS.MitigationFlags in w10 build 16215

Lets see EPROCESS.Flags3 in w10 build 16193:
unsigned long Flags3;
unsigned long Minimal:0:1;
unsigned long ReplacingPageRoot:1:1;
unsigned long DisableNonSystemFonts:2:1;
unsigned long AuditNonSystemFontLoading:3:1;
unsigned long Crashed:4:1;
unsigned long JobVadsAreTracked:5:1;
unsigned long VadTrackingDisabled:6:1;
unsigned long AuxiliaryProcess:7:1;
unsigned long SubsystemProcess:8:1;
unsigned long IndirectCpuSets:9:1;
unsigned long InPrivate:a:1;
unsigned long ProhibitRemoteImageMap:b:1;
unsigned long ProhibitLowILImageMap:c:1;
unsigned long SignatureMitigationOptIn:d:1;
unsigned long DisableDynamicCodeAllowOptOut:e:1;
unsigned long EnableFilteredWin32kAPIs:f:1;
unsigned long AuditFilteredWin32kAPIs:10:1;
unsigned long PreferSystem32Images:11:1;
unsigned long RelinquishedCommit:12:1;
unsigned long Reserved:13:1;
unsigned long HighGraphicsPriority:14:1;
unsigned long CommitFailLogged:15:1;
unsigned long ReserveFailLogged:16:1;
unsigned long DisableDynamicCodeAllowRemoteDowngrade:17:1;
unsigned long LoaderIntegrityContinuityEnabled:18:1;
unsigned long LoaderIntegrityContinuityAudit:19:1;
unsigned long ControlFlowGuardExportSuppressionEnabled:1a:1;
unsigned long FatalAccessTerminationRequested:1b:1;
unsigned long DisableSystemAllowedCpuSet:1c:1;
unsigned long ControlFlowGuardStrict:1d:1;

and compare it with EPROCESS.Flags3 in w10 build 16215:
unsigned long Flags3;
unsigned long Minimal:0:1;
unsigned long ReplacingPageRoot:1:1;
unsigned long Crashed:2:1;
unsigned long JobVadsAreTracked:3:1;
unsigned long VadTrackingDisabled:4:1;
unsigned long AuxiliaryProcess:5:1;
unsigned long SubsystemProcess:6:1;
unsigned long IndirectCpuSets:7:1;
unsigned long RelinquishedCommit:8:1;
unsigned long HighGraphicsPriority:9:1;
unsigned long CommitFailLogged:a:1;
unsigned long ReserveFailLogged:b:1;
unsigned long SystemProcess:c:1;

dramatic difference

понедельник, 5 июня 2017 г.

how to find PspUniqueJobIdTable

In his cool presentation Alex Ionescu said:
PspUniqueJobIdTable - no way to open/enumerate
Sure there are always some ways. Lets see xrefs to PspUniqueJobIdTable:
  • PspJobDelete
  • NtCreateJobObject
  • PspInitializeJobStructures
no exported functions in this list (well, NtCreateJobObject can be considered as such). Looks deep in PspJobDelete: 

loc_14001B6B4:                          ; CODE XREF: PspJobDelete+2A3
                                        ; PspJobDelete+17FEA8
  test    dword ptr [rbx+518h], 40000000h ; EJOB.JobFlags
  jnz     loc_14019B3AD

loc_14001B6C4:                          ; CODE XREF: PspJobDelete+17FEB6

  mov     rax, gs:188h
  dec     word ptr [rax+1E4h]
  mov     eax, [rbx+4C4h]               ; EJOB.JobId
  test    eax, eax
  jz      short loc_14001B701
  mov     rcx, cs:PspUniqueJobIdTable
  mov     edx, eax
  call    ExMapHandleToPointer

There is very long and noticeable signature for testing of EJOB.JobFlags with value 0x40000000: 18 05 00 00 00 00 00 40
If you searching it in .text section you get only 5-6 matches. Now question is how to get offset to EJOB.JobFlags. It can be done from exported function PsGetCurrentSilo:
PsGetCurrentSilo proc near
  mov     rax, gs:188h
  cmp     qword ptr [rax+7C8h], 0FFFFFFFFFFFFFFFDh
  jnz     short loc_1400B61BF
  mov     rax, [rax+220h]               ; KTHREAD.Process
  mov     rax, [rax+3B0h]               ; EPROCESS.Job
  test    rax, rax
  jz      short locret_1400B61BE

loc_1400B61A6:                          ; CODE XREF: PsGetCurrentSilo+3Cj
  test    dword ptr [rax+518h], 40000000h ; EJOB.JobFlags

And few words about enumerating - it`s just good old HANDLE_TABLE, so we can use ExEnumHandleTable and get all Jobs IDs

понедельник, 29 мая 2017 г.

wincheck rc8.57