C++ Get Handle of Open Sockets of a Program

﹥>﹥吖頭↗ 提交于 2019-12-17 12:48:42

问题


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

回答1:


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?.




回答2:


Ok, thanks to everyone that tried to solve my problem
After a lot of works I get how to handle it myself, this is how i tried to get the specified socket :

  • At the first I looked in to program's disassembly and find out the calls to WS2_32 Send function.

As the picture show there is a call to Socket send function at 0x467781 and the Socket handle saved to the stack in the EDX register

  • Now what i need to do is to Hook my code in to that function.

    void GetSocket(int Flag,int DataSize, char* Data, SOCKET Socket)
     {
         sSocket = Socket;
         sFlag = Flag;
         sDataSize = DataSize;
         sData = Data;
         SendPacket(sSocket,Data,DataSize); //Send packets manually
     }
    
    __declspec(naked) void MyFunc()
     {
        __asm
          {
               PUSH EDX // Socket
               PUSH ECX // Buffer
               PUSH EAX // Buffer Size
               PUSH 0   // Flag
               CALL GetSocket
               MOV EAX, sDataSize
               MOV ECX, sData
               MOV EDX, sWowSocket
               JMP [JumpAddress] // JumpAddress = 0x467787 (After that CALL)
           }
     }
    

    And now i all have to do is to change that CALL (in 0x467781) to a JMP to our function(MyFunc) and it can be done with the following function :

    *(DWORD*)   (0x467781  + 0x01)  =   (DWORD)MyFunc- (0x467781  + 0x05);
    

Now I'm done,I can easily see each packet that it sends to server and change them if necessary and also send my custom packets whit its Socket :)



来源:https://stackoverflow.com/questions/16262114/c-get-handle-of-open-sockets-of-a-program

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!