4.7 KiB
Detailed Code Breakdown: notabeacon.c
This document provides a comprehensive analysis of notabeacon.c, detailing its structural components, Windows API dependencies, and simulated behaviors.
1. Directives and Global State
Headers
#include <windows.h>: The core header file containing declarations for all the Windows API functions, data types (likeDWORD,HANDLE,BOOL), and macros used throughout the program.#include <stdio.h>: Standard input/output library used here exclusively for printing logging statements to the console (printf).
Global Variables
HANDLE g_hWorkerThread = NULL;
- Purpose: Acts as a globally accessible pointer reference to track the spawned background execution thread.
- Importance: Initializing it to
NULLprovides a predictable default state, allowing the cleanup routine inDLL_PROCESS_DETACHto verify if a thread was successfully initialized before attempting to close its handle.
2. Execution Routine: AgentLoop
DWORD WINAPI AgentLoop(LPVOID lpParam)
- Significance: This function serves as the entry point for the secondary thread spawned by the DLL. It matches the required
ThreadProcsignature (DWORDreturn type,WINAPIcalling convention, and a singleLPVOIDparameter).
Configuration & State Variables
int checkinCounter = 0;: Tracks how many times the simulated beacon has completed an iteration.DWORD sleepIntervalMs = 30000;: Configures a static 30,000 millisecond (30 seconds) timer interval, establishing the foundational cadence of the agent.
The Beaconing Simulation (while (TRUE))
The infinite loop simulates a command-and-control (C2) agent's operational cycle:
- Activity Metric Increment:
checkinCounter++tracks execution longevity. - Workload Simulation: ```c
SYSTEMTIME st;
GetLocalTime(&st);
Instead of carrying out malicious operations, the payload executes standard API calls to populate a `SYSTEMTIME` structure with the current local time coordinates (hours, minutes, seconds) and outputs them to stdout. This replicates benign host interaction telemetry. - The Jitter/Sleep Cycle:
The thread pauses execution entirely for 30 seconds. In offensive security architecture, this replicates a basic beacon interval, which limits host processing overhead and makes network traffic or process activity predictable.
Sleep(sleepIntervalMs);
3. Exported Functions
__declspec(dllexport) void voidRunTest(void)
- Purpose: The
__declspec(dllexport)storage-class attribute explicitly directs the compiler to addvoidRunTestto the DLL’s Export Address Table (EAT). - Utility: This allows tools like
rundll32.exeor dynamic loaders usingGetProcAddressto find and execute this specific code block directly without walking through the primary initialization path.
4. Entry Point: DllMain
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
- Purpose: This is the standard entry-point function for a dynamic-link library. The operating system calls this function when loading or unloading the module into a process's memory space.
Case: DLL_PROCESS_ATTACH
Triggered immediately when the DLL is first mapped into the virtual address space of a process.
-
Optimization Controls:
DisableThreadLibraryCalls(hinst);This call disables
DLL_THREAD_ATTACHandDLL_THREAD_DETACHnotifications for this DLL. It prevents the OS from triggeringDllMainevery time the host process creates or destroys threads, reducing performance overhead and preventing common deadlocks during manual mapping or injection operations. -
Thread Spawning:
g_hWorkerThread = CreateThread(NULL, 0, AgentLoop, NULL, 0, NULL);Because lengthy execution within
DllMaincan lock the loader lock and crash the host application, the DLL offloads its continuous loop immediately.AgentLoop: Points to the target function to execute.0(Parameter 5): Explicitly tells the OS to start the thread immediately rather than keeping it suspended.
-
Error Handling: If
CreateThreadreturnsNULL, the function logs a failure message and returnsFALSE, causing the operating system to fail the library loading process cleanly.
Case: DLL_PROCESS_DETACH
Triggered when the DLL is being unmapped from the host process's address space.
- Resource Cleanup:
Verifies if a thread handle exists. If it does,
if (g_hWorkerThread) { CloseHandle(g_hWorkerThread); }CloseHandledecreases the thread object's usage count, allowing the operating system to free kernel resources associated with that thread once it terminates.