вторник, 10 июля 2012 г.

netio!NsiRegisterChangeNotification(Ex)

This undocumented function set some callback for NSI providers. I`ll show how to find this registered callbacks. Quick look in disasm shows that this callbacks are stored somewhere deeply in structures linked in list with head in NsiNmpList, so lets check it with debugger:

kd> ? netio!NsiNmpList
Evaluate expression: -6184740751232 = fffffa60`00b97880
kd> dt _LIST_ENTRY fffffa60`00b97880
nt!_LIST_ENTRY
 [ 0xfffffa60`00b974e8 - 0xfffffa80`03240408 ]
   +0x000 Flink            : 0xfffffa60`00b974e8 _LIST_ENTRY [ 0xfffffa80`0168e018 - 0xfffffa60`00b97880 ]
   +0x008 Blink            : 0xfffffa80`03240408 _LIST_ENTRY [ 0xfffffa60`00b97880 - 0xfffffa80`018ec738 ]
kd> dp fffffa60`00b974e8
fffffa60`00b974e8  fffffa80`0168e018 fffffa60`00b97880
fffffa60`00b974f8  fffffa60`00b8b530 00000000`00000001
fffffa60`00b97508  00000000`00000000 fffffa60`00b8ee28
fffffa60`00b97518  00000000`00000000 00000000`00000000
fffffa60`00b97528  00000000`00000000 00000001`000e0002
fffffa60`00b97538  fffffa60`00b97538 fffffa60`00b97538
fffffa60`00b97548  00000000`00000000 00000000`00000000
fffffa60`00b97558  00000000`00000000 00000000`00000100
kd> u fffffa60`00b8b530 l1
NETIO!NPI_MS_NSI_MODULEID:
fffffa60`00b8b530 1800            sbb     byte ptr [rax],al
kd> u fffffa60`00b8ee28 l1
NETIO!NsipObjectProviderDispatch:
fffffa60`00b8ee28 0000            add     byte ptr [rax],al


It seems that first 2 pointers are LIST_ENTRY. Lets see some more samples:

kd> !pool fffffa80`0168e018 2
Pool page fffffa800168e018 region is Nonpaged pool
*fffffa800168e000 size:   d0 previous size:    0  (Allocated) *NMpc
        Owning component : Unknown (update pooltag.txt)

kd> dp fffffa80`0168e018
fffffa80`0168e018  fffffa80`0189f3f8 fffffa60`00b974e8
fffffa80`0168e028  fffffa60`00b8b548 00000000`00000002
fffffa80`0168e038  fffffa80`0168d270 fffffa60`00b8ffc0
fffffa80`0168e048  00000000`00000000 fffffa80`0168d30c
fffffa80`0168e058  00000000`00000000 00000001`000e0002
fffffa80`0168e068  fffffa80`0168e068 fffffa80`0168e068
fffffa80`0168e078  00000000`00000000 00000000`00000000
fffffa80`0168e088  00000000`00000000 00000000`00000100
kd> u fffffa60`00b8b548 l1
NETIO!NPI_MS_NMR_MODULEID:
fffffa60`00b8b548 1800            sbb     byte ptr [rax],al

kd> !pool fffffa80`0168d270 2
Pool page fffffa800168d270 region is Nonpaged pool
*fffffa800168d260 size:   50 previous size:   40  (Allocated) *RMcc
        Owning component : Unknown (update pooltag.txt)
kd> u fffffa60`00b8ffc0 l1
NETIO!NmrfpNsiProviderDispatch:
fffffa60`00b8ffc0 0000            add     byte ptr [rax],al
kd> !pool fffffa80`0168d30c 2
Pool page fffffa800168d30c region is Nonpaged pool
*fffffa800168d2b0 size:   80 previous size:   50  (Allocated) *NMRb
        Pooltag NMRb : Network Module Registrar Bindings, Binary : tcpip.sys
...

kd> dp fffffa80`018d9d48
fffffa80`018d9d48  fffffa80`018e0cc8 fffffa80`018adde8
fffffa80`018d9d58  fffffa60`00f26f28 00000000`00000006
fffffa80`018d9d68  fffffa80`018d9c60 fffffa60`00f2b5f0
fffffa80`018d9d78  00000000`00000000 fffffa80`018d43fc
fffffa80`018d9d88  fffffa80`032f2b60 00000001`000e0002
fffffa80`018d9d98  fffffa80`018d9d98 fffffa80`018d9d98
fffffa80`018d9da8  fffffa80`029784c0 fffffa80`018d9de0
fffffa80`018d9db8  00000000`00000000 00000000`00000100
kd> u fffffa60`00f26f28 l1
tcpip!NPI_MS_IPV4_MODULEID:
fffffa60`00f26f28 1800            sbb     byte ptr [rax],al
kd> u fffffa60`00f2b5f0 l1
tcpip!Ipv4NsiProviderDispatch:
fffffa60`00f2b5f0 0000            add     byte ptr [rax],al
kd> !pool fffffa80`032f2b60 2
Pool page fffffa80032f2b60 region is Unknown
*fffffa80032f2b50 size:  280 previous size:  270  (Allocated) *NSIr
        Pooltag NSIr : NSI Generic Buffers, Binary : nsi.dll


It seems that items in linked list NsiNmpList has structure like this:
struct NsiNmpItem
{
/* win32 win64 offsets */
/*   0x0   0x0 */  LIST_ENTRY List;
/*   0x8  0x10 */  PNPI_MODULEID ModId;
/*   0xC  0x18 */  DWORD Index;
/*  0x10  0x20 */  PVOID Unknown;  // RMcc tag
/*  0x14  0x28 */  PBYTE Dispatch;
/*  0x18  0x30 */  PVOID Unknown2;
/*  0x1C  0x38 */  PVOID Unknown3; // NMRb tag
/*  0x20  0x40 */  PBYTE CbGenericTable; // NSIr tag
};


The last field is especially suspicious:
kd> dp fffffa80`032f2b60 l20
fffffa80`032f2b60  fffffa80`032f2b60 fffffa80`032f2b60
fffffa80`032f2b70  00000000`00000000 fffffa80`032f2b78
fffffa80`032f2b80  fffffa80`032f2b78 00000000`00000000
fffffa80`032f2b90  fffffa80`032f2b90 fffffa80`032f2b90
fffffa80`032f2ba0  00000000`00000000 fffffa80`032f2ba8
fffffa80`032f2bb0  fffffa80`032f2ba8 00000000`00000000
fffffa80`032f2bc0  fffffa80`032f2bc0 fffffa80`032f2bc0
fffffa80`032f2bd0  00000000`00000000 fffffa80`032f2bd8
fffffa80`032f2be0  fffffa80`032f2bd8 00000000`00000000
fffffa80`032f2bf0  fffffa80`032f2bf0 fffffa80`032f2bf0
fffffa80`032f2c00  00000000`00000000 fffffa80`03247410
fffffa80`032f2c10  fffffa80`02b24df0 00000000`00000003
fffffa80`032f2c20  fffffa80`032f2c20 fffffa80`032f2c20
fffffa80`032f2c30  00000000`00000000 fffffa80`032f2c38
fffffa80`032f2c40  fffffa80`032f2c38 00000000`00000000
fffffa80`032f2c50  fffffa80`03246410 fffffa80`029a8670


Looks like hash table with linked lists, mostly empty. But check address fffffa80`03247410 from obvious non-empty list:
kd> !pool fffffa80`03247410 2
Pool page fffffa8003247410 region is Unknown
*fffffa8003247400 size:   60 previous size:   40  (Allocated) *NSIr
        Pooltag NSIr : NSI Generic Buffers, Binary : nsi.dll
kd> dp fffffa80`03247410
fffffa80`03247410  fffffa80`0380aab0 fffffa80`032f2c08
fffffa80`03247420  00000000`00000000 fffffa60`034cc568
fffffa80`03247430  fffffa60`034d2378 00000000`00000001
fffffa80`03247440  00000000`00060001 fffffa80`03247448
fffffa80`03247450  fffffa80`03247448 00000000`00000000
fffffa80`03247460  7249534e`02060006 00000000`00000000
fffffa80`03247470  fffffa80`02b210b0 fffffa80`029ef140
fffffa80`03247480  fffffa80`03247480 fffffa80`03247480
kd> u fffffa60`034cc568
tdx!TdxNaInterfaceChangeEvent:
fffffa60`034cc568 48895c2408      mov     qword ptr [rsp+8],rbx
fffffa60`034cc56d 48896c2410      mov     qword ptr [rsp+10h],rbp
fffffa60`034cc572 4889742418      mov     qword ptr [rsp+18h],rsi
fffffa60`034cc577 57              push    rdi
fffffa60`034cc578 4883ec20        sub     rsp,20h
fffffa60`034cc57c 33ff            xor     edi,edi
fffffa60`034cc57e 4885d2          test    rdx,rdx
fffffa60`034cc581 488bf2          mov     rsi,rdx
kd> dp fffffa80`0380aab0
fffffa80`0380aab0  fffffa80`0380f220 fffffa80`03247410
fffffa80`0380aac0  00000000`00000000 fffffa60`039d284c
fffffa80`0380aad0  00000000`00000000 00000000`00000001
fffffa80`0380aae0  00000000`00060001 fffffa80`0380aae8
fffffa80`0380aaf0  fffffa80`0380aae8 00000000`00000001
fffffa80`0380ab00  6c734d46`020c0006 fffffa80`0380ab08
fffffa80`0380ab10  00000000`00a8f201 fffff880`075aecb8
fffffa80`0380ab20  fffff880`075aecb8 fffffa80`02841520
kd> u fffffa60`039d284c
lltdio!TopUpdateNetworkCategoryInformation+0x6e0:
fffffa60`039d284c 4585c9          test    r9d,r9d
fffffa60`039d284f 0f85e4000000    jne     lltdio!TopUpdateNetworkCategoryInformation+0x7cd (fffffa60`039d2939)
fffffa60`039d2855 48895c2408      mov     qword ptr [rsp+8],rbx
fffffa60`039d285a 4889742410      mov     qword ptr [rsp+10h],rsi
fffffa60`039d285f 57              push    rdi
fffffa60`039d2860 4883ec20        sub     rsp,20h
fffffa60`039d2864 4183781410      cmp     dword ptr [r8+14h],10h
fffffa60`039d2869 488bda          mov     rbx,rdx
kd> dp fffffa80`0380f220
fffffa80`0380f220  fffffa80`02b24df0 fffffa80`0380aab0
fffffa80`0380f230  00000000`00000000 fffffa60`039e7a90
fffffa80`0380f240  00000000`00000000 00000000`00000001
fffffa80`0380f250  00000000`00060001 fffffa80`0380f258
fffffa80`0380f260  fffffa80`0380f258 00000000`00000001
fffffa80`0380f270  e9766544`02220006 00000000`00000000
fffffa80`0380f280  fffff880`00010eb0 00000000`000c000c
fffffa80`0380f290  fffff880`00a2c220 fffffa80`00000001
kd> u fffffa60`039e7a90
rspndr!ToppDeleteDiscoverySessionUnderLock+0x218:
fffffa60`039e7a90 4585c9          test    r9d,r9d
fffffa60`039e7a93 0f8513010000    jne     rspndr!ToppDeleteDiscoverySessionUnderLock+0x334 (fffffa60`039e7bac)
fffffa60`039e7a99 48895c2408      mov     qword ptr [rsp+8],rbx
fffffa60`039e7a9e 57              push    rdi
fffffa60`039e7a9f 4883ec20        sub     rsp,20h
fffffa60`039e7aa3 4183781410      cmp     dword ptr [r8+14h],10h
fffffa60`039e7aa8 488bda          mov     rbx,rdx
fffffa60`039e7aab 0f85f1000000    jne     rspndr!ToppDeleteDiscoverySessionUnderLock+0x32a (fffffa60`039e7ba2)


Gotcha ! Now we can define two more structure:
struct CbGenericTableItem // items in CbGenericTable
{
  LIST_ENTRY List; // points to
NsiCbNode list
  PVOID      Unknown;
};

struct NsiCbNode
{
  LIST_ENTRY List; // points to next
NsiCbNode
  PVOID      Unknown;
  PBYTE      Cb; // I want this !
};


One remaining problem is how to find size of CbGenericTable. Lets check it again:
kd> !pool fffffa80`032f2b60 2
Pool page fffffa80032f2b60 region is Unknown
*fffffa80032f2b50 size:  280 previous size:  270  (Allocated) *NSIr
        Pooltag NSIr : NSI Generic Buffers, Binary : nsi.dll


We now know that each item in hash table has size 0x18 bytes: 0x270 / 0x18 = 0x1A. Return to NsiNmpItem with index 6 contained our CbGenericTable:

kd> dp fffffa80`018d9d48
fffffa80`018d9d48  fffffa80`018e0cc8 fffffa80`018adde8
fffffa80`018d9d58  fffffa60`00f26f28 00000000`00000006
fffffa80`018d9d68  fffffa80`018d9c60 fffffa60`00f2b5f0
fffffa80`018d9d78  00000000`00000000 fffffa80`018d43fc
fffffa80`018d9d88  fffffa80`032f2b60 00000001`000e0002
fffffa80`018d9d98  fffffa80`018d9d98 fffffa80`018d9d98
fffffa80`018d9da8  fffffa80`029784c0 fffffa80`018d9de0
fffffa80`018d9db8  00000000`00000000 00000000`00000100

kd> dd fffffa60`00f2b5f0
fffffa60`00f2b5f0  00100000 0000001a 00f2ad00 fffffa60
fffffa60`00f2b600  00000004 00000000 00f32d08 fffffa60
fffffa60`00f2b610  00eead70 fffffa60 00ed1250 fffffa60
fffffa60`00f2b620  00000000 00000000 00eeace0 fffffa60
fffffa60`00f2b630  00002000 00000000 00f32cf0 fffffa60
fffffa60`00f2b640  00eeaef0 fffffa60 00ed1250 fffffa60
fffffa60`00f2b650  00000000 00000000 00e214e0 fffffa60
fffffa60`00f2b660  00001000 00000000 00f32cd8 fffffa60


Sample of callbacks list from vista sp2:
NsiNmp[1]: ModId FFFFFA6000B8B530 \SystemRoot\system32\drivers\NETIO.SYS
 Dispatch: FFFFFA6000B8EE28 \SystemRoot\system32\drivers\NETIO.SYS
NsiNmp[2]: ModId FFFFFA6000B8B548 \SystemRoot\system32\drivers\NETIO.SYS
 Dispatch: FFFFFA6000B8FFC0 \SystemRoot\system32\drivers\NETIO.SYS
NsiNmp[3]: ModId FFFFFA6000F26F70 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F53CE0 \SystemRoot\System32\drivers\tcpip.sys
NsiNmp[4]: ModId FFFFFA6000F26F58 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F533B8 \SystemRoot\System32\drivers\tcpip.sys
NsiNmp[5]: ModId FFFFFA6000F26F88 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F530F8 \SystemRoot\System32\drivers\tcpip.sys
NsiNmp[6]: ModId FFFFFA6000F26F28 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F2B5F0 \SystemRoot\System32\drivers\tcpip.sys
  Hash with 26 slots for callbacks at FFFFFA80032F2B60:
  (FFFFFA8003247410) FFFFFA60034CC568 \SystemRoot\system32\DRIVERS\tdx.sys
  (FFFFFA800380F220) FFFFFA60039D284C \SystemRoot\system32\DRIVERS\lltdio.sys
  (FFFFFA8002B24DF0) FFFFFA60039E7A90 \SystemRoot\system32\DRIVERS\rspndr.sys
  (FFFFFA80032F2C08) FFFFFA60055F0B7C \SystemRoot\System32\drivers\tcpipreg.sys
  (FFFFFA8003246410) FFFFFA60034CC4A8 \SystemRoot\system32\DRIVERS\tdx.sys
  (FFFFFA8003582090) FFFFFA60035930FC \SystemRoot\System32\DRIVERS\netbt.sys
  (FFFFFA80029A8670) FFFFFA6003536F50 \SystemRoot\system32\drivers\afd.sys
  (FFFFFA80032F2C50) FFFFFA60038B817C \SystemRoot\system32\drivers\nsiproxy.sys
NsiNmp[7]: ModId FFFFFA6000F26F40 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F2A948 \SystemRoot\System32\drivers\tcpip.sys
  Hash with 25 slots for callbacks at FFFFFA80032F28F0:
  (FFFFFA800324A410) FFFFFA60034CC568 \SystemRoot\system32\DRIVERS\tdx.sys
  (FFFFFA800380F1C0) FFFFFA60039D284C \SystemRoot\system32\DRIVERS\lltdio.sys
  (FFFFFA80032F2998) FFFFFA60039E7A90 \SystemRoot\system32\DRIVERS\rspndr.sys
  (FFFFFA8003249470) FFFFFA60034CC4A8 \SystemRoot\system32\DRIVERS\tdx.sys
  (FFFFFA80029F1360) FFFFFA6003536F50 \SystemRoot\system32\drivers\afd.sys
  (FFFFFA80032F29E0) FFFFFA60038B817C \SystemRoot\system32\drivers\nsiproxy.sys
NsiNmp[8]: ModId FFFFFA6000F26FA0 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F471F0 \SystemRoot\System32\drivers\tcpip.sys
NsiNmp[9]: ModId FFFFFA6000C59798 \SystemRoot\system32\drivers\ndis.sys
 Dispatch: FFFFFA6000C66520 \SystemRoot\system32\drivers\ndis.sys
  Hash with 14 slots for callbacks at FFFFFA80018E2520:
  (FFFFFA80018E2280) FFFFFA6000C1A7C0 \SystemRoot\system32\drivers\ndis.sys
  (FFFFFA80018E2340) FFFFFA6000C1A7C0 \SystemRoot\system32\drivers\ndis.sys
  (FFFFFA80018E2538) FFFFFA60034CC568 \SystemRoot\system32\DRIVERS\tdx.sys
  (FFFFFA80018E2400) FFFFFA6000C1A7C0 \SystemRoot\system32\drivers\ndis.sys
  (FFFFFA80018E24C0) FFFFFA6000C1A7C0 \SystemRoot\system32\drivers\ndis.sys
  (FFFFFA80018F4AC0) FFFFFA6000EF9EA0 \SystemRoot\System32\drivers\tcpip.sys
  (FFFFFA80018E25C8) FFFFFA6000EF9EA0 \SystemRoot\System32\drivers\tcpip.sys
NsiNmp[10]: ModId FFFFFA6000F26FB8 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F47470 \SystemRoot\System32\drivers\tcpip.sys
NsiNmp[11]: ModId FFFFFA6000F27060 \SystemRoot\System32\drivers\tcpip.sys
 Dispatch: FFFFFA6000F46C70 \SystemRoot\System32\drivers\tcpip.sys
  Hash with 9 slots for callbacks at FFFFFA80029EDF20:
NsiNmp[12]: ModId FFFFFA60034D23A8 \SystemRoot\system32\DRIVERS\tdx.sys
 Dispatch: FFFFFA60034D2508 \SystemRoot\system32\DRIVERS\tdx.sys

Комментариев нет:

Отправить комментарий