json_object* PackageDescription::toJSON() const
{
	json_object* json = NULL;
	if (m_isOldStyle) {
		json = json_object_new_object();
		json_object_object_add(json, (char*) "id",   json_object_new_string((char*) m_id.c_str()));
		json_object_object_add(json, (char*) "version", json_object_new_string(m_version.c_str()));
		json_object_object_add(json, (char*) "size", json_object_new_int((int)m_packageSize));

		json_object* apps = json_object_new_array();
		std::vector<std::string>::const_iterator appIdIt, appIdItEnd;
		for (appIdIt = m_appIds.begin(), appIdItEnd = m_appIds.end(); appIdIt != appIdItEnd; ++appIdIt) {
			json_object_array_add(apps, json_object_new_string((*appIdIt).c_str()));
		}
		json_object_object_add(json, (char*) "apps", apps);

	} else {
		json = json_tokener_parse(m_jsonString.c_str());
		if (!json || is_error(json)) {
			g_warning("%s: Failed to parse '%s' into a JSON string", __PRETTY_FUNCTION__, m_jsonString.c_str());
			return NULL;
		}
		json_object_object_add(json, (char*) "size", json_object_new_int((int)m_packageSize));

		json_object* label = JsonGetObject(json, "icon");
		if (label) {
			std::string icon = json_object_get_string(label);
			json_object_object_del(json, (char*) "icon");
			json_object_object_add(json, (char*) "icon", json_object_new_string((char*) (m_folderPath + "/" + icon).c_str()));
		}

		label = JsonGetObject(json, "miniicon");
		if (label) {
			std::string miniicon = json_object_get_string(label);
			json_object_object_del(json, (char*) "miniicon");
			json_object_object_add(json, (char*) "miniicon", json_object_new_string((char*) (m_folderPath + "/" + miniicon).c_str()));
		}

	}
	return json;
}
// static
ServiceDescription* ServiceDescription::fromFile(const std::string& filePath)
{
	bool success = false;
	ServiceDescription* serviceDesc = NULL;
	char* jsonStr = NULL;

	jsonStr = readFile(filePath.c_str());
	if (!jsonStr || !g_utf8_validate(jsonStr, -1, NULL)) {
		return NULL;
	}

	struct json_object* root = NULL;
	struct json_object* label = NULL;

	root = json_tokener_parse(jsonStr);
	if (!root || is_error( root )) {
		g_warning("Failed to parse '%s' into a JSON string", filePath.c_str());
		goto Done;
	}

	serviceDesc = new ServiceDescription();

	// ID: mandatory
	label = JsonGetObject(root, "id");
	if (label) {
		serviceDesc->m_id = json_object_get_string(label);
	} else {
		g_warning("service %s does not have an ID", filePath.c_str());
		goto Done;
	}

	serviceDesc->m_jsonString = json_object_to_json_string(root);

	success = true;

Done:

	if (root && !is_error(root))
		json_object_put(root);

	delete[] jsonStr;

	if (!success) {
		delete serviceDesc;
		return NULL;
	}

	return serviceDesc;
}
//static
int ApplicationDescription::utilExtractMimeTypes(struct json_object * jsonMimeTypeArray,std::vector<MimeRegInfo>& extractedMimeTypes)
{
    if (jsonMimeTypeArray == NULL || !json_object_is_type(jsonMimeTypeArray, json_type_array))
        return 0;

    json_object * label;

    /*
    "mimeTypes": [ 	{"mime":<string> , "stream":<bool> },
    				{ "extension":<string> , "stream":<bool> },
    				{ "urlPattern":<string;regexp> },
    				{ "scheme":<string;regexp> }
    			]
    */

    int rc=0;
    for (int listIdx=0; listIdx<json_object_array_length(jsonMimeTypeArray); ++listIdx) {
        struct json_object * jsonListObject = json_object_array_get_idx(jsonMimeTypeArray,listIdx);
        if (jsonListObject == NULL)
            continue;
        if (json_object_is_type(jsonListObject,json_type_object) == false)
            continue;
        MimeRegInfo mri;
        bool r = false;
        r |= extractFromJson(jsonListObject,"mime",mri.mimeType);
        r |= extractFromJson(jsonListObject,"extension",mri.extension);
        r |= extractFromJson(jsonListObject,"urlPattern",mri.urlPattern);
        r |= extractFromJson(jsonListObject,"scheme",mri.scheme);

        if ((label = JsonGetObject(jsonListObject,"stream")) == NULL)
            mri.stream = false;
        else
            mri.stream = json_object_get_boolean(label);

        if (r) {
            extractedMimeTypes.push_back(mri);
            ++rc;
        }
    }

    return rc;

}
//static
PackageDescription* PackageDescription::fromJson(json_object* root, const std::string& folderPath)
{
	if (!root)
		return NULL;

	bool success = false;

	PackageDescription* packageDesc = new PackageDescription();

	packageDesc->m_folderPath = folderPath;

	struct json_object* label = NULL;
	// ID: mandatory
	label = JsonGetObject(root, "id");
	if (label) {
		packageDesc->m_id = json_object_get_string(label);
		if (packageDesc->m_id == "") {
			g_warning("package %s has an empty ID field", folderPath.c_str());
			goto Done;
		}
	} else {
		g_warning("package %s does not have an ID", folderPath.c_str());
		goto Done;
	}

	// app (or apps) json array: optional
	label = JsonGetObject(root, "app");
	if (label) {
		packageDesc->m_appIds.push_back(std::string(json_object_get_string(label)));
	} else {
		label = JsonGetObject(root, "apps");
		if (label) {
			for (int i = 0; i < json_object_array_length(label); i++) {
				struct json_object* app = json_object_array_get_idx(label, i);
				if (app && !is_error(app)) {
					packageDesc->m_appIds.push_back(std::string(json_object_get_string(app)));
				}
			}
		}
	}

	// services json array: optional
	label = JsonGetObject(root, "services");
	if (label) {
		for (int i = 0; i < json_object_array_length(label); i++) {
			struct json_object* service = json_object_array_get_idx(label, i);
			if (service && !is_error(service)) {
				packageDesc->m_serviceIds.push_back(std::string(json_object_get_string(service)));
			}
		}
	}

	if (packageDesc->m_appIds.empty() && packageDesc->m_serviceIds.empty()) {
		g_warning("package %s does not have any apps or services", folderPath.c_str());
		goto Done;
	}

	// Optional parameters
	success = true;

	// version: optional
	label = JsonGetObject(root, "version");
	if (label) {
		packageDesc->m_version = json_object_get_string(label);
	}

	// accounts json array: optional
	label = JsonGetObject(root, "accounts");
	if (label) {
		for (int i = 0; i < json_object_array_length(label); i++) {
			struct json_object* accountId = json_object_array_get_idx(label, i);
			if (accountId && !is_error(accountId)) {
				packageDesc->m_accountIds.push_back(std::string(json_object_get_string(accountId)));
			}
		}
	}

	packageDesc->m_jsonString = json_object_to_json_string(root);

	Done:

	if (!success) {
		delete packageDesc;
		return NULL;
	}

	return packageDesc;
}
Exemple #5
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;
}