finally managed to multithread folder scanner and rtp. it may still have some bugs. but it works
147 lines
5.4 KiB
Plaintext
147 lines
5.4 KiB
Plaintext
#include "scan.h"
|
|
#include <windows.h>
|
|
#include <iostream>
|
|
#include <openssl/md5.h>
|
|
#include <windows.h>
|
|
#include <iostream>
|
|
#include "md5hash.h"
|
|
#include <string>
|
|
#include "well_known.h"
|
|
#include "log.h"
|
|
#include "virus_ctrl.h"
|
|
#ifndef SCAN_CPP
|
|
#define SCAN_CPP
|
|
int cnt = 0;
|
|
bool file_exists(const std::string& filePath) {
|
|
DWORD fileAttributes = GetFileAttributes(filePath.c_str());
|
|
|
|
if (fileAttributes == INVALID_FILE_ATTRIBUTES) {
|
|
// The file does not exist or there was an error
|
|
return false;
|
|
}
|
|
|
|
// Check if it's a regular file and not a directory
|
|
return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
|
}
|
|
|
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
|
void scan_files_recursive(const std::string& directory) {
|
|
std::string search_path = directory + "\\*.*";
|
|
WIN32_FIND_DATA find_file_data;
|
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
|
|
|
if (hFind == INVALID_HANDLE_VALUE) {
|
|
log(LOGLEVEL::ERR, "[ListFilesRecursive()]: Error opening directory: ", directory, " while scanning files inside folder.");
|
|
return;
|
|
}
|
|
|
|
do {
|
|
if (strcmp(find_file_data.cFileName, ".") == 0 || strcmp(find_file_data.cFileName, "..") == 0) {
|
|
continue; // Skip the current and parent directories
|
|
}
|
|
|
|
|
|
std::string full_path = directory + "\\" + find_file_data.cFileName;
|
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
|
// If it's a directory, recurse into it
|
|
scan_files_recursive(full_path);
|
|
}
|
|
else {
|
|
//we can use a modified version of action_scanfile for this
|
|
//action_scanfile_t(full_path.c_str());
|
|
|
|
cnt++;
|
|
if (cnt % 1000 == 0) {
|
|
printf("Processed %d files;\n", cnt);
|
|
}
|
|
}
|
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
|
|
|
FindClose(hFind);
|
|
}
|
|
int scan_hash(thread_local const std::string& filename, thread_local const std::string& hash) {//!!!! does not work with e.g. utf-16 or something like that. either ascii or utf8!!
|
|
thread_local HANDLE hFile = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
log(LOGLEVEL::ERR, "[scan_hash()]: Error opening database file: ", filename, " while searching for hash.", hash);
|
|
return 2;
|
|
}
|
|
|
|
thread_local HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
|
if (hMapping == NULL) {
|
|
log(LOGLEVEL::ERR, "[scan_hash()]: Error creating database file mapping: ", filename, " while searching for hash.");
|
|
CloseHandle(hFile);
|
|
return 2;
|
|
}
|
|
|
|
char* fileData = static_cast<char*>(MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0));
|
|
if (fileData == NULL) {
|
|
log(LOGLEVEL::ERR, "[scan_hash()]: Error mapping database file: ", filename, " while searching for hash.");
|
|
CloseHandle(hMapping);
|
|
CloseHandle(hFile);
|
|
return 2;
|
|
}
|
|
|
|
DWORD fileSize = GetFileSize(hFile, NULL);
|
|
std::string fileContent(fileData, fileSize);
|
|
|
|
// Search for the specific string in the file content
|
|
size_t foundPos = fileContent.find(hash);
|
|
if (foundPos != std::string::npos) {
|
|
UnmapViewOfFile(fileData);
|
|
CloseHandle(hMapping);
|
|
CloseHandle(hFile);
|
|
return 1;//found
|
|
}
|
|
|
|
// Unmap the memory and close the handles
|
|
UnmapViewOfFile(fileData);
|
|
CloseHandle(hMapping);
|
|
CloseHandle(hFile);
|
|
return 0;
|
|
}
|
|
int scan_hash(thread_local const char* hash) {
|
|
thread_local char* path = new char[600];
|
|
path[0] = '\0';
|
|
sprintf_s(path, 595, "%s\\%c%c.jdbf", DB_DIR, hash[0],hash[1]);
|
|
return scan_hash(path,hash);
|
|
}
|
|
|
|
|
|
//for singlethreaded scans
|
|
void action_scanfile(const char*filepath) {
|
|
if (strlen(filepath) == 0 or strcmp("", filepath) == 0 or file_exists(filepath) == false) {
|
|
//log(LOGLEVEL::ERR, "[action_scanfile()]: Error opening file: ", filepath, " while scanning file for viruses.");
|
|
return; //no filepath given or file not accessible
|
|
}
|
|
else {
|
|
char* hash = new char[300];
|
|
md5_file(filepath, hash);
|
|
if (scan_hash(hash) == 1) { //virus found
|
|
log(LOGLEVEL::VIRUS, "[action_scanfile()]: Virus found in file: ", filepath);
|
|
//add it to a database which stores filepaths of infected files
|
|
virus_ctrl_store(filepath, hash, "sf");
|
|
//afterwards do the processing with that file
|
|
virus_ctrl_process("sf");
|
|
}
|
|
delete[] hash;
|
|
}
|
|
}
|
|
//for multithreaded scans
|
|
void action_scanfile_t(thread_local const char* filepath) {
|
|
if (strlen(filepath) == 0 or strcmp("", filepath) == 0 or file_exists(filepath) == false) {
|
|
return; //no filepath given or file not accessible
|
|
}
|
|
else {
|
|
thread_local char* hash = new char[300];
|
|
md5_file(filepath, hash);
|
|
if (scan_hash(hash) == 1) { //virus found
|
|
log(LOGLEVEL::VIRUS, "[action_scanfile()]: Virus found in file: ", filepath);
|
|
//add it to a database which stores filepaths of infected files
|
|
virus_ctrl_store(filepath, hash, "sft");
|
|
//we do the processing at the end of the scan in order to not slow down the scan !!i have to remember to do this!!
|
|
//virus_ctrl_process("sft");
|
|
}
|
|
delete[] hash;
|
|
}
|
|
}
|
|
#endif |