Figure 1 Dependency Walker
Figure 2 Process Explorer
Figure 3 DllSpy
Figure 4 ProcessSpy
Figure 5 Methods for Enumerating Running Processes
Method | Platform | Note |
PSAPI |
Windows NT, Windows 2000, Windows XP |
Gets information about process, driver, module, memory, and working set |
Performance counters |
Windows NT, Windows 2000, Windows XP |
Provides more information than the process list and can be used from a remote computer |
TOOLHELP32 |
Windows 9x, Windows 2000, Windows XP |
Gets information about process, thread, module, and heap | Figure 6 Using CProcessList to List Running Processes // get one process after the other
CProcess* pProcess = NULL;
POSITION Pos = 0;
for (
pProcess = ProcessList.GetFirst(Pos);
(pProcess != NULL);
pProcess = ProcessList.GetNext(Pos)
)
{
if (pProcess != NULL)
{
// do what you want with the process information
}
}
Figure 7 Refreshing the Processes List void CProcessList::Refresh()
{
// don't forget to reset and free the current list
DefaultReset();
// store the current process list
DWORD aProcesses[MAX_PROCESS];
DWORD cbNeeded = 0;
// get a snapshot of the processes
if (!g_PSAPI.EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return;
// Calculate how many process IDs were returned
DWORD cProcesses = cbNeeded / sizeof(DWORD);
// attach a CProcess object to each process ID
DWORD dwProcessID;
CProcess* pProcess;
for (
DWORD dwCurrentProcess = 0;
dwCurrentProcess < cProcesses;
dwCurrentProcess++
)
{
dwProcessID = aProcesses[dwCurrentProcess];
// add the process definition into the map
pProcess = new CProcess(TRUE);
if (pProcess != NULL)
{
// fill in the process information for the current process ID
if (!pProcess->AttachProcess(aProcesses[dwCurrentProcess]))
delete pProcess;
else
// store into the map
m_ProcessMap[(LPVOID)dwProcessID] = pProcess;
}
}
// a second iteration is needed to know the process children
SetChildrenList();
}
Figure 8 Process Details
Method |
Description |
GetName |
Uses GetModuleBaseName with NULL as parameter but without the ".EXE" |
GetFileName |
Uses GetModuleFileNameEx with NULL as parameter |
GetMainWindowHandle GetMainWindowTitle |
See the GetMainWindowHandle discussion |
GetParentProcessID |
Uses NtQueryInformationProcess with ProcessBasicInformation |
GetKERNELHandleCount |
Uses NtQueryInformationProcess with ProcessHandleCount |
GetUSERHandleCount |
Uses GetGuiResources with GR_USEROBJECTS |
GetGDIHandleCount |
Uses GetGuiResources with GR_GDIOBJECTS |
GetWorkingSet |
Uses GetProcessMemoryInfo |
GetCmdLine |
See GetProcessCmdLine discussion |
GetOwner |
See GetProcessOwner details |
GetSessionID |
ProcessIdToSessionId (see Fast User Switching discussion) |
GetModuleList |
CModuleList is a wrapper class around EnumProcessModules and GetModuleFileNameEx |
GetChildrenCount and children list |
There is no API (even undocumented) to get the list of processes spawned by a process. But since the parent of each process is known, it is easy to add a process to the child list of its parent. (See the implementation of SetChildrenList) | Figure 10 TLIST Detailed Output for a Running Process C:\>tlist 632
632 CMD.EXE C:\WINNT\System32\cmd.exe - tlist 632
CWD: C:\
CmdLine: C:\WINNT\System32\cmd.exe /k cd "C:\"
VirtualSize: 13408 KB PeakVirtualSize: 13412 KB
WorkingSetSize: 948 KB PeakWorkingSetSize: 952 KB
NumberOfThreads: 1
968 Win32StartAddr:0x4ad1a420 LastErr:0x000000cb State:Waiting
5.0.2195.1600 shp 0x4ad00000 cmd.exe
5.0.2195.1600 shp 0x77f80000 ntdll.dll
5.0.2195.1600 shp 0x77e80000 KERNEL32.dll
5.0.2195.1600 shp 0x77e10000 USER32.dll
5.0.2195.1340 shp 0x77f40000 GDI32.DLL
5.0.2195.1600 shp 0x77db0000 ADVAPI32.dll
5.0.2195.1615 shp 0x77d40000 RPCRT4.DLL
6.1.8637.0 shp 0x78000000 MSVCRT.dll
Figure 12 ProcessXP Output 3 open sessions
ID State Window Station
0 (WTSActive) Console [Administrator]
1 (WTSDisconnected) [standard]
2 (WTSDisconnected) [Player]
30 running processes
0 0 ?
0 4 System \\NT AUTHORITY\SYSTEM
0 388 smss.exe \\NT AUTHORITY\SYSTEM
0 600 csrss.exe \\NT AUTHORITY\SYSTEM
0 632 winlogon.exe \\NT AUTHORITY\SYSTEM
0 676 services.exe \\NT AUTHORITY\SYSTEM
0 688 lsass.exe \\NT AUTHORITY\SYSTEM
0 856 svchost.exe \\NT AUTHORITY\SYSTEM
0 968 svchost.exe \\NT AUTHORITY\SYSTEM
0 1160 svchost.exe \\NT AUTHORITY\NETWORK SERVICE
0 1192 svchost.exe \\NT AUTHORITY\LOCAL SERVICE
0 1252 spoolsv.exe \\NT AUTHORITY\SYSTEM
0 1888 explorer.exe \\MACHINE\Administrator
0 2004 msmsgs.exe \\MACHINE\Administrator
0 104 svchost.exe \\NT AUTHORITY\SYSTEM
1 1496 csrss.exe \\NT AUTHORITY\SYSTEM
1 1172 winlogon.exe \\NT AUTHORITY\SYSTEM
1 1640 explorer.exe \\MACHINE\standard
1 1900 ctfmon.exe \\MACHINE\standard
1 352 notepad.exe \\MACHINE\standard
1 1896 freecell.exe \\MACHINE\standard
2 416 csrss.exe \\NT AUTHORITY\SYSTEM
2 268 winlogon.exe \\NT AUTHORITY\SYSTEM
2 1784 explorer.exe \\MACHINE\Player
0 1820 msiexec.exe \\NT AUTHORITY\SYSTEM
2 1544 ctfmon.exe \\MACHINE\Player
2 1632 msmsgs.exe \\MACHINE\Player
2 1268 wordpad.exe \\MACHINE\Player
0 1696 wuauclt.exe \\MACHINE\Administrator
0 1996 ProcessXP.exe \\MACHINE\Administrator
Figure 13 Module Walking Using TOOLHELP32 //
// Enumerate the module list for this process. Start by taking
// another ToolHelp32 snapshot, this time of the process's module list
//
HANDLE hSnapshotModule;
hSnapshotModule = pfnCreateToolhelp32Snapshot( TH32CS_SNAPMODULE,
procEntry.th32ProcessID );
if ( !hSnapshotModule )
continue;
// Iterate through each module in the snapshot
MODULEENTRY32 modEntry = { sizeof(MODULEENTRY32) };
BOOL fModWalkContinue;
for (fModWalkContinue = pfnModule32First(hSnapshotModule,&modEntry);
fModWalkContinue;
fModWalkContinue = pfnModule32Next(hSnapshotModule,&modEntry) )
{
// Hack! Cheezy way to figure out if this is EXE module itself
// If so, we don't want to add it to the module list
if ( 0 == stricmp( modEntry.szExePath, procEntry.szExeFile ) )
continue;
// Determine if this is a DLL we've already seen
PModuleInstance pModInst = modList.Lookup(modEntry.hModule,
modEntry.szExePath );
// If we haven't see it, add it to the list
if ( !pModInst )
pModInst = modList.Add( modEntry.hModule, modEntry.szExePath );
// Add this process to the list of processes using the DLL
pModInst->AddProcessReference( procEntry.th32ProcessID );
}
CloseHandle( hSnapshotModule ); // Done with module list snapshot
Figure 14 Accessor Methods
Accessor |
Notes |
HMODULE GetModuleHandle |
Address where the DLL is mapped |
CString& GetFullPathName |
From either TOOLHELP32::Module32xxx Or PSAPI::GetModuleFilenameEx |
CString& GetModuleName |
Same as GetFullPathName |
CString& GetPathName |
Same as GetFullPathName | Figure 15 Accessor Details
Accessor |
Notes |
DWORD GetBaseAddress |
Uses PE_EXE::GetImageBase to get the preferred loading address |
void GetFileTime(FILETIME& ft) |
Uses GetFileTime API from KERNEL32.DLL to know when it has been created, modified, and last accessed |
CString& GetFileTime |
Get the same info as the previous one but in text format using GetFileDateAsString/GetFileTimeAsString helper functions |
DWORD GetFileSize |
Uses PE_EXE::GetFileSize to get the size of the file in bytes |
CString& GetSubSystem |
Uses PE_EXE::GetSubSystem to know the module subsystem among the IMAGE_SUBSYSTEM_xxx values from winnt.h; in the last version of this file, IMAGE_SUBSYSTEM_XBOX could be found |
void GetLinkTime(FILETIME& ft) |
Uses PE_EXE::GetTimeDateStamp to discover when the module has been linked |
CString& GetLinkTime |
Gets the same info as the previous one but in text format using GetFileDateAsString/GetFileTimeAsString helper functions |
WORD GetLinkVersion |
Uses PE_EXE::GetLinkerVersion to get the version of linker used to build the module | Figure 16 File Types According to Version Information
Flag |
Description |
VS_FF_DEBUG |
Contains debugging information or is compiled with debugging features enabled |
VS_FF_INFOINFERRED |
Version structure was created dynamically; therefore, some of the members in this structure may be empty or incorrect. This flag should never be set in a file's VS_VERSIONINFO data |
VS_FF_PATCHED |
Has been modified and is not identical to the original shipping file of the same version number |
VS_FF_PRERELEASE |
A development version, not a commercially released product |
VS_FF_PRIVATEBUILD |
Not built using standard release procedures. If this flag is set, the StringFileInfo structure should contain a PrivateBuild entry |
VS_FF_SPECIALBUILD |
Built by the original company using standard release procedures but is a variation of the normal file of the same version number. If this flag is set, the StringFileInfo structure should contain a SpecialBuild entry | Figure 17 Flags in the dwFileType Field
Flag |
Description |
VFT_UNKNOWN |
Unknown to the system |
VFT_APP |
Contains an application |
VFT_DLL |
Contains a DLL |
VFT_DRV |
Contains a device driver. If dwFileType is VFT_DRV, dwFileSubtype contains a more specific description of the driver |
VFT_FONT |
Contains a font. If dwFileType is VFT_FONT, dwFileSubtype contains a more specific description of the font file |
VFT_VXD |
Contains a virtual device |
VFT_STATIC_LIB |
Contains a static-link library | |