Windows -! -adresse-kommandoen viser en anden værdi for den indledende brugerstørrelse for brugermodus

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg læser i Windows Internals, at når en tråd oprettes, er 1 MB virtuel hukommelse som standard forbeholdt brugerstakken. Ud af denne 1 MB vil kun den første side (0x1000) blive begået.


Jeg kan se dette, når jeg dumper billedhovedet ved hjælp af dumpbin.exe. Her er hvad dumpbin viser:
Indtast billedbeskrivelse her [14]


Men når jeg dumper adresselokalet for denne exe i Windbg ved hjælp af! Adresse kommando, ser jeg en forskel. Windbg viser mig, at den oprindelige engagerede størrelse er lig med 3 sider i.e 0x3000


Ved der nogen, hvorfor der er en forskel mellem den oprindelige stakforbrydelsesstørrelse, som billedoverskriften og debuggeren viser?

Bedste reference


Det er et godt spørgsmål, og nøglen til svaret er at forstå, hvad det indledende breakpoint er. Hvor begyndende er det for startere?


TLDR: Den oprindelige breakpoint er for sent. Den stak er allerede vokset.


Du har ikke delt det binære du har at gøre med, så jeg valgte et binært, der udviser den samme adfærd - cacls.exe på 64-bit Windows 10 (filversion: 10.0.14393.0).


Under det indledende breakpoint observerer vi:


CommandLine: "c:WindowsSystem32cacls.exe"
Symbol search path is: srv*
Executable search path is: 
ModLoad: 00007ff6`83bd0000 00007ff6`83bdc000   cacls.exe
ModLoad: 00007ff8`29ce0000 00007ff8`29eb1000   ntdll.dll
ModLoad: 00007ff8`27500000 00007ff8`275ab000   C:WindowsSystem32KERNEL32.DLL
ModLoad: 00007ff8`26f30000 00007ff8`2714d000   C:WindowsSystem32KERNELBASE.dll
ModLoad: 00007ff8`280b0000 00007ff8`2814e000   C:WindowsSystem32msvcrt.dll
ModLoad: 00007ff8`29b10000 00007ff8`29bb2000   C:WindowsSystem32advapi32.dll
ModLoad: 00007ff8`273d0000 00007ff8`27429000   C:WindowsSystem32sechost.dll
ModLoad: 00007ff8`254f0000 00007ff8`25522000   c:WindowsSystem32NTMARTA.dll
ModLoad: 00007ff8`27150000 00007ff8`27245000   C:WindowsSystem32ucrtbase.dll
ModLoad: 00007ff8`277c0000 00007ff8`278e1000   C:WindowsSystem32RPCRT4.dll
(1310.17b0): Break instruction exception - code 80000003 (first chance)
ntdll!LdrpDoDebuggerBreak+0x30:
00007ff8`29db34e0 cc              int     3
0:000> !dh -f cacls

File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
    8664 machine (X64)
       6 number of sections
57899A04 time date stamp Sat Jul 16 05:20:52 2016

       0 file pointer to symbol table
       0 number of symbols
      F0 size of optional header
      22 characteristics
            Executable
            App can handle >2gb addresses

OPTIONAL HEADER VALUES
     20B magic #
   14.00 linker version
    4C00 size of code
    3600 size of initialized data
       0 size of uninitialized data
    52F0 address of entry point
    1000 base of code
         ----- new -----
00007ff683bd0000 image base
    1000 section alignment
     200 file alignment
       3 subsystem (Windows CUI)
   10.00 operating system version
   10.00 image version
   10.00 subsystem version
    C000 size of image
     400 size of headers
    AF10 checksum
0000000000080000 size of stack reserve
0000000000002000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
    C160  DLL characteristics
            High entropy VA supported
            Dynamic base
            NX compatible
            Guard
            Terminal server aware
       0 [       0] address [size] of Export Directory
    7010 [     1CC] address [size] of Import Directory
    A000 [     7F0] address [size] of Resource Directory
    9000 [     2DC] address [size] of Exception Directory
       0 [       0] address [size] of Security Directory
    B000 [      54] address [size] of Base Relocation Directory
    6A10 [      38] address [size] of Debug Directory
       0 [       0] address [size] of Description Directory
       0 [       0] address [size] of Special Directory
       0 [       0] address [size] of Thread Storage Directory
    60E0 [      D0] address [size] of Load Configuration Directory
       0 [       0] address [size] of Bound Import Directory
    61B0 [     3B8] address [size] of Import Address Table Directory
       0 [       0] address [size] of Delay Import Directory
       0 [       0] address [size] of COR20 Header Directory
       0 [       0] address [size] of Reserved Directory

0:000> !address @rsp


Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...

Usage:                  Stack
Base Address:           00000049`8fbbc000
End Address:            00000049`8fbc0000
Region Size:            00000000`00004000 (  16.000 kB)
State:                  00001000          MEM\_COMMIT
Protect:                00000004          PAGE\_READWRITE
Type:                   00020000          MEM\_PRIVATE
Allocation Base:        00000049`8fb40000
Allocation Protect:     00000004          PAGE\_READWRITE
More info:              ~0k


Content source: 1 (target), length: 180


Vi ser den oprindelige stakforbindelse er 0x2000, men 0x4000 er faktisk forpligtet.


Men det er allerede meget sent under procesinitialiseringsprocessen (ingen ordsprog er beregnet). Al import DLL er allerede fyldt.


Det såkaldte 'indledende break-point' er simpelthen en (mere eller mindre 1 ) hardcoded int 3 instruktion kaldet af procesinitialiseringskoden i NTDLL. Hvis du ser på stakken på dette tidspunkt, kan du se den passende navngivne LdrpDoDebuggerBreak funktion, som kaldes af LdrpInitializeProcess:


0:000> k
 # Child-SP          RetAddr           Call Site
00 00000049`8fbbee80 00007ff8`29d72e22 ntdll!LdrpDoDebuggerBreak+0x30
01 00000049`8fbbeec0 00007ff8`29da8986 ntdll!LdrpInitializeProcess+0x1962
02 00000049`8fbbf2c0 00007ff8`29d59fae ntdll!\_LdrpInitialize+0x4e982
03 00000049`8fbbf340 00000000`00000000 ntdll!LdrInitializeThunk+0xe


På det tidspunkt, der skete, er stakken allerede brugt (for eksempel at indlæse statisk forbundne DLL'er og udføre deres initialiseringskode), så det bør ikke være meget overraskende, at stakken er vokset allerede.


For at undersøge processen, når den netop er blevet oprettet, skal vi bryde på procesfremstillingshændelsen i stedet for på det indledende breakpoint (hvilket ikke er det oprindelige som vi nu forstår).


Det kan vi enten gøre ved at bruge sxe cpr og .restart, ligesom jeg gjorde eller kørte WinDbg/NTSD med -xe cpr. At gøre det afslører noget interessant 2 :


0:000> .restart
CommandLine: C:WindowsSystem32cacls.exe

************* Symbol Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*
Symbol search path is: srv*
Executable search path is: 
ModLoad: 00007ff6`83bd0000 00007ff6`83bdc000   cacls.exe
00007ff8`29d470b0 4883ec48        sub     rsp,48h

0:000> .imgscan /l
MZ at 00007ff6`83bd0000, prot 00000002, type 01000000 - size c000
  Name: cacls.exe
  Loaded cacls.exe module
MZ at 00007ff8`29ce0000, prot 00000002, type 01000000 - size 1d1000
  Name: ntdll.dll
  Loaded ntdll.dll module

0:000> !address @rsp


Mapping file section regions...
Mapping module regions...
Mapping PEB regions...
Mapping TEB and stack regions...
Mapping heap regions...
Mapping page heap regions...
Mapping other regions...
Mapping stack trace database regions...
Mapping activation context regions...

Usage:                  Stack
Base Address:           0000004a`5428e000
End Address:            0000004a`54290000
Region Size:            00000000`00002000 (   8.000 kB)
State:                  00001000          MEM\_COMMIT
Protect:                00000004          PAGE\_READWRITE
Type:                   00020000          MEM\_PRIVATE
Allocation Base:        0000004a`54210000
Allocation Protect:     00000004          PAGE\_READWRITE
More info:              ~0k


Content source: 1 (target), length: 478


Den målte regionstørrelse er 0x2000 - som overskriften siger!


Hvis vi lader det fortsætte, vil vi til sidst komme til det indledende breakpoint med mere stablet comitted.





1 Jeg sagde mere eller mindre hardcoded, fordi den aktuelle kode for funktionen er


0:000> uf ntdll!LdrpDoDebuggerBreak
ntdll!LdrpDoDebuggerBreak:
00007ff8`29db34b0 4883ec38        sub     rsp,38h
00007ff8`29db34b4 488364242000    and     qword ptr [rsp+20h],0
00007ff8`29db34ba 41b901000000    mov     r9d,1
00007ff8`29db34c0 4c8d442440      lea     r8,[rsp+40h]
00007ff8`29db34c5 418d5110        lea     edx,[r9+10h]
00007ff8`29db34c9 48c7c1feffffff  mov     rcx,0FFFFFFFFFFFFFFFEh
00007ff8`29db34d0 e88b30fdff      call    ntdll!NtQueryInformationThread (00007ff8`29d86560)
00007ff8`29db34d5 85c0            test    eax,eax
00007ff8`29db34d7 780a            js      ntdll!LdrpDoDebuggerBreak+0x33 (00007ff8`29db34e3)  Branch

ntdll!LdrpDoDebuggerBreak+0x29:
00007ff8`29db34d9 807c244000      cmp     byte ptr [rsp+40h],0
00007ff8`29db34de 7503            jne     ntdll!LdrpDoDebuggerBreak+0x33 (00007ff8`29db34e3)  Branch

ntdll!LdrpDoDebuggerBreak+0x30:
00007ff8`29db34e0 cc              int     3
00007ff8`29db34e1 eb00            jmp     ntdll!LdrpDoDebuggerBreak+0x33 (00007ff8`29db34e3)  Branch

ntdll!LdrpDoDebuggerBreak+0x33:
00007ff8`29db34e3 4883c438        add     rsp,38h
00007ff8`29db34e7 c3              ret


Det gør ting som at kontrollere, om denne tråd skal 'være skjult for debuggeren', men det går grundlæggende i debuggeren.


2 .imgscan /l er nødvendig, fordi uden det får vi:


0:000> !address @rsp

No symbols for ntdll. Cannot continue.