Что здесь делает inc dword ptr gs: []? - PullRequest
0 голосов
/ 06 мая 2018

При отладке ядра Windows с WinDbg,

Я нашел следующую строку: inc dword ptr gs: [2EB8h]

Может кто-нибудь объяснить, что это значит? (Intel Syntax, x86, Windows-10)

enter image description here

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Этот ответ является просто расширением ответа Ниццы, за исключением того, что он используется для создания процесса-> cookie
Член KeSystemCalls в poi (nt! KiProcessorBlock) Структура

kd> ?? @@masm(poi(nt!KiProcessorBlock)) == @$prcb
bool true
kd> ? @$pcr
Evaluate expression: -2104316928 = 8292ac00
kd> ? @$pcr+120
Evaluate expression: -2104316640 = 8292ad20
kd> ? @$prcb
Evaluate expression: -2104316640 = 8292ad20
kd> ? poi(nt!KiProcessorBlock)
Evaluate expression: -2104316640 = 8292ad20

также используется для предоставления значений счетчика производительности для данных

"\ system \ System Calls / sec"

C:\>powershell -c "&{get-counter -counter \"\System\System Calls/sec\"}"

Timestamp                 CounterSamples
                          144196.186791101

, если следовать pdh api

s = PdhCollectQueryData(hQuery); 

можно наблюдать обращения к NtQueryInformationSystem с помощью SYSTEM_INFO_CLASS 2 == SystemPerformanceInformation, которая приводит к nt! ExpQuerySystemInformation на стороне ядра, заполняя информацию из KPRCB

kd> # \+590h nt!ExpQuerySystemInformation l 600
nt!ExpQuerySystemInformation+0x57f:
82a01d73 038290050000    add     eax,dword ptr [edx+590h]

kd> ?? #FIELD_OFFSET(nt!_KPRCB , KeSystemCalls)
long 0n1424

kd> ? 0n1424
Evaluate expression: 1424 = 00000590  <<<< (windows 7 sp2 32 bit )
0 голосов
/ 09 мая 2018

Сегмент GS в режиме kernel (windows x64) указывает на область управления процессором ядра ( KPCR ).

Вы можете сбросить его с помощью команды !pcr:

kd> !pcr
KPCR for Processor 0 at fffff802fbd73000:
    Major 1 Minor 1
    NtTib.ExceptionList: fffff802fd6d8000
        NtTib.StackBase: fffff802fd6d9070
       NtTib.StackLimit: 0000000000b0e968
     NtTib.SubSystemTib: fffff802fbd73000
          NtTib.Version: 00000000fbd73180
      NtTib.UserPointer: fffff802fbd737f0
          NtTib.SelfTib: 000000007f005000

                SelfPcr: 0000000000000000
                   Prcb: fffff802fbd73180
                   Irql: 0000000000000000
                    IRR: 0000000000000000
                    IDR: 0000000000000000
          InterruptMode: 0000000000000000
                    IDT: 0000000000000000
                    GDT: 0000000000000000
                    TSS: 0000000000000000

          CurrentThread: ffffe001e41a3080
             NextThread: 0000000000000000
             IdleThread: fffff802fbde9740

              DpcQueue: Unable to read nt!_KDPC_DATA.DpcListHead.Flink @ fffff802fbd75f00

Вы можете подтвердить, что KPCR действительно указан сегментным регистром GS, прочитав MSR (регистр, специфичный для модели) с именем IA32_GS_BASE (значение 0xc0000101):

kd> rdmsr 0xc0000101
msr[c0000101] = fffff802`fbd73000

Как вы можете видеть, они оба указывают, в моем примере, на 0xfffff802fbd73000.

ПЦР описывается структурой KPCR:

kd> dt nt!_kpcr
   +0x000 NtTib            : _NT_TIB
   +0x000 GdtBase          : Ptr64 _KGDTENTRY64
   +0x008 TssBase          : Ptr64 _KTSS64
   +0x010 UserRsp          : Uint8B
   +0x018 Self             : Ptr64 _KPCR
   +0x020 CurrentPrcb      : Ptr64 _KPRCB
   +0x028 LockArray        : Ptr64 _KSPIN_LOCK_QUEUE
   +0x030 Used_Self        : Ptr64 Void
   +0x038 IdtBase          : Ptr64 _KIDTENTRY64
   +0x040 Unused           : [2] Uint8B
   +0x050 Irql             : UChar
   +0x051 SecondLevelCacheAssociativity : UChar
   +0x052 ObsoleteNumber   : UChar
   +0x053 Fill0            : UChar
   +0x054 Unused0          : [3] Uint4B
   +0x060 MajorVersion     : Uint2B
   +0x062 MinorVersion     : Uint2B
   +0x064 StallScaleFactor : Uint4B
   +0x068 Unused1          : [3] Ptr64 Void
   +0x080 KernelReserved   : [15] Uint4B
   +0x0bc SecondLevelCacheSize : Uint4B
   +0x0c0 HalReserved      : [16] Uint4B
   +0x100 Unused2          : Uint4B
   +0x108 KdVersionBlock   : Ptr64 Void
   +0x110 Unused3          : Ptr64 Void
   +0x118 PcrAlign1        : [24] Uint4B
   +0x180 Prcb             : _KPRCB

Как видно, последнее поле структуры KPCR представляет собой другую структуру ( не указатель, а сама структура) с именем KPRCB (что означает блок управления процессором ядра) со смещением 0x180.

Вот начало этой структуры:

kd> dt nt!_kprcb
   +0x000 MxCsr            : Uint4B
   +0x004 LegacyNumber     : UChar
   +0x005 ReservedMustBeZero : UChar
   +0x006 InterruptRequest : UChar
   +0x007 IdleHalt         : UChar
   +0x008 CurrentThread    : Ptr64 _KTHREAD
   +0x010 NextThread       : Ptr64 _KTHREAD
   +0x018 IdleThread       : Ptr64 _KTHREAD
   +0x020 NestingLevel     : UChar
   +0x021 ClockOwner       : UChar
   +0x022 PendingTickFlags : UChar
   +0x022 PendingTick      : Pos 0, 1 Bit
   +0x022 PendingBackupTick : Pos 1, 1 Bit
   +0x023 IdleState        : UChar
   +0x024 Number           : Uint4B
   ...

Вышеупомянутый выход для краткости усечен, поскольку эта структура (и, следовательно, PCR) чрезвычайно велика: размер PCR в windows 10 x64 составляет 0x8040 байт (0x7EC0 для KPRCB).

Учитывая ваше смещение 0x2eb8 в GS (которое указывает на PCR), мы можем просто вычесть смещение KPRCB из PCR (0x180):

kd> ? 0x2eb8 - 0x180
Evaluate expression: 11576 = 00000000`00002d38

И затем проверьте, какое поле имеет смещение 0x2d38 в KPRCB:

0: kd> .shell -ci "dt nt!_kprcb" findstr /i 0x2d38
   +0x2d38 KeSystemCalls    : Uint4B

(примечание: вы можете просто dt nt!_kprcb и посмотреть на смещение 0x2d38).

Итак, увеличенное поле в вашем примере называется KeSystemCalls и представляет собой 32-разрядное поле (Uint4B), как показано в вашем коде.

Использование поля

Поиск в дизассемблере IDA (ntoskrnel.exe, windows 10 - x64) приводит к двум попаданиям в значение 0x2eb8:

  • KiSystemCall64
  • VslpDispatchIumSyscall

Первый - это «обычный» диспетчер системных вызовов, а второй - диспетчер системных вызовов для процессов IUM (он же Trustlets).

В обеих этих функциях использование поля одинаково (пример в KiSystemCall64):

.text:0000000140187360    call    r10 ; perform syscall
.text:0000000140187363
.text:0000000140187363 loc_140187363:
.text:0000000140187363    inc     dword ptr gs:2EB8h ; increment syscall counter

Таким образом, это поле является просто монотонным счетчиком количества системных вызовов, которые произошли с момента загрузки системы.

...