Пример #1
0
PPH_BYTES VirusTotalGetCachedDbHash(
    VOID
    )
{
    ULONG length;
    PUCHAR buffer;
    PPH_BYTES string;

    length = (ULONG)ProcessObjectDbHash.Length / sizeof(WCHAR) / 2;

    buffer = PhAllocate(length + 1);
    memset(buffer, 0, length + 1);

    PhHexStringToBuffer(&ProcessObjectDbHash, buffer);

    string = PhCreateBytes(buffer);

    for (SIZE_T i = 0; i < string->Length; i++)
        string->Buffer[i] = string->Buffer[i] ^ 0x0D06F00D;

    PhFree(buffer);
    return string;
}
Пример #2
0
NTSTATUS NTAPI VirusTotalProcessApiThread(
    _In_ PVOID Parameter
    )
{
    LONG priority;
    IO_PRIORITY_HINT ioPriority;

    // TODO: Workqueue support.
    priority = THREAD_PRIORITY_LOWEST;
    ioPriority = IoPriorityVeryLow;

    NtSetInformationThread(NtCurrentThread(), ThreadBasePriority, &priority, sizeof(LONG));
    NtSetInformationThread(NtCurrentThread(), ThreadIoPriority, &ioPriority, sizeof(IO_PRIORITY_HINT));

    Sleep(10 * 1000);

    do
    {
        ULONG i;
        INT64 resultLength;
        PSTR jsonArrayToSendString;
        PSTR jsonApiResult = NULL;
        PVOID jsonArray;
        PVOID rootJsonObject = NULL;
        PVOID dataJsonObject;
        PPH_LIST resultTempList = NULL;
        PPH_LIST virusTotalResults = NULL;

        jsonArray = CreateJsonArray();
        resultTempList = PhCreateList(30);

        PhAcquireQueuedLockExclusive(&ProcessListLock);

        for (i = 0; i < VirusTotalList->Count; i++)
        {
            PVIRUSTOTAL_FILE_HASH_ENTRY extension = VirusTotalList->Items[i];

            if (resultTempList->Count >= 30)
                break;

            if (!extension->Stage1)
            {
                extension->Stage1 = TRUE;

                PhAddItemList(resultTempList, extension);
            }
        }

        PhReleaseQueuedLockExclusive(&ProcessListLock);

        if (resultTempList->Count == 0)
        {
            Sleep(30 * 1000); // Wait 30 seconds
            goto CleanupExit;
        }

        for (i = 0; i < resultTempList->Count; i++)
        {
            VirusTotalBuildJsonArray(resultTempList->Items[i], jsonArray);
        }

        if (!(jsonArrayToSendString = GetJsonArrayString(jsonArray)))
            goto CleanupExit;

        if (!(jsonApiResult = VirusTotalSendHttpRequest(PhCreateBytes(jsonArrayToSendString))))
            goto CleanupExit;

        if (!(rootJsonObject = CreateJsonParser(jsonApiResult)))
            goto CleanupExit;

        if (!(dataJsonObject = JsonGetObject(rootJsonObject, "data")))
            goto CleanupExit;

        if (!(resultLength = GetJsonValueAsUlong(rootJsonObject, "result")))
            goto CleanupExit;

        if (virusTotalResults = VirusTotalJsonToResultList(dataJsonObject))
        {
            for (i = 0; i < virusTotalResults->Count; i++)
            {
                PVIRUSTOTAL_API_RESULT result = virusTotalResults->Items[i];

                if (result->Found)
                {
                    PVIRUSTOTAL_FILE_HASH_ENTRY entry = VirusTotalGetCachedResultFromHash(result->FileHash);

                    if (entry && !entry->Processed)
                    {
                        entry->Processed = TRUE;
                        entry->Found = result->Found;
                        entry->Positives = result->Positives;
                        entry->Total = result->Total;
 
                        if (!FindProcessDbObject(&entry->FileName->sr))
                        {
                            CreateProcessDbObject(
                                entry->FileName,
                                entry->Positives,
                                entry->Total,
                                result->FileHash
                                );
                        }
                    }
                }
            }
        }

CleanupExit:

        if (virusTotalResults)
        {
            for (i = 0; i < virusTotalResults->Count; i++)
            {
                PVIRUSTOTAL_API_RESULT result = virusTotalResults->Items[i];
            
            //    PhClearReference(&result->Permalink);
            //    PhClearReference(&result->FileHash);
            //    PhClearReference(&result->DetectionRatio);
            //
                PhFree(result);
            }
            
            PhDereferenceObject(virusTotalResults);
        }
        
        if (rootJsonObject)
        {
            CleanupJsonParser(rootJsonObject);
        }

        if (jsonArray)
        {
            CleanupJsonParser(jsonArray);
        }

        if (jsonApiResult)
        {
            PhFree(jsonApiResult);
        }

        if (resultTempList)
        {
            // Re-queue items without any results from VirusTotal.
            //for (i = 0; i < resultTempList->Count; i++)
            //{
            //    PVIRUSTOTAL_FILE_HASH_ENTRY result = resultTempList->Items[i];
            //    PPROCESS_EXTENSION extension = result->Extension;
            //
            //    if (extension->Retries > 3)
            //        continue;
            //
            //    if (PhIsNullOrEmptyString(result->FileResult))
            //    {
            //        extension->Stage1 = FALSE;
            //    }
            //
            //    extension->Retries++;
            //}

            PhDereferenceObject(resultTempList);
        }

        Sleep(5 * 1000); // Wait 5 seconds

    } while (VirusTotalHandle);

    return STATUS_SUCCESS;
}