Technical points:
1. Use the ntquerysysteminforamtion function to obtain all the system handles and obtain the socket handles.
2. Use the createconlhelp32snapshot function to obtain the system process snapshot and process details.
Implementation Details 1
Ntquerysysteminformation (DWORD, pdword, DWORD, pdword) is an API function not publicly available in windows. It contains four parameters. The first parameter specifies the type of system information we query, it can query 56 types of system information. to query the handle list, we define a constant
# Define nt_handle_list 16 (this value is obtained by data query );
The second parameter is a pointer, which is used to return the system handle list. before calling the ntquerysysteminformation function, you must allocate enough memory space for the pointer; otherwise, function calls may fail;
The third parameter specifies the memory space allocated for the system handle list, in bytes;
The fourth parameter is the size of the system handle list returned by ntquerysysteminformation;
Once the ntquerysysteminformation function is called successfully, all the handles in the system will be stored in the memory space pointed by the second parameter. Among them, the second parameter points to the first 32-digit number, it is the number of handles contained in the Buf, followed by the sequential handle pointer phandleinfo, pointing to the _ handleinfo structure:
Typedef struct _ handleinfo
{
Ushort dwpid;
Ushort creatorbacktraceindex;
Byte objtype;
Byte handleattributes;
Ushort hndloffset;
DWORD dwkeobject;
Ulong grantedaccess;
} Handleinfo, * phandleinfo;
The handle information includes the PID of the process to which the handle belongs, so that the process and socket can be associated. The socket handle type value is 0x1a (26). Therefore, retrieve all handles of the 0x1a type
Method: Socket S = (socket) handle;
Perform the getsockname operation to obtain the corresponding list of processes/ports. Otherwise, all the obtained handles belong to other processes. In NT, according to the process protection principle, A process cannot directly obtain various information about other processes, especially the handle. The same handle in different processes (the value of the handle is the same) is not the same. Therefore, you must also perform a conversion to convert the handles of other processes to the handles of this process. This conversion can be completed by simply calling the duplicatehandle function:
Duplicatehandle (handle, lphandle, DWORD, bool, DWORD );
Then you can use functions such as getsockname and getsockopt to obtain various socket attributes.
At this point, the process and Port Association work has been basically completed, but there are still some deficiencies, because of permission issues, so the system process cannot be viewed
Code:
Void getsockethandle (){
Handle hcurrentprocess = getcurrentprocess ();
Handle htoken;
/* Obtain the current process-level handle */
If (! : Openprocesstoken (hcurrentprocess, token_query | token_adjust_privileges, & htoken )){
MessageBox ("Open Process token failed! "," Error ", 0 );
Return false;
}
If (! Raiseprivileges (htoken, se_debug_name) {// Process Level Improvement
MessageBox ("Raise process failed! "," Error ");
Return false;
}
If (htoken) closehandle (htoken );
//////////////////////////////////////// //////////////////////////////////////// //////////////////
Pdword pdwhandlelist = (pdword) malloc (max_handle_list_buf); // temporary buffer
If (! Pdwhandlelist ){
MessageBox ("no enough memory for handle list! "," Error ");
Return false;
}
DWORD dwnumbytesret = 0;
// Obtain all system handles
If (ntquerysysteminformation (nt_handle_list, pdwhandlelist, max_handle_list_buf, & dwnumbytesret )){
MessageBox ("ntquerysysteminformation Return Error! "," Error ");
Return false;
}
//////////////////////////////////////// //////////////////////////////////////// //////////////////
DWORD dwnumentries; // Number of handles
Handle hproc;
Phandleinfo phandle;
Dwnumentries = pdwhandlelist [0]; // the first entry in the buffer zone is the number of handles.
Phandle = (phandleinfo) (pdwhandlelist + 1 );
//// // Obtain the corresponding information from the enumerated handle ////// //////////////////////////////////////// //
// Obtain information about each process
For (DWORD I = 0; I <dwnumentries; I ++) {// 1
If (phandle-> objtype = object_type_socket) & (phandle-> dwpid) {// 2 // determine whether it is
// Socket type
// Object_type_socket is the defined constant value 0x1a
If (phandle-> dwpid = m_nmypid) {// if this process is skipped
// Obtain the Process Handle
Hproc = OpenProcess (write_dac, false, phandle-> dwpid );
If (hproc) {// 3
Adjustdacl (hproc); // adjust the access control attribute of the target handle
Closehandle (hproc );
} // 3
Else {// 4
Break;
} // 4
Handle hmyhandle = NULL;
Hproc = OpenProcess (process_dup_handle, true, phandle-> dwpid );
If (hproc) {// 5
// Copy the obtained process handle to the current process handle
Duplicatehandle (hproc, (handle) phandle-> handoffset, hcurrentprocess,
& Hmyhandle, standard_rights_required, true, 0 );
If (hmyhandle! = NULL) {// 6
Socketinfo (hmyhandle, phandle); // obtain socket Information
} // 6
Closehandle (hmyhandle );
} // 5
// Closehandle (hproc );
}
} // 2
Phandle ++;
} // 1
If (pdwhandlelist ){
Free (pdwhandlelist );
}
If (hcurrentprocess ){
Closehandle (hcurrentprocess );
}
Return true;
}
Void socketinfo (handle requirehandle, phandleinfo phandlebuf)
{
Sockaddr_in name =;
Name. sin_family = af_inet;
Int namelen = sizeof (sockaddr_in );
Socket S = (socket) requirehandle;
// Obtain the detailed message of the socket process. The process ID uses the system snapshot to find the detailed information of the process.
// You can call the System Snapshot in kernel32.dll. This function will be supplemented later.
If (getsockname (S, (sockaddr *) & name, & namelen )! = Socket_error) {// 7
Targethandle [++ thindex]. m_hhandle = * phandlebuf;
Targethandle [thindex]. m_addr = Name;
Targethandle [thindex]. sockettype = 4;
Int optlen = 4;
Getsockopt (S, sol_socket, so_type, (char *) & targethandle [thindex]. sockettype, & optlen );
} // 7
Else closehandle (requirehandle );
}
Void adjustdacl (handle hprocess) // adjust the DACL and data structure of the target process. For function definition, see aclapi. h.
{
Sid world =;
Lptstr ptstrname = (lptstr) & world;
Explicit_access Ea = {// process Access Control Information
Standard_rights_all | specific_rights_all,
Set_access,
No_inheritance,
{
0, no_multiple_trustee,
Trustee_is_sid,
Trustee_is_user,
Ptstrname
}
};
ACL * pdacl = 0;
If (setentriesinacl (1, & EA, 0, & pdacl )! = Error_success ){
MessageBox ("setentriesinacl failed! "," Error ");
Return;
}
If (setsecurityinfo (hprocess, se_kernel_object, dacl_security_information, 0, pdacl, 0 )){
MessageBox ("setsecurity failed! "," Error ");
}
Localfree (pdacl );
}
Bool clocalscandlg: raiseprivileges (handle htoken, char * ppriv) // upgrade the process level.
{
Token_privileges tkp;
If (! : Lookupprivilegevalue (null, ppriv, & tkp. Privileges [0]. luid) {// obtain the current level
MessageBox ("Look up privilegevalue failed! "," Null ");
Return false;
} // Modify the process level
Tkp. privilegecount = 1;
Tkp. Privileges [0]. Attributes = se_privilege_enabled;
If (! : Adjusttokenprivileges (htoken, false, & tkp, 0, null, null) {// adjust the process level
MessageBox ("Adjust privileges failed! "," Error ");
Return false;
}
Return true;
}
2.
You can obtain the opened window and the PID of the port-consuming process from step 1. You can obtain the process snapshot in the system through createconlhelp32snapshot (DWORD dwflags, DWORD th32processid) in kernel32.dll, for more information, see the header file tlhelp32.h)
The first parameter is the System Snapshot type. Select th32cs_snapprocess here. The second parameter must be null.
If the call is successful, the System Snapshot handle is returned.
Process32first (handle hsnapshot, lpprocessentry32 lppe) and
Process32next (handle hsnapshot, lpprocessentry32 lppe) function to obtain process details
Structure of lpprocessentry32
Typedef struct tagprocessentry32 {
DWORD dwsize; // The structure size. before using the preceding two functions, you must assign a sizeof (processentry32) value)
DWORD cntusage;
DWORD th32processid; // process PID
DWORD th32defaultheapid;
DWORD th32moduleid;
DWORD cntthreads; // Number of threads
DWORD th32parentprocessid;
Long pcpriclassbase;
DWORD dwflags;
Char szexefile [max_path]; // process name
} Processentry32;
Typedef processentry32 * pprocessentry32;
Typedef processentry32 * lpprocessentry32;
Code:
Bool getsocketprocinfo ()
{
Int I;
Handle hsnapshot;
Processentry32 lppe;
Hsnapshot =: createconlhelp32snapshot (th32cs_snapprocess, 0); // obtain the System Snapshot
Lppe. dwsize = sizeof (lppe); // value assignment
Int ret =: process32first (hsnapshot, & lppe );
If (RET ){
Do {
For (I = 0; I <= thindex; I ++ ){
If (targethandle [I]. m_hhandle.dwpid = lppe. th32processid ){
Strcpy (targethandle [I]. m_hproclist.exename, lppe. szexefile );
Targethandle [I]. m_hproclist.cntthreads = lppe. cntthreads;
}
}
} While (: process32next (hsnapshot, & lppe ));
}
Closehandle (hsnapshot );
Return true;
}
Disadvantages:
Because the target process's handles are constantly copied during refresh, the system handles increase. The system memory is occupied, and the memory allocated to the structure is used up in advance. This will cause ntquerysysteminformation function errors.
Solution:
Create a PID linked list, record the PID, and assign different attributes of the PID to bool isnew to prevent duplicate replication.