VOID VirusTotalBuildJsonArray( _In_ PVIRUSTOTAL_FILE_HASH_ENTRY Entry, _In_ PVOID JsonArray ) { HANDLE fileHandle; FILE_NETWORK_OPEN_INFORMATION fileAttributeInfo; PPH_STRING hashString = NULL; if (NT_SUCCESS(PhQueryFullAttributesFileWin32( Entry->FileName->Buffer, &fileAttributeInfo ))) { Entry->CreationTime = VirusTotalTimeString(&fileAttributeInfo.CreationTime); } if (NT_SUCCESS(PhCreateFileWin32( &fileHandle, Entry->FileName->Buffer, FILE_GENERIC_READ, 0, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT // FILE_OPEN_FOR_BACKUP_INTENT ))) { if (NT_SUCCESS(HashFileAndResetPosition( fileHandle, &fileAttributeInfo.EndOfFile, Sha256HashAlgorithm, &hashString ))) { PVOID entry; Entry->FileHash = hashString; Entry->FileHashAnsi = PhConvertUtf16ToMultiByte(Entry->FileHash->Buffer); entry = PhCreateJsonObject(); PhAddJsonObject(entry, "autostart_location", ""); PhAddJsonObject(entry, "autostart_entry", ""); PhAddJsonObject(entry, "hash", Entry->FileHashAnsi->Buffer); PhAddJsonObject(entry, "image_path", Entry->FileNameAnsi->Buffer); PhAddJsonObject(entry, "creation_datetime", Entry->CreationTime ? Entry->CreationTime->Buffer : ""); PhAddJsonArrayObject(JsonArray, entry); } NtClose(fileHandle); } }
PVIRUSTOTAL_FILE_HASH_ENTRY VirusTotalAddCacheResult( _In_ PPH_STRING FileName, _In_ PPROCESS_EXTENSION Extension ) { PVIRUSTOTAL_FILE_HASH_ENTRY result; result = PhAllocate(sizeof(VIRUSTOTAL_FILE_HASH_ENTRY)); memset(result, 0, sizeof(VIRUSTOTAL_FILE_HASH_ENTRY)); PhReferenceObject(FileName); result->FileName = FileName; result->FileNameAnsi = PhConvertUtf16ToMultiByte(PhGetString(FileName)); result->Extension = Extension; PhAcquireQueuedLockExclusive(&ProcessListLock); PhAddItemList(VirusTotalList, result); PhReleaseQueuedLockExclusive(&ProcessListLock); return result; }
NTSTATUS NetworkPingThreadStart( _In_ PVOID Parameter ) { HANDLE icmpHandle = INVALID_HANDLE_VALUE; ULONG icmpCurrentPingMs = 0; ULONG icmpReplyCount = 0; ULONG icmpReplyLength = 0; PVOID icmpReplyBuffer = NULL; PPH_BYTES icmpEchoBuffer = NULL; IP_OPTION_INFORMATION pingOptions = { 255, // Time To Live 0, // Type Of Service IP_FLAG_DF, // IP header flags 0 // Size of options data }; PNETWORK_OUTPUT_CONTEXT context = (PNETWORK_OUTPUT_CONTEXT)Parameter; __try { // Create ICMP echo buffer. if (context->PingSize > 0 && context->PingSize != 32) { PPH_STRING randString; randString = PhCreateStringEx(NULL, context->PingSize * 2 + 2); // Create a random string to fill the buffer. PhGenerateRandomAlphaString(randString->Buffer, (ULONG)randString->Length / sizeof(WCHAR)); icmpEchoBuffer = PhConvertUtf16ToMultiByte(randString->Buffer); PhDereferenceObject(randString); } else { PPH_STRING version; // We're using a default length, query the PH version and use the previous buffer format. version = PhGetPhVersion(); if (version) { icmpEchoBuffer = FormatAnsiString("processhacker_%S_0x0D06F00D_x1", version->Buffer); PhDereferenceObject(version); } } if (context->IpAddress.Type == PH_IPV6_NETWORK_TYPE) { SOCKADDR_IN6 icmp6LocalAddr = { 0 }; SOCKADDR_IN6 icmp6RemoteAddr = { 0 }; PICMPV6_ECHO_REPLY2 icmp6ReplyStruct = NULL; // Create ICMPv6 handle. if ((icmpHandle = Icmp6CreateFile()) == INVALID_HANDLE_VALUE) __leave; // Set Local IPv6-ANY address. icmp6LocalAddr.sin6_addr = in6addr_any; icmp6LocalAddr.sin6_family = AF_INET6; // Set Remote IPv6 address. icmp6RemoteAddr.sin6_addr = context->IpAddress.In6Addr; icmp6RemoteAddr.sin6_port = _byteswap_ushort((USHORT)context->NetworkItem->RemoteEndpoint.Port); // Allocate ICMPv6 message. icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMPV6_ECHO_REPLY), icmpEchoBuffer); icmpReplyBuffer = PhAllocate(icmpReplyLength); memset(icmpReplyBuffer, 0, icmpReplyLength); InterlockedIncrement(&context->PingSentCount); // Send ICMPv6 ping... icmpReplyCount = Icmp6SendEcho2( icmpHandle, NULL, NULL, NULL, &icmp6LocalAddr, &icmp6RemoteAddr, icmpEchoBuffer->Buffer, (USHORT)icmpEchoBuffer->Length, &pingOptions, icmpReplyBuffer, icmpReplyLength, context->MaxPingTimeout ); icmp6ReplyStruct = (PICMPV6_ECHO_REPLY2)icmpReplyBuffer; if (icmpReplyCount > 0 && icmp6ReplyStruct) { BOOLEAN icmpPacketSignature = FALSE; if (icmp6ReplyStruct->Status != IP_SUCCESS) { InterlockedIncrement(&context->PingLossCount); } if (_memicmp( icmp6ReplyStruct->Address.sin6_addr, context->IpAddress.In6Addr.u.Word, sizeof(icmp6ReplyStruct->Address.sin6_addr) ) != 0) { InterlockedIncrement(&context->UnknownAddrCount); } icmpPacketSignature = _memicmp( icmpEchoBuffer->Buffer, icmp6ReplyStruct->Data, icmpEchoBuffer->Length ) == 0; if (!icmpPacketSignature) { InterlockedIncrement(&context->HashFailCount); } icmpCurrentPingMs = icmp6ReplyStruct->RoundTripTime; } else { InterlockedIncrement(&context->PingLossCount); } } else { IPAddr icmpLocalAddr = 0; IPAddr icmpRemoteAddr = 0; PICMP_ECHO_REPLY icmpReplyStruct = NULL; // Create ICMPv4 handle. if ((icmpHandle = IcmpCreateFile()) == INVALID_HANDLE_VALUE) __leave; // Set Local IPv4-ANY address. icmpLocalAddr = in4addr_any.s_addr; // Set Remote IPv4 address. icmpRemoteAddr = context->IpAddress.InAddr.s_addr; // Allocate ICMPv4 message. icmpReplyLength = ICMP_BUFFER_SIZE(sizeof(ICMP_ECHO_REPLY), icmpEchoBuffer); icmpReplyBuffer = PhAllocate(icmpReplyLength); memset(icmpReplyBuffer, 0, icmpReplyLength); InterlockedIncrement(&context->PingSentCount); // Send ICMPv4 ping... icmpReplyCount = IcmpSendEcho2Ex( icmpHandle, NULL, NULL, NULL, icmpLocalAddr, icmpRemoteAddr, icmpEchoBuffer->Buffer, (USHORT)icmpEchoBuffer->Length, &pingOptions, icmpReplyBuffer, icmpReplyLength, context->MaxPingTimeout ); icmpReplyStruct = (PICMP_ECHO_REPLY)icmpReplyBuffer; if (icmpReplyStruct && icmpReplyCount > 0) { BOOLEAN icmpPacketSignature = FALSE; if (icmpReplyStruct->Status != IP_SUCCESS) { InterlockedIncrement(&context->PingLossCount); } if (icmpReplyStruct->Address != context->IpAddress.InAddr.s_addr) { InterlockedIncrement(&context->UnknownAddrCount); } if (icmpReplyStruct->DataSize == icmpEchoBuffer->Length) { icmpPacketSignature = _memicmp( icmpEchoBuffer->Buffer, icmpReplyStruct->Data, icmpReplyStruct->DataSize ) == 0; } icmpCurrentPingMs = icmpReplyStruct->RoundTripTime; if (!icmpPacketSignature) { InterlockedIncrement(&context->HashFailCount); } } else { InterlockedIncrement(&context->PingLossCount); } } InterlockedIncrement(&context->PingRecvCount); if (context->PingMinMs == 0 || icmpCurrentPingMs < context->PingMinMs) context->PingMinMs = icmpCurrentPingMs; if (icmpCurrentPingMs > context->PingMaxMs) context->PingMaxMs = icmpCurrentPingMs; context->CurrentPingMs = icmpCurrentPingMs; PhAddItemCircularBuffer_ULONG(&context->PingHistory, icmpCurrentPingMs); } __finally { if (icmpEchoBuffer) { PhDereferenceObject(icmpEchoBuffer); } if (icmpHandle != INVALID_HANDLE_VALUE) { IcmpCloseHandle(icmpHandle); } if (icmpReplyBuffer) { PhFree(icmpReplyBuffer); } } PostMessage(context->WindowHandle, WM_PING_UPDATE, 0, 0); return STATUS_SUCCESS; }