XP system traverses all processes

Source: Internet
Author: User
Tags filetime

At least four methods (from zol ):

Method 1

The first method is to use the API functions provided by toolhelp service. Three key functions are used: createconlhelp32snapshot (), process32first (), and process32next (). The following describes the prototype and parameters of the three functions;

Handle winapi createconlhelp32snapshot (
DWORD dwflags, // type of information to be viewed by the System Snapshot
DWORD th32processid // The value 0 indicates the current process
);
Bool winapi process32first (
Handle hsnapshot, // snapshot handle created by createconlhelp32snapshot ()
Lpprocessentry32 lppe // point to the process entry Structure
);
Bool winapi process32next (
Handle hsnapshot, // The parameter here is the same as process32first
Lpprocessentry32 lppe // same as above
);

First, use createconlhelp32snapshot () to create a System Snapshot handle (hprocess is the snapshot handle we declare to save the creation ):

Hprocess = createconlhelp32snapshot (th32cs_snapprocess, 0 );
Then call process32first () to obtain the first process information in the System Snapshot (report is a bool type as the next process record in the System Snapshot ):

Report = process32first (hprocess, pinfo );
Then we use a loop call to traverse all running processes in the system:

While (report)
{
Hmodule = createconlhelp32snapshot (th32cs_snapmodule, pinfo-> th32processid );
Module32first (hmodule, minfo );
Getmediapathname (minfo-> szexepath, route path, 256 );
Printf ("% s --- % Sn", pinfo-> szexefile, export path );
Report = process32next (hprocess, pinfo );
}

The pen once decompiled pslist.exe in the pstoolstool package and found that this method is used. If you query msdn, you can find a more comprehensive source program than this function.

Method 2

The second method is also very common. The sample code can be found through msdn, which is implemented through the API functions enumprocesses and enumprocessmodules provided by psapi. dll. Note that the SDK package provided by Visual Studio does not provide the corresponding psapi. h and the corresponding import warehouse, I was wondering at the time that the example in msdn could not be compiled, and later I found that "psapi" was not found during compilation. H ". Well, msdn should at least tell us that they all contain psapi. dll and use the depend tool provided by VC. In this way, we can find the function entry addresses by ourselves.

Knowledge: C, C ++, and general function names are essentially an address. In Win32 API, It is the entry address that points to the function implementation in the DLL module where the function is located.

The following is the implementation process of the second method: first, define the functions used in psapi. DLL to facilitate subsequent display calls.

// The function enumprocesses in psaipi. dll is used to enumerate processes.
Typedef bool (_ stdcall * enumprocesses) (// note that the call convention is-stdcall
DWORD * pprocessids, // point to the process ID array chain
Dword cb, // the size of the ID array, measured in bytes
DWORD * pbytesreturned); // The returned bytes.
// The function enumprocessmodules in psapi. dll is used to enumerate process modules.
Typedef bool (_ stdcall * enumprocessmodules )(
Handle hprocess, // Process Handle
Hmodule * lphmodule, // points to the module handle array chain
Dword cb, // module handle array size, byte count
Lpdword lpcbneeded); // number of bytes required to store the handle of all modules
// The getmodulefilenameex function in psapi. dll obtains the Process Module name.
Typedef DWORD (_ stdcall * getmodulefilenameex )(
Handle hprocess, // Process Handle
Hmodule, // Process Handle
Lptstr lpfilename, // full path name of the storage module
DWORD nsize // lpfilename buffer size, Character Calculation
);

Well, you can clearly see these original function names through the comments before each defined function, and then of course you need to load the psapi. dll that contains these function modules:
Hpsdll = loadlibrary ("psapi. dll ");
Then, through the DLL entry, we can find the address of each function:

Penumprocesses =
(Enumprocesses) getprocaddress (hpsdll, "enumprocesses ");
Penumprocessmodules =
(Enumprocessmodules) getprocaddress (hpsdll, "enumprocessmodules ");
Pgetmodulefilenameex =
(Getmodulefilenameex) getprocaddress (hpsdll, "getmodulefilenameexa ");
Note that the third function name is getmodulefilenameexa. In DLL, there is a function that separates the end of a and W. A refers to the ANSI string mode, and W refers to the Unicode mode. Therefore, we can use the following statement to enumerate processes:
Penumprocesses (processid, sizeof (processid), & needed );
Processcount = needed/sizeof (DWORD );

For (I = 0; I <processcount; I ++)
{
// Open the process
Hprocess = OpenProcess (process_query_information | process_vm_read,
False, processid [I]);
If (hprocess)
{
Penumprocessmodules (hprocess, & hmodule, sizeof (hmodule), & needed );
Pgetmodulefilenameex (hprocess, hmodule, path, sizeof (PATH ));
Getmediapathname (path, path, 256 );
ITOA (processid [I], temp, 10 );
Printf ("% s --- % Sn", path, temp );
}
Else
Printf ("failed !!! N ");
}
Of course, you can find many provided psapi. h header files and the corresponding psapi. Lib library on Google, so that you can use this method more conveniently.

Method 3

Maybe you know the first two methods all over the world. It's no big deal! Well, you may not know the third method I have introduced. This method is implemented by using the Terminal Service API functions wtsopenserver () and wtsenumerateprocess () in Windows NT/2000. Both functions are defined in wtsapi32.dll. For more information about Terminal Services, see msdn.
First, let's demonstrate the prototype of the two functions:
Typedef handle (_ stdcall * wtsopenserver )(
Lptstr pservername // The Terminal Service name specified by NetBIOS. If we view information about all processes on the local terminal, we can use nbtstat-An on the console command line to obtain the NetBIOS Name of the local machine. 3.
);

Typedef bool (_ stdcall * wtsenumerateprocesses )(
Handle hserver, // handle returned by wtsopenserver
DWORD reserved, // reserved value, 0
DWORD version, // specify the version required by enumeration, which must be 1
Pwts_process_info * ppprocessinfo, // this parameter is critical and stores the process name and process ID.
DWORD * pcount // number pointer used to store the wts_process_info structure in ppprocessinfo
);

As before, you must first load the wtsapi32.dll module to obtain the key function address:

Hwtsapi32 = loadlibrary ("wtsapi32.dll ");
Pwtsopenserver
= (Wtsopenserver) getprocaddress (hwtsapi32, "wtsopenservera ");
Pwtsenumerateprocesses
= (Wtsenumerateprocesses) getprocaddress (hwtsapi32, "wtsenumerateprocessesa ");

Use argv [1] to assign a value to the terminal service name (Here we assign the local NetBIOS name) and enable this service:

Char * szservername = argv [1];
Hwtsserver = pwtsopenserver (szservername );

Then we start to traverse all processes on the terminal server. Here we refer to all processes on the local machine.
If (! Pwtsenumerateprocesses (hwtsserver,
0,
1,
& Pwtspi,
& Dwcount ))
{
Printf ("Enum processes error: % DN", getlasterror ());
Return;
};

For (INT I = 0; I <dwcount; I ++)
{
Printf ("ps_id: % dttps_name: % Sn", pwtspi [I]. processid, pwtspi [I]. pprocessname );
}

How is it? Cool, it works the same way as the previous two methods!

Method 4

Finally, I will introduce a method for least people. This method is displayed on the Phantom brigade forum. The source code provided later is also copied from them. This method also provides us with a good idea.

The fourth method is implemented using the native API's ntquerysysteminformation function. Similarly, if the function is not imported to the database, you must define the original form. The entire implementation is not difficult, but it is a bit annoying, because in the parameter structure of the function, I checked msdn for a long time to find these related structures. Let's take a look at the implementation of this method.
First, the original user-defined function:

Typedef ntstatus (_ stdcall * pzwquerysysteminformation)
(In system_information_class systeminformationclass,
In out pvoid systeminformation,
In ulong systeminformationlength,
Out Pulong returnlength );
Then, as before, find the entry address of zwquerysysteminformation In The NTDLL. dll module:

Hmodule = getmodulehandle (lpctstr) "NTDLL. dll ");
Pzwquerysysteminformation = (pzwquerysysteminformation)
Getprocaddress (hmodule, (lpctstr) "zwquerysysteminformation ");
Obtain the first process information pointing to the process information array chain:
Psystemprocessinformation = (system_process_information *) pvprocesslist;

Like method 1, method 2, after obtaining the first process information, start looping and list the remaining processes:
While (true)
{
If (psystemprocessinformation-> nextentrydelta = 0) // if it is the last one, terminate the loop.
Break;

Psystemprocessinformation = (system_process_information *) (pchar) psystemprocessinformation + psystemprocessinformation-> nextentrydelta );
Pprocessname = (char *) malloc (psystemprocessinformation-> processname. Length + 2 );
}

Note that in the system_process_information structure, the process name type is unicode_string, And the buffer member in unicode_string defines the Unicode type.
Typedef struct _ system_process_information
{
DWORD nextentrydelta;
DWORD dthreadcount;
DWORD dreserved01;
DWORD dreserved02;
DWORD dreserved03;
DWORD dreserved04;
DWORD dreserved05;
DWORD dreserved06;
Filetime ftcreatetime;/* relative to 01-01-1601 */
Filetime ftusertime;/* 100 nsec units */
Filetime ftkerneltime;/* 100 nsec units */
Unicode_string processname; // This is the process name
DWORD basepriority;
DWORD duniqueprocessid; // process ID
DWORD dparentprocessid;
DWORD dhandlecount;
DWORD dreserved07;
DWORD dreserved08;
DWORD vmcounters;
DWORD dcommitcharge;
Pvoid threadinfos [1];
} System_process_information, * psystem_process_information;

Typedef struct _ unicode_string {
Ushort length;
Ushort maximumlength;
Pwstr buffer; // note that the Unicode type is used here.
} Unicode_string, * punicode_string;

Therefore, we need to call widechartomultibyte () to restore it to an ANSI string for output:
Widechartomultibyte (cp_acp,
0,
Psystemprocessinformation-> processname. buffer,
Psystemprocessinformation-> processname. Length + 1,
Pprocessname,
Psystemprocessinformation-> processname. Length + 1,
Null,
Null );

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.