//初始化 HashTable InitHashTable(int TableSize) { HashTable H; if (TableSize < MinTableSize) { printf("Error! Table size too small!\n"); return NULL; } //分配空间给散列表 H = HashTable(malloc(sizeof(struct HashTbl))); if (H == NULL) printf("Error! Out of space!\n"); H->TableSize = NextPrime(TableSize); //分配空间给每一个链表 H->TheLists = (List*)(malloc(sizeof(List)*H->TableSize)); if (H->TheLists == NULL) printf("Error! Out of space!\n"); for (int i = 0; i < H->TableSize; ++i) { H->TheLists[i] = List(malloc(sizeof(struct ListNode))); if (H->TheLists[i] == NULL) printf("Error! Out of space!\n"); else H->TheLists[i]->next = NULL; } return H; }
vector<NETWORK_ENTRY> GetSockets( ) /*++ Routine Description: Description. Arguments: - Return Value: vector<NETWORK_ENTRY>. --*/ { ULONG64 TableAddr; ULONG64 TableCountAddr; PULONG64 Table = NULL; ULONG TableCount; vector<NETWORK_ENTRY> NetworkEntries; ULONG ProcessorType; ULONG PlateformId, Major, Minor, ServicePackNumber; if (g_Ext->m_Control->GetActualProcessorType(&ProcessorType) != S_OK) goto CleanUp; if (g_Ext->m_Control->GetSystemVersion(&PlateformId, &Major, &Minor, NULL, NULL, NULL, &ServicePackNumber, NULL, NULL, NULL) != S_OK) goto CleanUp; // g_Ext->Dml("Major: %d, Minor: %d, ProcessorType = %x\n", Major, Minor, ProcessorType); if ((Minor < 6000) && (ProcessorType == IMAGE_FILE_MACHINE_I386)) { if (g_Ext->m_Symbols->GetOffsetByName("tcpip!AddrObjTable", &TableAddr) != S_OK) goto CleanUp; if (g_Ext->m_Symbols->GetOffsetByName("tcpip!AddrObjTableSize", &TableCountAddr) != S_OK) goto CleanUp; if (ReadPointersVirtual(1, TableAddr, &TableAddr) != S_OK) goto CleanUp; if (g_Ext->m_Data->ReadVirtual(TableCountAddr, &TableCount, sizeof(ULONG), NULL) != S_OK) goto CleanUp; Table = (PULONG64)malloc(TableCount * sizeof(ULONG64)); if (ReadPointersVirtual(TableCount, TableAddr, Table) != S_OK) goto CleanUp; for (UINT i = 0; i < TableCount; i += 1) { Network::OBJECT_ENTRY_X86 ObjectEntry = { 0 }; NETWORK_ENTRY NetworkEntry = { 0 }; if (Table[i] == 0) continue; if (g_Ext->m_Data->ReadVirtual(Table[i], &ObjectEntry, sizeof(Network::OBJECT_ENTRY_X86), NULL) != S_OK) goto CleanUp; NetworkEntry.ObjectPtr = Table[i]; NetworkEntry.CreationTime = ObjectEntry.CreationTime; NetworkEntry.ProcessId = ObjectEntry.ProcessId; NetworkEntry.Protocol = ObjectEntry.Protocol; NetworkEntry.Local.Port = (ObjectEntry.Port[1] << 8) | ObjectEntry.Port[0]; NetworkEntry.Local.IPv4_Addr[3] = ObjectEntry.LocalAddress[3]; NetworkEntry.Local.IPv4_Addr[2] = ObjectEntry.LocalAddress[2]; NetworkEntry.Local.IPv4_Addr[1] = ObjectEntry.LocalAddress[1]; NetworkEntry.Local.IPv4_Addr[0] = ObjectEntry.LocalAddress[0]; NetworkEntry.State = TcbListenState; NetworkEntries.push_back(NetworkEntry); } } else if (Minor > 6000) { if (g_Ext->m_Symbols->GetOffsetByName("tcpip!PartitionCount", &TableCountAddr) != S_OK) goto CleanUp; ReadPointer(GetExpression("tcpip!PartitionTable"), &TableAddr); if (!TableAddr) goto CleanUp; if (g_Ext->m_Data->ReadVirtual(TableCountAddr, &TableCount, sizeof(ULONG), NULL) != S_OK) goto CleanUp; ULONG ListEntrySize = GetTypeSize("nt!_LIST_ENTRY"); ULONG PoolHeaderSize = GetTypeSize("nt!_POOL_HEADER"); ExtRemoteUnTyped PartitionTable(TableAddr, "tcpip!_PARTITION_TABLE"); for (UINT PartitionIndex = 0; PartitionIndex < TableCount; PartitionIndex += 1) { NETWORK_ENTRY NetworkEntry = { 0 }; // g_Ext->Dml(" -> Partition[%d].HashTables = 0x%I64X\n", PartitionIndex, Partition->HashTables); ExtRemoteTyped HashTable("(nt!_RTL_DYNAMIC_HASH_TABLE *)@$extin", PartitionTable.ArrayElement(PartitionIndex).Field("HashTables").GetPtr()); ULONG64 Directory = HashTable.Field("Directory").GetPtr(); ULONG TableEntries = HashTable.Field("TableSize").GetUlong(); for (UINT i = 0; i < TableEntries; i += 1) { ExtRemoteTypedList List(Directory + i * ListEntrySize, "nt!_LIST_ENTRY", "Flink"); for (List.StartHead(); List.HasNode(); List.Next()) { ULONG64 Current = List.GetNodeOffset(); if (!IsValid(Current)) break; ExtRemoteUnTyped Tcb(Current, "tcpip!_TCB"); Tcb.SubtractOffset("HashTableEntry"); ExtRemoteTyped PoolHeader("(nt!_POOL_HEADER *)@$extin", Tcb.GetPointerTo() - PoolHeaderSize); if (PoolHeader.Field("PoolTag").GetUlong() != 'EpcT') continue; //# Seen as 0x1f0 on Vista SP0, 0x1f8 on Vista SP2 and 0x210 on 7 //# Seen as 0x320 on Win7 SP0 x64 ULONG PoolSize; if (PoolHeader.Field("BlockSize").GetTypeSize() == sizeof(USHORT)) { PoolSize = PoolHeader.Field("BlockSize").GetUshort() * 0x10; } else { PoolSize = PoolHeader.Field("BlockSize").GetUlong() * 0x10; } if (PoolSize < 0x100) continue; ULONG64 SrcAddress = 0; ULONG64 DstAddress = 0; NetworkEntry.Protocol = PROTOCOL_TCP; NetworkEntry.State = Tcb.Field("State").GetUlong(); NetworkEntry.Local.Port = Tcb.Field("LocalPort").GetUshort(); NetworkEntry.Remote.Port = Tcb.Field("RemotePort").GetUshort(); DstAddress = Tcb.Field("Path", TRUE).Field("DestinationAddress").GetPtr(); if (IsValid(Tcb.Field("Path").GetPtr() && IsValid(Tcb.Field("Path", TRUE).Field("SourceAddress").GetPtr()) && IsValid(Tcb.Field("Path", TRUE).Field("SourceAddress", TRUE).Field("Identifier").GetPtr()) && IsValid(Tcb.Field("Path", TRUE).Field("SourceAddress", TRUE).Field("Identifier", TRUE).Field("Address").GetPtr()))) { SrcAddress = Tcb.Field("Path", TRUE).Field("SourceAddress", TRUE).Field("Identifier", TRUE).Field("Address").GetPtr(); } if (DstAddress && g_Ext->m_Data->ReadVirtual(DstAddress, &NetworkEntry.Remote.IPv4_Addr, sizeof(NetworkEntry.Remote.IPv4_Addr), NULL) != S_OK) goto CleanUp; if (SrcAddress && g_Ext->m_Data->ReadVirtual(SrcAddress, &NetworkEntry.Local.IPv4_Addr, sizeof(NetworkEntry.Local.IPv4_Addr), NULL) != S_OK) goto CleanUp; ExtRemoteTyped OwningProcess("(nt!_EPROCESS *)@$extin", Tcb.Field("OwningProcess").GetPtr()); NetworkEntry.ProcessId = OwningProcess.Field("UniqueProcessId").GetPtr(); OwningProcess.Field("ImageFileName").GetString((LPSTR)NetworkEntry.ProcessName, sizeof(NetworkEntry.ProcessName)); NetworkEntries.push_back(NetworkEntry); } } } } CleanUp: if (Table) free(Table); return NetworkEntries; }