You are on page 1of 11

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M.

Ferris RMF Network Security July 2010

Looking at Processes, Modules, and Threads with Powershell 2.0 Part I


Ryan M. Ferris RMF Network Security rev.07/30/10
These are some notes I have gathered on querying objects concerning process,modules,threads in PowerShell. This paper is primarily concerned with comparing changes in loaded processes, modules, and threads over time. My notes concern these TypeNames in Powershell 2.0: System.Diagnostics.Process System.Diagnostics.ProcessModuleCollection System.Diagnostics.ProcessThreadCollection System.Management.ManagementObject#root\cimv2\Win32_Process System.Management.ManagementObject#root\cimv2\Win32_Thread

PS (Get-Process)
The 'Get-Process' cmdlet (alias 'ps') for the .NET class System.Diagnostics.Process has both Module and Thread collection derived classes. The 'ps' cmdlet has 51 properties including the ProcessModule and the ProcessThread Collections: $a=ps $a | gm | ? {$_.MemberType -eq "Property"}
TypeName: System.Diagnostics.Process Name ---BasePriority Container EnableRaisingEvents ExitCode ExitTime Handle HandleCount HasExited Id MachineName MainModule MainWindowHandle MainWindowTitle MaxWorkingSet MinWorkingSet Modules NonpagedSystemMemorySize NonpagedSystemMemorySize64 PagedMemorySize PagedMemorySize64 PagedSystemMemorySize PagedSystemMemorySize64 PeakPagedMemorySize MemberType ---------Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Definition ---------System.Int32 BasePriority {get;} System.ComponentModel.IContainer Container {get;} System.Boolean EnableRaisingEvents {get;set;} System.Int32 ExitCode {get;} System.DateTime ExitTime {get;} System.IntPtr Handle {get;} System.Int32 HandleCount {get;} System.Boolean HasExited {get;} System.Int32 Id {get;} System.String MachineName {get;} System.Diagnostics.ProcessModule MainModule {get;} System.IntPtr MainWindowHandle {get;} System.String MainWindowTitle {get;} System.IntPtr MaxWorkingSet {get;set;} System.IntPtr MinWorkingSet {get;set;} System.Diagnostics.ProcessModuleCollection Modules {get;} System.Int32 NonpagedSystemMemorySize {get;} System.Int64 NonpagedSystemMemorySize64 {get;} System.Int32 PagedMemorySize {get;} System.Int64 PagedMemorySize64 {get;} System.Int32 PagedSystemMemorySize {get;} System.Int64 PagedSystemMemorySize64 {get;} System.Int32 PeakPagedMemorySize {get;}

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
PeakPagedMemorySize64 PeakVirtualMemorySize PeakVirtualMemorySize64 PeakWorkingSet PeakWorkingSet64 PriorityBoostEnabled PriorityClass PrivateMemorySize PrivateMemorySize64 PrivilegedProcessorTime ProcessName ProcessorAffinity Responding SessionId Site StandardError StandardInput StandardOutput StartInfo StartTime SynchronizingObject Threads TotalProcessorTime UserProcessorTime VirtualMemorySize VirtualMemorySize64 WorkingSet WorkingSet64 Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property Property System.Int64 PeakPagedMemorySize64 {get;} System.Int32 PeakVirtualMemorySize {get;} System.Int64 PeakVirtualMemorySize64 {get;} System.Int32 PeakWorkingSet {get;} System.Int64 PeakWorkingSet64 {get;} System.Boolean PriorityBoostEnabled {get;set;} System.Diagnostics.ProcessPriorityClass PriorityClass {get;set;} System.Int32 PrivateMemorySize {get;} System.Int64 PrivateMemorySize64 {get;} System.TimeSpan PrivilegedProcessorTime {get;} System.String ProcessName {get;} System.IntPtr ProcessorAffinity {get;set;} System.Boolean Responding {get;} System.Int32 SessionId {get;} System.ComponentModel.ISite Site {get;set;} System.IO.StreamReader StandardError {get;} System.IO.StreamWriter StandardInput {get;} System.IO.StreamReader StandardOutput {get;} System.Diagnostics.ProcessStartInfo StartInfo {get;set;} System.DateTime StartTime {get;} System.ComponentModel.ISynchronizeInvoke SynchronizingObject {get;set;} System.Diagnostics.ProcessThreadCollection Threads {get;} System.TimeSpan TotalProcessorTime {get;} System.TimeSpan UserProcessorTime {get;} System.Int32 VirtualMemorySize {get;} System.Int64 VirtualMemorySize64 {get;} System.Int32 WorkingSet {get;} System.Int64 WorkingSet64 {get;}

($a | gm | ? {$_.MemberType -eq "Property"}).count 51 We can get at all this process information with the 'ps' alias for defaults fields or we can call customized fields by name or by alias with the 'selectobject' cmdlet. For example, the alias CPU below is 'TotalProcessorTime.TotalSeconds': ps | Select Name,ID,VM,WS,CPU | ft -auto Name ---ApMsgFwd ApntEx Apoint audiodg BDTUpdateService CCP chrome .... Id VM --3320 52310016 504 69910528 3464 105451520 936 58421248 1804 70451200 3836 210313216 1076 146034688 WS -5046272 6344704 11116544 20250624 8712192 42381312 30068736 CPU --5.9904384 0.1716011 13.5252867 1.4352092 4.3836281 12.1836781

The 'sort-object' cmdlet can be applied to the pipeline as well: ps | Select Name,ID,VM,WS,CPU | Sort ID | ft -auto Name ---Idle System svchost Id -0 4 124 VM -0 51748864 96813056 WS CPU -- --24576 43925504 18530304 10.6860685

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
svchost svchost ApntEx ... 308 265789440 145620992 273.6569542 356 546394112 93216768 67.3300316 504 69910528 6344704 0.1716011

We can also us a 'foreach' language command to help us powerfully invoke the System.Diagnostics.ProcessModuleCollection and System.Diagnostics.ProcessThreadCollection. Note that the 'foreach' language command is distinct from the Powershell's 'foreach-object' cmdlet. Please see help 'about_foreach' for more information. foreach ($id in ( Get-Process | ? {$_.Modules} )) {write $id.MainModule} (or alternatively) foreach ($id in ( Get-Process | ? {$_.Name} )) {write $id.MainModule} Size(K) ------80 32 176 112 ModuleName ---------ApMsgFwd.exe Apntex.exe Apoint.exe BDTUpdateService.exe FileName -------C:\Program C:\Program C:\Program C:\Program

...

Files\Apoint\ApMsgFwd.exe Files\Apoint\Apntex.exe Files\Apoint\Apoint.exe Files (x86)\Spyware Doctor\BDT\BDTUpdateService.exe

We can find module information (as opposed to process information) about all currently loaded MainModules (e.g. binaries) with: $findGP=foreach ($id in ( Get-Process | ? {$_.Modules} )) {write $id.MainModule} $findGP | ft * | more Size Company --80 32 176 112 40 944 ... ------Alps Electr... Alps Electr... Alps Electr... Threat Expe... Google Inc. FileVersion ----------7, 0, 0, 20 7.0.1.29 7.0.7.156 2, 0, 6, 15 1.0.0.0 0.0.0.0 ProductVersion Description -------------7, 0, 0, 20 7.0.1.29 7.0.7.156 2, 0, 6, 15 1.0.0.0 0.0.0.0 ----------ApMsgFwd Alps Pointi... Alps Pointi... Browser Def... CCP Google Chrome Product ------ApMsgFwd Alps Pointi... Alps Pointi... Threat Expe... CCP Google Chrome ModuleName ---------ApMsgFwd.exe Apntex.exe Apoint.exe BDTUpdateSe... CCP.exe chrome.exe FileName -------C:\Program ... C:\Program ... C:\Program ... C:\Program ... C:\Program ... C:\Users\Ad... BaseAddress ModuleMemorySi EntryPointAddr ze ess ----------- -------------- -------------4194304 81920 4205648 4194304 32768 4205088 4194304 180224 4243984 4194304 114688 4228632 589824 40960 612350 1900544 966656 2188746

The get-Process cmdlet also access System.Diagnostics.ProcessThreadCollection. Usually, this is done with 'ps': $modules=ps $modules | % {$_.Threads} But we can also do this with the 'foreach' language command. foreach ($id in ( Get-Process | ? {$_.Modules} )) {write $id.Threads} BasePriority CurrentPriority Id IdealProcessor PriorityBoostEnabled PriorityLevel : : : : : : 6 11 3324 True Normal

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
PrivilegedProcessorTime StartAddress StartTime ThreadState TotalProcessorTime UserProcessorTime ... : : : : : : 00:00:04.6800300 2003135024 7/21/2010 10:21:45 AM Wait 00:00:06.3960410 00:00:01.7160110

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
The syntax below allows the user to take full advantages of Powershell's flexible query, member coupling, and .NET classes reach. Below we are storing to and then displaying from the variable $FWAPI all ModuleNames (binaries) that import "FirewallAPI.dll": $FWAPI=foreach ($id in ( Get-Process | ? {$_.Modules -match "FirewallAPI.dll"} )) {write $id.MainModule} $FWAPI | ft *
Size Company ---3024 44 44 44 44 44 44 ------Microsoft Microsoft Microsoft Microsoft Microsoft Microsoft Microsoft Co... Co... Co... Co... Co... Co... Co... FileVersion ----------6.0.6000.163... 6.0.6000.163... 6.0.6000.163... 6.0.6000.163... 6.0.6000.163... 6.0.6000.163... 6.0.6000.163... ProductVersion -------------6.0.6000.16386 6.0.6000.16386 6.0.6000.16386 6.0.6000.16386 6.0.6000.16386 6.0.6000.16386 6.0.6000.16386 Description ----------Windows Expl... Host Process... Host Process... Host Process... Host Process... Host Process... Host Process... Product ------Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr W... W... W... W... W... W... W... ModuleName ---------Explorer.EXE svchost.exe svchost.exe svchost.exe svchost.exe svchost.exe svchost.exe FileName -------C:\Windows\E... C:\Windows\S... C:\Windows\s... C:\Windows\s... C:\Windows\s... C:\Windows\s... C:\Windows\s... BaseAddress ModuleMemorySiz EntryPointAddre FileVersionInfo Site e ss ----------- --------------- --------------- --------------- ---4279566336 3096576 4279720368 File: ... 4291166208 45056 4291175332 File: ... 4291166208 45056 4291175332 File: ... 4291166208 45056 4291175332 File: ... 4291166208 45056 4291175332 File: ... 4291166208 45056 4291175332 File: ... 4291166208 45056 4291175332 File: ...

...

We can also use the 'Select-object' cmdlet as so: $FWAPI | Select ModuleName,ModuleMemorySize,EntryPointAddress,BaseAddress | ft -auto ModuleName ModuleMemorySize EntryPointAddress BaseAddress ------------------------- ----------------- ----------Explorer.EXE 3096576 4279720368 4279566336 svchost.exe 45056 4291175332 4291166208 svchost.exe 45056 4291175332 4291166208 svchost.exe 45056 4291175332 4291166208 svchost.exe 45056 4291175332 4291166208 svchost.exe 45056 4291175332 4291166208 svchost.exe 45056 4291175332 4291166208 It is also possible to use complicated comparative operators for MainModule queries: $findMM=foreach ($id in ( Get-Process | ? { $_.Modules -like "*(rsaenh.dll)*" -and $_.Modules -like "*(iphlpapi.dll)*"} )) {write $id.MainModule} $findMM | Select Modulename,FileName,ModuleMemorySize,Size,EntryPointAddress,BaseAddress,Description,Company | ft -auto
ModuleName ---------EvtEng.exe explorer.exe lsass.exe powershell.exe SearchIndexer.exe svchost.exe svchost.exe svchost.exe svchost.exe svchost.exe svchost.exe VAIOUpdt.exe WinMail.exe WLANExt.exe wmpnetwk.exe FileName ModuleMemorySize Size EntryPointAddress BaseAddress Description ----------------------- ---- ----------------- ----------- ----------C:\Program Files\Intel\WiFi\bin\EvtEng.exe 1421312 1388 5369266128 5368709120 Intel(R) PROSet/Wireless Event Log Service C:\Windows\explorer.exe 3096576 3024 4285946288 4285792256 Windows Explorer C:\Windows\system32\lsass.exe 28672 28 4280556092 4280549376 Local Security Authority Process C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe 479232 468 10464548 10420224 Windows PowerShell C:\Windows\system32\SearchIndexer.exe 626688 612 4280555876 4280156160 Microsoft Windows Search Indexer C:\Windows\system32\svchost.exe 45056 44 4290388900 4290379776 Host Process for Windows Services C:\Windows\System32\svchost.exe 45056 44 4290388900 4290379776 Host Process for Windows Services C:\Windows\System32\svchost.exe 45056 44 4290388900 4290379776 Host Process for Windows Services C:\Windows\system32\svchost.exe 45056 44 4290388900 4290379776 Host Process for Windows Services C:\Windows\system32\svchost.exe 45056 44 4290388900 4290379776 Host Process for Windows Services C:\Windows\system32\svchost.exe 45056 44 4290388900 4290379776 Host Process for Windows Services C:\Program Files\Sony\VAIO Update 4\VAIOUpdt.exe 1212416 1184 4572064 4194304 VAIO Update C:\Program Files\Windows Mail\WinMail.exe 421888 412 4283198448 4283170816 Windows Mail C:\Windows\system32\WLANExt.exe 110592 108 4293084340 4293001216 Windows Wireless LAN 802.11 Extensibility Framework C:\Program Files\Windows Media Player\wmpnetwk.exe 1236992 1208 4292013948 4291035136 Windows Media Player Network Sharing Service Company ------Intel(R) Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation Sony Corporation Microsoft Corporation Microsoft Corporation Microsoft Corporation

Now, we query every module (dll) loaded by the process svchost.exe: $SVChost_lm=foreach ($id in ( Get-Process | ? {$_.Name -like "svchost"} )) {write $id.Modules} $SVChost_lm | ft *

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010

Size Company ---44 1560 1204 624 1056 ------Microsoft Microsoft Microsoft Microsoft Microsoft Co... Co... Co... Co... Co... ----------6.0.6000.163... 6.0.6001.180... 6.0.6001.180... 7.0.6002.180... 6.0.6002.180...

FileVersion -------------6.0.6000.16386 6.0.6001.18000 6.0.6001.18000 7.0.6002.18005 6.0.6002.18005

ProductVersion ----------Host Process... NT Layer DLL Windows NT B... Windows NT C... Advanced Win...

Description ------Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr W... W... W... W... W...

Product ---------svchost.exe ntdll.dll kernel32.dll msvcrt.dll ADVAPI32.dll

ModuleName -------C:\Windows\S... C:\Windows\s... C:\Windows\s... C:\Windows\s... C:\Windows\s...

FileName

BaseAddress ModuleMemorySiz EntryPointAddre FileVersionInfo Site e ss ----------- --------------- --------------- --------------- ---4291166208 45056 4291175332 File: ... 2002976768 1597440 0 File: ... 2001731584 1232896 2001843376 File: ... 8791785996288 638976 8791786005352 File: ... 8791782391808 1081344 8791782638856 File: ...

But we can do better yet. There are multiple svchost.exe per session. We want to prepend the svchost process ID prior to dumping the modules specific to each: $SVChost_lm=foreach ($id in ( Get-Process | ? {$_.Name -like "svchost"} )) {write $id.Name,$id.ID,$id.Modules} $SVChost_lm | ft svchost 124 Size(K) ------44 1560 1204 624 1056 1292 1476 152 112 820 400 ... We can find module information about all currently loaded main modules (binaries) and their modules (dlls) with: $findAllModules=foreach ($id in ( Get-Process | ? {$_.Modules} )) {write $id.MainModule,$id.Modules} $findAllModules | ft * | more
Size Company ---80 80 1560 1204 1056 1292 820 400 460 624 ------Alps Electr... Alps Electr... Microsoft C... Microsoft C... Microsoft C... Microsoft C... Microsoft C... Microsoft C... Microsoft C... Microsoft C... FileVersion ----------7, 0, 0, 20 7, 0, 0, 20 6.0.6001.18... 6.0.6001.18... 6.0.6002.18... 6.0.6001.18... 6.0.6001.18... 6.0.6002.18... 6.0.6000.16... 7.0.6002.18... ProductVersion Description -------------7, 0, 0, 20 7, 0, 0, 20 6.0.6001.18000 6.0.6001.18000 6.0.6002.18005 6.0.6001.18000 6.0.6001.18000 6.0.6002.18005 6.0.6000.16386 7.0.6002.18005 ----------ApMsgFwd ApMsgFwd NT Layer DLL Windows NT ... Advanced Wi... Remote Proc... Multi-User ... GDI Client DLL Shell Light... Windows NT ... Product ------ApMsgFwd ApMsgFwd Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr Microsoftr ModuleName ---------ApMsgFwd.exe ApMsgFwd.exe ntdll.dll kernel32.dll ADVAPI32.dll RPCRT4.dll USER32.dll GDI32.dll SHLWAPI.dll msvcrt.dll FileName -------C:\Program ... C:\Program ... C:\Windows\... C:\Windows\... C:\Windows\... C:\Windows\... C:\Windows\... C:\Windows\... C:\Windows\... C:\Windows\... BaseAddress ModuleMemorySi EntryPointAddr ze ess ----------- -------------- -------------4194304 81920 4205648 4194304 81920 4205648 2004090880 1597440 0 2001993728 1232896 2002105520 8791772364800 1081344 8791772611848 8791760961536 1323008 8791761215904 2003238912 839680 2003343380 8791787765760 409600 8791787790452 8791765942272 471040 8791766014032 8791787110400 638976 8791787119464

ModuleName ---------svchost.exe ntdll.dll kernel32.dll msvcrt.dll ADVAPI32.dll RPCRT4.dll wevtsvc.dll USERENV.dll Secur32.dll USER32.dll GDI32.dll

FileName -------C:\Windows\System32\svchost.exe C:\Windows\system32\ntdll.dll C:\Windows\system32\kernel32.dll C:\Windows\system32\msvcrt.dll C:\Windows\system32\ADVAPI32.dll C:\Windows\system32\RPCRT4.dll c:\windows\system32\wevtsvc.dll c:\windows\system32\USERENV.dll c:\windows\system32\Secur32.dll C:\Windows\system32\USER32.dll C:\Windows\system32\GDI32.dll

... ... ... ... ... ... ... ...

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
To compare the listing of every executable and their modules over time we can use compare-object (alias diff): $a=foreach ($id in ( Get-Process | ? {$_.Modules} )) {write $id.Name,$id.ID,$id.Modules} sleep -seconds 10 # Start notepad now $b=foreach ($id in ( Get-Process | ? {$_.Modules} )) {write $id.Name,$id.ID,$id.Modules} $c=diff $a $b $c | fl * | out-file modulelog Raw output like the following is produced: InputObject : notepad SideIndicator : => InputObject : 1712 SideIndicator : => InputObject : {System.Diagnostics.ProcessModule (notepad.exe), System.Diagnostics.ProcessModule (ntdll.dll), System.Diagnostics.ProcessModule (kernel32.dll), System.Diagnostics.ProcessModule (ADVAPI32.dll )...} SideIndicator : => We can 'unroll' all the 'diff' object with $d=$c | % {$_.InputObject} $d notepad 1712 Size(K) ------188 1560 1204 ... or with selection and/or sorting of module and process specific properties: $d=$c | % {$_.InputObject} | Select ModuleName,FileName,ModuleMemorySize,EntryPointAddress | Sort EntryPointAddress $d | ft -wrap -auto
ModuleName ---------ntdll.dll kernel32.dll USER32.dll notepad.exe smum64.dll FileName -------C:\Windows\system32\ntdll.dll C:\Windows\system32\kernel32.dll C:\Windows\system32\USER32.dll C:\Windows\system32\notepad.exe C:\Program Files (x86)\Spyware Doctor\smum64.dll ModuleMemorySize ---------------1597440 1232896 839680 192512 282624 EntryPointAddress ----------------0 2002105520 2003343380 4282241460 8791685212184

ModuleName ---------notepad.exe ntdll.dll kernel32.dll

FileName -------C:\Windows\system32\notepad.exe C:\Windows\system32\ntdll.dll C:\Windows\system32\kernel32.dll

... We can the use semantics below to create an object ($FindLots) that displays process name, process ID, process filename followed by the modules and threads that belong to that process.

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
$FindLots=foreach ($id in ( Get-Process | ? {$_.Name} )) {$id.Name,$id.ID,$id.Path,$id.Modules,$id.Threads} $FindLots | gm | findstr TypeName TypeName: TypeName: TypeName: TypeName: System.String System.Int32 System.Diagnostics.ProcessModuleCollection System.Diagnostics.ProcessThreadCollection

This type of 'hybrid' object produces output that first lists the process name,PID and full path to the binary followed by all the modules and then all the threads loaded by the respective process: $FindLots | ft ApMsgFwd 3320 C:\Program Files\Apoint\ApMsgFwd.exe Size(K) ------80 1560 1204 1056 1292 820 400 ... BasePriority CurrentPriority Id IdealProcessor PriorityBoostEnabled PriorityLevel PrivilegedProcessorTime ... : : : : : : : 6 8 3324 True Normal 00:00:02.9484189 ModuleName ---------ApMsgFwd.exe ntdll.dll kernel32.dll ADVAPI32.dll RPCRT4.dll USER32.dll GDI32.dll FileName -------C:\Program Files\Apoint\ApMsgFwd.exe C:\Windows\system32\ntdll.dll C:\Windows\system32\kernel32.dll C:\Windows\system32\ADVAPI32.dll C:\Windows\system32\RPCRT4.dll C:\Windows\system32\USER32.dll C:\Windows\system32\GDI32.dll

Comparing 'hybrid' (mixed 'Typename') objects produces some problematic results since the original objects have to be reset to process and thread based arrays and then compared. $a=foreach ($id in ( Get-Process | ? {$_.Name} )) {$id.Name,$id.ID,$id.Path,$id.Modules,$id.Threads} sleep -seconds 10 # start mspaint $b=foreach ($id in ( Get-Process | ? {$_.Name} )) {$id.Name,$id.ID,$id.Path,$id.Modules,$id.Threads} $aa=$a | ? {$_.Item} $bb=$b | ? {$_.Item} $cc=compare-object $aa $bb The resulting objects lose the linkage between process and module when they become 'ParameterizedProperties': $bb | gm | findstr Property

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
Item Count Item Count ParameterizedProperty Property ParameterizedProperty Property System.Diagnostics.ProcessModule Item(int index) {get;} System.Int32 Count {get;} System.Diagnostics.ProcessThread Item(int index) {get;} System.Int32 Count {get;}

However, we still have list of binaries, modules, and threads that have changed: $cc InputObject SideIndicator ----------------------{1808, 3132, 3140, 3240...} => {System.Diagnostics.ProcessModule (mspaint.exe), System.Diagnostics.ProcessModule (ntdll.dll), S... => {3676, 3896, 3912, 1264...} => {228, 236, 240, 304...} => {640, 636, 748, 1008...} => ... $cc | % {$_.InputObject} | more BasePriority CurrentPriority Id IdealProcessor PriorityBoostEnabled PriorityLevel PrivilegedProcessorTime StartAddress StartTime ThreadState ... ModuleName FileName BaseAddress ModuleMemorySize EntryPointAddress ... : : : : : : : : : : : : : : : 8 10 1808 True Normal 00:00:01.1700075 1999661616 7/30/2010 10:55:03 AM Wait

mspaint.exe C:\Windows\system32\mspaint.exe 4285464576 614400 4285797576

$cc | % {$_.InputObject} | findstr ModuleName ModuleName : mspaint.exe ModuleName : ntdll.dll ModuleName : kernel32.dll ModuleName : ADVAPI32.dll ModuleName : RPCRT4.dll ... $cc | % {$_.InputObject} | Sort Id | findstr /V "IdealProcessor" | findstr Id Id : 228 Id : 236 Id : 240 Id : 304 ...

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010

GWMI (Windows Management Instrumentation)


A comparison between alias' ps (get-process) and gwmi (get-WMIObject) shows that gwmi uses the PID of each process as a handle to display much the same process information as ps. WMI is a comprehensive database of Windows objects of all types. A full discussion is beyond the scope of this document. However, WMI's database and management format does make time slice comparisons straightforward. $i=ps $j=gwmi win32_process diff $i $j InputObject ----------\\RMFVISTA\root\cimv2:Win32_Process.Handle="0" \\RMFVISTA\root\cimv2:Win32_Process.Handle="4" \\RMFVISTA\root\cimv2:Win32_Process.Handle="524" \\RMFVISTA\root\cimv2:Win32_Process.Handle="656" ... System.Diagnostics.Process (ApMsgFwd) System.Diagnostics.Process (ApntEx) System.Diagnostics.Process (Apoint) System.Diagnostics.Process (audiodg) System.Diagnostics.Process (BDTUpdateService) ... Note how the 'Handle' field is the same as the process ID in the gwmi query below: $j=gwmi win32_process $j | Select ProcessId, Name, Handle, HandleCount | Sort ProcessId, HandleCount | ft -auto ProcessId --------0 4 176 432 512 632 ... Name ---System Idle Process System Tcpview.exe svchost.exe smss.exe wmpnscfg.exe Handle HandleCount ------ ----------0 0 4 1729 176 308 432 1439 512 28 632 133 SideIndicator ------------=> => => => <= <= <= <= <=

Comparing process command lines is straightforward with WMI: $a=foreach ($id in ( gwmi win32_process | ? {$_.HANDLE} )) {write $id.CommandLine} sleep -seconds 10 # Start notepad now $b=foreach ($id in ( gwmi win32_process | ? {$_.HANDLE} )) {write $id.CommandLine} $c=diff $a $b $c InputObject ----------SideIndicator -------------

All information and methods subject to revision and not guaranteed. Use at your own risk.

Looking at Processes, Modules, and Threads with Powershell 2.0 All Rights Reserved Ryan M. Ferris RMF Network Security July 2010
"C:\Windows\system32\notepad.exe" => $c | % {$_.InputObject} "C:\Windows\system32\notepad.exe" GWMI also has a win32_thread component with a feature not so easily access in System.Diagnostic.Process : a relative path link from process handle or 'PID'. This makes linking threads with their processes more straightforward. $j=gwmi win32_thread $j | Select ProcessHandle, Handle, StartAddress | Sort ProcessHandle, Handle | ft -auto ProcessHandle ------------0 0 1004 1004 1004 ... Handle StartAddress ------ -----------0 54986864 1 54986864 1392 1997105712 1688 1997105712 2160 1997105712

each thread to

$j | % {$_.__RELPATH} Win32_Thread.Handle="0",ProcessHandle="0" Win32_Thread.Handle="1",ProcessHandle="0" Win32_Thread.Handle="8",ProcessHandle="4" Win32_Thread.Handle="16",ProcessHandle="4" Win32_Thread.Handle="20",ProcessHandle="4" Win32_Thread.Handle="24",ProcessHandle="4" ... Because WMI's win32_thread class links process handles (PID) explicitly with thread handles, we can definitively see which processes have changed or created new thread handles in the diff below. $a=foreach ($id in ( gwmi win32_thread | ? {$_.HANDLE} )) {write $id.ProcessHandle} sleep -seconds 10 # Start notepad now $b=foreach ($id in ( gwmi win32_thread | ? {$_.HANDLE} )) {write $id.ProcessHandle} $c=diff $a $b $c | % {ps -id $_.inputobject} | Select ProcessName,ID | ft -auto ProcessName ----------services svchost svchost svchost explorer SearchIndexer notepad Id -748 664 700 1288 3088 3676 4116

All information and methods subject to revision and not guaranteed. Use at your own risk.

You might also like