BOOLEAN StoreManager::GetSmLogEntries( ) /*++ Routine Description: Description. Arguments: - Return Value: BOOLEAN. --*/ { // SMP_LOG_BUFFER32 Log32; SMP_LOG_BUFFER64 Log64; ULONG64 SmLogBuffer = ExtRemoteTypedEx::GetPointer(m_SmGlobalsAddress + m_SmLogCtxOffset); ULONG64 SmLogBufferNext; ULONG BytesRead; PSM_LOG_ENTRY32 pLogEntry32 = NULL, le32 = NULL; PSM_LOG_ENTRY64 pLogEntry64 = NULL, le64 = NULL; SM_LOG_ENTRY64 LogEntry; BOOLEAN Is64Bit = (g_Ext->m_Control->IsPointer64Bit() == S_OK) ? TRUE : FALSE; BOOLEAN Result = FALSE; if (!SmLogBuffer) { goto CleanUp; } g_Ext->Dml("<col fg=\"changed\">" " ID # Action EPROCESS Application Name Page Count Priority Virtual Address Range" "</col>\n" " ---- ------ ------------------ ---------------- ---------- -------- -------------------------------------\n"); while (SmLogBuffer) { ULONG EntryCount, EntryMax; // g_Ext->Dml("SmLogBuffer = 0x%I64X m_SmpLogBufferSize = 0x%x\n", SmLogBuffer, m_SmpLogBufferSize); if (ExtRemoteTypedEx::ReadVirtual(SmLogBuffer, &Log64, m_SmpLogBufferSize, &BytesRead) != S_OK) { g_Ext->Err("Error1: Failed to read log.\n"); goto CleanUp; } if (Is64Bit) { EntryCount = Log64.EntryCount; EntryMax = Log64.EntryMax; SmLogBufferNext = Log64.Link; } else { EntryCount = ((PSMP_LOG_BUFFER32)&Log64)->EntryCount; SmLogBufferNext = ((PSMP_LOG_BUFFER32)&Log64)->Link; } if (EntryCount == 0) { // g_Ext->DmlWarn("Store Manager logs are empty.\n"); goto CleanUp; } // g_Ext->Dml("SmLogBuffer = %I64X, EntryCount = %d, EntryMax = %d\n", EntryCount, EntryMax); pLogEntry64 = (PSM_LOG_ENTRY64)malloc(EntryCount * m_SmLogEntrySize); if (pLogEntry64 == NULL) goto CleanUp; if (!Is64Bit) { pLogEntry32 = (PSM_LOG_ENTRY32)pLogEntry64; pLogEntry64 = NULL; } if (ExtRemoteTypedEx::ReadVirtual(SmLogBuffer + m_SmpLogBufferSize, (pLogEntry64) ? (PVOID)pLogEntry64 : (PVOID)pLogEntry32, EntryCount * m_SmLogEntrySize, &BytesRead) != S_OK) { g_Ext->Err("Error2: Failed to read log. (p = %I64X, 0x%x)\n", SmLogBuffer + m_SmpLogBufferSize, EntryCount * m_SmLogEntrySize); goto CleanUp; } for (ULONG Index = 0; Index < EntryCount; Index += 1) { if (pLogEntry64) le64 = &pLogEntry64[Index]; else le32 = &pLogEntry32[Index]; RtlZeroMemory(&LogEntry, sizeof(LogEntry)); if (le32) { LogEntry.PageCount = le32->PageCount; LogEntry.AllFlags = le32->AllFlags; LogEntry.KeyDescriptor.ProcessKey = le32->KeyDescriptor.ProcessKey; LogEntry.KeyDescriptor.VirtualAddress = le32->KeyDescriptor.VirtualAddress; } else { LogEntry = *le64; } if ((LogEntry.KeyDescriptor.Flags.PageType == SmPageTypeProcess) && IsValid(LogEntry.KeyDescriptor.ProcessKey)) { CHAR ImageName[17] = { 0 }; ExtRemoteTyped OwningProcess("(nt!_EPROCESS *)@$extin", LogEntry.KeyDescriptor.ProcessKey); OwningProcess.Field("ImageFileName").GetString((LPSTR)ImageName, sizeof(ImageName)); g_Ext->Dml(" %4d %-8s <link cmd=\"!dml_proc 0x%I64X\">0x%016I64X</link> <col fg=\"emphfg\">%-16s</col> %10d P%-8d 0x%016I64X-0x%016I64X\n", Index, LogEntryType[LogEntry.Flags.Type], LogEntry.KeyDescriptor.ProcessKey, LogEntry.KeyDescriptor.ProcessKey, ImageName, LogEntry.PageCount, LogEntry.Flags.Priority, LogEntry.KeyDescriptor.VirtualAddress * PAGE_SIZE, (LogEntry.KeyDescriptor.VirtualAddress + LogEntry.PageCount) * PAGE_SIZE); } SmLogEntries.push_back(LogEntry); SmLogBuffer = SmLogBufferNext; } // SmLogBuffer initialized above. } Result = TRUE; CleanUp: if (Result == FALSE) { g_Ext->Warn("-> Storage manager logs are empty!\n"); } if (pLogEntry64) free(pLogEntry64); if (pLogEntry32) free(pLogEntry32); return Result; }
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; }