26 #define TCPIP_MAX_PARTITION_CNT 0x40 29 #define NET_BYTE_ORDER(Word) (((Word) >> 8) | ((Word) << 8)) 32 #define VALID_PORT(Port) (0 != (Port) && 49151 != (Port)) 35 #define WINNET_LIST_ITERS_CAP 64 109 #define ADDR_FAM_OFFSET (gGuest.Guest64 ? (gGuest.OSVersion >= 9200 ? 0x18 : 0x14) : 0xC) 163 #undef ADDR_FAM_OFFSET 203 return IntKernVirtMemRead(addr,
sizeof(Endpoint->LocalAddress), &Endpoint->LocalAddress, NULL);
233 QWORD addr, local, remote;
325 if (off + 2 *
sizeof(
WORD) +
sizeof(
DWORD) > Size)
530 size_t sz, originalOffset;
539 if (NULL == Invariants)
549 if (NULL == Endpoint)
565 offset = originalOffset;
593 if (offset + sz < originalOffset)
599 status =
IntStructFill(map + offset, sz, Invariants, Count, LogErrors, Endpoint);
656 WARNING(
"[WARNING] Failed to fill endpoint from 0x%016llx: 0x%08x\n", Gva, status);
659 for (
size_t i = 0; i <
ARRAYSIZE(invs); i++)
707 WARNING(
"[WARNING] Failed to fill listener from 0x%016llx: 0x%08x\n", Gva, status);
711 for (
size_t i = 0; i <
ARRAYSIZE(invs); i++)
763 WARNING(
"[WARNING] Failed to extract tcp endpoint from 0x%016llx: 0x%08x\n", flink, status);
767 Callback(&net, Context);
772 WARNING(
"[WARNING] IntKernVirtMemFetchWordSize failed for 0x%016llx: 0x%08x\n", old, status);
783 ERROR(
"[ERROR] Entry @ 0x%016llx points to itself\n", old);
821 #define TCP_DIRECTORY_ENTRY_CNT 0x80 822 #define TCP_DIRECTORY_ENTRY_SIZE (2ull * (gGuest.WordSize)) 823 #define TCP_DIRECTORY_SIZE (TCP_DIRECTORY_ENTRY_CNT * TCP_DIRECTORY_ENTRY_SIZE) 843 ERROR(
"[ERROR] IntKernVirtMemFetchWordSize failed for 0x%016llx: 0x%08x\n",
855 dir =
gGuest.
Guest64 ? tbl.Ht64.Directory : tbl.Ht32.Directory;
856 cnt =
gGuest.
Guest64 ? tbl.Ht64.NonEmptyBuckets : tbl.Ht32.NonEmptyBuckets;
871 WARNING(
"[WARNING] IntWinNetIterateLinkedList failed: 0x%08x\n", status);
876 #undef TCP_DIRECTORY_SIZE 877 #undef TCP_DIRECTORY_ENTRY_SIZE 878 #undef TCP_DIRECTORY_ENTRY_CNT 905 #define WINNET_CLEAN_PTR_MASK ((QWORD)0xFFFFFFFFFFFFFFFCull) 923 Callback(&net, Context);
938 #undef WINNET_CLEAN_PTR_MASK 971 size_t pasz, offListener, offPa;
979 offListener = 2 *
sizeof(
QWORD);
995 ERROR(
"[ERROR] BitMaskAlloc failed\n");
1003 ERROR(
"[ERROR] IntKernVirtMemRead failed to read 0x%x bytes from 0x%016llx: 0x%08x\n",
1008 for (
DWORD i = 1; i < sz; i++)
1010 #define TCP_PORT_ASSIGNMENT_ARRAY_INDEX(i) (((i) >> 8) & 0xFF) 1011 #define TCP_PORT_ASSIGNMENT_INDEX(i) ((i) & 0xFF) 1047 WARNING(
"[WARNING] IntWinNetIterateSlinkedList failed: 0x%08x\n", status);
1050 #undef TCP_PORT_ASSIGNMENT_INDEX 1051 #undef TCP_PORT_ASSIGNMENT_ARRAY_INDEX 1088 const union _PARTITION
1092 } *part = (
const union _PARTITION *)Buffer;
1094 sz =
gGuest.
Guest64 ?
sizeof(part->Part64) :
sizeof(part->Part32);
1107 for (
size_t i = 0; i <
ARRAYSIZE(part->Part64); i++)
1214 addr = PartitionPointer;
1224 addr -=
sizeof(
DWORD);
1280 TRACE(
"[WINNET] Found tcpip!ParitionTable @ 0x%016llx pointing to" 1281 " 0x%016llx with %u elements of size 0x%x from 0x%016llx\n",
1333 *(
DWORD *)((size_t)map + off);
1383 QWORD inetCmp, tcpCmp, pool;
1477 (addr & PAGE_OFFSET) == 0)
1485 (addr & PAGE_OFFSET) == 0)
1526 QWORD pool, sz, buf, pa;
1559 size_t p = (size_t)map + i;
1589 TRACE(
"[WINNET] Found tcpip!TcpPortPool @ 0x%016llx, BitmapBuffer @ 0x%016llx, " 1590 "and port assignment array @ 0x%016llx from 0x%016llx:0x%016llx\n", pool,
1632 ERROR(
"[ERROR] Failed to find `tcpip.sys`\n");
1636 TRACE(
"[WINNET] tcpip.sys @ 0x%016llx\n", drv->
BaseVa);
1641 ERROR(
"[ERROR] Failed to find `.data` section in `tcpip.sys`: 0x%08x\n", status);
1654 ERROR(
"[ERROR] IntVirtMemMap failed for 0x%016llx: 0x%08x\n", gva, status);
1709 ERROR(
"[ERROR] IntWinNetFindTcpObjects failed ( 0x%016llx, 0x%016llx): 0x%08x\n",
1717 WARNING(
"[WARNING] IntWinNetParseTcpPartition failed: 0x%08x\n", status);
1723 WARNING(
"[WARNING] IntWinNetParseTcpBitmap failed: 0x%08x\n", status);
1750 if (proc != Endpoint->OwnerProcess)
1760 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
1808 IntNetAddrToStr(Endpoint->AddressFamily, &Endpoint->LocalAddress, local);
1809 IntNetAddrToStr(Endpoint->AddressFamily, &Endpoint->RemoteAddress, remote);
1811 LOG(
"[WINNET] Endpoint @ 0x%016llx Local %s:%d Remote %s:%d State %s Owner 0x%016llx (%s:%u)\n",
1812 Endpoint->Endpoint, local, Endpoint->LocalPort, remote, Endpoint->RemotePort,
1814 Endpoint->OwnerProcess->Name, Endpoint->OwnerProcess->Pid);
This is the structure as documented in ntddk.h.
BYTE Bits[]
The bit array.
INTSTATUS IntWinNetSendProcessConnections(WIN_PROCESS_OBJECT *Process)
Send connection events for all active connections whose owner is the given process.
static INTSTATUS IntWinNetGetTcpPortPool(QWORD Gva, QWORD *PortPool)
Get the address of a tcp port pool for windows versions before RS1.
#define ROUND_UP(what, to)
#define TCP_DIRECTORY_ENTRY_SIZE
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
#define TCP_PORT_ASSIGNMENT_ARRAY_INDEX(i)
static INTSTATUS IntWinNetGetTcpListener(QWORD Gva, INTRONET_ENDPOINT *Endpoint)
Search for a tcp endpoint structure from a given address.
EVENT_CONNECTION_EVENT Connection
union _ADDRINFO::@196 Addr32
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
INTSTATUS IntWinNetDumpConnections(void)
Dump all active guest connections.
INTRONET_PORT LocalPort
Local port.
#define TCP_PORT_ASSIGNMENT_INDEX(i)
QWORD BaseVa
The guest virtual address of the kernel module that owns this driver object.
#define INT_SUCCESS(Status)
QWORD Table
Will hold the address of the TCP partition table.
static INTSTATUS IntWinNetGetAddrInfo(const BYTE *Buffer, size_t Size, size_t *Offset, void *Context)
Callback to get the address information from a guest buffer.
static INTRO_NET_AF IntWinNetConvertAf(WORD Af)
Convert a windows address family value to an introcore one.
#define INT_STATUS_NOT_NEEDED_HINT
INTRONET_PORT RemotePort
Remote port.
static INTSTATUS IntWinNetParseTcpPartition(PFUNC_IntWinNetCallback Callback, void *Context)
Iterate through the tcpip!PartitionTable and invoke the callback on each found connection.
INTRO_NET_AF AddressFamily
Address family.
WIN_PROCESS_OBJECT * OwnerProcess
Pointer to the process that owns the connection.
INTSTATUS IntKernVirtMemFetchWordSize(QWORD GuestVirtualAddress, void *Data)
Reads a guest pointer from the guest kernel memory.
struct _ADDRINFO::@196::@197 Win7
int INTSTATUS
The status data type.
#define POOL_TAG_TCHT
Tcp Hash Table.
BYTE BitMaskTest(BITMASK *BitMask, DWORD BitPos)
Tests a bit in a BITMASK.
DWORD OSVersion
Os version.
Describe information about the TCP partition containing endpoints.
static INTSTATUS IntWinNetGetLocalAddr(QWORD Gva, INTRONET_ENDPOINT *Endpoint)
Get the local address of a connection from a given address.
#define INT_STATUS_NOT_FOUND
INTSTATUS IntStructFill(const void *Buffer, size_t Size, INT_STRUCT_INVARIANT *Invariants, size_t Count, BOOLEAN LogErrors, void *Context)
Fill an internal structure with information gathered from the guest by applying a list of invariants ...
#define NET_BYTE_ORDER(Word)
Switch a WORD from network endianness to little endina.
BITMASK * BitMaskAlloc(size_t Size)
Creates a new BITMASK.
static INTSTATUS IntWinNetGetTcpEndpoint(QWORD Gva, INTRONET_ENDPOINT *Endpoint)
Search for a TCP endpoint structure from a given address.
#define POOL_TAG_INCO
Inet Compartment.
#define WIN_POOL_BLOCK_SIZE
const char * IntNetStateToString(INTRO_NET_STATE State)
Converts a connection state to a string.
#define WIN_POOL_HEADER_SIZE
#define INT_STATUS_BUFFER_OVERFLOW
static INTSTATUS IntWinNetFindTcpObjects(void)
Iterate through the .data section of tcpip.sys and attempt to find the objects that we need to initia...
#define INTRO_OPT_EVENT_CONNECTIONS
Enable connection events.
static INTSTATUS IntWinNetDumpConnection(const INTRONET_ENDPOINT *Endpoint, void *Context)
Log a connection.
#define POOL_TAG_INCS
Inet Compartment Set.
static INTSTATUS IntWinNetSendConnectionEvent(const INTRONET_ENDPOINT *Endpoint, void *Context)
Send a connection event.
Describes a kernel driver.
KERNEL_DRIVER * IntDriverFindByName(const void *Name)
Searches for a driver by its name.
#define WINNET_LIST_ITERS_CAP
Upper limit for iterating through guest linked lists.
#define INTRONET_MIN_BUFFER_SIZE
The minimum buffer size needed for the textual representation of an IP address.
DWORD Count
Will hold the number of elements inside the partition table.
static INTSTATUS IntWinNetCheckPartition(const BYTE *Buffer, size_t Size)
Check wether a buffer contains a valid undocumented tcpip!_PARTITION object.
DWORD Size
Will hold the size of a partition element.
GENERIC_ALERT gAlert
Global alert buffer.
#define INT_STATUS_ALIGNMENT_INCONSISTENCY
INTSTATUS IntKernVirtMemFetchDword(QWORD GuestVirtualAddress, DWORD *Data)
Reads 4 bytes from the guest kernel memory.
#define INT_STATUS_ALREADY_INITIALIZED
static INTSTATUS IntWinNetGetOwner(const BYTE *Buffer, size_t Size, size_t *Offset, void *Context)
Callback to get the owner process from a guest buffer.
static INTSTATUS IntWinNetSearchForAlloc(QWORD Gva, DWORD Tag, QWORD *Alloc)
Search for an allocation with given tag.
Structure that describe the kernel objects needed by introcore to extract connections.
This is the structure as documented in ntddk.h.
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
static INTSTATUS IntWinNetGetAddrFam(const BYTE *Buffer, size_t Size, size_t *Offset, void *Context)
Callback to get the address family from a guest buffer.
#define TCPIP_MAX_PARTITION_CNT
Maximum allowed count for the tcpip!PartitionCount value.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
DWORD IntNetAddrToStr(const INTRO_NET_AF Family, const INTRONET_ADDRESS *Address, CHAR *String)
Converts an IP address to a string.
QWORD Current
The currently used options.
Describe information about the TCP port pool containing listeners.
BOOLEAN Found
TRUE if we managed to find the elements above.
#define POOL_TAG_TCCO
Tcp Compartment.
static INTSTATUS IntWinNetGetTcpPortPoolFromCompartment(QWORD Gva, QWORD *PortPool)
Get the address of a tcp port pool for windows RS1 and newer.
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
static INTSTATUS IntWinNetGetPortsAndState(const BYTE *Buffer, size_t Size, size_t *Offset, void *Context)
Callback to get the ports and state from a guest buffer.
static INTSTATUS IntWinNetFindTcpBitmap(QWORD Gva, QWORD Addr)
Get tcpip!TcpPortPool information form the guest and initialize gWinNet.
TIMER_FRIENDLY void IntDumpBuffer(const void *Buffer, QWORD Gva, DWORD Length, DWORD RowLength, DWORD ElementLength, BOOLEAN LogHeader, BOOLEAN DumpAscii)
This function dumps a given buffer in a user friendly format.
#define INT_STRUCT_MAX_INVARIANT_CNT
Upper limit of the number of invariants to be applied to a bufffer.
#define INT_STATUS_INVALID_PARAMETER_5
static INTSTATUS IntWinNetGetListenerAddressInfo(const BYTE *Buffer, size_t Size, size_t *Offset, void *Context)
Callback to get the address family and local address from a guest buffer.
union _IMAGE_SECTION_HEADER::@214 Misc
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
#define VALID_PORT(Port)
Check if a port is valid. Not the best check, but a valid check.
INTRO_NET_STATE State
Connection state.
Informational event containing the connections opened by a process. See EVENT_CONNECTION_EVENT.
#define IntPeGetSectionHeaderByName(Base, Buff, Name, Cr3, Sec)
static INTSTATUS IntWinNetIterateSlinkedList(INTRONET_PORT Port, QWORD Gva, PFUNC_IntWinNetCallback Callback, void *Context)
Iterate through a single linked list of tcpip endpoint structures and invoke the callback on each val...
#define INT_STATUS_ALREADY_INITIALIZED_HINT
static INTSTATUS IntWinNetParseTcpBitmap(PFUNC_IntWinNetCallback Callback, void *Context)
Will iterate through the guest port bitmap and invoke the callback on each valid connection.
#define _Inout_updates_(expr)
#define ROUND_DOWN(what, to)
#define UNREFERENCED_PARAMETER(P)
struct _ADDRINFO::@196::@198 Win8AndAbove
struct _WINNET_STATE gWinNet
TIMER_FRIENDLY void IntDumpGvaEx(QWORD Gva, DWORD Length, QWORD Cr3, DWORD RowLength, DWORD ElementLength, BOOLEAN LogHeader, BOOLEAN DumpAscii)
This function dumps a given GVA in a user friendly format. This function uses IntDumpBuffer to perfor...
static INTSTATUS IntWinNetIterateConnections(PFUNC_IntWinNetCallback Callback, void *Context)
Iterate through guest connections and invoke the callback on each one.
#define POOL_TAG_TCPE
Tcp Endpoint.
INTSTATUS(* PFUNC_IntWinNetCallback)(const INTRONET_ENDPOINT *Connection, void *Context)
#define _In_reads_bytes_(expr)
#define POOL_TAG_TCPL
Tcp Listener.
struct _WINNET_STATE::_PARTITION Partition
#define INT_STATUS_INVALID_OBJECT_TYPE
BYTE Ipv6[16]
IPv6 address.
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
GUEST_STATE gGuest
The current guest state.
#define _Function_class_(expr)
struct _LOCAL_ADDRESS::@199 Addr32
INTRONET_ADDRESS RemoteAddress
Remote address.
#define INT_STATUS_INVALID_DATA_TYPE
#define FIX_GUEST_POINTER(is64, x)
Masks the unused part of a Windows guest virtual address.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByEprocess(QWORD Eprocess)
Finds a process by the address of its _EPROCESS structure.
QWORD PortAssignment
Will hold the address of the array of inet port assignment arrays in the port pool.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
struct _ADDRINFO::@195 Addr64
#define POOL_TAG_INNL
Used to search for address family.
#define INT_STATUS_INVALID_PARAMETER_1
size_t Offset
Offset from where the field/structure is to be extracted.
Event structure for connections.
struct _WINNET_STATE::_BITMAP Bitmap
void IntAlertFillConnection(const INTRONET_ENDPOINT *Connection, EVENT_CONNECTION_EVENT *Event)
Saves information about a guest connection in an event.
INTRONET_ADDRESS LocalAddress
Local address.
enum _INTRO_NET_AF INTRO_NET_AF
Address family.
#define POOL_TAG_INPA
Inet Port Array.
QWORD Buffer
Will hold the address of the bitmap buffer in the port pool.
void BitMaskFree(BITMASK **BitMask)
Frees a BITMASK allocated by BitMaskAlloc.
BOOLEAN Found
TRUE if we managed to find the elements above.
#define TCP_DIRECTORY_ENTRY_CNT
#define INT_STATUS_INVALID_PARAMETER_2
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
INTRO_NET_STATE IntNetConvertState(const DWORD State)
Converts a guest connection state to an Introcore connection state.
BYTE Ipv4[4]
IPv4 address.
struct _LOCAL_ADDRESS::@200 Addr64
static INTSTATUS IntWinNetFillTcpStruct(const QWORD Gva, INT_STRUCT_INVARIANT *Invariants, size_t Count, DWORD PoolTag, BOOLEAN LogErrors, INTRONET_ENDPOINT *Endpoint)
Wrapper over IntStructFill to map a guest page and perform the search there.
#define WINNET_CLEAN_PTR_MASK
#define INT_STATUS_INVALID_DATA_SIZE
static INTSTATUS IntWinNetFindTcpPartition(QWORD PartitionAddress, QWORD PartitionPointer)
Get tcpip!PartitionTable information from the guest and initialize gWinNet.
static INTSTATUS IntWinNetIterateLinkedList(QWORD Gva, PFUNC_IntWinNetCallback Callback, void *Context)
Iterate through a doubly linked list of tcpip!_TCP_ENDPOINT structures and invoke the callback on eac...
This structure describes a running process inside the guest.
#define INT_STATUS_INSUFFICIENT_RESOURCES
#define INT_OFFSET_NOT_INITIALIZED
Specifies that an offset value is yet to be searched for.
#define INT_STATUS_INVALID_PARAMETER_3