Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

portuser.cpp

292 views
Skip to first unread message

William R. Epp

unread,
May 8, 2002, 9:48:24 PM5/8/02
to
In case anyone was looking for this, Gary Nebbett is the author. I
made some minor changes (indicated with // wre). Something like this
should compile it:
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 <winsock2.h>
#include <stdio.h>

#include <psapi.h> // wre


#undef PSLIST_ENTRY
#define PSLIST_ENTRY ::PSINGLE_LIST_ENTRY

namespace NT {
extern "C" {

#pragma warning(disable: 4005) // macro redefinition
#pragma warning(disable: 4201) // nonstandard extension
#include <ddk/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(&section, 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;

for (pfn = 0; pfn < reserved; pfn++)

if (lowmem[pfn * 0x400 + 0x300] == pfn * 0x1000 + 0x67) break;

UnmapViewOfFile(lowmem);

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 = "<no filename>";

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_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);

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)
{
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) {

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()
{
Kmem kmem;

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");

return 0;
}


arkadyf

unread,
May 9, 2002, 3:14:05 AM5/9/02
to
Thanks William , maybe you have the source for W9x ?
Arkady

William R. Epp <res0...@verizon.net> wrote in message
news:vpkjdugmm8faj0a0m...@4ax.com...

adara

unread,
May 9, 2002, 6:37:50 AM5/9/02
to
The source is not full ,something is missing..
can you please repost it or send it to me by mail
thank you

William R. Epp

unread,
May 10, 2002, 6:13:37 PM5/10/02
to
Don't have any, haven't looked but that would probably be a lot harder
to find.

On Thu, 9 May 2002 09:14:05 +0200, "arkadyf" <ark...@hotmail.com>
wrote:

William R. Epp

unread,
May 10, 2002, 6:14:53 PM5/10/02
to
You do need the Windows DDK from www.microsoft.com to compile/link
this source - otherwise it is complete.

On Thu, 9 May 2002 03:37:50 -0700, "adara" <ada...@hotmail.com>
wrote:

Amit S

unread,
Dec 21, 2004, 3:49:24 AM12/21/04
to
The source is not full
Few lines after NT::FILE_OBJECT tcpfo = in the main() function are
missing. can you please post it again or mail it to me at
ami...@cybage.com or amita...@yahoo.com. Thanks in advance

Arkady Frenkel

unread,
Dec 22, 2004, 5:30:40 AM12/22/04
to
Search in google for code for portuser provided in this NG few times.
BTW that obsolete in XP
Arkady

"Amit S" <amita...@yahoo.com> wrote in message
news:1103618964....@c13g2000cwb.googlegroups.com...

lad

unread,
Dec 28, 2004, 4:00:05 AM12/28/04
to
I have a question, could you help me:
How to write the same program to run on win98
Thanks very much!

Arkady Frenkel

unread,
Dec 29, 2004, 12:30:47 PM12/29/04
to
You can use LSP for winsock in W98 for that
Arkady

"lad" <dung...@yahoo.com> wrote in message
news:1104224405.6...@z14g2000cwz.googlegroups.com...

0 new messages