Files
Sigma-C2/agent/processes.c

118 lines
4.3 KiB
C

#include <windows.h>
#include <tlhelp32.h>
// Function to get process list as a string using a pre-allocated buffer
// Returns the number of bytes written to the buffer (excluding null terminator)
// Returns -1 if the buffer is too small or on error
int GetProcessList(char* buffer, size_t bufferSize) {
if (!buffer || bufferSize < 1) {
return -1;
}
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
HANDLE hProcess;
char szProcessName[MAX_PATH] = "N/A";
WCHAR architecture[16] = L"Unknown";
char username[256] = "Unknown";
// Position tracker for buffer
size_t position = 0;
// Take a snapshot of all processes in the system
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
return -1;
}
// Set the size of the structure before using it
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return -1;
}
// Now walk through the snapshot of processes
do {
// Reset variables for each process
strcpy(szProcessName, pe32.szExeFile);
wcscpy(architecture, L"Unknown");
strcpy(username, "Unknown");
// Get a handle to the process
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
if (hProcess != NULL) {
// Get architecture information
BOOL isWow64 = FALSE;
if (IsWow64Process(hProcess, &isWow64)) {
wcscpy(architecture, isWow64 ? L"x86" : L"x64");
}
// Get user information
HANDLE hToken = NULL;
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
DWORD needed = 0;
TOKEN_USER* pUserInfo = NULL;
GetTokenInformation(hToken, TokenUser, NULL, 0, &needed);
if (needed > 0) {
pUserInfo = (TOKEN_USER*)malloc(needed);
if (pUserInfo) {
if (GetTokenInformation(hToken, TokenUser, pUserInfo, needed, &needed)) {
WCHAR szUserName[256] = L"";
WCHAR szDomainName[256] = L"";
DWORD dwUserNameSize = 256;
DWORD dwDomainNameSize = 256;
SID_NAME_USE sidType;
LPWSTR stringSid = NULL;
if (ConvertSidToStringSidW(pUserInfo->User.Sid, &stringSid)) {
if (LookupAccountSidW(NULL, pUserInfo->User.Sid, szUserName, &dwUserNameSize,
szDomainName, &dwDomainNameSize, &sidType)) {
// Convert wide char to multi-byte for our output
wcstombs(username, szUserName, sizeof(username)-1);
}
LocalFree(stringSid);
}
}
free(pUserInfo);
}
}
CloseHandle(hToken);
}
CloseHandle(hProcess);
}
// Format for CSV: PID,PPID,Process_Name,Architecture,Username
char architectureStr[16] = "";
wcstombs(architectureStr, architecture, sizeof(architectureStr)-1);
char line[MAX_PATH*2] = {0};
int lineLength = snprintf(line, sizeof(line), "%ld,%ld,%s,%s,%s\n",
pe32.th32ProcessID,
pe32.th32ParentProcessID,
szProcessName,
architectureStr,
username);
// Check if we have enough space in the buffer
if (position + lineLength >= bufferSize - 1) {
CloseHandle(hProcessSnap);
return -1; // Buffer too small
}
// Add line to buffer
strcpy(buffer + position, line);
position += lineLength;
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
// Ensure null termination
buffer[position] = '\0';
return (int)position;
}