C++获取程序的开放套接字的句柄

Sha*_*yar 13 c++ winapi

如何获得程序创建的套接字的套接字ID(句柄)?

我知道我可以在所有程序中获得所有打开的套接字,GetTcpTable()但它有两个问题:

  1. 它显示了所有程序套接字
  2. 它不返回套接字的ID(句柄)

jww*_*jww 6

正如雷米所说,它并非无足轻重.你必须调用OpenProcessPROCESS_DUP_HANDLE系统中的每个进程.你可能也需要PROCESS_QUERY_INFORMATIONPROCESS_VM_READ,但我从来没有需要它(我见过其他使用它的代码).

对于每个流程,您可以访问捐赠流程的句柄表NtQuerySystemInformation(信息类别为SystemHandleInformation).最后,你打电话DuplicateHandle让流程处理你的句柄.

在枚举捐赠者进程的句柄表时,您必须过滤句柄类型.对于您复制的每个句柄,请NtQueryObject使用ObjectTypeInformation.如果类型是套接字,则将其保持打开状态并将其放入列表中.否则,关闭它然后继续.

要执行比较,代码看起来类似于下面.该类型返回为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 */ }
Run Code Online (Sandbox Code Playgroud)

如果没有Socket类型(我不记得),你应该尝试获取与句柄相关联的名称(它仍然是a UNICODE_STRING),并寻找\\Device\\Tcp.这个时候,你会使用相同的句柄,但拨打NtQueryObjectObjectNameInformation:

// 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 */ }
Run Code Online (Sandbox Code Playgroud)

几年前,我自己和另一个人做了类似的事情.我们使用互斥锁和事件来替代特权的防病毒组件,而不是套接字,这些组件来自其用户区域UI程序(与IPC的特权组件共享句柄).看老狗和新技巧:你知道你的手柄在哪里吗?.