Zine.net online

Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc
w Szukaj

mgrzeg.net - Admin on Rails :)

Start systemu, a PspInsertProcess

Podczas tworzenia nowego procesu system tworzy odpowiedni obiekt jądra, o którym już na tym blogu pisałem (w kontekście żetonu zabezpieczeń, ukrywania procesów, czy też ochrony procesu). Przy okazji ukrywania procesów wspominałem o liście aktywnych procesów, która wykorzystywana jest głównie do celów statystycznych, jednak nie napisałem, jak procesy dołączane są do tej listy. Dziś spróbujemy to nadrobić.

Mark Russinovich w swojej Książce (przez ‘duże K’, żeby wszyscy wiedzieli o której mowa ;)) w rozdziale poświęconym procesom i ich tworzeniu pisze, iż nowy obiekt związany z procesem dołączany jest do listy aktywnych procesów (PsActiveProcessHead), przy użyciu funkcji PspInsertProcess. Nie ma jeszcze żadnego aktywnego wątku, ale mamy już całkiem sporo informacji o procesie, w tym ‘ImageFileName’, czyli 15-bajtową tablicę zawierającą nazwę procesu, a także przydzielony identyfikator procesu ‘UniqueProcessId’.

Korzystając z tego faktu, postanowiłem dla ćwiczenia zrobić log uruchamianych procesów na wirtualnym Windows 7 x64.

Analiza

Startujemy system i zatrzymujemy się na samym początku

kd> k
Child-SP          RetAddr           Call Site
fffff800`00b9cdf8 fffff800`0292117d nt!DebugService2+0x5
fffff800`00b9ce00 fffff800`02d13449 nt!DbgLoadImageSymbols+0x4d
fffff800`00b9ce50 fffff800`02ac5816 nt!KdInitSystem+0x429
fffff800`00b9cfc0 00000000`00000000 nt!KiSystemStartup+0x126
kd> lm
start             end                 module name
fffff800`02811000 fffff800`02df9000   nt         (pdb symbols)          c:\websymbols\ntkrnlmp.pdb\ABD176D2C7AE41B88BBF2837A09A462C2\ntkrnlmp.pdb

Unable to enumerate kernel-mode unloaded modules, HRESULT 0x80004005

kd> x nt!PspInsertProcess
fffff800`02b36c50 nt!PspInsertProcess (<no parameter info>)

Jak widać, mamy jeden moduł i jesteśmy ‘na dzień dobry’. Plik z symbolami jest, więc możemy zakładać pułapkę.

kd> bp nt!PspInsertProcess
kd> g
Breakpoint 0 hit
nt!PspInsertProcess:
fffff800`02b36c50 4489442418      mov     dword ptr [rsp+18h],r8d

Zaczynamy od określenia parametrów funkcji. Skoro jest to Windows 7 64-bit, to parametry funkcji przekazywane są przez rejestry rcx, rdx, r8, r9, a dalej stos (vide post Skywinga). Robimy zatem zrzut stosu wywołań oraz rejestrów.

kd> kb
RetAddr           : Args to Child                                                           : Call Site
fffff800`02cffd72 : fffff6fb`7e280000 fffff800`00000004 fffff8a0`00005000 0000007f`ffffffff : nt!PspInsertProcess
fffff800`02db8875 : 00000000`00000002 fffff800`00812700 fffff800`00812700 00000000`00000000 : nt!PspCreateProcess+0x212
fffff800`02db8a00 : fffff800`00812700 fffff800`00812700 00000000`00000001 00000000`0000005c : nt!PspInitPhase0+0x495
fffff800`02dbd15c : fffff800`00812700 00000000`0000005c 00000000`00000100 00000000`00000006 : nt!PsInitSystem+0x40
fffff800`02ad7f73 : fffff800`00000000 fffff800`02a02e80 fffff800`00b9c8c0 00000000`00000001 : nt!InitBootProcessor+0x93c
fffff800`02ac5886 : 12131011`16171415 1a1b1819`1e1f1c1d 02030001`06070405 0a0b0809`0e0f0c0d : nt!KiInitializeKernel+0x833
00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiSystemStartup+0x196
kd> r
rax=0000000000000000 rbx=0000000000000000 rcx=fffffa80018d0450
rdx=0000000000000000 rsi=0000000000000000 rdi=fffffa80018d0450
rip=fffff80002b36c50 rsp=fffff80000b9c258 rbp=0000000000000000
 r8=00000000001fffff  r9=0000000000000000 r10=0000000000000001
r11=fffff80002a88300 r12=0000000000000000 r13=0000000000000000
r14=fffff80002a10cc0 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
nt!PspInsertProcess:
fffff800`02b36c50 4489442418      mov     dword ptr [rsp+18h],r8d ss:0018:fffff800`00b9c270=00500000

Zobaczmy co się działo z rejestrami i stosem przed wywołaniem PspInsertProcess

kd> ub nt!PspCreateProcess+0x212 L20
nt!PspCreateProcess+0x181:
fffff800`02cffce1 488d44245c      lea     rax,[rsp+5Ch]
fffff800`02cffce6 4889442438      mov     qword ptr [rsp+38h],rax
fffff800`02cffceb 488364243000    and     qword ptr [rsp+30h],0
fffff800`02cffcf1 44897c2428      mov     dword ptr [rsp+28h],r15d
fffff800`02cffcf6 488b842488000000 mov     rax,qword ptr [rsp+88h]
fffff800`02cffcfe 4889442420      mov     qword ptr [rsp+20h],rax
fffff800`02cffd03 4c8bce          mov     r9,rsi
fffff800`02cffd06 4c8b442478      mov     r8,qword ptr [rsp+78h]
fffff800`02cffd0b 418ad5          mov     dl,r13b
fffff800`02cffd0e 488bcb          mov     rcx,rbx
fffff800`02cffd11 e8ca38e3ff      call    nt!PspAllocateProcess (fffff800`02b335e0)
fffff800`02cffd16 448be0          mov     r12d,eax
fffff800`02cffd19 85c0            test    eax,eax
fffff800`02cffd1b 0f88c9000000    js      nt!PspCreateProcess+0x28a (fffff800`02cffdea)
fffff800`02cffd21 448be8          mov     r13d,eax
fffff800`02cffd24 89442450        mov     dword ptr [rsp+50h],eax
fffff800`02cffd28 b805000000      mov     eax,5
fffff800`02cffd2d 8d4802          lea     ecx,[rax+2]
fffff800`02cffd30 837c245c00      cmp     dword ptr [rsp+5Ch],0
fffff800`02cffd35 0f45c1          cmovne  eax,ecx
fffff800`02cffd38 488d8c24a0000000 lea     rcx,[rsp+0A0h]
fffff800`02cffd40 48894c2438      mov     qword ptr [rsp+38h],rcx
fffff800`02cffd45 89442430        mov     dword ptr [rsp+30h],eax
fffff800`02cffd49 488b842480000000 mov     rax,qword ptr [rsp+80h]
fffff800`02cffd51 4889442428      mov     qword ptr [rsp+28h],rax
fffff800`02cffd56 897c2420        mov     dword ptr [rsp+20h],edi
fffff800`02cffd5a 458bcf          mov     r9d,r15d
fffff800`02cffd5d 448b442458      mov     r8d,dword ptr [rsp+58h]
fffff800`02cffd62 488bd3          mov     rdx,rbx
fffff800`02cffd65 488b7c2468      mov     rdi,qword ptr [rsp+68h]
fffff800`02cffd6a 488bcf          mov     rcx,rdi
fffff800`02cffd6d e8de6ee3ff      call    nt!PspInsertProcess (fffff800`02b36c50)


Strzelam (bo dokumentacji nie ma), że w rcx jest adres nowego procesu (a właściwie struktury _EPROCESS reprezentującej proces), natomiast czuj mi podpowiada, że w rdx znajdziemy adres procesu rodzica :) Na tym etapie jeszcze tego nie widać (rdx = 0), ale spróbujmy to zebrać do kupy i zrobić zrzut.

kd> dt nt!_EPROCESS @rcx ImageFileName UniqueProcessId
   +0x180 UniqueProcessId : 0x00000000`00000004 Void
   +0x2e0 ImageFileName   : [15]  ""

Jak się okazuje, nazwa procesu jest pusta, do tego proces macierzysty to same zera, więc nie ma sensu robić zrzutu.

Zakładam pułapkę (tu uwaga - zdecydowanie lepiej byłoby wyrzucić całe to polecenie, ładnie sformatowane do osobnego skryptu i pułapkę ustawić na skrypt, ale pozostawiam to jako proste ćwiczenie)

kd> bp nt!PspInsertProcess "r? $t0=((nt!_EPROCESS*) @rcx);r? $t1=((nt!_EPROCESS*) @rdx);as /ma ${/v:ProcName} @@c++(@$t0->ImageFileName);as /ma ${/v:PProcName} @@c++(@$t1->ImageFileName);as /x ${/v:Pid} @@c++(@$t0->UniqueProcessId);as /x ${/v:PPid} @@c++(@$t1->UniqueProcessId);.echo ${ProcName}, ${PProcName}, ${Pid}, ${PPid};g"

i robię zrzut całości. Poniżej moje wyniki, zebrane w tabelki, oczywiście kolejne pozycje w kolejności chronologicznej.

Wyniki

Process Name Parent Process Name Pid Parent Pid
0x4
smss.exe System 0xf4 0x4
autochk.exe smss.exe 0x100 0xf4
smss.exe smss.exe 0x148 0xf4
csrss.exe smss.exe 0x150 0x148
smss.exe smss.exe 0x17c 0xf4
wininit.exe smss.exe 0x184 0x148
csrss.exe smss.exe 0x18c 0x17c
winlogon.exe smss.exe 0x1b0 0x17c
services.exe wininit.exe 0x1f8 0x184
lsass.exe wininit.exe 0x200 0x184
lsm.exe wininit.exe 0x208 0x184
svchost.exe services.exe 0x264 0x1f8
svchost.exe services.exe 0x2b0 0x1f8
svchost.exe services.exe 0x2ec 0x1f8
LogonUI.exe winlogon.exe 0x324 0x1b0
svchost.exe services.exe 0x350 0x1f8
svchost.exe services.exe 0x368 0x1f8
audiodg.exe svchost.exe 0x3b8 0x2ec
svchost.exe services.exe 0x64 0x1f8
svchost.exe services.exe 0x1f0 0x1f8
spoolsv.exe services.exe 0x42c 0x1f8
svchost.exe services.exe 0x45c 0x1f8
svchost.exe services.exe 0x4c8 0x1f8
vmtoolsd.exe services.exe 0x534 0x1f8
net.exe vmtoolsd.exe 0x5c8 0x534
conhost.exe csrss.exe 0x5fc 0x150
net1.exe net.exe 0x61c 0x5c8
TPAutoConnSvc. services.exe 0x634 0x1f8
cmd.exe vmtoolsd.exe 0x6c0 0x534
conhost.exe csrss.exe 0x6c8 0x150
dllhost.exe services.exe 0x6dc 0x1f8
WmiPrvSE.exe svchost.exe 0x708 0x264
dllhost.exe services.exe 0x734 0x1f8
msdtc.exe services.exe 0x794 0x1f8

Lista procesów uruchamianych podczas startu systemu, do momentu pojawienia się okna logowania.

Process Name Parent Process Name Pid Parent Pid
VSSVC.exe services.exe 0x4a4 0x1f8
dllhost.exe svchost.exe 0x598 0x264
taskhost.exe services.exe 0x6cc 0x1f8
AtBroker.exe winlogon.exe 0x620 0x1b0
userinit.exe winlogon.exe 0x17c 0x1b0
dwm.exe svchost.exe 0xfc 0x350
explorer.exe userinit.exe 0x584 0x17c
TPAutoConnect. TPAutoConnSvc. 0x870 0x634
conhost.exe csrss.exe 0x878 0x18c
VMwareTray.exe explorer.exe 0x894 0x584
vmtoolsd.exe explorer.exe 0x89c 0x584
SearchIndexer. services.exe 0x92c 0x1f8
SearchProtocol SearchIndexer. 0x9a8 0x92c
SearchFilterHo SearchIndexer. 0x9bc 0x92c
mscorsvw.exe services.exe 0xa78 0x1f8
mscorsvw.exe services.exe 0xa94 0x1f8
sppsvc.exe services.exe 0xabc 0x1f8
svchost.exe services.exe 0xae0 0x1f8
WmiPrvSE.exe svchost.exe 0xb58 0x264
taskhost.exe services.exe 0x88c 0x1f8
wuauclt.exe svchost.exe 0x858 0x368

Lista procesów uruchamianych po zalogowaniu do systemu

Process Name Parent Process Name Pid Parent Pid
LogonUI.exe winlogon.exe 0x698 0x1b0
LogonUI.exe wininit.exe 0x9a0 0x184

Lista procesów uruchamianych podczas zamykania systemu

Jako ćwiczenie pozostawiam zrzut w przypadku Windows XP, tudzież wersji 32-bit Visty, lub Windows 7. Nie ma tam problemu z przekazywaniem parametrów - wszystko idzie przez stos, a adres struktury _EPROCESS mamy w rejestrze eax. Miłej zabawy! :)

Opublikowane 29 lipca 2012 16:27 przez mgrzeg

Powiadamianie o komentarzach

Jeżeli chciałbyś otrzymywać email gdy ta wypowiedź zostanie zaktualizowana, to zarejestruj się tutaj

Subskrybuj komentarze za pomocą RSS

Komentarze:

Brak komentarzy

Co o tym myślisz?

(wymagane) 
(opcjonalne)
(wymagane) 

  
Wprowadź kod: (wymagane)
Wyślij

Subskrypcje

W oparciu o Community Server (Personal Edition), Telligent Systems