trying to debug app
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -2,6 +2,14 @@
|
|||||||
"Version": 1,
|
"Version": 1,
|
||||||
"WorkspaceRootPath": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\",
|
"WorkspaceRootPath": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\",
|
||||||
"Documents": [
|
"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\\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\\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\\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\\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}"
|
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:scan.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
|
||||||
@@ -15,29 +23,25 @@
|
|||||||
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative: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\\utils.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:utils.h||{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\\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}",
|
"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}"
|
"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\\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\\utils.h||{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}"
|
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:utils.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\\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\\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_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}"
|
"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\\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\\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\\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}"
|
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:connect.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
|
||||||
@@ -54,10 +58,6 @@
|
|||||||
"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}",
|
"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}"
|
"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\\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\\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\\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}"
|
"RelativeMoniker": "D:0:0:{56E65283-AAC9-43F6-9613-72BE8D648AC4}|client_backend.vcxproj|solutionrelative:update.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}"
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"DocumentGroups": [
|
"DocumentGroups": [
|
||||||
{
|
{
|
||||||
"DockedWidth": 200,
|
"DockedWidth": 200,
|
||||||
"SelectedChildIndex": 2,
|
"SelectedChildIndex": 11,
|
||||||
"Children": [
|
"Children": [
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
@@ -118,32 +118,32 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 13,
|
"DocumentIndex": 8,
|
||||||
"Title": "scan.h",
|
"Title": "scan.h",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h",
|
||||||
"RelativeDocumentMoniker": "scan.h",
|
"RelativeDocumentMoniker": "scan.h",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.h",
|
||||||
"RelativeToolTip": "scan.h",
|
"RelativeToolTip": "scan.h",
|
||||||
"ViewState": "AQIAAAkAAAAAAAAAAABRwBMAAAAPAAAA",
|
"ViewState": "AQIAAA0AAAAAAAAAAAAAABUAAAADAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
|
||||||
"WhenOpened": "2024-03-13T06:41:43.701Z"
|
"WhenOpened": "2024-03-13T06:41:43.701Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 0,
|
"DocumentIndex": 2,
|
||||||
"Title": "scan.cpp",
|
"Title": "scan.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp",
|
||||||
"RelativeDocumentMoniker": "scan.cpp",
|
"RelativeDocumentMoniker": "scan.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\scan.cpp",
|
||||||
"RelativeToolTip": "scan.cpp",
|
"RelativeToolTip": "scan.cpp",
|
||||||
"ViewState": "AQIAAMwAAAAAAAAAAAAkwNgAAAA0AAAA",
|
"ViewState": "AQIAAEYBAAAAAAAAAAAawGcBAAAtAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-01-28T20:40:06.248Z",
|
"WhenOpened": "2024-01-28T20:40:06.248Z",
|
||||||
"EditorCaption": ""
|
"EditorCaption": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 9,
|
"DocumentIndex": 10,
|
||||||
"Title": "connect.cpp",
|
"Title": "connect.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.cpp",
|
||||||
"RelativeDocumentMoniker": "connect.cpp",
|
"RelativeDocumentMoniker": "connect.cpp",
|
||||||
@@ -155,31 +155,32 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 4,
|
"DocumentIndex": 1,
|
||||||
"Title": "client_backend.cpp",
|
"Title": "client_backend.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
|
||||||
"RelativeDocumentMoniker": "client_backend.cpp",
|
"RelativeDocumentMoniker": "client_backend.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\client_backend.cpp",
|
||||||
"RelativeToolTip": "client_backend.cpp",
|
"RelativeToolTip": "client_backend.cpp",
|
||||||
"ViewState": "AQIAAEIAAAAAAAAAAAAAAGkAAAAJAAAA",
|
"ViewState": "AQIAADkAAAAAAAAAAAAawEwAAAA4AAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-01-28T20:40:06.279Z"
|
"WhenOpened": "2024-01-28T20:40:06.279Z",
|
||||||
|
"EditorCaption": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 5,
|
"DocumentIndex": 6,
|
||||||
"Title": "thread_ctrl.cpp",
|
"Title": "thread_ctrl.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp",
|
||||||
"RelativeDocumentMoniker": "thread_ctrl.cpp",
|
"RelativeDocumentMoniker": "thread_ctrl.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\thread_ctrl.cpp",
|
||||||
"RelativeToolTip": "thread_ctrl.cpp",
|
"RelativeToolTip": "thread_ctrl.cpp",
|
||||||
"ViewState": "AQIAAAYAAAAAAAAAAAAAADUAAABGAAAA",
|
"ViewState": "AQIAAAAAAAAAAAAAAAAAABwAAAAsAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-03-13T06:52:01.533Z"
|
"WhenOpened": "2024-03-13T06:52:01.533Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 7,
|
"DocumentIndex": 9,
|
||||||
"Title": "local_com.cpp",
|
"Title": "local_com.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_com.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_com.cpp",
|
||||||
"RelativeDocumentMoniker": "local_com.cpp",
|
"RelativeDocumentMoniker": "local_com.cpp",
|
||||||
@@ -191,15 +192,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 8,
|
"DocumentIndex": 5,
|
||||||
"Title": "virus_ctrl.cpp",
|
"Title": "virus_ctrl.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp",
|
||||||
"RelativeDocumentMoniker": "virus_ctrl.cpp",
|
"RelativeDocumentMoniker": "virus_ctrl.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\virus_ctrl.cpp",
|
||||||
"RelativeToolTip": "virus_ctrl.cpp",
|
"RelativeToolTip": "virus_ctrl.cpp",
|
||||||
"ViewState": "AQIAAEsAAAAAAAAAAAAIwHYAAAARAAAA",
|
"ViewState": "AQIAAFQAAAAAAAAAAAAAACoAAAAAAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-02-18T12:49:41.861Z"
|
"WhenOpened": "2024-02-18T12:49:41.861Z",
|
||||||
|
"EditorCaption": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
@@ -215,7 +217,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 12,
|
"DocumentIndex": 13,
|
||||||
"Title": "log.h",
|
"Title": "log.h",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.h",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\log.h",
|
||||||
"RelativeDocumentMoniker": "log.h",
|
"RelativeDocumentMoniker": "log.h",
|
||||||
@@ -239,25 +241,26 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 6,
|
"DocumentIndex": 0,
|
||||||
"Title": "check_dir.cpp",
|
"Title": "check_dir.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp",
|
||||||
"RelativeDocumentMoniker": "check_dir.cpp",
|
"RelativeDocumentMoniker": "check_dir.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_dir.cpp",
|
||||||
"RelativeToolTip": "check_dir.cpp",
|
"RelativeToolTip": "check_dir.cpp",
|
||||||
"ViewState": "AQIAAAAAAAAAAAAAAAAAABUAAAAAAAAA",
|
"ViewState": "AQIAAGIAAAAAAAAAAAAawKUAAAAAAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-03-13T06:48:31.009Z"
|
"WhenOpened": "2024-03-13T06:48:31.009Z",
|
||||||
|
"EditorCaption": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 1,
|
"DocumentIndex": 3,
|
||||||
"Title": "utils.cpp",
|
"Title": "utils.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.cpp",
|
||||||
"RelativeDocumentMoniker": "utils.cpp",
|
"RelativeDocumentMoniker": "utils.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.cpp",
|
||||||
"RelativeToolTip": "utils.cpp",
|
"RelativeToolTip": "utils.cpp",
|
||||||
"ViewState": "AQIAAD8AAAAAAAAAAAAAABgAAAAFAAAA",
|
"ViewState": "AQIAAAAAAAAAAAAAAAAAABkAAAAEAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-03-14T15:55:22.469Z",
|
"WhenOpened": "2024-03-14T15:55:22.469Z",
|
||||||
"EditorCaption": ""
|
"EditorCaption": ""
|
||||||
@@ -324,7 +327,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 10,
|
"DocumentIndex": 11,
|
||||||
"Title": "connect.h",
|
"Title": "connect.h",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.h",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\connect.h",
|
||||||
"RelativeDocumentMoniker": "connect.h",
|
"RelativeDocumentMoniker": "connect.h",
|
||||||
@@ -336,26 +339,26 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 2,
|
"DocumentIndex": 4,
|
||||||
"Title": "check_process.cpp",
|
"Title": "check_process.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp",
|
||||||
"RelativeDocumentMoniker": "check_process.cpp",
|
"RelativeDocumentMoniker": "check_process.cpp",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\check_process.cpp",
|
||||||
"RelativeToolTip": "check_process.cpp",
|
"RelativeToolTip": "check_process.cpp",
|
||||||
"ViewState": "AQIAABIAAAAAAAAAAAAAADgAAABGAAAA",
|
"ViewState": "AQIAABUAAAAAAAAAAAAAADMAAAAaAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|",
|
||||||
"WhenOpened": "2024-03-14T13:35:33.369Z",
|
"WhenOpened": "2024-03-14T13:35:33.369Z",
|
||||||
"EditorCaption": ""
|
"EditorCaption": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 3,
|
"DocumentIndex": 7,
|
||||||
"Title": "utils.h",
|
"Title": "utils.h",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.h",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.h",
|
||||||
"RelativeDocumentMoniker": "utils.h",
|
"RelativeDocumentMoniker": "utils.h",
|
||||||
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.h",
|
"ToolTip": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\utils.h",
|
||||||
"RelativeToolTip": "utils.h",
|
"RelativeToolTip": "utils.h",
|
||||||
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAoAAAAuAAAA",
|
"ViewState": "AQIAAAAAAAAAAAAAAAAAAAsAAAAbAAAA",
|
||||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
|
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|",
|
||||||
"WhenOpened": "2024-03-14T15:55:30.524Z"
|
"WhenOpened": "2024-03-14T15:55:30.524Z"
|
||||||
},
|
},
|
||||||
@@ -373,7 +376,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$type": "Document",
|
"$type": "Document",
|
||||||
"DocumentIndex": 11,
|
"DocumentIndex": 12,
|
||||||
"Title": "local_schedule.cpp",
|
"Title": "local_schedule.cpp",
|
||||||
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_schedule.cpp",
|
"DocumentMoniker": "C:\\Users\\janis\\Documents\\Projekte_mit_c\\ma\\ma\\src\\client_backend\\local_schedule.cpp",
|
||||||
"RelativeDocumentMoniker": "local_schedule.cpp",
|
"RelativeDocumentMoniker": "local_schedule.cpp",
|
||||||
|
|||||||
@@ -45,8 +45,19 @@ void process_changes(const FILE_NOTIFY_INFORMATION* pInfo) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//log(LOGLEVEL::INFO_NOSEND, "[process_changes()]: File ", filename_str, " has been changed. Scanning it for viruses");
|
//log(LOGLEVEL::INFO_NOSEND, "[process_changes()]: File ", filename_str, " has been changed. Scanning it for viruses");
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {//if there is for more than 30 seconds no thread available, chances are high, that the threads did not temrinate correctly but aren t running anymore. so set the counter to 0 because else it might just stop the scan.
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[process_changes()]: Scanning new file: ", filename_str);
|
||||||
std::thread scan_thread(scan_file_t, filename_str);
|
std::thread scan_thread(scan_file_t, filename_str);
|
||||||
scan_thread.detach();
|
scan_thread.detach();
|
||||||
|
Sleep(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +102,11 @@ void monitor_directory(LPCSTR directory) {
|
|||||||
CloseHandle(hDir);
|
CloseHandle(hDir);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (overlapped.hEvent == NULL) {
|
||||||
|
log(LOGLEVEL::ERR, "[monitor_directory()]: Error creating event for directory changes: ", GetLastError(), " while monitoring directory for changes");
|
||||||
|
CloseHandle(hDir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
log(LOGLEVEL::INFO, "[monitor_directory()]: Monitoring directory: ", directory, " for changes");
|
log(LOGLEVEL::INFO, "[monitor_directory()]: Monitoring directory: ", directory, " for changes");
|
||||||
|
|
||||||
// Wait for changes
|
// Wait for changes
|
||||||
@@ -107,8 +122,7 @@ void monitor_directory(LPCSTR directory) {
|
|||||||
do {
|
do {
|
||||||
process_changes(pInfo);
|
process_changes(pInfo);
|
||||||
|
|
||||||
pInfo = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(
|
pInfo = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(reinterpret_cast<BYTE*>(pInfo) + pInfo->NextEntryOffset);
|
||||||
reinterpret_cast<BYTE*>(pInfo) + pInfo->NextEntryOffset);
|
|
||||||
|
|
||||||
} while (pInfo->NextEntryOffset != 0);
|
} while (pInfo->NextEntryOffset != 0);
|
||||||
|
|
||||||
|
|||||||
@@ -49,11 +49,22 @@ void monitor_processes() {
|
|||||||
strcpy_s(path, MAX_PATH, exePath);
|
strcpy_s(path, MAX_PATH, exePath);
|
||||||
for (size_t z = 0; z < strlen(path); z++)
|
for (size_t z = 0; z < strlen(path); z++)
|
||||||
path[z] = tolower(path[z]);
|
path[z] = tolower(path[z]);
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[monitor_processes()]: New process: ", path);
|
||||||
if (is_valid_path(path)) { //filter out invalid paths and paths with weird characters
|
if (is_valid_path(path)) { //filter out invalid paths and paths with weird characters
|
||||||
if (!is_folder_included(path) || is_folder_excluded(path)) {
|
if (!is_folder_included(path) || is_folder_excluded(path)) {
|
||||||
// Don't scan excluded files or folders
|
// Don't scan excluded files or folders
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {//if there is for more than 30 seconds no thread available, chances are high, that the threads did not temrinate correctly but aren t running anymore. so set the counter to 0 because else it might just stop the scan.
|
||||||
|
set_num_threads(0);
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[monitor_processes()]: Resetting thread counter because of timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[monitor_processes()]: Scanning process: ", path);
|
||||||
std::thread scan_thread(scan_process_t, path);
|
std::thread scan_thread(scan_process_t, path);
|
||||||
scan_thread.detach();
|
scan_thread.detach();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
#include "virus_ctrl.h"
|
#include "virus_ctrl.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "check_process.h"
|
#include "check_process.h"
|
||||||
|
#include "utils.h"
|
||||||
int main(int argc, char*argv[]) {
|
int main(int argc, char*argv[]) {
|
||||||
|
|
||||||
//log(LOGLEVEL::INFO, "[main()]:Starting main thread.");
|
//log(LOGLEVEL::INFO, "[main()]:Starting main thread.");
|
||||||
//return 0;
|
//return 0;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,2 +1,37 @@
|
|||||||
Quellen werden auf Modulabhängigkeiten überprüft...
|
Quellen werden auf Modulabhängigkeiten überprüft...
|
||||||
|
check_dir.cpp
|
||||||
|
C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\check_dir.cpp(49,38): warning C4018: ">=": Konflikt zwischen "signed" und "unsigned"
|
||||||
|
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(36,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(36,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
|
||||||
|
]
|
||||||
|
|
||||||
client_backend.vcxproj -> C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe
|
client_backend.vcxproj -> C:\Users\janis\Documents\Projekte_mit_c\ma\ma\src\client_backend\x64\Debug\client_backend.exe
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -8,6 +8,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "md5hash.h"
|
#include "md5hash.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -34,6 +35,15 @@ int cnt = 0;
|
|||||||
int num_threads = 0;
|
int num_threads = 0;
|
||||||
int all_files = 0;
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
//load all the db files into memory
|
//load all the db files into memory
|
||||||
int initialize(const std::string& folderPath) {
|
int initialize(const std::string& folderPath) {
|
||||||
for (char firstChar = '0'; firstChar <= 'f'; ++firstChar) {
|
for (char firstChar = '0'; firstChar <= 'f'; ++firstChar) {
|
||||||
@@ -115,9 +125,9 @@ void cleanup() {
|
|||||||
//the latest and fastest version of searching a hash by now
|
//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_) {
|
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
|
// Check if the file mapping is already open for the given filename
|
||||||
std::string dbname;
|
thread_local std::string dbname;
|
||||||
std::string hash;
|
thread_local std::string hash;
|
||||||
std::string filepath;
|
thread_local std::string filepath;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(fileHandlesMutex);
|
std::lock_guard<std::mutex> lock(fileHandlesMutex);
|
||||||
dbname = dbname_;
|
dbname = dbname_;
|
||||||
@@ -161,98 +171,134 @@ int search_hash(const std::string& dbname_, const std::string& hash_, const std:
|
|||||||
return 0; // Not found
|
return 0; // Not found
|
||||||
}
|
}
|
||||||
|
|
||||||
//function to get num of files in idr and its subdirs etc
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
int get_num_files(const std::string& directory) {
|
int get_num_files(const std::string& directory) {
|
||||||
std::string search_path = directory + "\\*.*";
|
std::string search_path = directory + "\\*.*";
|
||||||
WIN32_FIND_DATA find_file_data;
|
WIN32_FIND_DATA find_file_data;
|
||||||
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
int num_files = 0;
|
int num_files = 0;
|
||||||
|
|
||||||
if (hFind == INVALID_HANDLE_VALUE) {
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path.c_str(), " while scanning files inside directory.");
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
return 0;
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
// Stack to store directories to be traversed iteratively
|
||||||
if (strcmp(find_file_data.cFileName, ".") == 0 || strcmp(find_file_data.cFileName, "..") == 0) {
|
std::stack<std::string> directories;
|
||||||
continue; // Skip the current and parent directories
|
directories.push(directory);
|
||||||
}
|
|
||||||
|
|
||||||
const std::string full_path = directory + "\\" + find_file_data.cFileName;
|
while (!directories.empty()) {
|
||||||
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
std::string current_dir = directories.top();
|
||||||
// If it's a directory, recurse into it
|
directories.pop();
|
||||||
num_files += get_num_files(full_path);
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
num_files++;
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
}
|
//std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
} while (FindNextFile(hFind, &find_file_data) != 0);
|
}
|
||||||
FindClose(hFind);
|
}
|
||||||
|
|
||||||
return num_files;
|
return num_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
void scan_folder(const std::string& directory) {
|
void scan_folder(const std::string& directory) {
|
||||||
std::string search_path = directory + "\\*.*";
|
directories.push(directory);
|
||||||
WIN32_FIND_DATA find_file_data;
|
|
||||||
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
|
||||||
|
|
||||||
if (hFind == INVALID_HANDLE_VALUE) {
|
while (!directories.empty()) {
|
||||||
log(LOGLEVEL::WARN, "[scan_folder()]: Could not open directory: ", search_path.c_str(), " while scanning files inside directory.");
|
std::string current_dir = directories.top();
|
||||||
return;
|
directories.pop();
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
std::string search_path = current_dir + "\\*.*";
|
||||||
if (strcmp(find_file_data.cFileName, ".") == 0 || strcmp(find_file_data.cFileName, "..") == 0) {
|
WIN32_FIND_DATA find_file_data;
|
||||||
continue; // Skip the current and parent directories
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
}
|
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
const std::string full_path = directory + "\\" + find_file_data.cFileName;
|
do {
|
||||||
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
if (strcmp(find_file_data.cFileName, ".") == 0 || strcmp(find_file_data.cFileName, "..") == 0) {
|
||||||
// If it's a directory, recurse into it
|
continue; // Skip the current and parent directories
|
||||||
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
|
|
||||||
int thread_timeout = 0;
|
|
||||||
while (num_threads >= std::thread::hardware_concurrency()) {
|
|
||||||
Sleep(10);
|
|
||||||
thread_timeout++;
|
|
||||||
if (thread_timeout == 100 * 60) {//if there is for more than 30 seconds no thread available, chances are high, that the threads did not temrinate correctly but aren t running anymore. so set the counter to 0 because else it might just stop the scan.
|
|
||||||
num_threads = 0;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (is_valid_path(full_path)) { //filter out invalid paths and paths with weird characters
|
const std::string full_path = current_dir + "\\" + find_file_data.cFileName;
|
||||||
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
if (fileSize > 4000000000) {//4gb
|
// If it's a directory, add it to the stack
|
||||||
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
directories.push(full_path);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::thread scan_thread(scan_file_t, full_path);
|
// Do multithreading here
|
||||||
scan_thread.detach();
|
int thread_timeout = 0;
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path);
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
//printf("Thread timeout: %d\n", thread_timeout);
|
||||||
|
if (thread_timeout == 100 * 20) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path);
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
if (cnt % 100 == 0) {
|
||||||
|
printf("Processed %d files;\n", cnt);
|
||||||
|
//printf("Number of threads: %d\n", num_threads);
|
||||||
|
}
|
||||||
|
if (cnt % 1000 == 0) {
|
||||||
|
int actual_threads = get_num_threads();
|
||||||
|
if(get_num_threads()>actual_threads)
|
||||||
|
set_num_threads(actual_threads);//correct value of threads minus the main and the rtp thread
|
||||||
|
printf("Number of threads: %d\n", get_num_threads());
|
||||||
|
//send progress to com file
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "progress " << (cnt * 100 / (all_files + 1)) << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}else
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
FindClose(hFind);
|
||||||
cnt++;
|
|
||||||
if (cnt % 100 == 0) {
|
|
||||||
printf("Processed %d files;\n", cnt);
|
|
||||||
//printf("Number of threads: %d\n", num_threads);
|
|
||||||
}
|
|
||||||
if (cnt % 1000 == 0) {
|
|
||||||
//send progress to com file
|
|
||||||
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
|
||||||
if (answer_com.is_open()) {
|
|
||||||
answer_com << "progress " << (cnt*100/(all_files+1)) << "\n";
|
|
||||||
answer_com.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (FindNextFile(hFind, &find_file_data) != 0);
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[scan_folder()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
FindClose(hFind);
|
//std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -307,7 +353,7 @@ void action_scanfolder(const std::string& folderpath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void scan_file_t(const std::string& filepath_) {
|
void scan_file_t(const std::string& filepath_) {
|
||||||
num_threads++;
|
set_num_threads(get_num_threads() + 1);
|
||||||
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* db_path = new char[300];
|
||||||
thread_local char* hash = new char[300];
|
thread_local char* hash = new char[300];
|
||||||
@@ -320,9 +366,10 @@ void scan_file_t(const std::string& filepath_) {
|
|||||||
}
|
}
|
||||||
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
|
sprintf_s(db_path, 295, "%s\\%c%c.jdbf", DB_DIR, hash[0], hash[1]);
|
||||||
search_hash(db_path, hash, filepath);
|
search_hash(db_path, hash, filepath);
|
||||||
num_threads--;
|
set_num_threads(get_num_threads() - 1);
|
||||||
}
|
}
|
||||||
void scan_process_t(const std::string& filepath_) {
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
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* db_path = new char[300];
|
||||||
thread_local char* hash = new char[300];
|
thread_local char* hash = new char[300];
|
||||||
@@ -336,5 +383,6 @@ void scan_process_t(const std::string& filepath_) {
|
|||||||
log(LOGLEVEL::VIRUS, "[scan_process_t()]: Killing process: ", filepath);
|
log(LOGLEVEL::VIRUS, "[scan_process_t()]: Killing process: ", filepath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
388
src/client_backend/scan.cpp~RF2b9c1f.TMP
Normal file
388
src/client_backend/scan.cpp~RF2b9c1f.TMP
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path);
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
//printf("Thread timeout: %d\n", thread_timeout);
|
||||||
|
if (thread_timeout == 100 * 20) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path);
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
if (cnt % 100 == 0) {
|
||||||
|
printf("Processed %d files;\n", cnt);
|
||||||
|
//printf("Number of threads: %d\n", num_threads);
|
||||||
|
}
|
||||||
|
if (cnt % 1000 == 0) {
|
||||||
|
int actual_threads = get_num_threads();
|
||||||
|
if(get_num_threads()>actual_threads)
|
||||||
|
set_num_threads(actual_threads);//correct value of threads minus the main and the rtp thread
|
||||||
|
printf("Number of threads: %d\n", get_num_threads());
|
||||||
|
//send progress to com file
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "progress " << (cnt * 100 / (all_files + 1)) << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[scan_folder()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
366
src/client_backend/scan.cpp~RF469c204.TMP
Normal file
366
src/client_backend/scan.cpp~RF469c204.TMP
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
0
src/client_backend/scan.cpp~RF469e80a.TMP
Normal file
0
src/client_backend/scan.cpp~RF469e80a.TMP
Normal file
367
src/client_backend/scan.cpp~RF469e81a.TMP
Normal file
367
src/client_backend/scan.cpp~RF469e81a.TMP
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
368
src/client_backend/scan.cpp~RF46a5887.TMP
Normal file
368
src/client_backend/scan.cpp~RF46a5887.TMP
Normal file
@@ -0,0 +1,368 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
369
src/client_backend/scan.cpp~RF4708bfe.TMP
Normal file
369
src/client_backend/scan.cpp~RF4708bfe.TMP
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[scan_folder()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
382
src/client_backend/scan.cpp~RF4748023.TMP
Normal file
382
src/client_backend/scan.cpp~RF4748023.TMP
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path);
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
if (cnt % 100 == 0) {
|
||||||
|
printf("Processed %d files;\n", cnt);
|
||||||
|
//printf("Number of threads: %d\n", num_threads);
|
||||||
|
}
|
||||||
|
if (cnt % 1000 == 0) {
|
||||||
|
//send progress to com file
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "progress " << (cnt * 100 / (all_files + 1)) << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[scan_folder()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
384
src/client_backend/scan.cpp~RF4948855.TMP
Normal file
384
src/client_backend/scan.cpp~RF4948855.TMP
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
#ifndef SCAN_CPP
|
||||||
|
#define SCAN_CPP
|
||||||
|
#include "scan.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <stack>
|
||||||
|
#include <time.h>
|
||||||
|
#include "md5hash.h"
|
||||||
|
#include <string>
|
||||||
|
#include "well_known.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "virus_ctrl.h"
|
||||||
|
#include "app_ctrl.h"
|
||||||
|
#include <mutex> // Include the mutex header
|
||||||
|
#include <filesystem>
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int num_threads = 0;
|
||||||
|
int all_files = 0;
|
||||||
|
|
||||||
|
int get_num_threads() {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
return num_threads;
|
||||||
|
}
|
||||||
|
int set_num_threads(int num) {
|
||||||
|
std::lock_guard<std::mutex> lock(numThreadsMutex);
|
||||||
|
num_threads = num;
|
||||||
|
return 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
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
UnmapViewOfFile(fileData[entry.first]);
|
||||||
|
CloseHandle(mappingHandles[entry.first]);
|
||||||
|
CloseHandle(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the global maps
|
||||||
|
{
|
||||||
|
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
|
||||||
|
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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fileData for subsequent searches
|
||||||
|
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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to get num of files in idr and its subdirs etc (iterative)
|
||||||
|
int get_num_files(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);
|
||||||
|
int num_files = 0;
|
||||||
|
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE) {
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << search_path << " while scanning files inside directory." << std::endl;
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", search_path, " while scanning files inside directory.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack to store directories to be traversed iteratively
|
||||||
|
std::stack<std::string> directories;
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
search_path = current_dir + "\\*.*";
|
||||||
|
hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
num_files++;
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[get_num_files()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[get_num_files()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this is the main function to scan folders. it will then start multuiple threads based on the number of cores / settings
|
||||||
|
std::stack<std::string> directories; // Stack to store directories to be scanned
|
||||||
|
|
||||||
|
void scan_folder(const std::string& directory) {
|
||||||
|
directories.push(directory);
|
||||||
|
|
||||||
|
while (!directories.empty()) {
|
||||||
|
std::string current_dir = directories.top();
|
||||||
|
directories.pop();
|
||||||
|
|
||||||
|
std::string search_path = current_dir + "\\*.*";
|
||||||
|
WIN32_FIND_DATA find_file_data;
|
||||||
|
HANDLE hFind = FindFirstFile(search_path.c_str(), &find_file_data);
|
||||||
|
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE) {
|
||||||
|
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 = current_dir + "\\" + find_file_data.cFileName;
|
||||||
|
if (find_file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// If it's a directory, add it to the stack
|
||||||
|
directories.push(full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Do multithreading here
|
||||||
|
int thread_timeout = 0;
|
||||||
|
while (get_num_threads() >= std::thread::hardware_concurrency()) {
|
||||||
|
Sleep(10);
|
||||||
|
thread_timeout++;
|
||||||
|
if (thread_timeout == 100 * 60) {
|
||||||
|
// If there is no available thread for more than 30 seconds, reset the thread counter
|
||||||
|
set_num_threads(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Scanning file: ", full_path);
|
||||||
|
if (is_valid_path(full_path)) { // Filter out invalid paths and paths with weird characters
|
||||||
|
std::uintmax_t fileSize = std::filesystem::file_size(full_path);
|
||||||
|
if (fileSize > 4000000000) { // 4GB
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: File too large to scan: ", full_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::thread scan_thread(scan_file_t, full_path);
|
||||||
|
scan_thread.detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[scan_folder()]: Invalid path: ", full_path);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
if (cnt % 100 == 0) {
|
||||||
|
printf("Processed %d files;\n", cnt);
|
||||||
|
//printf("Number of threads: %d\n", num_threads);
|
||||||
|
}
|
||||||
|
if (cnt % 1000 == 0) {
|
||||||
|
set_num_threads(get_num_running_threads()-1-1);//correct value of threads minus the main and the rtp thread
|
||||||
|
printf("Number of threads: %d\n", num_threads);
|
||||||
|
//send progress to com file
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "progress " << (cnt * 100 / (all_files + 1)) << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (FindNextFile(hFind, &find_file_data) != 0);
|
||||||
|
FindClose(hFind);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log(LOGLEVEL::ERR_NOSEND, "[scan_folder()]: Could not open directory: ", current_dir, " while scanning files inside directory.");
|
||||||
|
//std::cerr << "[scan_folder()]: Could not open directory: " << current_dir << " while scanning files inside directory." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//for singlethreaded scans
|
||||||
|
void action_scanfile(const std::string& filepath_) {
|
||||||
|
thread_init();
|
||||||
|
const std::string filepath(filepath_);
|
||||||
|
char* db_path = new char[300];
|
||||||
|
char* hash = new char[300];
|
||||||
|
if (is_valid_path(filepath_)) { //filter out invalid paths and paths with weird characters
|
||||||
|
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]);
|
||||||
|
if (search_hash(db_path, hash, filepath) != 1) {
|
||||||
|
//notify desktop client by writing to answer_com file
|
||||||
|
//if there is now virus, we notify here. if there is a virus we only notify in the virus_ctrl_process function
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "not_found " << "\"" << filepath_ << "\"" << " " << hash << " " << "no_action_taken" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log(LOGLEVEL::INFO_NOSEND, "[action_scanfile()]: Invalid path: ", filepath_);
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
void action_scanfolder(const std::string& folderpath) {
|
||||||
|
thread_init();
|
||||||
|
thread_local std::string folderpath_(folderpath);
|
||||||
|
cnt = 0;
|
||||||
|
all_files = get_num_files(folderpath_);
|
||||||
|
//tell the desktop client that the scan has started
|
||||||
|
std::ofstream answer_com1(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com1.is_open()) {
|
||||||
|
answer_com1 << "start " << all_files << "\n";
|
||||||
|
answer_com1.close();
|
||||||
|
}
|
||||||
|
scan_folder(folderpath_);
|
||||||
|
std::ofstream answer_com(ANSWER_COM_PATH, std::ios::app);
|
||||||
|
if (answer_com.is_open()) {
|
||||||
|
answer_com << "end " << "\"" << "nothing" << "\"" << " " << "nothing" << " " << "nothing" << "\n";
|
||||||
|
answer_com.close();
|
||||||
|
}
|
||||||
|
thread_shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scan_file_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
void scan_process_t(const std::string& filepath_) {
|
||||||
|
set_num_threads(get_num_threads() + 1);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_num_threads(get_num_threads() - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -17,4 +17,6 @@ void action_scanfolder(const std::string& folderpath);
|
|||||||
void scan_file_t(const std::string& filepath_);
|
void scan_file_t(const std::string& filepath_);
|
||||||
int initialize(const std::string& folderPath);
|
int initialize(const std::string& folderPath);
|
||||||
void scan_process_t(const std::string& filepath_);
|
void scan_process_t(const std::string& filepath_);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
int get_num_threads();
|
||||||
|
int set_num_threads(int num_threads);
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <tlhelp32.h>
|
#include <tlhelp32.h>
|
||||||
|
#include <winternl.h>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
@@ -118,4 +119,30 @@ bool file_exists(const std::string& filePath) {
|
|||||||
|
|
||||||
// Check if it's a regular file and not a directory
|
// Check if it's a regular file and not a directory
|
||||||
return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_num_running_threads() {
|
||||||
|
DWORD runningThreads = 0;
|
||||||
|
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||||
|
|
||||||
|
if (hSnapshot != INVALID_HANDLE_VALUE) {
|
||||||
|
THREADENTRY32 te;
|
||||||
|
te.dwSize = sizeof(THREADENTRY32);
|
||||||
|
|
||||||
|
if (Thread32First(hSnapshot, &te)) {
|
||||||
|
do {
|
||||||
|
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
|
||||||
|
sizeof(te.th32OwnerProcessID)) {
|
||||||
|
if (te.th32OwnerProcessID == GetCurrentProcessId()) {
|
||||||
|
runningThreads++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
te.dwSize = sizeof(THREADENTRY32);
|
||||||
|
} while (Thread32Next(hSnapshot, &te));
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(hSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
return runningThreads;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ void kill_process(const std::string& path);
|
|||||||
void startup(LPCTSTR lpApplicationName);
|
void startup(LPCTSTR lpApplicationName);
|
||||||
void split(const std::string& input, char delimiter, std::string& out1, std::string& out2);
|
void split(const std::string& input, char delimiter, std::string& out1, std::string& out2);
|
||||||
bool is_valid_path(const std::string& filename);
|
bool is_valid_path(const std::string& filename);
|
||||||
bool file_exists(const std::string& filename);
|
bool file_exists(const std::string& filename);
|
||||||
|
int get_num_running_threads();
|
||||||
Binary file not shown.
Reference in New Issue
Block a user