mirror of
https://github.com/dobin/RedEdr
synced 2026-08-09 12:30:51 +00:00
137 lines
4.0 KiB
C++
137 lines
4.0 KiB
C++
#include <windows.h>
|
|
#include <evntrace.h>
|
|
#include <tdh.h>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <wchar.h>
|
|
#include <mutex>
|
|
#include <condition_variable>
|
|
#include <thread>
|
|
|
|
#include "../Shared/common.h"
|
|
#include "logging.h"
|
|
#include "kernelreader.h"
|
|
#include "process_resolver.h"
|
|
#include "piping.h"
|
|
#include "event_aggregator.h"
|
|
|
|
#pragma comment (lib, "wintrust.lib")
|
|
#pragma comment(lib, "dbghelp.lib")
|
|
#pragma comment(lib, "crypt32.lib")
|
|
|
|
|
|
// KernelReader: Reads events from the kernel pipe (from Kernel Callbacks)
|
|
|
|
|
|
// Private variables
|
|
bool KernelReaderThreadStopFlag = FALSE;
|
|
HANDLE kernel_pipe = NULL;
|
|
PipeServer* kernelPipeServer = NULL;
|
|
HANDLE threadReadyness; // ready to accept clients
|
|
|
|
// Private functions
|
|
DWORD WINAPI KernelReaderProcessingThread(LPVOID param);
|
|
void CheckEventForNewObservable(wchar_t* line);
|
|
|
|
|
|
void KernelReaderInit(std::vector<HANDLE>& threads) {
|
|
const wchar_t* data = L"";
|
|
threadReadyness = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
if (threadReadyness == NULL) {
|
|
LOG_A(LOG_ERROR, "KernelReader: Failed to create event for thread readyness");
|
|
return;
|
|
}
|
|
|
|
LOG_A(LOG_INFO, "!KernelReader: Start thread");
|
|
HANDLE thread = CreateThread(NULL, 0, KernelReaderProcessingThread, (LPVOID)data, 0, NULL);
|
|
if (thread == NULL) {
|
|
LOG_A(LOG_ERROR, "KernelReader: Failed to create thread for trace session logreader");
|
|
return;
|
|
}
|
|
|
|
WaitForSingleObject(threadReadyness, INFINITE);
|
|
threads.push_back(thread);
|
|
}
|
|
|
|
|
|
DWORD WINAPI KernelReaderProcessingThread(LPVOID param) {
|
|
// Loop which accepts new clients
|
|
while (!KernelReaderThreadStopFlag) {
|
|
kernelPipeServer = new PipeServer(L"KernelReader");
|
|
kernelPipeServer->Start(KERNEL_PIPE_NAME, TRUE);
|
|
SetEvent(threadReadyness); // signal the event
|
|
if (!kernelPipeServer->WaitForClient()) {
|
|
LOG_A(LOG_ERROR, "KernelReader: WaitForClient failed");
|
|
kernelPipeServer->Shutdown();
|
|
continue;
|
|
}
|
|
|
|
while (!KernelReaderThreadStopFlag) {
|
|
std::vector<std::wstring> events = kernelPipeServer->ReceiveBatch();
|
|
if (events.empty()) {
|
|
break;
|
|
}
|
|
for (const auto& event : events) {
|
|
g_EventAggregator.do_output(event);
|
|
CheckEventForNewObservable((wchar_t*) event.c_str());
|
|
}
|
|
}
|
|
|
|
kernelPipeServer->Shutdown();
|
|
delete kernelPipeServer;
|
|
kernelPipeServer = NULL;
|
|
}
|
|
|
|
LOG_A(LOG_INFO, "!DllReader Server Thread: end");
|
|
return 0;
|
|
}
|
|
|
|
|
|
void CheckEventForNewObservable(wchar_t* line) {
|
|
// Check if "observe:1" exists
|
|
wchar_t* observe_str = wcsstr(line, L"observe:");
|
|
if (!observe_str) {
|
|
return;
|
|
}
|
|
|
|
// something like
|
|
// "type:kernel;time:133711655617407173;callback:create_process;krn_pid:5564;pid:4240;name:\\Device\\HarddiskVolume2\\Windows\\System32\\notepad.exe;ppid:5564;parent_name:\\Device\\HarddiskVolume2\\Windows\\explorer.exe;observe:1"
|
|
// find "observe:<int>" and pid from "pid:<int>"
|
|
int observe_value = 0;
|
|
swscanf_s(observe_str, L"observe:%d", &observe_value);
|
|
if (observe_value == 1) {
|
|
// Now extract the pid
|
|
wchar_t* pid_str = wcsstr(line, L";pid:");
|
|
if (pid_str) {
|
|
int pid = 0;
|
|
swscanf_s(pid_str, L";pid:%d", &pid);
|
|
LOG_A(LOG_WARNING, "KernelReader: observe pid: %d (%d)", pid, observe_value);
|
|
g_ProcessResolver.getObject(pid); // FIXME this actually creates the process
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void KernelReaderShutdown() {
|
|
KernelReaderThreadStopFlag = TRUE;
|
|
|
|
if (! kernelPipeServer->IsConnected()) {
|
|
PipeClient pipeClient;
|
|
wchar_t buf[KRN_CONFIG_LEN] = { 0 };
|
|
pipeClient.Connect(KERNEL_PIPE_NAME);
|
|
pipeClient.Receive(buf, KRN_CONFIG_LEN);
|
|
pipeClient.Send((wchar_t*)L"");
|
|
pipeClient.Disconnect();
|
|
}
|
|
else {
|
|
// Connected
|
|
kernelPipeServer->Shutdown(); // if connected
|
|
kernelPipeServer = NULL;
|
|
delete kernelPipeServer;
|
|
}
|
|
}
|
|
|