Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Get Handle of Open Sockets of a Program

Tags:

c++

winapi

How is it possible to get the Socket ID (Handle) of the created sockets of a program?

I know I can get all the open sockets in all programs by GetTcpTable() but it has two problems:

  1. It shows all programs sockets
  2. It doesn't return ID (Handle) of sockets
like image 275
Shahriyar Avatar asked Apr 28 '13 10:04

Shahriyar


People also ask

How do you check if a socket is open?

The sockstat command lists open Internet or UNIX domain sockets. The following options are available: -c Show connected sockets. -l Show listening sockets. -h Show a usage summary.

What is a socket handle?

socket-handle. A handle variable that references a socket object created by the CREATE SOCKET statement and that allows you to connect to, read from and write to a socket.

How do I see open sockets in Windows?

One of the simplest ways to check for open ports is to use NetStat.exe. You can find this tool in the System32 folder on Windows 10. With NetStat, you can see open ports or ports that a specific host uses.

How do I find sockets in Linux?

Using Netstat Command The flag -l tells netstat to print all listening sockets, -t shows all TCP connections, -u displays all UDP connections and -p enables printing of application/program name listening on the port. To print numeric values rather than service names, add the -n flag.


1 Answers

As Remy said, its not trivial. You have to call OpenProcess with PROCESS_DUP_HANDLE for each process in the system. You might also need PROCESS_QUERY_INFORMATION and PROCESS_VM_READ, but I've never needed it (I've seen other code that uses it).

For each process, you access the donor process's handle table with NtQuerySystemInformation (with an information class of SystemHandleInformation). Finally, you call DuplicateHandle to make the process's handle your handle, too.

You will have to filter the handle types when enumerating the donor process's handle table. For each handle you have duplicated, call NtQueryObject with ObjectTypeInformation. If the type is a socket, you keep it open and put it in your list. Otherwise, close it and go on.

To perform the compare, the code looks similar to below. The type is returned as a UNICODE_STRING:

// info was returned from NtQueryObject, ObjectTypeInformation
POBJECT_TYPE_INFORMATION pObjectTypeInfo = (POBJECT_TYPE_INFORMATION)(LPVOID)info;

wstring type( pObjectTypeInfo->Name.Buffer, pObjectTypeInfo->Name.Length );
if( 0 != wcscmp( L"Socket", type.c_str() ) ) { /* Not a Socket */ }

If there is no Socket type (I don't recall), you should try to get the name associated with the handle (its still a UNICODE_STRING), and look for \\Device\\Tcp. This time, you would use the same handle, but call NtQueryObject with ObjectNameInformation:

// info was returned from NtQueryObject, ObjectNameInformation
POBJECT_NAME_INFORMATION pObjectNameInfo = (POBJECT_NAME_INFORMATION)(LPVOID)info;

wstring name( pObjectNameInfo->Name.Buffer, pObjectNameInfo->Name.Length );
if( name.substr(0, 11) == "\\Device\\Tcp" ) ) { /* It's a TCP Socket */ }

Myself an another fellow did similar a few years ago. Instead of Sockets, we used Mutexes and Events to crash privileged Antivirus components from their userland UI program (which was sharing handles with the privileged component for IPC). See Old Dogs and New Tricks: Do You Know Where Your Handles Are?.

like image 133
jww Avatar answered Sep 21 '22 12:09

jww