fixing crashes, adding threadsafety and changing welcome.,php

This commit is contained in:
jakani24
2024-03-12 13:14:40 +01:00
parent e264f4c22a
commit b219fbab8e
33 changed files with 1384 additions and 680 deletions

View File

@@ -2,85 +2,77 @@
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:scan.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:check_process.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\md5hash.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:md5hash.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:connect.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:check_dir.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:scan.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:virus_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:check_process.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:settings.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:client_backend.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_com.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:local_com.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_schedule.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:local_schedule.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\update.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:update.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:thread_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:virus_ctrl.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:log.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\md5hash.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:md5hash.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_schedule.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:local_schedule.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:client_backend.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:thread_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:scan.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:settings.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_com.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:local_com.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:log.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:settings.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:check_dir.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:connect.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\security.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:security.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:check_process.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\app_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:app_ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\permissions.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:permissions.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\update.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:update.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\queue _ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:queue _ctrl.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
},
{
"AbsoluteMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}",
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:connect.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
}
],
"DocumentGroupContainers": [
@@ -90,41 +82,56 @@
"DocumentGroups": [
{
"DockedWidth": 200,
"SelectedChildIndex": 13,
"SelectedChildIndex": 17,
"Children": [
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "security.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\security.cpp",
"RelativeDocumentMoniker": "security.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\security.cpp",
"RelativeToolTip": "security.cpp",
"ViewState": "AQIAABsAAAAAAAAAAAAAADoAAAA2AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-03-12T10:18:22.033Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 14,
"Title": "virus_ctrl.h",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.h",
"RelativeDocumentMoniker": "virus_ctrl.h",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.h",
"RelativeToolTip": "virus_ctrl.h",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAkAAAATAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
"WhenOpened": "2024-03-11T12:26:05.127Z"
"Title": "permissions.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\permissions.cpp",
"RelativeDocumentMoniker": "permissions.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\permissions.cpp",
"RelativeToolTip": "permissions.cpp",
"ViewState": "AQIAAAQAAAAAAAAAAAAIwDsAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-03-12T10:18:17.369Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "check_process.h",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.h",
"RelativeDocumentMoniker": "check_process.h",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.h",
"RelativeToolTip": "check_process.h",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAYAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
"WhenOpened": "2024-03-10T14:40:13.284Z"
"DocumentIndex": 13,
"Title": "app_ctrl.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\app_ctrl.cpp",
"RelativeDocumentMoniker": "app_ctrl.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\app_ctrl.cpp",
"RelativeToolTip": "app_ctrl.cpp",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAwAAAAPAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-03-12T10:10:59.685Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 1,
"DocumentIndex": 12,
"Title": "check_process.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp",
"RelativeDocumentMoniker": "check_process.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp",
"RelativeToolTip": "check_process.cpp",
"ViewState": "AQIAABgAAAAAAAAAAAAAADQAAAAtAAAA",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAYAAAARAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-03-10T14:40:03.094Z",
"EditorCaption": ""
@@ -137,63 +144,40 @@
"RelativeDocumentMoniker": "md5hash.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\md5hash.cpp",
"RelativeToolTip": "md5hash.cpp",
"ViewState": "AQIAAB4AAAAAAAAAAAAkwCoAAAAqAAAA",
"ViewState": "AQIAACQAAAAAAAAAAAAAADUAAAA1AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-03-09T19:22:09.647Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 17,
"Title": "settings.h",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.h",
"RelativeDocumentMoniker": "settings.h",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.h",
"RelativeToolTip": "settings.h",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAkAAAAXAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
"WhenOpened": "2024-03-09T13:50:21.91Z"
},
{
"$type": "Document",
"DocumentIndex": 18,
"Title": "connect.h",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.h",
"RelativeDocumentMoniker": "connect.h",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.h",
"RelativeToolTip": "connect.h",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAsAAABPAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
"WhenOpened": "2024-03-09T12:32:01.859Z"
},
{
"$type": "Document",
"DocumentIndex": 4,
"DocumentIndex": 10,
"Title": "check_dir.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp",
"RelativeDocumentMoniker": "check_dir.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp",
"RelativeToolTip": "check_dir.cpp",
"ViewState": "AQIAADEAAAAAAAAAAAAIwGgAAAAAAAAA",
"ViewState": "AQIAAEkAAAAAAAAAAAAIwHYAAACFAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-02-25T13:36:05.414Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 15,
"DocumentIndex": 1,
"Title": "log.h",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.h",
"RelativeDocumentMoniker": "log.h",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.h",
"RelativeToolTip": "log.h",
"ViewState": "AQIAAFMAAAAAAAAAAAAkwG8AAAAqAAAA",
"ViewState": "AQIAAFMAAAAAAAAAAAAkwFsAAAAjAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
"WhenOpened": "2024-02-25T09:02:55.874Z"
"WhenOpened": "2024-02-25T09:02:55.874Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 16,
"DocumentIndex": 9,
"Title": "log.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.cpp",
"RelativeDocumentMoniker": "log.cpp",
@@ -201,72 +185,77 @@
"RelativeToolTip": "log.cpp",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAB8AAAAFAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-02-25T09:08:59.07Z"
"WhenOpened": "2024-02-25T09:08:59.07Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 10,
"DocumentIndex": 8,
"Title": "local_com.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_com.cpp",
"RelativeDocumentMoniker": "local_com.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_com.cpp",
"RelativeToolTip": "local_com.cpp",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAcAAAAeAAAA",
"ViewState": "AQIAAAAAAAAAAAAAAAAAADYAAAAYAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.217Z"
"WhenOpened": "2024-01-28T20:40:06.217Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 8,
"DocumentIndex": 7,
"Title": "settings.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.cpp",
"RelativeDocumentMoniker": "settings.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\settings.cpp",
"RelativeToolTip": "settings.cpp",
"ViewState": "AQIAALIAAAAAAAAAAAAkwNUAAAACAAAA",
"ViewState": "AQIAAMwAAAAAAAAAAAAIwAMBAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.264Z"
"WhenOpened": "2024-01-28T20:40:06.264Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 13,
"DocumentIndex": 5,
"Title": "thread_ctrl.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp",
"RelativeDocumentMoniker": "thread_ctrl.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp",
"RelativeToolTip": "thread_ctrl.cpp",
"ViewState": "AQIAABgAAAAAAAAAAAAAADUAAAAoAAAA",
"ViewState": "AQIAABUAAAAAAAAAAAAAADMAAAAFAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.264Z"
"WhenOpened": "2024-01-28T20:40:06.264Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "client_backend.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
"RelativeDocumentMoniker": "client_backend.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
"RelativeToolTip": "client_backend.cpp",
"ViewState": "AQIAAAAAAAAAAAAAAAAAABkAAABBAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.279Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
"DocumentIndex": 6,
"Title": "scan.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp",
"RelativeDocumentMoniker": "scan.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp",
"RelativeToolTip": "scan.cpp",
"ViewState": "AQIAALIAAAAAAAAAAAAkwNkAAAA2AAAA",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAKEAAAAAAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.248Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 12,
"DocumentIndex": 4,
"Title": "client_backend.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
"RelativeDocumentMoniker": "client_backend.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
"RelativeToolTip": "client_backend.cpp",
"ViewState": "AQIAADMAAAAAAAAAAAAAAFsAAAAhAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.279Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 15,
"Title": "update.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\update.cpp",
"RelativeDocumentMoniker": "update.cpp",
@@ -274,35 +263,25 @@
"RelativeToolTip": "update.cpp",
"ViewState": "AQIAACwAAAAAAAAAAAAkwFIAAAAWAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.248Z"
"WhenOpened": "2024-01-28T20:40:06.248Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 11,
"DocumentIndex": 3,
"Title": "local_schedule.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_schedule.cpp",
"RelativeDocumentMoniker": "local_schedule.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_schedule.cpp",
"RelativeToolTip": "local_schedule.cpp",
"ViewState": "AQIAAAAAAAAAAAAAAAAAAFcAAAAvAAAA",
"ViewState": "AQIAAGYAAAAAAAAAAAAAAJoAAAAaAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.279Z"
"WhenOpened": "2024-01-28T20:40:06.279Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "scan.h",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h",
"RelativeDocumentMoniker": "scan.h",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h",
"RelativeToolTip": "scan.h",
"ViewState": "AQIAAAAAAAAAAAAAAAAAABIAAAAyAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
"WhenOpened": "2024-01-28T20:40:06.295Z"
},
{
"$type": "Document",
"DocumentIndex": 19,
"DocumentIndex": 16,
"Title": "queue _ctrl.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\queue _ctrl.cpp",
"RelativeDocumentMoniker": "queue _ctrl.cpp",
@@ -310,11 +289,12 @@
"RelativeToolTip": "queue _ctrl.cpp",
"ViewState": "AQIAAAAAAAAAAAAAAAAAACsAAAABAAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-01-28T20:40:06.295Z"
"WhenOpened": "2024-01-28T20:40:06.295Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 3,
"DocumentIndex": 17,
"Title": "connect.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.cpp",
"RelativeDocumentMoniker": "connect.cpp",
@@ -327,15 +307,16 @@
},
{
"$type": "Document",
"DocumentIndex": 6,
"DocumentIndex": 0,
"Title": "virus_ctrl.cpp",
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp",
"RelativeDocumentMoniker": "virus_ctrl.cpp",
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp",
"RelativeToolTip": "virus_ctrl.cpp",
"ViewState": "AQIAAHsAAAAAAAAAAAAAAJMAAAAkAAAA",
"ViewState": "AQIAADAAAAAAAAAAAAAAAEkAAAA+AAAA",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
"WhenOpened": "2024-02-18T12:49:41.861Z"
"WhenOpened": "2024-02-18T12:49:41.861Z",
"EditorCaption": ""
}
]
}

View File

@@ -0,0 +1,244 @@
#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;
unsigned int num_threads = 0;
//load all the db files into memory
int 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);
return 1;
}
// 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);
return 2;
}
// 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);
return 3;
}
// Store the handles in the global maps
fileHandles[filename] = hFile;
mappingHandles[filename] = hMapping;
fileData[filename] = fileDataPtr;
}
}
return 0;
}
// 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();
}
std::mutex searchMutex;
int search_hash(const std::string& dbname_, const std::string& hash_, const std::string& filepath_) {
std::string dbname(dbname_);
std::string hash(hash_);
std::string filepath(filepath_);
auto fileIter = fileHandles.find(dbname);
if (fileIter == fileHandles.end() && dbname_.find("c:.jdbf") == std::string::npos) {
log(LOGLEVEL::ERR_NOSEND, "[search_hash()]: File mapping not initialized for ", dbname);
return 2;
}
else if (fileIter == fileHandles.end()) {
return 2;
}
DWORD fileSize;
std::string fileContent;
{
// Retrieve file size and content
fileSize = GetFileSize(fileHandles[dbname], NULL);
fileContent = fileData[dbname];
} // Release the lock immediately after retrieving the required data
// Search for the specific string in the file content
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::WARN, "[scan_folder()]: Could not open directory: ", search_path.c_str(), " while scanning files inside directory.");
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);
}
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path, "threads: ",num_threads);
std::thread scan_thread(scan_file_t, full_path);
scan_thread.detach();
//Sleep(1);
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();
delete[] db_path;
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_) {
num_threads++;
thread_local const std::string filepath(filepath_);
thread_local char* db_path = new char[300];
thread_local char* hash = new char[300];
thread_local std::string hash_(md5_file_t(filepath));
if (strlen(hash_.c_str()) < 290)
strcpy_s(hash, 295, hash_.c_str());
else{
strcpy_s(hash, 295, "");
log(LOGLEVEL::ERR_NOSEND, "[scan_file_t()]: Could not calculate hash for file: ", filepath);
}
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
search_hash(db_path, hash, filepath);
num_threads--;
}
void scan_process_t(const std::string& filepath_) {
num_threads++;
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]);
if (search_hash(db_path, hash, filepath) == 1) {
//check if need to kill process
if (get_setting("virus_ctrl:virus_process_found:kill") == 1) {
//kill the process
kill_process(filepath.c_str());
log(LOGLEVEL::VIRUS, "[scan_process_t()]: Killing process: ", filepath);
}
}
num_threads--;
}
#endif

View File

@@ -0,0 +1,241 @@
#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;
unsigned int num_threads = 0;
//load all the db files into memory
int 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);
return 1;
}
// 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);
return 2;
}
// 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);
return 3;
}
// Store the handles in the global maps
fileHandles[filename] = hFile;
mappingHandles[filename] = hMapping;
fileData[filename] = fileDataPtr;
}
}
return 0;
}
// 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() and dbname_.find("c:.jdbf") == std::string::npos) {
log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname);
return 2;
}
else if (fileIter == fileHandles.end()) {
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::WARN, "[scan_folder()]: Could not open directory: ", search_path.c_str(), " while scanning files inside directory.");
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);
}
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path, "threads: ",num_threads);
std::thread scan_thread(scan_file_t, full_path);
scan_thread.detach();
//Sleep(1);
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();
delete[] db_path;
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_) {
num_threads++;
thread_local const std::string filepath(filepath_);
thread_local char* db_path = new char[300];
thread_local char* hash = new char[300];
thread_local std::string hash_(md5_file_t(filepath));
if (strlen(hash_.c_str()) < 290)
strcpy_s(hash, 295, hash_.c_str());
else{
strcpy_s(hash, 295, "");
log(LOGLEVEL::ERR_NOSEND, "[scan_file_t()]: Could not calculate hash for file: ", filepath);
}
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
search_hash(db_path, hash, filepath);
num_threads--;
}
void scan_process_t(const std::string& filepath_) {
num_threads++;
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]);
if (search_hash(db_path, hash, filepath) == 1) {
//check if need to kill process
if (get_setting("virus_ctrl:virus_process_found:kill") == 1) {
//kill the process
kill_process(filepath.c_str());
log(LOGLEVEL::VIRUS, "[scan_process_t()]: Killing process: ", filepath);
}
}
num_threads--;
}
#endif

View File

@@ -9,6 +9,11 @@
#include "virus_ctrl.h"
#include "scan.h"
#include "settings.h"
#include <mutex> // Include the mutex header
// Define a mutex for thread synchronization
std::mutex monitorMutex;
bool is_directory(const std::string& path) {
DWORD attributes = GetFileAttributes(path.c_str());
@@ -19,24 +24,25 @@ bool is_directory(const std::string& path) {
return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
void process_changes(const FILE_NOTIFY_INFORMATION* pInfo) {
// Allocate a buffer for the file name and copy the content
std::wstring fileName(pInfo->FileName, pInfo->FileNameLength / sizeof(wchar_t));
//convert wstring to string
// Convert wstring to string
std::string filename_str(fileName.begin(), fileName.end());
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);
if (!is_folder_included(filename_str.c_str()) or is_directory(filename_str) or is_folder_excluded(filename_str.c_str())) {
//dont scan excluded files or folders
return;
if (!is_folder_included(filename_str.c_str()) || is_directory(filename_str) || is_folder_excluded(filename_str.c_str())) {
// Don't scan excluded files or folders
return;
}
else {
std::thread scan_thread(scan_file_t, filename_str);
scan_thread.detach();
}
//log(LOGLEVEL::INFO, "[process_changes()]: File change: ", filename_str.c_str(), " while monitoring directory for changes");
}
void monitor_directory(LPCSTR directory) {
@@ -71,7 +77,6 @@ void monitor_directory(LPCSTR directory) {
buffer,
bufferSize,
TRUE,
//FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_FILE_NAME,
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
NULL,
&overlapped,
@@ -111,7 +116,7 @@ void monitor_directory(LPCSTR directory) {
buffer,
bufferSize,
TRUE,
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_FILE_NAME,
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE |FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_SIZE,
NULL,
&overlapped,
NULL) == 0) {
@@ -136,9 +141,12 @@ void monitor_directory(LPCSTR directory) {
}
void folder_scanner() {
//we are in a completely seperate thread then the main thread; unlimited resources wuhuii
//start the watch dir function used to monitor the dir for new files
// Lock access to the monitor function
std::lock_guard<std::mutex> lock(monitorMutex);
// We are in a completely separate thread than the main thread; unlimited resources wuhuii
// Start the watch dir function used to monitor the dir for new files
monitor_directory("C:\\");
}
#endif // !CHECK_DIR_CPP
#endif // !CHECK_DIR_CPP

View File

@@ -5,6 +5,9 @@
#include "app_ctrl.h"
#include "settings.h"
#include "scan.h"
#include <mutex> // Include the mutex header
std::mutex mtx; // Declare a mutex for thread synchronization
void monitor_processes() {
static DWORD previousProcessIds[1024] = { 0 }; // Previous snapshot of process IDs
@@ -17,55 +20,55 @@ void monitor_processes() {
DWORD numProcesses = bytesReturned / sizeof(DWORD);
// Check for new processes
//log(LOGLEVEL::INFO_NOSEND, "[monitor_processes()]: Checking for new processes; having ",numProcesses, " currently running");
for (DWORD i = 0; i < numProcesses; ++i) {
DWORD processId = processIds[i];
BOOL isNewProcess = TRUE;
// Check if the process is new
for (DWORD j = 0; j < 1024; ++j) {
if (processId == previousProcessIds[j]) {
isNewProcess = FALSE;
break;
{
std::lock_guard<std::mutex> guard(mtx); // Lock the mutex
for (DWORD j = 0; j < 1024; ++j) {
if (processId == previousProcessIds[j]) {
isNewProcess = FALSE;
break;
}
}
}
} // Unlock the mutex automatically when 'guard' goes out of scope
// If the process is new, get its executable path and print it
if (isNewProcess) {
// Open the process
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
if (hProcess != NULL) {
// Get the full path of the executable
TCHAR exePath[500];
char path[500+1];
if (GetModuleFileNameEx(hProcess, NULL, exePath, 500) > 0) {
// Print the full path of the executable
strcpy_s(path, 500, exePath);
//convert to lower case
for(int z=0;z<strlen(path);z++)
TCHAR exePath[MAX_PATH];
char path[MAX_PATH];
if (GetModuleFileNameEx(hProcess, NULL, exePath, MAX_PATH) > 0) {
strcpy_s(path, MAX_PATH, exePath);
for (int z = 0; z < strlen(path); z++)
path[z] = tolower(path[z]);
//scan the file
if (!is_folder_included(path) or is_folder_excluded(path)) {
//dont scan excluded files or folders
}
if (!is_folder_included(path) || is_folder_excluded(path)) {
// Don't scan excluded files or folders
}
else {
//log(LOGLEVEL::INFO, "[monitor_processes()]: New Process to scan: ", path, " while monitoring processes");
std::thread scan_thread(scan_process_t, path);
scan_thread.detach();
}
std::thread scan_thread(scan_process_t, path);
scan_thread.detach();
}
}
// Close the process handle
CloseHandle(hProcess);
}
}
}
// Update the previous snapshot of process IDs
memcpy(previousProcessIds, processIds, sizeof(DWORD) * 1024);
{
std::lock_guard<std::mutex> guard(mtx); // Lock the mutex
memcpy(previousProcessIds, processIds, sizeof(DWORD) * 1024);
} // Unlock the mutex automatically when 'guard' goes out of scope
}
else {
log(LOGLEVEL::ERR, "[monitor_processes()]: Error enumerating processes");
}
log(LOGLEVEL::ERR, "[monitor_processes()]: Error enumerating processes");
}
}
void process_scanner() {
//we are in a thread so we can do this, unlimited resources wuhuiii

View File

@@ -1 +0,0 @@
C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\2022\COMMUNITY\TEAM TOOLS\STATIC ANALYSIS TOOLS\\RULE SETS\NATIVERECOMMENDEDRULES.RULESET

View File

@@ -1,66 +1,3 @@
 Quellen werden auf Modulabhängigkeiten überprüft...
app_ctrl.h
Kompilieren...
app_ctrl.h
app_ctrl.cpp
check_dir.cpp
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(4537,18): warning C4244: "=": Konvertierung von "wchar_t" in "char", möglicher Datenverlust
(Quelldatei „check_dir.cpp“ wird kompiliert)
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xutility(4537,18):
der Vorlageninstanziierungskontext (der älteste zuerst) ist
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\check_dir.cpp(27,29):
Siehe Verweis auf die gerade kompilierte Instanziierung "std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string<std::_String_iterator<std::_String_val<std::_Simple_types<_Elem>>>,0>(_Iter,_Iter,const _Alloc &)" der Funktions-Vorlage.
with
[
_Elem=wchar_t,
_Iter=std::_String_iterator<std::_String_val<std::_Simple_types<wchar_t>>>,
_Alloc=std::allocator<char>
]
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\check_dir.cpp(27,29):
Ersten Verweis auf "std::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string" in "process_changes" anzeigen
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xstring(2600,17):
Siehe Verweis auf die gerade kompilierte Instanziierung "void std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Construct_from_iter<wchar_t*,wchar_t*,_Size_type>(_Iter,const _Sent,_Size)" der Funktions-Vorlage.
with
[
_Size_type=unsigned __int64,
_Iter=wchar_t *,
_Sent=wchar_t *,
_Size=unsigned __int64
]
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\xstring(2756,18):
Siehe Verweis auf die gerade kompilierte Instanziierung "_OutIt *std::_Copy_n_unchecked4<wchar_t*,_Size,char*>(_InIt,_SizeTy,_OutIt)" der Funktions-Vorlage.
with
[
_OutIt=char *,
_Size=unsigned __int64,
_InIt=wchar_t *,
_SizeTy=unsigned __int64
]
check_process.cpp
client_backend.cpp
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend.cpp(112,24): warning C4244: "Argument": Konvertierung von "_Rep" in "DWORD", möglicher Datenverlust
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend.cpp(112,24): warning C4244: with
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend.cpp(112,24): warning C4244: [
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend.cpp(112,24): warning C4244: _Rep=__int64
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend.cpp(112,24): warning C4244: ]
connect.cpp
local_com.cpp
local_schedule.cpp
log.cpp
md5hash.cpp
permissions.cpp
queue _ctrl.cpp
scan.cpp
security.cpp
settings.cpp
thread_ctrl.cpp
update.cpp
virus_ctrl.cpp
Code Analysis für C/C++ wird ausgeführt...
Code wird generiert...
client_backend.vcxproj -> C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\check_dir.cpp(89): warning C6387: "overlapped.hEvent" könnte "0" sein: dies entspricht nicht der Spezifikation für Funktion "WaitForSingleObject".
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\check_dir.cpp(105): warning C6387: "overlapped.hEvent" könnte "0" sein: dies entspricht nicht der Spezifikation für Funktion "ResetEvent". In Zeile 89 finden Sie einen früheren Ort, an dem dies vorkommen kann.
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\check_dir.cpp(134): warning C6387: "overlapped.hEvent" könnte "0" sein: dies entspricht nicht der Spezifikation für Funktion "CloseHandle".
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\connect.cpp(118): warning C6031: Rückgabewert wird ignoriert: "fscanf".

View File

@@ -1,4 +1,2 @@
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\libcrypto-3-x64.dll
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend\x64\Debug\client_b.C1767528.Up2Date
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe.lastcodeanalysissucceeded
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\client_backend\x64\Debug\NativeCodeAnalysis.read.1.tlog

View File

@@ -148,7 +148,9 @@ int check_for_sched_tasks(const char* sched_name, const char* sched_path) {
localtime_s(&current_time, &t);
//printf("%s\n", datetime);
//log(LOGLEVEL::INFO, "[check_for_sched_tasks()]: Checking task: ", taskname, " with schedule: ", datetime);
if (strcmp(datetime, "") != 0 && strcmp(command, "") != 0 && strcmp(taskname, "") != 0) {
//log(LOGLEVEL::INFO, "[check_for_sched_tasks()]: Checking task: ", taskname, " with schedule: ", datetime);
if (is_task_due(taskname, datetime, current_time)) {
//printf("command:%s\n", command);
//printf("path:%s\n", path);

View File

@@ -1,80 +1,80 @@
#pragma warning(disable:4996)
#include "md5hash.h"
#include "log.h"
int md5_file( const char*path, char*md5Hash) {
std::ifstream file(path, std::ios::binary);
#include <mutex> // Include the mutex header
#include <fstream> // Include the fstream header
// Define a mutex for thread synchronization
std::mutex fileMutex_hash;
int md5_file(const char* path, char* md5Hash) {
std::ifstream file(path, std::ios::binary);
if (!file) {
//this creates way to many logs
//log(LOGLEVEL::ERR, "[md5_file()]: Could not open file for scanning ",path);
// Log the error if needed (uncomment if required)
// log(LOGLEVEL::ERR, "[md5_file()]: Could not open file for scanning ", path);
return 1;
}
// Initialize OpenSSL's MD5 context
MD5_CTX md5Context;
MD5_CTX md5Context;
MD5_Init(&md5Context);
// Read and update the context with the file's content
char buffer[1024];
char buffer[1024];
while (file.good()) {
file.read(buffer, sizeof(buffer));
MD5_Update(&md5Context, buffer, file.gcount());
}
// Finalize the MD5 hash and store it in result
unsigned char result[MD5_DIGEST_LENGTH];
unsigned char result[MD5_DIGEST_LENGTH];
MD5_Final(result, &md5Context);
// Close the file
file.close();
// Store the MD5 hash in a char array
//char md5Hash[2 * MD5_DIGEST_LENGTH + 1]; // +1 for null-terminator
for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
snprintf(&md5Hash[i * 2], 3, "%02x", result[i]);
}
return 0;
}
//thread save implementation
std::string md5_file_t(const std::string& path_) {
//log(LOGLEVEL::INFO, "[md5_file_t()]: Calculating MD5 hash of file ", path_);
thread_local std::string path (path_);
thread_local FILE* fp = fopen(path.c_str(), "rb");
std::string path(path_);
FILE* fp = fopen(path.c_str(), "rb");
if (!fp) {
//this creates way to many logs
//log(LOGLEVEL::WARN, "[md5_file_t()]: Could not open file for scanning ", path.c_str());
return path; //we return the path because else it moight crash ()if we sen da nullptr
// Log the error if needed (uncomment if required)
// log(LOGLEVEL::WARN, "[md5_file_t()]: Could not open file for scanning ", path.c_str());
return path; // Return the path because otherwise, it might crash (if we send a nullptr)
}
// Lock access to the file
std::lock_guard<std::mutex> lock(fileMutex_hash);
// Initialize OpenSSL's MD5 context
thread_local MD5_CTX md5Context;
MD5_CTX md5Context;
MD5_Init(&md5Context);
// Read and update the context with the file's content
thread_local char buffer[1024];
thread_local size_t bytesRead;
char buffer[1024];
size_t bytesRead;
while ((bytesRead = fread(buffer, 1, 1024, fp)) > 0) {
MD5_Update(&md5Context, buffer, bytesRead);
}
// Finalize the MD5 hash and store it in result
thread_local unsigned char result[MD5_DIGEST_LENGTH];
unsigned char result[MD5_DIGEST_LENGTH];
MD5_Final(result, &md5Context);
// Close the file
fclose(fp);
// Convert the MD5 hash to a string using snprintf
thread_local char* md5Hash = (char*)malloc(2 * MD5_DIGEST_LENGTH + 1);
if (!md5Hash) {
return path; // Allocation failure
}
char md5Hash[2 * MD5_DIGEST_LENGTH + 1];
for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {
snprintf(&md5Hash[i * 2], 3, "%02x", result[i]);
}
//log(LOGLEVEL::INFO, "[md5_file_t()]: MD5 hash of file ", path, " is ", md5Hash);
return md5Hash;
}
return std::string(md5Hash);
}

View File

@@ -4,6 +4,8 @@
#include <iostream>
#include <fstream>
#include <string>
#include <mutex>
#include <unordered_map>
int md5_file(const char* path, char* md5Hash);
//char* md5_file_t(const char* path_);
std::string md5_file_t(const std::string& path_);

View File

@@ -3,19 +3,28 @@
#define _WIN32_WINNT 0x0500
#pragma comment(lib, "advapi32.lib")
#include "permissions.h"
#include <mutex> // Include mutex for synchronization
// Mutex for synchronizing file operations
std::mutex fileMutex;
/*
1 create file (as admin)
2 set file as read only (also as admin)
file cannot be deleted or modified by anyone. admin can delete
*/
//mark as readonly
int protect_file(char* path) {
std::lock_guard<std::mutex> lock(fileMutex); // Lock the mutex
return _chmod(path, _S_IREAD);
}
//mark as readwrite
int unprotect_file(char* path) {
return _chmod(path, _S_IWRITE | _S_IREAD);
std::lock_guard<std::mutex> lock(fileMutex); // Lock the mutex
return _chmod(path, _S_IWRITE | _S_IREAD);
}
//deny all access and only grant access to admins
@@ -34,7 +43,7 @@ BOOL create_file_protection(SECURITY_ATTRIBUTES* pSA)
TEXT("(D;OICI;GA;;;AN)") // Deny access to unauthenticated users
//TEXT("(D;OICI;GA;;;AU)") // Deny access to authenticated users do not execute else not even admins have rights anymore :(
TEXT("(A;OICI;GA;;;BA)"); // Allow full control to builtin administrators
TEXT("(A;OICI;GA;;;AA)"); // Allow full control to normal administrators
TEXT("(A;OICI;GA;;;AA)"); // Allow full control to normal administrators
if (NULL == pSA)
@@ -47,4 +56,4 @@ BOOL create_file_protection(SECURITY_ATTRIBUTES* pSA)
NULL);
}
#endif
#endif

View File

@@ -1,3 +1,5 @@
#ifndef SCAN_CPP
#define SCAN_CPP
#include "scan.h"
#include <windows.h>
#include <iostream>
@@ -13,14 +15,21 @@
#include "log.h"
#include "virus_ctrl.h"
#include "app_ctrl.h"
#ifndef SCAN_CPP
#define SCAN_CPP
#include <mutex> // Include the mutex header
// Define mutexes for thread synchronization
std::mutex fileHandlesMutex;
std::mutex mappingHandlesMutex;
std::mutex fileDataMutex;
std::mutex cntMutex;
std::mutex numThreadsMutex;
std::unordered_map<std::string, HANDLE> fileHandles;
std::unordered_map<std::string, HANDLE> mappingHandles;
std::unordered_map<std::string, char*> fileData;
int cnt = 0;
unsigned int num_threads=0;
unsigned int num_threads = 0;
//load all the db files into memory
int initialize(const std::string& folderPath) {
@@ -32,7 +41,7 @@ int initialize(const std::string& folderPath) {
}
// Create the filename based on the naming convention
std::string filename = folderPath +"\\" + firstChar + secondChar + ".jdbf";
std::string filename = folderPath + "\\" + firstChar + secondChar + ".jdbf";
//printf("Loading %s\n", filename.c_str());
// Open the file
@@ -45,7 +54,7 @@ int initialize(const std::string& folderPath) {
// 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);
// log(LOGLEVEL::ERR, "[initialize()]: Error creating database file mapping: ", filename);
CloseHandle(hFile);
return 2;
}
@@ -60,15 +69,23 @@ int initialize(const std::string& folderPath) {
}
// Store the handles in the global maps
fileHandles[filename] = hFile;
mappingHandles[filename] = hMapping;
fileData[filename] = fileDataPtr;
{
std::lock_guard<std::mutex> lock(fileHandlesMutex);
fileHandles[filename] = hFile;
}
{
std::lock_guard<std::mutex> lock(mappingHandlesMutex);
mappingHandles[filename] = hMapping;
}
{
std::lock_guard<std::mutex> lock(fileDataMutex);
fileData[filename] = fileDataPtr;
}
}
}
return 0;
}
// Call this function when you are done using the file mappings
void cleanup() {
for (const auto& entry : fileHandles) {
@@ -78,31 +95,59 @@ void cleanup() {
}
// Clear the global maps
fileHandles.clear();
mappingHandles.clear();
fileData.clear();
{
std::lock_guard<std::mutex> lock(fileHandlesMutex);
fileHandles.clear();
}
{
std::lock_guard<std::mutex> lock(mappingHandlesMutex);
mappingHandles.clear();
}
{
std::lock_guard<std::mutex> lock(fileDataMutex);
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_);
std::string dbname;
std::string hash;
std::string filepath;
{
std::lock_guard<std::mutex> lock(fileHandlesMutex);
dbname = dbname_;
}
{
std::lock_guard<std::mutex> lock(fileDataMutex);
hash = hash_;
}
{
std::lock_guard<std::mutex> lock(mappingHandlesMutex);
filepath = filepath_;
}
thread_local auto fileIter = fileHandles.find(dbname);
if (fileIter == fileHandles.end() and dbname_.find("c:.jdbf") == std::string::npos) {
auto fileIter = fileHandles.find(dbname);
if (fileIter == fileHandles.end() && dbname_.find("c:.jdbf") == std::string::npos) {
log(LOGLEVEL::ERR, "[search_hash()]: File mapping not initialized for ", dbname);
return 2;
}else if (fileIter == fileHandles.end()) {
}
else if (fileIter == fileHandles.end()) {
return 2;
}
// Use fileData for subsequent searches
thread_local DWORD fileSize = GetFileSize(fileHandles[dbname], NULL);
thread_local std::string fileContent(fileData[dbname], fileSize);
DWORD fileSize;
std::string fileContent;
{
std::lock_guard<std::mutex> lock(fileDataMutex);
fileSize = GetFileSize(fileHandles[dbname], NULL);
fileContent = std::string(fileData[dbname], fileSize);
}
// Search for the specific string in the file content
thread_local size_t foundPos = fileContent.find(hash);
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());
@@ -112,6 +157,10 @@ int search_hash(const std::string& dbname_, const std::string& hash_, const std:
}
return 0; // Not found
}
// Rest of the code remains unchanged...
bool file_exists(const std::string& filePath) {
DWORD fileAttributes = GetFileAttributes(filePath.c_str());
@@ -131,7 +180,7 @@ void scan_folder(const std::string& directory) {
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
if (hFind == INVALID_HANDLE_VALUE) {
log(LOGLEVEL::WARN, "[scan_folder()]: Could not open directory: ", search_path.c_str() , " while scanning files inside directory.");
log(LOGLEVEL::WARN, "[scan_folder()]: Could not open directory: ", search_path.c_str(), " while scanning files inside directory.");
return;
}
@@ -147,15 +196,17 @@ void scan_folder(const std::string& directory) {
scan_folder(full_path);
}
else {
//action scanfile_t will start the trheads for scanning the hashes
//action_scanfile_t(full_path.c_str());
//action scanfile_t will start the trheads for scanning the hashes
//action_scanfile_t(full_path.c_str());
//do multithreading here
//do multithreading here
while (num_threads >= std::thread::hardware_concurrency()) {
Sleep(10);
}
Sleep(10);
}
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path, "threads: ",num_threads);
std::thread scan_thread(scan_file_t, full_path);
scan_thread.detach();
//Sleep(1);
cnt++;
if (cnt % 100 == 0) {
@@ -171,13 +222,13 @@ void scan_folder(const std::string& directory) {
//for singlethreaded scans
void action_scanfile(const char*filepath) {
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();
thread_shutdown();
delete[] db_path;
return; //no filepath given or file not accessible
}
@@ -192,20 +243,26 @@ void action_scanfile(const char*filepath) {
delete[] db_path;
thread_shutdown();
}
void action_scanfolder(const char*folderpath) {
thread_init();
void action_scanfolder(const char* folderpath) {
thread_init();
cnt = 0;
thread_local std::string folderpath_ (folderpath);
scan_folder(folderpath_);
thread_shutdown();
thread_local std::string folderpath_(folderpath);
scan_folder(folderpath_);
thread_shutdown();
}
void scan_file_t(const std::string& filepath_) {
num_threads++;
thread_local const std::string filepath (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());
thread_local std::string hash_(md5_file_t(filepath));
if (strlen(hash_.c_str()) < 290)
strcpy_s(hash, 295, hash_.c_str());
else{
strcpy_s(hash, 295, "");
log(LOGLEVEL::ERR_NOSEND, "[scan_file_t()]: Could not calculate hash for file: ", filepath);
}
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
search_hash(db_path, hash, filepath);
num_threads--;

View File

@@ -1,68 +1,72 @@
#include "security.h"
#include <mutex> // Include the mutex header
int check_cert(const char*cert,const char*secrets_path) {
FILE* fp;
if (fopen_s(&fp, secrets_path, "r") != 0) {
return 1;
}
else {
char*secrets = new char[505];
while (!feof(fp)) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
if (strcmp("cert", secrets) == 0) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
if (strcmp(cert, secrets) == 0) {
fclose(fp);
delete[] secrets;
return 0;
}
}
}
fclose(fp);
delete[] secrets;
return 2;
}
fclose(fp);
std::mutex fileMutex_sec; // Mutex to synchronize file access
int check_cert(const char* cert, const char* secrets_path) {
FILE* fp;
if (fopen_s(&fp, secrets_path, "r") != 0) {
return 1;
}
else {
char secrets[505]; // Allocate memory on the stack
std::lock_guard<std::mutex> lock(fileMutex_sec); // Lock file access
while (!feof(fp)) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
if (strcmp("cert", secrets) == 0) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
if (strcmp(cert, secrets) == 0) {
fclose(fp);
return 0;
}
}
}
fclose(fp);
return 2;
}
}
char* get_apikey(const char* secrets_path) {
FILE* fp;
if (fopen_s(&fp, secrets_path, "r") != 0) {
return 0;
}
else {
char*secrets = new char[505];
while (!feof(fp)) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
if (strcmp("apikey", secrets) == 0) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
fclose(fp);
return secrets;
}
}
fclose(fp);
delete[] secrets;
return 0;
}
fclose(fp);
FILE* fp;
if (fopen_s(&fp, secrets_path, "r") != 0) {
return nullptr;
}
else {
char secrets[505]; // Allocate memory on the stack
std::lock_guard<std::mutex> lock(fileMutex_sec); // Lock file access
while (!feof(fp)) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
if (strcmp("apikey", secrets) == 0) {
fscanf_s(fp, "%s", secrets, 500); // get the secret
fclose(fp);
return secrets; // Return a dynamically allocated copy
}
}
fclose(fp);
return nullptr;
}
}
char* get_machineid(const char* secrets_path) {
FILE* fp;
if (fopen_s(&fp, secrets_path, "r") != 0) {
return nullptr;
}
else {
char secrets[300]; // Allocate memory on the stack
std::lock_guard<std::mutex> lock(fileMutex_sec); // Lock file access
while (!feof(fp)) {
fscanf_s(fp, "%s", secrets, 295); // get the secret
if (strcmp("machineid", secrets) == 0) {
fscanf_s(fp, "%s", secrets, 295); // get the secret
fclose(fp);
return secrets; // Return a dynamically allocated copy
}
}
fclose(fp);
return nullptr;
}
}
char* get_machineid(const char*secrets_path){
FILE* fp;
if (fopen_s(&fp, secrets_path, "r") != 0) {
return 0;
}
else {
char* secrets = new char[300];
while (!feof(fp)) {
fscanf_s(fp, "%s", secrets, 295); // get the secret
if (strcmp("machineid", secrets) == 0) {
fscanf_s(fp, "%s", secrets, 295); // get the secret
fclose(fp);
return secrets;
}
}
fclose(fp);
delete[] secrets;
return 0;
}
fclose(fp);
}

View File

@@ -3,248 +3,257 @@
#include "settings.h"
#include "well_known.h"
#include "log.h"
#include <mutex> // Include the mutex header
// Define mutexes for thread synchronization
std::mutex settingsMutex;
std::mutex logMutex;
int setting_virus_ctrl_virus_found_action = 0;
char*setting_server_server_url = new char[300];
char exluded_folders[100][300];
char* setting_server_server_url = new char[300];
char excluded_folders[100][300];
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_process_scan_status = 1; //0=off, 1=on
bool setting_virus_ctrl_virus_process_found_kill = 1; //0=do not kill, 1=kill
bool setting_communication_unsafe_tls = 0; //0=do not allow communication via unsfae, slef signed certs, 1=allwo communication via unsafe, self signed certs
bool setting_communication_unsafe_tls = 0; //0=do not allow communication via unsafe, self-signed certs, 1=allow communication via unsafe, self-signed certs
int srv_log_timeout = 0;
int log_timeout_reset = 0;
void load_included_folders();
void load_excluded_folders();
int load_settings() {
FILE* fp;
FILE* fp;
if (fopen_s(&fp, SETTINGS_DB, "r")!=0) {
log(LOGLEVEL::ERR, "[load_settings()]: Could not open settings file. ", SETTINGS_DB);
strcpy_s(setting_server_server_url, 295, "nan");
return 1;
}
else {
char*settings_cmd=new char[505];
char*settings_arg=new char[300];
fscanf_s(fp, "%s", settings_cmd, 500); //the cert is always the firs tline
while (!feof(fp)) {
fscanf_s(fp, "%s", settings_cmd, 295); // get the command
//now check which setting it is.
if (strcmp(settings_cmd, "virus_ctrl:virus_found:action") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
if (strcmp(settings_arg, "remove") == 0) {
setting_virus_ctrl_virus_found_action = 1; //1=remove
}
else if (strcmp(settings_arg, "quarantine") == 0) {
setting_virus_ctrl_virus_found_action = 2; //2=quarantine
}
else if (strcmp(settings_arg, "ignore") == 0) {
setting_virus_ctrl_virus_found_action = 3; //3=ignore
}
else if (strcmp(settings_arg, "call_srv") == 0) {
setting_virus_ctrl_virus_found_action = 4; //4=call_srv <= only call the server and tell it, do not remove or quarantine
}
}
else if (strcmp(settings_cmd, "server:server_url") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
strcpy_s(setting_server_server_url, 295, settings_arg);
}
else if (strcmp(settings_cmd, "rtp_folder_scan:status") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
if (strcmp(settings_arg, "true") == 0) {
setting_rtp_folder_scan_status = 1; //1=on
}
else if (strcmp(settings_arg, "false") == 0) {
setting_rtp_folder_scan_status = 0; //0=off
}
}
else if (strcmp(settings_cmd, "rtp_process_scan:status") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
if (strcmp(settings_arg, "true") == 0) {
setting_rtp_process_scan_status = 1; //1=on
}
else if (strcmp(settings_arg, "false") == 0) {
setting_rtp_process_scan_status = 0; //0=off
}
}
else if (strcmp(settings_cmd, "communication:unsafe_tls") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
if (strcmp(settings_arg, "allow") == 0) {
setting_communication_unsafe_tls = 1; //1=on
}
else if (strcmp(settings_arg, "block") == 0) {
setting_communication_unsafe_tls = 0; //0=off
}
}
else if (strcmp(settings_cmd, "virus_ctrl:virus_process_found:kill") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
if (strcmp(settings_arg, "true") == 0) {
setting_virus_ctrl_virus_process_found_kill = 1; //1=on
}
else if (strcmp(settings_arg, "false") == 0) {
setting_virus_ctrl_virus_process_found_kill = 0; //0=off
}
}
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings file operations
}
if (fopen_s(&fp, SETTINGS_DB, "r") != 0) {
log(LOGLEVEL::ERR, "[load_settings()]: Could not open settings file. ", SETTINGS_DB);
strcpy_s(setting_server_server_url, 295, "nan");
return 1;
}
else {
char* settings_cmd = new char[505];
char* settings_arg = new char[300];
fscanf_s(fp, "%s", settings_cmd, 500); //the cert is always the first line
while (!feof(fp)) {
fscanf_s(fp, "%s", settings_cmd, 295); // get the command
//now check which setting it is.
if (strcmp(settings_cmd, "virus_ctrl:virus_found:action") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
if (strcmp(settings_arg, "remove") == 0) {
setting_virus_ctrl_virus_found_action = 1; //1=remove
}
else if (strcmp(settings_arg, "quarantine") == 0) {
setting_virus_ctrl_virus_found_action = 2; //2=quarantine
}
else if (strcmp(settings_arg, "ignore") == 0) {
setting_virus_ctrl_virus_found_action = 3; //3=ignore
}
else if (strcmp(settings_arg, "call_srv") == 0) {
setting_virus_ctrl_virus_found_action = 4; //4=call_srv <= only call the server and tell it, do not remove or quarantine
}
}
else if (strcmp(settings_cmd, "server:server_url") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
strcpy_s(setting_server_server_url, 295, settings_arg);
}
else if (strcmp(settings_cmd, "rtp_folder_scan:status") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
setting_rtp_folder_scan_status = (strcmp(settings_arg, "true") == 0); //1=on, 0=off
}
else if (strcmp(settings_cmd, "rtp_process_scan:status") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
setting_rtp_process_scan_status = (strcmp(settings_arg, "true") == 0); //1=on, 0=off
}
else if (strcmp(settings_cmd, "communication:unsafe_tls") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
setting_communication_unsafe_tls = (strcmp(settings_arg, "allow") == 0); //1=allow, 0=block
}
else if (strcmp(settings_cmd, "virus_ctrl:virus_process_found:kill") == 0) {
fscanf_s(fp, "%s", settings_arg, 295); // get the argument
setting_virus_ctrl_virus_process_found_kill = (strcmp(settings_arg, "true") == 0); //1=kill, 0=do not kill
}
}
delete[] settings_cmd;
delete[] settings_arg;
}
load_included_folders();
load_excluded_folders();
fclose(fp);
return 0;
delete[] settings_cmd;
delete[] settings_arg;
}
load_included_folders();
load_excluded_folders();
fclose(fp);
return 0;
}
//we have two different get_setting functions. One for int and one for char* return values
int get_setting(const char*setting_name) {
if (strcmp(setting_name, "virus_ctrl:virus_found:action") == 0) {
return setting_virus_ctrl_virus_found_action;
}
if (strcmp(setting_name, "virus_ctrl:virus_process_found:kill") == 0) {
return setting_virus_ctrl_virus_process_found_kill;
}
else if (strcmp(setting_name, "rtp_folder_scan:status") == 0) {
return setting_rtp_folder_scan_status;
}
else if (strcmp(setting_name, "rtp_process_scan:status") == 0) {
return setting_rtp_process_scan_status;
}
else if (strcmp(setting_name, "communication:unsafe_tls") == 0) {
return setting_communication_unsafe_tls;
}
// We have two different get_setting functions. One for int and one for char* return values
int get_setting(const char* setting_name) {
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
return -1;
if (strcmp(setting_name, "virus_ctrl:virus_found:action") == 0) {
return setting_virus_ctrl_virus_found_action;
}
if (strcmp(setting_name, "virus_ctrl:virus_process_found:kill") == 0) {
return setting_virus_ctrl_virus_process_found_kill;
}
else if (strcmp(setting_name, "rtp_folder_scan:status") == 0) {
return setting_rtp_folder_scan_status;
}
else if (strcmp(setting_name, "rtp_process_scan:status") == 0) {
return setting_rtp_process_scan_status;
}
else if (strcmp(setting_name, "communication:unsafe_tls") == 0) {
return setting_communication_unsafe_tls;
}
return -1;
}
int get_setting(const char* setting_name,char*out) {
if (strcmp(setting_name, "server:server_url") == 0) {
strcpy_s(out, 295, setting_server_server_url);
return 0;
}
return -1;
int get_setting(const char* setting_name, char* out) {
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
if (strcmp(setting_name, "server:server_url") == 0) {
strcpy_s(out, 295, setting_server_server_url);
return 0;
}
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[505];
fscanf_s(fp, "%s", path, 500); //the cert is always the firs tline
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;
}
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[505];
fscanf_s(fp, "%s", path, 500); //the cert is always the first line
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.");
}
}
}
fclose(fp);
delete[] path;
}
}
void load_excluded_folders() {
FILE* fp;
if (fopen_s(&fp, EXCLUDED_FOLDERS, "r") != 0) {
log(LOGLEVEL::ERR, "[load_excluded_folders()]: Could not open excluded folders file. ", EXCLUDED_FOLDERS);
return;
}
else {
char* path = new char[505];
fscanf_s(fp, "%s", path,500); //the cert is always the firs tline
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 (excluded_folders_size < 95) {
strcpy_s(exluded_folders[excluded_folders_size], 295, path);
excluded_folders_size++;
}
else {
log(LOGLEVEL::ERR, "[load_excluded_folders()]: Excluded 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;
}
FILE* fp;
if (fopen_s(&fp, EXCLUDED_FOLDERS, "r") != 0) {
log(LOGLEVEL::ERR, "[load_excluded_folders()]: Could not open excluded folders file. ", EXCLUDED_FOLDERS);
return;
}
else {
char* path = new char[505];
fscanf_s(fp, "%s", path, 500); //the cert is always the first line
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 (excluded_folders_size < 95) {
strcpy_s(excluded_folders[excluded_folders_size], 295, path);
excluded_folders_size++;
}
else {
log(LOGLEVEL::ERR, "[load_excluded_folders()]: Excluded folders array is full. Cannot add more folders.");
}
}
}
fclose(fp);
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_included(const char* path) {
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
for (int i = 0; i < included_folders_size; i++) {
if (strstr(path, included_folders[i]) != 0 && strcmp(included_folders[i], "") != 0 && strcmp(included_folders[i], " ") != 0) {
return true;
}
}
return false;
}
bool is_folder_excluded(const char* path) {
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) {
return true;
}
}
return false;
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
for (int i = 0; i < excluded_folders_size; i++) {
if (strstr(path, excluded_folders[i]) != 0 && strcmp(excluded_folders[i], "") != 0 && strcmp(excluded_folders[i], " ") != 0) {
return true;
}
}
return false;
}
void print_inclusuions() {
for (int i = 0; i < excluded_folders_size; i++) {
log(LOGLEVEL::INFO, "[print_exclusions()]: Excluded folder: ", exluded_folders[i]);
}
void print_inclusions() {
std::lock_guard<std::mutex> lock(logMutex); // Lock access to log printing
for (int i = 0; i < excluded_folders_size; i++) {
log(LOGLEVEL::INFO, "[print_exclusions()]: Excluded folder: ", excluded_folders[i]);
}
}
int log_timeout_get() {
return srv_log_timeout;
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
return srv_log_timeout;
}
void log_timeout_set(int timeout) {
srv_log_timeout = timeout;
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
srv_log_timeout = timeout;
}
void log_timeout_reset_set(int timeout) {
log_timeout_reset = timeout;
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
log_timeout_reset = timeout;
}
int log_timeout_reset_get() {
return log_timeout_reset;
std::lock_guard<std::mutex> lock(settingsMutex); // Lock access to settings variables
return log_timeout_reset;
}
#endif
#endif

View File

@@ -35,27 +35,32 @@ int start_thread(const char* command) {
char* out2 = new char[100]; //for the command
char* out1 = new char[300]; //for the arguments
split((char*)command,';', (char*)out1, (char*)out2);
log(LOGLEVEL::INFO, "[start_thread()]: starting command: ", out1, " with arguments: ",out2);
//log(LOGLEVEL::INFO, "[start_thread()]: starting command: ", out1, " with arguments: ",out2);
//printf("out1: %s\n", out1);
//printf("out2: %s\n", out2);
//determine what should be executed
if (strcmp(out1, "scanfile") == 0) {
log(LOGLEVEL::INFO, "[start_thread()]: starting scanfile with arguments: ", out2);
//start a new thread with the scanfile function
std::thread t1(action_scanfile, out2);
t1.detach();
}
else if (strcmp(out1, "scanfolder") == 0) {
//start a new thread with the scanfolder function
log(LOGLEVEL::INFO, "[start_thread()]: starting scanfolder with arguments: ", out2);
std::thread t1(action_scanfolder, out2);
//log(LOGLEVEL::INFO, "[start_thread()]: started scanfolder with arguments: ", out2);
t1.detach();
}
else if (strcmp(out1, "update_settings") == 0) {
//start a new thread with the scanfolder function
log(LOGLEVEL::INFO, "[start_thread()]: starting update_settings with arguments: ", out2);
std::thread t1(action_update_settings);
t1.detach();
}
else if (strcmp(out1, "update_db") == 0) {
//start a new thread with the scanfolder function
log(LOGLEVEL::INFO, "[start_thread()]: starting update_db with arguments: ", out2);
std::thread t1(action_update_settings);
t1.detach();
}

View File

@@ -0,0 +1,78 @@
#ifndef THREAD_CTRL_CPP
#define THREAD_CTRL_CPP
#include "thread_ctrl.h"
#include "log.h"
#include "well_known.h"
#include "scan.h"
#include "app_ctrl.h"
#include "update.h"
void split(char* input,const char delimiter, char* out1, char* out2) {
//split a string at the delimiter. the delimiter only occurs once. so the first part is out1 and the second part is out2
int i = 0;
int j = 0;
int k = 0;
while (input[i] != '\0') {
if (input[i] == delimiter) {
out1[j] = '\0';
i++;
while (input[i] != '\0') {
out2[k] = input[i];
i++;
k++;
}
out2[k] = '\0';
return;
}
else {
out1[j] = input[i];
i++;
j++;
}
}
}
int start_thread(const char* command) {
if (can_run_thread()) {
char* out2 = new char[100]; //for the command
char* out1 = new char[300]; //for the arguments
split((char*)command,';', (char*)out1, (char*)out2);
//log(LOGLEVEL::INFO, "[start_thread()]: starting command: ", out1, " with arguments: ",out2);
//printf("out1: %s\n", out1);
//printf("out2: %s\n", out2);
//determine what should be executed
if (strcmp(out1, "scanfile") == 0) {
log(LOGLEVEL::INFO, "[start_thread()]: starting scanfile with arguments: ", out2);
//start a new thread with the scanfile function
std::thread t1(action_scanfile, out2);
t1.detach();
}
else if (strcmp(out1, "scanfolder") == 0) {
//start a new thread with the scanfolder function
log(LOGLEVEL::INFO, "[start_thread()]: starting scanfolder with arguments: ", out2);
std::thread t1(action_scanfolder, out2);
log(LOGLEVEL::INFO, "[start_thread()]: started scanfolder with arguments: ", out2);
t1.detach();
}
else if (strcmp(out1, "update_settings") == 0) {
//start a new thread with the scanfolder function
log(LOGLEVEL::INFO, "[start_thread()]: starting update_settings with arguments: ", out2);
std::thread t1(action_update_settings);
t1.detach();
}
else if (strcmp(out1, "update_db") == 0) {
//start a new thread with the scanfolder function
log(LOGLEVEL::INFO, "[start_thread()]: starting update_db with arguments: ", out2);
std::thread t1(action_update_settings);
t1.detach();
}
while (can_run_thread()) {
//delay a bit, in order to wait until the thread is started
Sleep(10);
}
delete[] out1;
delete[] out2;
}
return 0;
}
#endif

View File

@@ -6,8 +6,12 @@
#include "settings.h"
#include "connect.h"
#include "security.h"
#include <mutex> // Include the mutex header
// Define a mutex for thread synchronization
std::mutex virusCtrlMutex;
int virus_ctrl_store( const char*path, const char*hash, const char*id) {
std::lock_guard<std::mutex> lock(virusCtrlMutex); // Lock the mute
FILE* fp;
char *db_path = new char[300];
strcpy_s(db_path, 295,VIRUS_CTRL_DB);
@@ -25,6 +29,7 @@ int virus_ctrl_store( const char*path, const char*hash, const char*id) {
}
}
int virus_ctrl_process( const char* id) {
std::lock_guard<std::mutex> lock(virusCtrlMutex); // Lock the mute
//take actions based on settings.
//eg delete infected files, quarantine them, etc
Sleep(100); //wait for the file to be written to the disk else the process that createt the file might not be finished yet
@@ -66,7 +71,27 @@ int virus_ctrl_process( const char* id) {
log(LOGLEVEL::ERR, "[virus_ctrl_process()]:Error while removing infected file: ", path," ",hash);
else
log(LOGLEVEL::VIRUS, "[virus_ctrl_process()]:Removed Virus: ", path, " ", hash, "");
break;
//call the server and say him that we have found a virus.
url[0] = '\0';
if (get_setting("server:server_url", url) == 0 or strcmp(url, "nan") == 0) {
strcat_s(url, 1000, "/api/php/virus/notify_virus.php?");
strcat_s(url, 1000, "file=");
strcat_s(url, 1000, url_encode(path));
strcat_s(url, 1000, "&hash=");
strcat_s(url, 1000, hash);
strcat_s(url, 1000, "&action=");
strcat_s(url, 1000, "remove");
strcat_s(url, 1000, "&machine_id=");
strcat_s(url, 1000, get_machineid(SECRETS));
strcat_s(url, 1000, "&apikey=");
strcat_s(url, 1000, get_apikey(SECRETS));
if (connect_to_srv(url, server_response, 100, get_setting("communication:unsafe_tls")) != 0 or strcmp("wrt_ok", server_response) != 0)
log(LOGLEVEL::ERR, "[virus_ctrl_process()]:Error while notifying server about virus: ", path, " ", hash);
}
else {
log(LOGLEVEL::ERR, "[virus_ctrl_process()]:Error while notifying server about virus: ", path, " ", hash);
}
break;
case 2://quarantine
strcpy_s(quarantine_path, 295, QUARANTINE_PATH);
@@ -76,7 +101,27 @@ int virus_ctrl_process( const char* id) {
log(LOGLEVEL::ERR, "[virus_ctrl_process()]:Error while quarantining infected file: ", path," ",hash);
else
log(LOGLEVEL::VIRUS, "[virus_ctrl_process()]:Quarantined Virus: ", path, " ", hash, " to ", quarantine_path);
break;
//call the server and say him that we have found a virus.
url[0] = '\0';
if (get_setting("server:server_url", url) == 0 or strcmp(url, "nan") == 0) {
strcat_s(url, 1000, "/api/php/virus/notify_virus.php?");
strcat_s(url, 1000, "file=");
strcat_s(url, 1000, url_encode(path));
strcat_s(url, 1000, "&hash=");
strcat_s(url, 1000, hash);
strcat_s(url, 1000, "&action=");
strcat_s(url, 1000, "quarantine");
strcat_s(url, 1000, "&machine_id=");
strcat_s(url, 1000, get_machineid(SECRETS));
strcat_s(url, 1000, "&apikey=");
strcat_s(url, 1000, get_apikey(SECRETS));
if (connect_to_srv(url, server_response, 100, get_setting("communication:unsafe_tls")) != 0 or strcmp("wrt_ok", server_response) != 0)
log(LOGLEVEL::ERR, "[virus_ctrl_process()]:Error while notifying server about virus: ", path, " ", hash);
}
else {
log(LOGLEVEL::ERR, "[virus_ctrl_process()]:Error while notifying server about virus: ", path, " ", hash);
}
break;
case 3://ignore
//ignore this file and just continue. but for good measure we should log it

View File

@@ -47,7 +47,7 @@ $filter_query = "&loglevel=$loglevel&logtext=$logtext&machine_id=$machine_id&tim
<h4>View log</h4>
</div>
<div class="card-body" style="overflow-x:auto">
<!-- table with all users => delete button -->
<!-- table with all log entrys => delete button -->
<?php
//include db pw
include "../../../config.php";
@@ -150,6 +150,7 @@ $filter_query = "&loglevel=$loglevel&logtext=$logtext&machine_id=$machine_id&tim
echo '<td><input type="text" class="form-control" name="loglevel" placeholder="' . str_replace("%","",$loglevel) . '"></td>';
echo '<td><input type="text" class="form-control" name="logtext" placeholder="' . str_replace("%","",$logtext) . '"></td>';
echo '<td><input type="text" class="form-control" name="machine_id" placeholder="' . str_replace("%","",$machine_id) . '"></td>';
//echo '<td><input type="text" class="form-control" name="time" placeholder="' . str_replace("%","",$machine_location) . '"></td>';
echo '<td><input type="text" class="form-control" name="time" placeholder="' . str_replace("%","",$time) . '"></td>';
echo '<td><button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#delete_all">Delete log</button></td>';
echo '</form>';
@@ -161,6 +162,7 @@ $filter_query = "&loglevel=$loglevel&logtext=$logtext&machine_id=$machine_id&tim
echo '<td>' . $row["loglevel"] . '</td>';
echo '<td>' . $row["logtext"] . '</td>';
echo '<td>' . $row["machine_id"] . '</td>';
//echo '<td>' . $row["machine_location"] . '</td>';
echo '<td>' . $row["time"] . '</td>';
echo '<td><a href="view_log.php?delete=' . $row["id"] . $filter_query . '&page=' . $current_page . '">delete</a></td>';
echo '</tr>';

View File

@@ -11,6 +11,14 @@ if (!isset($_SESSION['username']) or !isset($_SESSION["login"])) {
$username = $_SESSION['username'];
$perms = $_SESSION["perms"];
$email = $_SESSION["email"];
$machine_id = isset($_GET["machine_id"]) ? $_GET["machine_id"] : "";
$path = isset($_GET["path"]) ? $_GET["path"] : "";
$hash = isset($_GET["hash"]) ? $_GET["hash"] : "";
$action = isset($_GET["action"]) ? $_GET["action"] : "";
$filter_query = "&hash=$hash&path=$path&machine_id=$machine_id&action=$action";
?>
<!DOCTYPE html>
<html lang="en">
@@ -31,89 +39,161 @@ $email = $_SESSION["email"];
</div>
<div class="card-body">
<h4>Current Threads</h4>
<?php
include "../../../config.php";
if(isset($_GET["delete"])){
$entryid=htmlspecialchars($_GET["delete"]);
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "DELETE FROM vir_notify WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $entryid);
// Execute the statement
$stmt->execute();
$stmt->close();
$conn->close();
}
// Create a connection
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
// Check the connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT count(*) AS vir_count FROM vir_notify";
$stmt = $conn->prepare($sql);
// Execute the statement
$stmt->execute();
// Get the result
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$num_of_entrys=$row["vir_count"];
$stmt->close();
$conn->close();
//now list of all the entrys => machineid, file, hash, action taken
// Create a connection
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
// Check the connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$last_id=-1;
//create the table header
echo('<table class="table">');
echo('<thead>');
echo('<tr>');
echo('<th>Entryid</th><th>Machineid</th><th>File</th><th>Hash</th><th>Action Taken</th><th>Delete</th>');
echo('</tr>');
echo('</thead>');
echo('<tbody>');
while($num_of_entrys!=0){
$sql = "SELECT * FROM vir_notify where id > $last_id";
$stmt = $conn->prepare($sql);
// Execute the statement
$stmt->execute();
// Get the result
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$last_id=$row["id"];
$machineid=$row["machine_id"];
$hash=$row["hash"];
$file=$row["path"];
$action=$row["action"];
echo('<tr>');
echo('<td>'.$last_id.'</td>');
echo('<td>'.$machineid.'</td>');
echo('<td>'.$file.'</td>');
echo('<td>'.$hash.'</td>');
echo('<td>'.$action.'</td>');
echo('<td><a href="welcome.php?delete='.$last_id.'">delete</a></td>');
echo('</tr>');
$stmt->close();
$num_of_entrys--;
}
echo('</tbody>');
echo('</table>');
$conn->close();
?>
<!-- table with all log entrys => delete button -->
<?php
//include db pw
include "../../../config.php";
//delete entry if requested and if user has rights to do that
if(isset($_GET["delete"])){
if($perms[3]!=="1"){
echo '<div class="alert alert-danger" role="alert">
You are not allowed to delete log entries. (insufficient permissions)
</div>';
}else{
$id=htmlspecialchars($_GET["delete"]);
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "DELETE FROM vir_notify WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $id);
// Execute the statement
$stmt->execute();
$stmt->close();
$conn->close();
echo '<div class="alert alert-success" role="alert">
Log entry deleted.
</div>';
}
}
if(isset($_GET["delete_all"])){
if($perms[3]!=="1"){
echo '<div class="alert alert-danger" role="alert">
You are not allowed to delete log entries. (insufficient permissions)
</div>';
}else{
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "DELETE FROM vir_notify";
$stmt = $conn->prepare($sql);
// Execute the statement
$stmt->execute();
$stmt->close();
$conn->close();
echo '<div class="alert alert-success" role="alert">
Log deleted.
</div>';
}
}
// Define page size and current page
$page_size = 50;
$current_page = isset($_GET['page']) ? intval($_GET['page']) : 1;
$offset = ($current_page - 1) * $page_size;
// Get total number of log entries based on filters
$conn = new mysqli($DB_SERVERNAME, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT count(*) AS log_count FROM vir_notify WHERE path LIKE ? AND hash LIKE ? AND machine_id LIKE ? AND action LIKE ?";
$stmt = $conn->prepare($sql);
$path = "%" . $path . "%";
$hash = "%" . $hash . "%";
$machine_id = "%" . $machine_id . "%";
$action = "%" . $action . "%";
$stmt->bind_param("ssss", $path, $hash, $machine_id, $action);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
$total_entries = $row["log_count"];
// Calculate total pages
$total_pages = ceil($total_entries / $page_size);
// Query log entries for the current page with filters
$sql = "SELECT * FROM vir_notify WHERE path LIKE ? AND hash LIKE ? AND machine_id LIKE ? AND action LIKE ? ORDER BY id DESC LIMIT ?, ?";
$stmt = $conn->prepare($sql);
$path = "%" . $path . "%";
$hash = "%" . $hash . "%";
$machine_id = "%" . $machine_id . "%";
$action = "%" . $action . "%";
$stmt->bind_param("ssssii", $path, $hash, $machine_id, $action, $offset, $page_size);
$stmt->execute();
$result = $stmt->get_result();
// Display log entries
echo '<table class="table" style="overflow-x:auto">';
echo '<thead>';
echo '<tr>';
echo '<th>Entry id</th><th>Machine id</th><th>File</th><th>Hash</th><th>Action taken</th><th>Delete entry</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
// Display filter options
echo '<tr>';
echo '<form action="welcome.php" method="get">';
echo '<input type="hidden" name="filter_submit" value="true">';
echo '<td><button type="submit" class="btn btn-primary btn-block">Filter</button></td>';
echo '<td><input type="text" class="form-control" name="machine_id" placeholder="' . str_replace("%","",$machine_id) . '"></td>';
echo '<td><input type="text" class="form-control" name="path" placeholder="' . str_replace("%","",$path) . '"></td>';
echo '<td><input type="text" class="form-control" name="hash" placeholder="' . str_replace("%","",$hash) . '"></td>';
//echo '<td><input type="text" class="form-control" name="time" placeholder="' . str_replace("%","",$machine_location) . '"></td>';
echo '<td><input type="text" class="form-control" name="action" placeholder="' . str_replace("%","",$action) . '"></td>';
echo '<td><button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#delete_all">Delete log</button></td>';
echo '</form>';
echo '</tr>';
while($row = $result->fetch_assoc()) {
echo '<tr>';
echo '<td>' . $row["id"] . '</td>';
echo '<td>' . $row["machine_id"] . '</td>';
echo '<td>' . $row["path"] . '</td>';
echo '<td>' . $row["hash"] . '</td>';
//echo '<td>' . $row["machine_location"] . '</td>';
echo '<td>' . $row["action"] . '</td>';
echo '<td><a href="welcome.php?delete=' . $row["id"] . $filter_query . '&page=' . $current_page . '">delete</a></td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
$conn->close();
// Display pagination links with filter query
echo '<nav aria-label="Page navigation">';
echo '<ul class="pagination justify-content-center">';
for ($i = 1; $i <= $total_pages; $i++) {
echo '<li class="page-item ' . ($i == $current_page ? 'active' : '') . '"><a class="page-link" href="welcome.php?page=' . $i . $filter_query . '">' . $i . '</a></li>';
}
echo '</ul>';
echo '</nav>';
?>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="delete_all" tabindex="-1" aria-labelledby="delete_all_label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="delete_all_label">WARNING</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Warning! You are about to delete the entyre System0 log.<br>This cannot be undone.<br>We highly recommend exporting the entyre log, before deleting it.<br>
You will not be able to undo this step. Important security evidence will be lost, if you press the "delete" button!
</div>
<div class="modal-footer">
<button style="width:70%" type="button" class="btn btn-primary" data-bs-dismiss="modal">Cancel</button>
<a style="width:25%" class="btn btn-danger" href="welcome.php?delete_all">Delete log</a>
</div>
</div>
</div>
</body>
</html>