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; }
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; }