Re: Problem getting Remote Address of Connected Sockets using Gary Nab
- From: "Arkady Frenkel" <arkadyf@xxxxxxxxxxxxxxxx>
- Date: Thu, 15 Sep 2005 17:52:30 +0200
Are you sure that hObject is socket handle ? Check that ,seems that not like
this. Additionally
look at GetTcpTable from IPHLPAPI
Arkady
"George" <George@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:EE5A423B-C1D0-446E-B4D9-72EDDDD667CB@xxxxxxxxxxxxxxxx
>I am using Gary Nabbett's Code to Get Process IDs of All Connected Sockets
>on
> a Windows 2000 machine. The code works fine, However, it doesn't print the
> remote address - the one socket is connected to. I tried looking into DDK
> and
> Win32 but can't find it. I know for sure that SysInternals has a software
> that shows Process IDs on Windows 2000 OS and the code would be somewhat
> similar to this one.
>
> BTW, I tried using "getpeername" [see code] and provided it the Handle
> [Supposed to be a Socket Handle], but getpeername returned with an error
> 10038 = Invalid handle??
>
> Does anyone know whats going on in here? All I need is the remote address
> and I'm good!
>
> Thanks!
>
>
> Here is All the Code - Just Copy/Paste it and check it out:
> -----------------------------------------------------------------
>
>
>
> /*cl -c -Ox -W3 -MD -nologo -D_X86_=1 -DSTRICT -DWIN32_LEAN_AND_MEAN
> portuser.cpp
> link -release -incremental:no -pdb:none -subsystem:console -nologo
> -out:portuser.exe portuser.obj kernel32.lib advapi32.lib ws2_32.lib
> ntdll.lib psapi.lib
>
> */
> #include "stdafx.h"
> #include <winsock2.h>
> #include <stdio.h>
> #include <conio.h>
> #include <psapi.h> // wre
>
>
> #undef PSLIST_ENTRY
> #define PSLIST_ENTRY ::PSINGLE_LIST_ENTRY
>
> BOOL CodeError = FALSE;
>
> namespace NT {
> extern "C" {
>
> #pragma warning(disable: 4005) // macro redefinition
> #pragma warning(disable: 4201) // nonstandard extension
> #include <ntddk.h> // wre
> #include <tdikrnl.h>
> #pragma warning(default: 4005)
> #pragma warning(default: 4201)
>
> typedef enum _SYSTEM_INFORMATION_CLASS {
> SystemHandleInformation = 16
> } SYSTEM_INFORMATION_CLASS;
>
> NTSYSAPI
> NTSTATUS
> NTAPI
> ZwQuerySystemInformation(
> IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
> OUT PVOID SystemInformation,
> IN ULONG SystemInformationLength,
> OUT PULONG ReturnLength OPTIONAL
> );
>
> typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
> USHORT UniqueProcessId;
> USHORT CreatorBackTraceIndex;
> UCHAR ObjectTypeIndex;
> UCHAR HandleAttributes; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
> USHORT HandleValue;
> PVOID Object;
> ACCESS_MASK GrantedAccess;
> } SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
>
> typedef struct _SYSTEM_HANDLE_INFORMATION {
> ULONG NumberOfHandles;
> SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
> } SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
>
> typedef struct _HARDWARE_PTE {
> ULONG Valid : 1;
> ULONG Write : 1;
> ULONG Owner : 1;
> ULONG WriteThrough : 1;
> ULONG CacheDisable : 1;
> ULONG Accessed : 1;
> ULONG Dirty : 1;
> ULONG LargePage : 1;
> ULONG Global : 1;
> ULONG CopyOnWrite : 1;
> ULONG Prototype : 1;
> ULONG reserved : 1;
> ULONG PageFrameNumber : 20;
> } HARDWARE_PTE, *PHARDWARE_PTE;
> }
> }
> using NT::NTSTATUS;
>
>
> class Kmem {
> public:
> Kmem();
> ~Kmem();
> ULONG Copy(ULONG, PVOID, ULONG) const;
> ULONG RawCopy(ULONG, PVOID, ULONG) const;
> template<class T> T Get(T* va) const {T x[1] = {0};
> Copy(ULONG(va), x, sizeof x); return x[0];}
> private:
> PVOID MapSystemPage(ULONG, ULONG) const;
> ULONG FindPde() const;
> ULONG AnyPde() const;
> ULONG MyPde() const;
> HANDLE section;
> NT::PHARDWARE_PTE pde;
> };
>
> Kmem::Kmem()
> {
> NT::UNICODE_STRING name; NT::RtlInitUnicodeString(&name,
> L"\\Device\\PhysicalMemory");
> NT::OBJECT_ATTRIBUTES oa = {sizeof oa, 0, &name, OBJ_CASE_INSENSITIVE};
>
> NT::ZwOpenSection(§ion, SECTION_MAP_READ, &oa);
>
> pde = NT::PHARDWARE_PTE(MapViewOfFile(section, FILE_MAP_READ, 0,
> FindPde(), 0x1000));
> }
>
> Kmem::~Kmem()
> {
> UnmapViewOfFile(pde);
>
> CloseHandle(section);
> }
>
> ULONG Kmem::FindPde() const
> {
> ULONG pde = MyPde();
>
> return pde == 0 ? AnyPde() : pde;
> }
>
> ULONG Kmem::MyPde() const
> {
> unsigned short tr; __asm str tr;
>
> LDT_ENTRY tss;
>
> GetThreadSelectorEntry(GetCurrentThread(), tr, &tss);
>
> ULONG va = (tss.HighWord.Bits.BaseHi << 24) +(tss.HighWord.Bits.BaseMid
> << 16) + tss.BaseLow;
>
> ULONG pa = va & ~0x80000000;
>
> ULONG cr3; RawCopy(pa + 0x1C, &cr3, sizeof cr3);
>
> return (cr3 & 0xFFF) == 0 ? cr3 : 0;
> }
>
> ULONG Kmem::AnyPde() const
> {
> const int reserved = 0xA0;
>
> PULONG lowmem = PULONG(MapViewOfFile(section, FILE_MAP_READ, 0, 0,
> reserved * 0x1000));
> ULONG pfn;
>
> //*** Note: lowmem would be NULL if the User Doesn't Have enough Rights.
> If
> //its NULL then stop executing this code or it will Generate Exceptions
> if (lowmem != NULL)
> {
> for (pfn = 0; pfn < reserved; pfn++)
> {
> if (lowmem[pfn * 0x400 + 0x300] == pfn * 0x1000 + 0x67)
> break;
> }
> }
> else
> {
> //Set Error Flag
> CodeError = TRUE;
> }
>
> UnmapViewOfFile(lowmem);
>
> if (lowmem == NULL)
> return 0;
> else
> return pfn * 0x1000;
> }
>
> PVOID Kmem::MapSystemPage(ULONG va, ULONG prot) const
> {
> ULONG offset;
>
> NT::HARDWARE_PTE pte1 = pde[va >> 22];
>
> if (!pte1.Valid) return 0;
>
> if (pte1.LargePage == 0) {
>
> NT::PHARDWARE_PTE table = NT::PHARDWARE_PTE(MapViewOfFile(section,
> FILE_MAP_READ, 0, pte1.PageFrameNumber << 12, 0x1000));
>
> NT::HARDWARE_PTE pte2 = table[(va >> 12) & 0x3ff];
>
> UnmapViewOfFile(table);
>
> if (!pte2.Valid) return 0;
>
> offset = pte2.PageFrameNumber << 12;
> }
> else
> offset = (pte1.PageFrameNumber << 12) + (va & 0x3ff000);
>
> return MapViewOfFile(section, prot, 0, offset, PAGE_SIZE);
> }
>
> ULONG Kmem::Copy(ULONG va, PVOID p, ULONG n) const
> {
> ULONG m = 0;
>
> for (ULONG y, x = va; x < va + n; x += y) {
>
> PVOID q = MapSystemPage(x, FILE_MAP_READ);
>
> if (q == 0) return m;
>
> y = min(n - m, PAGE_SIZE - BYTE_OFFSET(x));
>
> memcpy(PBYTE(p) + m, PBYTE(q) + BYTE_OFFSET(x), y);
>
> UnmapViewOfFile(q);
>
> m += y;
> }
>
> return m;
> }
>
> ULONG Kmem::RawCopy(ULONG pa, PVOID p, ULONG n) const
> {
> ULONG m = 0;
>
> for (ULONG y, x = pa; x < pa + n; x += y) {
>
> PVOID q = MapViewOfFile(section, FILE_MAP_READ, 0, x & ~0xFFF,
> 0x1000);
>
> if (q == 0) return m;
>
> y = min(n - m, PAGE_SIZE - BYTE_OFFSET(x));
>
> memcpy(PBYTE(p) + m, PBYTE(q) + BYTE_OFFSET(x), y);
>
> UnmapViewOfFile(q);
>
> m += y;
> }
>
> return m;
> }
>
> /* wre */
> char *getProcessFilename (ULONG pid)
> {
>
> const C_MAX_NBR = 256
> ;
> DWORD dwaProcessIds [C_MAX_NBR],
> dwNbrProcesses,
> dwNbrModules
> ;
> HANDLE hProcess
> ;
> HMODULE hmaModules [C_MAX_NBR]
> ;
> char cFilename[MAX_PATH]
> ;
> char *pReturn
> ;
>
> pReturn = "System";
>
> int iSuccess = EnumProcesses (dwaProcessIds, sizeof (dwaProcessIds),
> &dwNbrProcesses);
>
> dwNbrProcesses /= sizeof (dwaProcessIds[0]);
>
> if (iSuccess) {
>
> for (unsigned i = 0; i < dwNbrProcesses; i++) {
>
> if (pid == dwaProcessIds [i])
> {
> hProcess = OpenProcess (PROCESS_QUERY_INFORMATION |
> PROCESS_VM_READ,
> FALSE, dwaProcessIds [i]);
>
> EnumProcessModules (hProcess, hmaModules, sizeof (hmaModules),
> &dwNbrModules);
>
> dwNbrModules /= sizeof (hmaModules [0]);
>
> if (GetModuleFileNameEx (hProcess, hmaModules [0], cFilename,
> sizeof
> (cFilename)))
> {
> pReturn = cFilename;
> }
>
> CloseHandle (hProcess);
> }
> }
> }
>
>
> return pReturn;
> } /* getProcessFilename () */
> /* wre */
>
>
> HANDLE OpenDevice(PCWSTR name)
> {
> NT::UNICODE_STRING s; NT::RtlInitUnicodeString(&s, name);
> NT::OBJECT_ATTRIBUTES oa = {sizeof oa, 0, &s,
> OBJ_CASE_INSENSITIVE};
> NT::IO_STATUS_BLOCK iosb;
> HANDLE h;
>
> NT::ZwOpenFile(&h, SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ |
> FILE_SHARE_WRITE, 0);
>
> return h;
> }
>
> NT::PSYSTEM_HANDLE_INFORMATION GetHandles()
> {
> ULONG n = 0x100;
> NT::PSYSTEM_HANDLE_INFORMATION hi = new
> NT::SYSTEM_HANDLE_INFORMATION[n];
>
> while (NT::ZwQuerySystemInformation(NT::SystemHandleInformation,
> hi, n * sizeof *hi, 0)
> == STATUS_INFO_LENGTH_MISMATCH)
>
> delete [] hi, hi = new NT::SYSTEM_HANDLE_INFORMATION[n *= 2];
>
> return hi;
> }
>
> ULONG FindHandle(NT::PSYSTEM_HANDLE_INFORMATION hi, ULONG pid, HANDLE
> h)
> {
> for (ULONG i = 0; i < hi->NumberOfHandles; i++)
>
> if (hi->Handles[i].UniqueProcessId == pid &&
> HANDLE(hi->Handles[i].HandleValue) == h)
>
> return i;
>
> return 0;
> }
>
> HANDLE CopyHandle(ULONG pid, HANDLE h)
> {
> HANDLE hObject = 0;
>
> HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid);
>
> DuplicateHandle(hProcess, h, GetCurrentProcess(), &hObject, 0, FALSE,
> DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
>
> CloseHandle(hProcess);
>
> return hObject;
> }
>
> VOID DispAddr(ULONG pid, PCSTR protocol, NT::PTDI_ADDRESS_INFO addr)
> {
> NT::PTA_IP_ADDRESS ipaddr = NT::PTA_IP_ADDRESS(&addr->Address);
>
> PUCHAR c = PUCHAR(&ipaddr->Address[0].Address[0].in_addr);
>
> LONG TAAddressCount = addr->Address.TAAddressCount;
>
> printf("%4ld %s %3d.%3d.%3d.%3d:%-4hu %s\n",
> // wre
> pid, protocol, int(c[0]), int(c[1]), int(c[2]), int(c[3]),
> ntohs(ipaddr->Address[0].Address[0].sin_port), getProcessFilename
> (pid)); // wre
> }
>
> VOID Scan(const Kmem &kmem, NT::PSYSTEM_HANDLE_INFORMATION hi, UCHAR file,
> NT::PDEVICE_OBJECT device, PCSTR protocol)
> {
> sockaddr sock_address;
> int sock_add_size = sizeof(sock_address);
>
>
> OVERLAPPED o = {0, 0, 0, 0, CreateEvent(0, TRUE, FALSE, 0)};
>
> for (ULONG i = 0; i < hi->NumberOfHandles; i++)
> {
> if (hi->Handles[i].ObjectTypeIndex == file)
> {
> NT::FILE_OBJECT fo = kmem.Get(NT::PFILE_OBJECT(hi->Handles[i].Object));
>
> if (fo.DeviceObject == device && (fo.FsContext2 ==
> PVOID(TDI_TRANSPORT_ADDRESS_FILE) || fo.FsContext2 ==
> PVOID(TDI_CONNECTION_FILE)))
> {
> HANDLE hObject = CopyHandle(hi->Handles[i].UniqueProcessId,
> HANDLE(hi->Handles[i].HandleValue));
>
> if (hObject)
> {
> sock_add_size = sizeof(sock_address);
>
> int Err = getpeername((SOCKET)hObject, &sock_address,
> &sock_add_size);
> if (Err == 0)
> {
> //Valid Socket - Print Remote Address
> //printf(sock_address.sin_addr.s_b1);
> printf("Found");
> }
> else
> {
> Err = WSAGetLastError();
> Err = 1;
> }
>
> NT::TDI_REQUEST_QUERY_INFORMATION reqaddr = {{0},
> TDI_QUERY_ADDRESS_INFO};
> NT::TDI_REQUEST_QUERY_INFORMATION reqconn = {{0},
> TDI_QUERY_CONNECTION_INFO};
> NT::TDI_CONNECTION_INFO conn = {0};
> NT::TDI_ADDRESS_INFO addr[3] = {0};
>
> if (fo.FsContext2 == PVOID(TDI_TRANSPORT_ADDRESS_FILE) ||
> DeviceIoControl(hObject, IOCTL_TDI_QUERY_INFORMATION, &reqconn, sizeof
> reqconn, &conn, sizeof conn, 0, &o))
> {
> if (DeviceIoControl(hObject, IOCTL_TDI_QUERY_INFORMATION, &reqaddr,
> sizeof reqaddr, addr, sizeof addr, 0, &o))
> {
> DispAddr(hi->Handles[i].UniqueProcessId, protocol, addr);
> }
> }
>
>
>
> CloseHandle(hObject);
> }
> }
> }
> }
>
> CloseHandle(o.hEvent);
> }
>
> BOOL EnablePrivilege(PCSTR name)
> {
> TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};
> LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid);
>
> HANDLE hToken;
> OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
> &hToken);
>
> AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0);
> BOOL rv = GetLastError() == ERROR_SUCCESS;
>
> CloseHandle(hToken);
> return rv;
> }
>
> int main()
> {
> DWORD StartTime = GetTickCount();
>
> //Initialize WinSock to be Used by this Process
> WSADATA wsaData;
> int err;
>
> WORD wVersionRequested = MAKEWORD( 2, 2 );
>
> err = WSAStartup( wVersionRequested, &wsaData );
>
>
> Kmem kmem;
>
> if (CodeError == TRUE)
> {
> //Most Probably the User doesn't have Enough
> //rights so the Code can't continue
> printf("Not Enough Rights!");
>
> getche();
>
> return 0;
> }
>
> EnablePrivilege(SE_DEBUG_NAME);
>
> HANDLE tcp = OpenDevice(L"\\Device\\Tcp");
> HANDLE udp = OpenDevice(L"\\Device\\Udp");
>
> NT::PSYSTEM_HANDLE_INFORMATION hi = GetHandles();
>
> ULONG tcpi = FindHandle(hi, GetCurrentProcessId(), tcp);
> ULONG udpi = FindHandle(hi, GetCurrentProcessId(), udp);
>
> NT::FILE_OBJECT tcpfo =
> kmem.Get(NT::PFILE_OBJECT(hi->Handles[tcpi].Object));
> NT::FILE_OBJECT udpfo =
> kmem.Get(NT::PFILE_OBJECT(hi->Handles[udpi].Object));
>
> CloseHandle(tcp);
> CloseHandle(udp);
>
> Scan(kmem, hi, hi->Handles[tcpi].ObjectTypeIndex, tcpfo.DeviceObject,
> "TCP");
> Scan(kmem, hi, hi->Handles[udpi].ObjectTypeIndex,
> udpfo.DeviceObject, "UDP");
>
> DWORD EndTime = GetTickCount();
>
> WCHAR szBuffer[128];
> swprintf(szBuffer, L"Total Time: %d", (EndTime - StartTime));
> wprintf(szBuffer);
>
> getche();
>
> return 0;
> }
.
- Follow-Ups:
- Prev by Date: Re: A question about Networking a small LAN
- Next by Date: Re: A question about Networking a small LAN
- Previous by thread: Re: A question about Networking a small LAN
- Next by thread: Re: Problem getting Remote Address of Connected Sockets using Gary
- Index(es):