2017-01-30 9 views
1

Я читал в Windows Internals, что при создании потока по умолчанию зарезервирован для 1 пользователя виртуальной памяти 1 МБ. Из этого 1 МБ будет зафиксирована только первая страница (0x1000).! Команда адреса показывает другое значение для начального размера фиксации стека режима пользователя

Я вижу это, когда я сбрасываю заголовок изображения с помощью dumpbin.exe. Вот что показывает dumpbin: enter image description here

Однако, когда я удаляю адресное пространство этого exe в команде Windbg с помощью! Address, я вижу разницу. Windbg показывает мне, что начальный фиксированный размер равен 3 страницам i.e 0x3000

Кто-нибудь знает, почему существует разница между начальным размером фиксации стека, отображаемым заголовком изображения и отладчиком?

+0

Как (особенно когда?) Вы присоедините к процессу? Можете ли вы описать всю процедуру, пожалуйста? Вопрос в том, действительно ли вы получили начальное состояние, или вы слишком поздно это сделали? –

+0

Я использовал опцию «Открыть исполняемый файл» в Windbg и открыл исполняемый файл. Затем я попробовал! Адресную команду, чтобы увидеть области адресов, включая стек. – Neena

+0

ОК, поэтому вы останавливаетесь при начальной точке останова. Это хорошо. –

ответ

2

Это хороший вопрос, и ключ к ответу заключается в понимании начальной точки останова. Как это началось, для начинающих?

TLDR: начальная точка останова слишком поздно. Этот стек уже вырос.

Вы не использовали двоичный файл, с которым имеете дело, поэтому я выбрал двоичный код, который демонстрирует то же поведение - cacls.exe на 64-разрядной версии Windows 10 (версия файла: 10.0.14393.0).

Во время начальной точки останова мы наблюдаем:

CommandLine: "c:\Windows\System32\cacls.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:\Windows\System32\KERNEL32.DLL 
ModLoad: 00007ff8`26f30000 00007ff8`2714d000 C:\Windows\System32\KERNELBASE.dll 
ModLoad: 00007ff8`280b0000 00007ff8`2814e000 C:\Windows\System32\msvcrt.dll 
ModLoad: 00007ff8`29b10000 00007ff8`29bb2000 C:\Windows\System32\advapi32.dll 
ModLoad: 00007ff8`273d0000 00007ff8`27429000 C:\Windows\System32\sechost.dll 
ModLoad: 00007ff8`254f0000 00007ff8`25522000 c:\Windows\System32\NTMARTA.dll 
ModLoad: 00007ff8`27150000 00007ff8`27245000 C:\Windows\System32\ucrtbase.dll 
ModLoad: 00007ff8`277c0000 00007ff8`278e1000 C:\Windows\System32\RPCRT4.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 

Мы видим начальный стек фиксации размер 0x2000, но 0x4000 фактически совершено.

Но это уже очень поздно во время процесса инициализации процесса (каламбур не предназначен). Например, вся загрузочная DLL уже загружена.

так называемая «обкатка точка» просто (более или менее) жёстко int 3 инструкции называется кодом процесс initializtion в NTDLL. Если вы посмотрите на стек на этом этапе вы увидите метко назвали LdrpDoDebuggerBreak функции, которая вызывается 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 

К тому времени, которое произошло в стеке уже используется (например, для загрузки статический DLL и выполнить их код инициализации), поэтому не стоит удивляться, что стек уже вырос.

Чтобы проверить процесс, когда он только что был создан, нам нужно разбить событие создания процесса, а не на исходную точку останова (что не так, как мы теперь понимаем).

Мы можем сделать это либо с помощью sxe cpr, и .restart ing, как я сделал или работает WinDbg/NTSD с -xe cpr. Делать это показывает что-то интересное :

0:000> .restart 
CommandLine: C:\Windows\System32\cacls.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 

Целенаправленная размер области является 0x2000 - как говорит заголовок!

Если мы позволим ему продолжить, мы, в конечном счете, доберемся до начальной точки останова с большим количеством стека.


Я сказал, более или менее жёстко, потому что фактический код функции

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 

Это делает такие вещи, как проверить это нить, является ли или не быть «скрыты от отладчика» , но в основном он просто ломается в отладчик.

The .imgscan /l необходима, потому что без него мы получаем:

0:000> !address @rsp 

No symbols for ntdll. Cannot continue. 
+0

Отлично, это имеет смысл сейчас. Я попытался взломать процесс создания, как вы объяснили, и смог увидеть, что размер начального стека совпадает с тем, что мы видим в заголовке изображения, как и должно быть. Спасибо вам за помощь. – Neena