netstat in kernel mode

Before Vista, invoking netstat would eventually result in IOCTL_TCP_QUERY_INFORMATION_EX to be send to \Device\Tcp that would return a table with all bound ports and existing connections. On Vista, netstat invokes \Device\Nsi, which invokes netio.sys!NsiEnumerateObjectsAllParametersEx to obtain the same information.

My question is: is there a way, other than reverse engineering the call to NsiEnumerateObjectsAllParametersEx, to perform netstat from a kernel driver? Is there another source, e.g., WFP, that I could query using a documented API? I guess I can always use iphlpapi.dll in a user-space program and push that information to the kernel, but I am looking for something that does not move data unnecessarily between the kernel and user space.

Thanks,
–aydan

Anyone would like to chime in? I guess I finally found a question with no answers…

–aydan

On Vista and later you can see in the kernel-mode IP Helper API will be of service.

Thomas F. Divine

I think you (or a recent post) demonstrated that it is understood that…

  1. In NT5 this is a reverse engineering / undocumented TCPIP.SYS
    IRP_MJ_DEVICE_CONTROL problem.

  2. In NT6 I would expect you can get this information from the Kernel Mode
    IPHelper since you can get it from User Mode IPHelper with
    MIB_TCPROW_OWNER_MODULE / TCPIP_OWNER_MODULE_BASIC_INFO.

But maybe not. Let us know.

Good Luck,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Tuesday, October 27, 2009 1:46 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] netstat in kernel mode

Anyone would like to chime in? I guess I finally found a question with no
answers…

–aydan


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

It turns out that GetTcpTable and variants eventually call NsiAllocateAndGetTable. In user-space this function is implemented in nsi.dll and the implementation works by calling \Device\Nsi to satisfy NsiEnumerateObjectsAllParameters. The NSI proxy driver validates the arguments and proxies the call to netio.sys, which actually exports a function called NsiEnumerateObjectsAllParameters. Looking at the exports list of netio.sys I found an export called NsiAllocateAndGetTable, which is exactly the function I was tracing in user-space.

After disassembling both functions I realized that they produce the same result and take the same arguments (12 of them!). My searches to find any information on these functions was futile, so I had to figure out what those arguments are on my own.

Anyway, I have a working prototype now (only for x64, but should be easy to port to x86): my kernel driver can easily enumerate all extant network links/ports. I just hope that the interface I had to reverse engineer is stable and not going to change…

–aydan

And what is wrong with the documented kernel mode IP Helper routines?

Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Thursday, October 29, 2009 5:58 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] netstat in kernel mode

It turns out that GetTcpTable and variants eventually call
NsiAllocateAndGetTable. In user-space this function is implemented in
nsi.dll and the implementation works by calling \Device\Nsi to satisfy
NsiEnumerateObjectsAllParameters. The NSI proxy driver validates the
arguments and proxies the call to netio.sys, which actually exports a
function called NsiEnumerateObjectsAllParameters. Looking at the exports
list of netio.sys I found an export called NsiAllocateAndGetTable, which is
exactly the function I was tracing in user-space.

After disassembling both functions I realized that they produce the same
result and take the same arguments (12 of them!). My searches to find any
information on these functions was futile, so I had to figure out what those
arguments are on my own.

Anyway, I have a working prototype now (only for x64, but should be easy to
port to x86): my kernel driver can easily enumerate all extant network
links/ports. I just hope that the interface I had to reverse engineer is
stable and not going to change…

–aydan


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Please don’t reverse engineer undocumented details. Please don’t encourage other people to use undocumented functions by posting your musings to a publicly-archived list. Your story below is anyway incomplete – e.g., do you know which locks must be held? (I don’t want an answer to that question).

I enjoy disassembling code; it is like a fun logic puzzle. But then when you ship a product on this, real customers see bluescreens. BTW, my team owns this code and I am planning breaking changes to this interface.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Thursday, October 29, 2009 2:58 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] netstat in kernel mode

It turns out that GetTcpTable and variants eventually call NsiAllocateAndGetTable. In user-space this function is implemented in nsi.dll and the implementation works by calling \Device\Nsi to satisfy NsiEnumerateObjectsAllParameters. The NSI proxy driver validates the arguments and proxies the call to netio.sys, which actually exports a function called NsiEnumerateObjectsAllParameters. Looking at the exports list of netio.sys I found an export called NsiAllocateAndGetTable, which is exactly the function I was tracing in user-space.

After disassembling both functions I realized that they produce the same result and take the same arguments (12 of them!). My searches to find any information on these functions was futile, so I had to figure out what those arguments are on my own.

Anyway, I have a working prototype now (only for x64, but should be easy to port to x86): my kernel driver can easily enumerate all extant network links/ports. I just hope that the interface I had to reverse engineer is stable and not going to change…

–aydan


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Perhaps Mr. Tippet would care to comment on whether or not what the OP
wishes to accomplish is directly possible on NT6 with Kernel Mode IP Helper
and thus help not only to discourage this exercise but also render it moot?

Regards,
Dave Cattley

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Jeffrey Tippet
Sent: Thursday, October 29, 2009 10:00 PM
To: Windows System Software Devs Interest List
Subject: RE: RE:[ntdev] netstat in kernel mode

Please don’t reverse engineer undocumented details. Please don’t encourage
other people to use undocumented functions by posting your musings to a
publicly-archived list. Your story below is anyway incomplete – e.g., do
you know which locks must be held? (I don’t want an answer to that
question).

I enjoy disassembling code; it is like a fun logic puzzle. But then when
you ship a product on this, real customers see bluescreens. BTW, my team
owns this code and I am planning breaking changes to this interface.

David,

The documented kernel mode IP Helper routines seem not to offer this functionality. I spent a lot of time examining the header files and did not find any function that would give me a table of the currently bound ports and active connections. This functionality, based on my current understanding, is officially exported only to user-space code. Please correct me if I am wrong, because I would love to use a documented function.

Thanks,
–aydan

Jeffrey,

As I mentioned in my reply to David, I would love a documented way of obtaining a table with all bound ports and connections in *KERNEL* mode, but everything I found so far refers only to *USER* mode. Please prove me wrong. It would save me and my company a lot of time.

There are several reasons for needing this functionality:

  1. When my driver starts, it needs to be able to perform essentially what “nestat -anop tcp” does so that it initializes its “knowledge” about the world: what ports are currently bound and what connections are active. Arguably I can do this in user-space (and I have in the past), but the problem is that the driver will need that information periodically, so that:
  • it can detect when an extant port/connection are terminated
  • it can deal with #2
    I personally think that performing the query in user space and sending the information back to the driver every few seconds is a bad idea.
  1. The driver adds a number of WFP callouts and needs a way to determine when a server port gets unbound. To the best of my knowledge there is no WFP notification for unbound ports prior to Windows 7. Since the driver allocates state per server bound port, I need a way to clean up that state. I addition, our product must report the fact that a port has been unbound within 15 seconds or so from the port actually being unbound.

Please let me know if there are viable alternatives to what I am doing that would meet my requirements.

Thanks a lot,
Best,
–aydan

>But then when you ship a product on this

Usually, people ship the products based on such things if there are no alternatives.

If the software publisher company needs a feature, and a feature can only be implemented using such undocumented stuff use, hooks etc - then such a product will be shipped.

Sometimes, MS helps with this - for instance, with ATA commands sending, which was broken for a very long time (filtering is still impossible except by hooking the ATA miniport driver on load).

But note that such a help from MS usually appears in the newest OS only, and people still use hooks and undocumented functions for downlevel OSes.

Also note that there are documented functions which were undocumented pre-Vista, but working fine from NT4 up to and including Vista. PsLookupProcessByProcessId is a sample.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> I personally think that performing the query in user space and sending the information back to the

driver every few seconds is a bad idea.

Every few seconds is fine. I think this is what numerous tray icons do to update their status.

Every few milliseconds is not OK.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

I don’t know of any way to do it in kernelmode. That’s ok, since there are easy and obvious ways to do it in usermode. Usermode is where all the “complicated” stuff should happen anyway. Kernelmode is not meant to be a completely general development platform.

I know it’s tantalizing, since it seems like Microsoft has hidden the API that (according to incomplete reverse-engineering) might instantly solve your immediate problem. But “there is no alternative (in kernelmode)” isn’t enough justification to add a ton of extra risk to your product. Not to mention the extra time it will cost me and my team as we discover your product through bugcheck reports, root-cause the issue, follow up with your QA team to get this fixed, and publish a hardblock for your app in the next version of Windows.

The tone of this email is not meant to be nasty; I’m sorry if it reads harshly. I’m really only trying to help both of us and our mutual customers. I have taken as feedback that this information might need to be exposed in kernelmode – in planning future versions of Windows, we will balance this feedback against our desire to have most code move to usermode, as well as against our other priorities. I have also passed your earlier mail “To TDI Filter or not” to the WFP and WSK teams, who are taking it into consideration as well. We really do want you to be able to ship great products on Windows.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Friday, October 30, 2009 5:02 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] netstat in kernel mode

Jeffrey,

As I mentioned in my reply to David, I would love a documented way of obtaining a table with all bound ports and connections in *KERNEL* mode, but everything I found so far refers only to *USER* mode. Please prove me wrong. It would save me and my company a lot of time.

There are several reasons for needing this functionality:

  1. When my driver starts, it needs to be able to perform essentially what “nestat -anop tcp” does so that it initializes its “knowledge” about the world: what ports are currently bound and what connections are active. Arguably I can do this in user-space (and I have in the past), but the problem is that the driver will need that information periodically, so that:
  • it can detect when an extant port/connection are terminated
  • it can deal with #2
    I personally think that performing the query in user space and sending the information back to the driver every few seconds is a bad idea.
  1. The driver adds a number of WFP callouts and needs a way to determine when a server port gets unbound. To the best of my knowledge there is no WFP notification for unbound ports prior to Windows 7. Since the driver allocates state per server bound port, I need a way to clean up that state. I addition, our product must report the fact that a port has been unbound within 15 seconds or so from the port actually being unbound.

Please let me know if there are viable alternatives to what I am doing that would meet my requirements.

Thanks a lot,
Best,
–aydan


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Some 13 years back I did reverse engineer the mechanisms behind the
likes of netstat.exe, arp.exe and route.exe. It was ugly and not
worth reproducing. The information was organised along the lines of
OSI terminology and layout and unless you came from that background
it was all rather counter intuitive.

I recall that this was all part of working out how to do multicast in
kernel mode with TDI - another thing that was never documented.

Given what I learned then, I’ve always recommended that network
management tasks be done in user mode and if necessary to pass the
results to the driver, it’s far easier.

Mark.

At 18:51 31/10/2009, Jeffrey Tippet wrote:

I don’t know of any way to do it in kernelmode. That’s ok, since
there are easy and obvious ways to do it in usermode. Usermode is
where all the “complicated” stuff should happen anyway. Kernelmode
is not meant to be a completely general development platform.

I know it’s tantalizing, since it seems like Microsoft has hidden
the API that (according to incomplete reverse-engineering) might
instantly solve your immediate problem. But “there is no
alternative (in kernelmode)” isn’t enough justification to add a ton
of extra risk to your product. Not to mention the extra time it
will cost me and my team as we discover your product through
bugcheck reports, root-cause the issue, follow up with your QA team
to get this fixed, and publish a hardblock for your app in the next
version of Windows.

The tone of this email is not meant to be nasty; I’m sorry if it
reads harshly. I’m really only trying to help both of us and our
mutual customers. I have taken as feedback that this information
might need to be exposed in kernelmode – in planning future
versions of Windows, we will balance this feedback against our
desire to have most code move to usermode, as well as against our
other priorities. I have also passed your earlier mail “To TDI
Filter or not” to the WFP and WSK teams, who are taking it into
consideration as well. We really do want you to be able to ship
great products on Windows.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Friday, October 30, 2009 5:02 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] netstat in kernel mode

Jeffrey,

As I mentioned in my reply to David, I would love a documented way
of obtaining a table with all bound ports and connections in
*KERNEL* mode, but everything I found so far refers only to *USER*
mode. Please prove me wrong. It would save me and my company a lot of time.

There are several reasons for needing this functionality:

  1. When my driver starts, it needs to be able to perform
    essentially what “nestat -anop tcp” does so that it initializes its
    “knowledge” about the world: what ports are currently bound and what
    connections are active. Arguably I can do this in user-space (and I
    have in the past), but the problem is that the driver will need that
    information periodically, so that:
  • it can detect when an extant port/connection are terminated
  • it can deal with #2
    I personally think that performing the query in user space and
    sending the information back to the driver every few seconds is a bad idea.
  1. The driver adds a number of WFP callouts and needs a way to
    determine when a server port gets unbound. To the best of my
    knowledge there is no WFP notification for unbound ports prior to
    Windows 7. Since the driver allocates state per server bound port, I
    need a way to clean up that state. I addition, our product must
    report the fact that a port has been unbound within 15 seconds or so
    from the port actually being unbound.

Please let me know if there are viable alternatives to what I am
doing that would meet my requirements.

Thanks a lot,
Best,
–aydan


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

> Some 13 years back I did reverse engineer the mechanisms behind the

likes of netstat.exe, arp.exe and route.exe. It was ugly and not
worth reproducing. The information was organised along the lines of
OSI terminology and layout and unless you came from that background
it was all rather counter intuitive.

IIRC that info was organized for SNMP in MIB values, am I wrong?

I recall that this was all part of working out how to do multicast in
kernel mode with TDI - another thing that was never documented.

IOCTL_TCP_SET_INFORMATION_EX, yes, undocumented, rev.eng. the WSH helper DLL to find this.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

At 00:16 01/11/2009, Maxim S. Shatskih wrote:

> Some 13 years back I did reverse engineer the mechanisms behind the
> likes of netstat.exe, arp.exe and route.exe. It was ugly and not
> worth reproducing. The information was organised along the lines of
> OSI terminology and layout and unless you came from that background
> it was all rather counter intuitive.

IIRC that info was organized for SNMP in MIB values, am I wrong?

> I recall that this was all part of working out how to do multicast in
> kernel mode with TDI - another thing that was never documented.

IOCTL_TCP_SET_INFORMATION_EX, yes, undocumented, rev.eng. the WSH
helper DLL to find this.

Max, yes it was tucked away in MIB structures. Once you got the hang
of it, it was quite fun to play with. I haven’t looked at how they
do this with the new protocol stacks but I did once show that the
original IP Helper routines were just wrappers to
IOCTL_TCP_SET_INFORMATION_EX and not some clever new functionality.

Mark