Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Getting list of modules loaded by a process

3,646 views
Skip to first unread message

forestial

unread,
Mar 24, 2008, 10:05:02 AM3/24/08
to
I wanted to see the list of DLLs etc. loaded by a process.

> get-process feeddemon | select modules

looks like it would do the job, but it shows only

Modules
-------
{FeedDemon.exe, ntdll.dll, wow64.dll, wow64win.dll...}

and I can't figure out how to see the complete list.

> get-process feeddemon | select modules | get-member

shows that this is a PSCustomObject...

TypeName: System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
ToString Method System.String ToString()
Modules NoteProperty System.Diagnostics.ProcessModuleCollection
Modules=System.Diagnostics.ProcessModuleCollection

I though the ToString() method might help, but it returns a zero-length
(empty) string.

What other techniques are available for extracting the full content of a
NoteProperty? I want to see the full list of modules this process has
loaded, not the truncated {FeedDemon.exe, ntdll.dll, wow64.dll,
wow64win.dll...}

Tomas Restrepo [MVP]

unread,
Mar 24, 2008, 10:19:19 AM3/24/08
to
Forestial

>I wanted to see the list of DLLs etc. loaded by a process.
>
>> get-process feeddemon | select modules
>
> looks like it would do the job, but it shows only

Try "select -expand modules" instead. It should do the trick.


--
Tomas Restrepo
http://www.devdeo.com/
http://www.winterdom.com/weblog/

Kiron

unread,
Mar 24, 2008, 10:22:08 AM3/24/08
to
Use Select-Object's -Expand parameter to see the collection:
 
get-process <process> | select -expand modules

--
Kiron

Marco Shaw [MVP]

unread,
Mar 24, 2008, 10:25:26 AM3/24/08
to
>
> What other techniques are available for extracting the full content of a
> NoteProperty? I want to see the full list of modules this process has
> loaded, not the truncated {FeedDemon.exe, ntdll.dll, wow64.dll,
> wow64win.dll...}

get-process powershell|select modules|foreach-object{$_.modules}

Marco

--
Microsoft MVP - Windows PowerShell
http://www.microsoft.com/mvp

PowerGadgets MVP
http://www.powergadgets.com/mvp

Blog:
http://marcoshaw.blogspot.com

Shay Levi

unread,
Mar 24, 2008, 10:26:56 AM3/24/08
to

(get-process feeddemon).modules

-----
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com

forestial

unread,
Mar 24, 2008, 10:46:01 AM3/24/08
to
Thanks Marco; this works but it's puzzling me: if I read the command
correctly it seems to suggest that the 'modules' property in turn has a
'modules' property...

... hmmm; indeed

> get-process feeddemon | select modules | get-member seems to confirm this:

TypeName: System.Management.Automation.PSCustomObject

Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
ToString Method System.String ToString()
Modules NoteProperty System.Diagnostics.ProcessModuleCollection
Modules=System.Diagnostics.ProcessModuleCollection

forestial

unread,
Mar 24, 2008, 10:50:00 AM3/24/08
to
Shay,

Thanks; this indeed works but I am wondering how this is different from my
initial attempt (get-process feeddemon | select modules)?

I guess the 'select' is constructing a new object to hold what is coming
down the pipleline, whereas your technique just goes straight to the
'modules' property of the process object.

Ymek...@gmail.com

unread,
Mar 24, 2008, 2:29:19 PM3/24/08
to
You can use the "Expand Property" feature of select-object to expand that
out:

get-process feeddemon | select -expand modules

Mike

Marco Shaw [MVP]

unread,
Mar 24, 2008, 2:37:18 PM3/24/08
to
forestial wrote:
> Thanks Marco; this works but it's puzzling me: if I read the command
> correctly it seems to suggest that the 'modules' property in turn has a
> 'modules' property...
>
> ... hmmm; indeed

I see what you mean. The NoteProperty is the result of ETS
(http://msdn2.microsoft.com/en-us/library/cc136149(VS.85).aspx) since a
custom object is being returned.

Marco

Hal Rottenberg

unread,
Mar 24, 2008, 2:38:19 PM3/24/08
to
forestial wrote:
> Thanks Marco; this works but it's puzzling me: if I read the command
> correctly it seems to suggest that the 'modules' property in turn has a
> 'modules' property...

I believe this is a symptom of PowerShell's auto-flattening of objects as they
pass through the pipeline. I agree it is weird. I often end up indexing into
the array during ad-hoc stuff until I find what I am looking for, and then go
with the foreach-object method for a script or function. e.g.:

(get-process powershell)[0].modules

I didn't notice the Select-Object -expand parameter until this past Saturday and
was blown away. :)

--

Hal Rottenberg
Blog: http://halr9000.com
Webmaster, Psi (http://psi-im.org)
Co-host, PowerScripting Podcast (http://powerscripting.net)

Shay Levi

unread,
Mar 24, 2008, 3:31:52 PM3/24/08
to

The first statment, using select, shows that there is only one object (PSCustomObject)
that wraps all ProcessModule objects, one for each moudle found. To unfold it
you use the -expand parameter or pipe it to foreach.

The second statment, using the modules member, gets direct access to the
ProcessModuleCollection.

PS 38> (gps powershell | select modules) | foreach {$_.gettype()}

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object

PS 39> (gps powershell).modules | foreach {$_.gettype()}

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ProcessModule System.ComponentModel.Component
True False ProcessModule System.ComponentModel.Component
True False ProcessModule System.ComponentModel.Component
(...)

Keith Hill [MVP]

unread,
Mar 24, 2008, 4:40:47 PM3/24/08
to
"forestial" <fore...@discussions.microsoft.com> wrote in message news:2A145EB6-0379-42D9...@microsoft.com...

> I wanted to see the list of DLLs etc. loaded by a process.

This is one of my favorite demos to sw devs:

155# Get-Process | select ProcessName -expand Modules -ea 0 | where {$_.ModuleName -match 'msvc.*?\.dll'} | Group Module
Name | Sort Count -desc

Count Name                      Group
----- ----                      -----
  107 msvcrt.dll                {adcist, Agilent.TMFramework.Connectivity.AgilentIOLibrariesService, Agilent.TMFrame...
   39 MSVCR80.dll               {Agilent.TMFramework.Connectivity.AgilentIOLibrariesService, Agilent.TMFramework.Con...
   22 MSVCR71.dll               {AluSchedulerSvc, ccApp, ccSvcHst, DefWatch...}
   16 MSVCP71.dll               {AluSchedulerSvc, ccApp, ccSvcHst, DefWatch...}
   13 wbemsvc.dll               {explorer, explorer, powershell, powershell...}
    9 MSVCP80.dll               {devenv, devenv, iexplore, iprocsvr...}
    2 comsvcs.dll               {MSASCui, wlmail}
    2 MSVCP60.dll               {lkcitdl, svchost}
    2 msvcm80.dll               {devenv, devenv}
    1 MSVCR90.dll               {WINWORD}

and


97> gc FindRebasedModules.ps1
param([int]$processId = $(throw "A process id must be provided."))

$printHdr = $true
$modules = get-process -id $processId | select -expand Modules -ea silentlycontinue
foreach ($module in $modules) {
    $imageBase = (Get-PEHeader $module.Filename).ImageBase
    $actualBase = $module.BaseAddress.ToInt32()
    if ($actualBase -ne $imageBase) {
        if ($printHdr) {
            "`nModule Relocations in Process Id: $processId"
            "--------------------------------------------"
            $printHdr = $false
        }
        "{0}`n    Image base: 0x{1:X8}`n    Loaded at:  0x{2:X8}" -f $module.Filename, $imageBase, $actualBase
    }
}

FindRebasedModules $pid

Module Relocations in Process Id: 5376
--------------------------------------------
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
    Image base: 0x01000000
    Loaded at:  0x00690000
C:\Windows\system32\ntdll.dll
    Image base: 0x77ED0000
    Loaded at:  0x773B0000
C:\Windows\system32\kernel32.dll
    Image base: 0x77DF0000
    Loaded at:  0x76860000
C:\Windows\system32\ADVAPI32.dll
    Image base: 0x77C80000
    Loaded at:  0x75C80000
...

Note the Get-PEHeader is a PSCX cmdlet:

--
Keith
http://www.codeplex.com/powershellcx
0 new messages