This commit is contained in:
jakani24
2024-02-07 16:27:52 +01:00
parent e22e586895
commit b5b3bc06a1
30 changed files with 301 additions and 8 deletions

View File

@@ -156,7 +156,7 @@ void process_changes(const FILE_NOTIFY_INFORMATION* pInfo) {
filename_str = "c:\\" + filename_str; filename_str = "c:\\" + filename_str;
//scan the file and send it to virus_ctrl if it is a virus and then process it //scan the file and send it to virus_ctrl if it is a virus and then process it
std::transform(filename_str.begin(), filename_str.end(), filename_str.begin(), ::tolower); std::transform(filename_str.begin(), filename_str.end(), filename_str.begin(), ::tolower);
if (is_folder_excluded(filename_str.c_str()) or is_directory(filename_str.c_str())) { if (!is_folder_included(filename_str.c_str()) or is_directory(filename_str.c_str()) or is_folder_excluded(filename_str.c_str())) {
//dont scan excluded files or folders //dont scan excluded files or folders
return; return;
} }

View File

@@ -89,9 +89,11 @@ int search_hash(const std::string& dbname_, const std::string& hash_, const std:
thread_local std::string filepath (filepath_); thread_local std::string filepath (filepath_);
thread_local auto fileIter = fileHandles.find(dbname); thread_local auto fileIter = fileHandles.find(dbname);
if (fileIter == fileHandles.end()) { if (fileIter == fileHandles.end() and dbname_.find("c:.jdbf") == std::string::npos) {
log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname); log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname);
return 2; return 2;
}else if (fileIter == fileHandles.end()) {
return 2;
} }
// Use fileData for subsequent searches // Use fileData for subsequent searches

View File

@@ -0,0 +1,209 @@
#include "scan.h"
#include <windows.h>
#include <iostream>
#include <openssl/md5.h>
#include <windows.h>
#include <iostream>
#include <thread>
#include <chrono>
#include <time.h>
#include "md5hash.h"
#include <string>
#include "well_known.h"
#include "log.h"
#include "virus_ctrl.h"
#include "app_ctrl.h"
#ifndef SCAN_CPP
#define SCAN_CPP
std::unordered_map<std::string, HANDLE> fileHandles;
std::unordered_map<std::string, HANDLE> mappingHandles;
std::unordered_map<std::string, char*> fileData;
int cnt = 0;
int num_threads=0;
//load all the db files into memory
void initialize(const std::string& folderPath) {
for (char firstChar = '0'; firstChar <= 'f'; ++firstChar) {
for (char secondChar = '0'; secondChar <= 'f'; ++secondChar) {
// Ensure that the characters are valid hexadecimal digits
if (!std::isxdigit(firstChar) || !std::isxdigit(secondChar) or std::isupper(firstChar) or std::isupper(secondChar)) {
continue;
}
// Create the filename based on the naming convention
std::string filename = folderPath +"\\" + firstChar + secondChar + ".jdbf";
//printf("Loading %s\n", filename.c_str());
// Open the file
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, "[initialize()]: Error opening database file: ", filename);
continue; // Move on to the next file if there's an error
}
// Create the file mapping
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMapping == NULL) {
log(LOGLEVEL::ERR, "[initialize()]: Error creating database file mapping: ", filename);
CloseHandle(hFile);
continue; // Move on to the next file if there's an error
}
// Map the file into memory
char* fileDataPtr = static_cast<char*>(MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0));
if (fileDataPtr == NULL) {
log(LOGLEVEL::ERR, "[initialize()]: Error mapping database file: ", filename);
CloseHandle(hMapping);
CloseHandle(hFile);
continue; // Move on to the next file if there's an error
}
// Store the handles in the global maps
fileHandles[filename] = hFile;
mappingHandles[filename] = hMapping;
fileData[filename] = fileDataPtr;
}
}
}
// Call this function when you are done using the file mappings
void cleanup() {
for (const auto& entry : fileHandles) {
UnmapViewOfFile(fileData[entry.first]);
CloseHandle(mappingHandles[entry.first]);
CloseHandle(entry.second);
}
// Clear the global maps
fileHandles.clear();
mappingHandles.clear();
fileData.clear();
}
//the latest and fastest version of searching a hash by now
int search_hash(const std::string& dbname_, const std::string& hash_, const std::string& filepath_) {
// Check if the file mapping is already open for the given filename
thread_local std::string dbname (dbname_);
thread_local std::string hash (hash_);
thread_local std::string filepath (filepath_);
thread_local auto fileIter = fileHandles.find(dbname);
if (fileIter == fileHandles.end() or dbname_.find("c:.jdbf") != std::string::npos) {
log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname);
return 2;
}
// Use fileData for subsequent searches
thread_local DWORD fileSize = GetFileSize(fileHandles[dbname], NULL);
thread_local std::string fileContent(fileData[dbname], fileSize);
// Search for the specific string in the file content
thread_local size_t foundPos = fileContent.find(hash);
if (foundPos != std::string::npos) {
log(LOGLEVEL::VIRUS, "[search_hash()]: Found virus: ", hash, " in file: ", filepath);
virus_ctrl_store(filepath.c_str(), hash.c_str(), hash.c_str());
//afterwards do the processing with that file
virus_ctrl_process(hash.c_str());
return 1; // Found
}
return 0; // Not found
}
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_folder(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, "[scan_folder()]: Error opening directory: ", search_path.c_str() , " 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
}
const 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_folder(full_path);
}
else {
//action scanfile_t will start the trheads for scanning the hashes
//action_scanfile_t(full_path.c_str());
//do multithreading here
while (num_threads >= std::thread::hardware_concurrency()) {
Sleep(10);
}
num_threads++;
std::thread scan_thread(scan_file_t, full_path);
scan_thread.detach();
cnt++;
if (cnt % 100 == 0) {
printf("Processed %d files;\n", cnt);
//printf("Number of threads: %d\n", num_threads);
}
}
} while (FindNextFile(hFind, &find_file_data) != 0);
FindClose(hFind);
}
//for singlethreaded scans
void action_scanfile(const char*filepath) {
thread_init();
char* db_path = new char[300];
//log(LOGLEVEL::INFO, "[action_scanfile_t()]: Scanning file: ", filepath);
if (strlen(filepath) == 0 or strcmp("", filepath) == 0 or file_exists(filepath) == false) {
thread_shutdown();
return; //no filepath given or file not accessible
}
else {
char* hash = new char[300];
hash[0] = '\0';
strcpy_s(hash, 295, md5_file_t(filepath).c_str());
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
search_hash(db_path, hash, filepath);
delete[] hash;
}
delete[] db_path;
thread_shutdown();
}
void action_scanfolder(const char*folderpath) {
thread_init();
cnt = 0;
thread_local std::string folderpath_ (folderpath);
scan_folder(folderpath_);
thread_shutdown();
}
void scan_file_t(const std::string& filepath_) {
thread_local const std::string filepath (filepath_);
thread_local char* db_path = new char[300];
thread_local char* hash = new char[300];
strcpy_s(hash,295 ,md5_file_t(filepath).c_str());
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
search_hash(db_path, hash, filepath);
num_threads--;
}
#endif

View File

@@ -7,7 +7,10 @@ int setting_virus_ctrl_virus_found_action = 0;
char*setting_server_server_url = new char[300]; char*setting_server_server_url = new char[300];
char exluded_folders[100][300]; char exluded_folders[100][300];
int excluded_folders_size = 0; int excluded_folders_size = 0;
char included_folders[100][300];
int included_folders_size = 0;
bool setting_rtp_folder_scan_status = 1; //0=off, 1=on bool setting_rtp_folder_scan_status = 1; //0=off, 1=on
void load_included_folders();
void load_excluded_folders(); void load_excluded_folders();
int load_settings() { int load_settings() {
FILE* fp; FILE* fp;
@@ -58,6 +61,7 @@ int load_settings() {
delete[] settings_cmd; delete[] settings_cmd;
delete[] settings_arg; delete[] settings_arg;
} }
load_included_folders();
load_excluded_folders(); load_excluded_folders();
return 0; return 0;
} }
@@ -82,6 +86,47 @@ int get_setting(const char* setting_name,char*out) {
return -1; return -1;
} }
void load_included_folders() {
FILE* fp;
if (fopen_s(&fp, INCLUDED_FOLDERS, "r") != 0) {
log(LOGLEVEL::ERR, "[load_included_files()]: Could not open included folders file. ", INCLUDED_FOLDERS);
return;
}
else {
char* path = new char[300];
while (!feof(fp)) {
//get the path of an excluded folder
path[0] = '\0';
//the path is encapsulated with "
int cnt = 0;
int chr = 0;
chr = fgetc(fp);
if (chr == '\"') {
chr = 0;
while (cnt < 295 && chr != '\"') {
chr = fgetc(fp); //get a char
if (chr != '\"')
path[cnt] = chr;
path[cnt + 1] = '\0';
cnt++;
}
//now add the path to the array
if (included_folders_size < 95) {
strcpy_s(included_folders[included_folders_size], 295, path);
included_folders_size++;
}
else {
log(LOGLEVEL::ERR, "[load_included_files()]: included folders array is full. Cannot add more folders.");
}
}
//else { we dont need to error out here. it is normal that it givs errors at the last lien of the file. but nothing bad happens, so errors arent needed
// log(LOGLEVEL::ERR, "[load_excluded_folders()]: Error while processing excluded folders database. Expected \" but got ", chr);
//}
}
fclose(fp);
delete[] path;
}
}
void load_excluded_folders() { void load_excluded_folders() {
FILE* fp; FILE* fp;
if (fopen_s(&fp, EXCLUDED_FOLDERS, "r") != 0) { if (fopen_s(&fp, EXCLUDED_FOLDERS, "r") != 0) {
@@ -123,6 +168,14 @@ void load_excluded_folders() {
delete[] path; delete[] path;
} }
} }
bool is_folder_included(const char*path) {
for (int i = 0; i < included_folders_size; i++) {
if (strstr(path,included_folders[i]) != 0 and strcmp(included_folders[i],"")!=0 and strcmp(included_folders[i], " ") != 0 ) {
return true;
}
}
return false;
}
bool is_folder_excluded(const char* path) { bool is_folder_excluded(const char* path) {
for (int i = 0; i < excluded_folders_size; i++) { for (int i = 0; i < excluded_folders_size; i++) {
if (strstr(path, exluded_folders[i]) != 0 and strcmp(exluded_folders[i], "") != 0 and strcmp(exluded_folders[i], " ") != 0) { if (strstr(path, exluded_folders[i]) != 0 and strcmp(exluded_folders[i], "") != 0 and strcmp(exluded_folders[i], " ") != 0) {
@@ -131,7 +184,7 @@ bool is_folder_excluded(const char*path) {
} }
return false; return false;
} }
void print_exclusions() { void print_inclusuions() {
for (int i = 0; i < excluded_folders_size; i++) { for (int i = 0; i < excluded_folders_size; i++) {
log(LOGLEVEL::INFO, "[print_exclusions()]: Excluded folder: ", exluded_folders[i]); log(LOGLEVEL::INFO, "[print_exclusions()]: Excluded folder: ", exluded_folders[i]);
} }

View File

@@ -6,6 +6,7 @@
int get_setting(const char* setting_name); int get_setting(const char* setting_name);
int get_setting(const char* setting_name,char*out); int get_setting(const char* setting_name,char*out);
int load_settings(); int load_settings();
bool is_folder_included(const char* path);
bool is_folder_excluded(const char* path); bool is_folder_excluded(const char* path);
void print_exclusions(); void print_inclusions();
#endif #endif

View File

@@ -34,5 +34,6 @@
#define PERIODIC_FOLDER_SCAN "C:\\Program Files\\cyberhex\\secure\\database\\folder\\periodic_folder_scan.txt" #define PERIODIC_FOLDER_SCAN "C:\\Program Files\\cyberhex\\secure\\database\\folder\\periodic_folder_scan.txt"
#define PERIODIC_FOLDER_SCAN_TEMP_DB "C:\\Program Files\\cyberhex\\secure\\database\\folder\\temp_db.txt" #define PERIODIC_FOLDER_SCAN_TEMP_DB "C:\\Program Files\\cyberhex\\secure\\database\\folder\\temp_db.txt"
#define INCLUDED_FOLDERS "C:\\Program Files\\cyberhex\\secure\\settings\\included_folders.txt"
#define EXCLUDED_FOLDERS "C:\\Program Files\\cyberhex\\secure\\settings\\excluded_folders.txt" #define EXCLUDED_FOLDERS "C:\\Program Files\\cyberhex\\secure\\settings\\excluded_folders.txt"
#endif // !WELL_KNOWN_H #endif // !WELL_KNOWN_H

View File

@@ -1,2 +1,4 @@
 Quellen werden auf Modulabhängigkeiten überprüft...  Quellen werden auf Modulabhängigkeiten überprüft...
scan.cpp
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\scan.cpp(153,32): warning C4018: ">=": Konflikt zwischen "signed" und "unsigned"
client_backend.vcxproj -> C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe client_backend.vcxproj -> C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe

Binary file not shown.

Binary file not shown.

View File

@@ -25,6 +25,31 @@ include "../../../config.php";
$setting_virus_ctrl_virus_found_action = "not configured yet"; $setting_virus_ctrl_virus_found_action = "not configured yet";
$setting_server_server_url="not configured yet"; $setting_server_server_url="not configured yet";
$setting_rtp_folder_scan_status=0; $setting_rtp_folder_scan_status=0;
function safe_settings(){
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD,$DB_DATABASE);
if ($conn->connect_error) {
$success=0;
die("Connection failed: " . $conn->connect_error);
}
$value=htmlspecialchars($_GET["value"]);
//update what should be done if a virus is found
if($_GET["name"]=="setting_virus_ctrl_virus_found_action"){
$stmt = $conn->prepare("INSERT INTO settings (value) VALUES (?) WHERE name = 'virus_ctrl:virus_found:action' DUPLICATE KEY UPDATE value = ? WHERE name = 'virus_ctrl:virus_found:action';");
$stmt->bind_param("ss", $value,$value);
$stmt->execute();
$stmt->close();
$conn->close();
}
//update rtp folder scanner
if($_GET["name"]=="setting_virus_ctrl_virus_found_action"){
$stmt = $conn->prepare("INSERT INTO settings (value) VALUES (?) WHERE name = 'rtp_folder_scan:status';");
$stmt->bind_param("ss", $value,$value);
$stmt->execute();
$stmt->close();
$conn->close();
}
}
function load_settings(){ function load_settings(){
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE); $conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
if ($conn->connect_error) { if ($conn->connect_error) {