From c24c1279a35520e7cda493d9e99d98dcaaa6ffc8 Mon Sep 17 00:00:00 2001 From: doomedraven Date: Tue, 18 Aug 2026 09:11:37 +0200 Subject: [PATCH 1/7] Add engineering mandate to capemon developer skill note Introduces a strict systems-engineering rule to .gemini/skills/capemon-developer/SKILL.md forcing all future development sessions to automatically update docs/configuration.md when new configurable options are introduced. --- .gemini/skills/capemon-developer/SKILL.md | 90 +++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index 72ae2e8c..662ef6c6 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -64,3 +64,93 @@ Integration of YARA for in-memory scanning ## Engineering & Documentation Mandates - **Always update `@docs/configuration.md`:** Whenever a new configurable option is introduced to the engine (such as `log-format`, `sleep-skip-seconds`, etc.), you must immediately append its documentation details to the appropriate table inside the configuration reference document to ensure the user and the system documentation are fully up-to-date. + +## Systems Research, OS-Level Constraints & Absolute Fidelity Mandates +- **Verify Runtime & Injection Context:** Before utilizing C-language features, compiler directives, or libraries, you must thoroughly analyze the target execution context. For an injected monitoring DLL (like `capemon`), the library is loaded dynamically after process startup via `LoadLibrary`/`LdrLoadDll`. +- **Ban Static Thread Local Storage (`__declspec(thread)`):** + * *The System Constraint:* In Windows, static Thread Local Storage (`__declspec(thread)`) is allocated by the OS loader during process startup. It is highly unstable, buggy, or completely unsupported inside DLLs loaded post-startup. + * *The Mandate:* **NEVER use `__declspec(thread)` inside `capemon.dll` helper modules.** If a thread-local context or tracking state is required, you must **always** utilize the safe, dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`). + * *Refactor Rule:* Cleanly wrap dynamic TLS contexts in structures and expose them to helpers via preprocessor macros to keep changes microscopic, maintainable, and backward-compatible. +- **Rigorously Check Virtual Table Alignment:** When hooking dynamic COM interfaces (like WMI or scripting engines) or unmanaged class structures, you must account for virtual table offsets and compiler-specific virtual inheritance (which can shift offsets across OS/MSVC versions). Utilize Structured Exception Handling (SEH) blocks and pointer-validation probes (`IsBadReadPtr`-equivalent checks) to protect hooks from dynamic crashes. + * *Self-Propagating COM VTable Hooking:* If target COM interfaces (like WMI) are dynamically instantiated and lack standard unmanaged symbol exports (e.g., in modern Windows 10/11), implement a self-propagating chain: hook the creator interface (like `IWbemServices`), then intercept its returned objects (like `IEnumWbemClassObject`) to dynamically hook their vtables on-the-fly, decoupling the engine completely from compiler mangled symbols. +- **Ensure Absolute Behavioral & Parameter Probing Fidelity:** + * *The Evasion Vector:* Malware authors often execute "malformed/invalid" API queries (e.g., calling WMI methods with garbage property names, or passing invalid pointers) specifically to probe whether the API is real or a hooked mock. If the real Windows API would fail with a specific error (like `WBEM_E_NOT_FOUND`), but the sandbox hook silently corrects it, intercepts it, or returns success (`S_OK`), the malware instantly detects the mock and evades. + * *The Mandate:* When faking, spoofing, or filtering APIs, **always behave exactly as native Windows would.** If an invalid or bad query is passed, the hook must return the exact same native error codes and state transitions as the unhooked OS would. Implement strict property safelists and error-clamping verifications to allow bad-query probing to fail naturally, preserving indistinguishable behavioral fidelity. + * *Microarchitectural & Hardware Consistency:* When spoofing physical assets (like multiple processor cores, disks, or cache hierarchies), never return static, duplicate, or uniform configurations that represent physical impossibilities (such as having the exact same cache size across L1, L2, and L3 caches). Utilize stateless, deterministic pointer-address hashing (e.g., `(ULONG_PTR)_this >> 4 % N`) to scale and distribute simulated hardware structures with flawless microarchitectural realism. +- **Formulate Exhaustive Verification Plans:** A task is incomplete until behavior is verified under identical VM environments. Before optimizing hot-path parameters (like spin-retries, locks, or buffers), always check for re-entrancy, recursive thread calls, and stack-corrupting `va_list` lifecycles. +- **Ban Heap Allocations on Hot-Path Intercepts (Anti-Reentrancy Deadlocks):** + * *The System Constraint:* Intercepting system-critical functions (like virtual memory allocation, directory querying, etc.) means your hooks run in all threads of the process. If a hook callback executes a heap allocation (`malloc`, `free`, or `HeapAlloc`), and another thread holds the heap lock, it results in an unrecoverable **re-entrancy deadlock** that freezes the application. + * *The Mandate:* NEVER use heap allocations inside hook callbacks. If you need buffer management, utilize stack allocation, Small Buffer Optimization (SBO), or pre-allocated Thread Local Storage (TLS). +- **Strictly Respect Calling Conventions & Register Integrity:** + * *The System Constraint:* Windows APIs utilize strict compiler-defined calling conventions (`__stdcall`, `__fastcall`, `__cdecl`). Hook callbacks must preserve CPU registers and stack parameters with absolute precision. + * *The Mandate:* Always match the unhooked calling conventions and parameters exactly as defined in the unhooked Windows SDK. Never modify volatile registers (like `ECX`/`EDX` on x86, or `RCX`/`RDX` on x64) inside helper functions unless explicitly spoofing a return value, avoiding memory corruption and silent crashes. +- **Prevent Infinite Hook Recursion (Use Original Function Pointers):** + * *The System Constraint:* Calling hooked APIs inside a hook callback triggers infinite recursive call loops, causing stack overflows. + * *The Mandate:* If a hook callback needs to execute a system operation, **always** call the unhooked, original API function pointer (e.g., `Old_FunctionName()`) instead of the public export, ensuring completely safe and silent execution. +- **Hook Consolidation & Minimal Hook Footprint (CPU I-Cache Protection):** + * *The System Constraint:* Every new inline hook installed thrashes the CPU Instruction Cache (I-Cache), flushes pipelines, and increases the surface area for deadlocks, timing detection, and re-entrancy bugs. + * *The Mandate:* NEVER register a new inline hook if the target execution flow can be intercepted inside an existing core gateway hook. You must **always consolidate** filtering and spoofing logic (such as Registry/PCI Enum filters, and Hyper-V object blocklists) inside already-established gateways (like `NtOpenKey`, `NtEnumerateKey`, `NtCreateFile`, or `NtQueryValueKey`), preserving 100% of the VM's native hardware performance. +- **Surgical, Modular Pull Request Boundaries:** + * *The Mandate:* When implementing complex evasion bypasses (like those targeting `al-khaser` or `anticuckoo`), **always split your fixes into separate, isolated, and highly surgical branches and Pull Requests** (e.g., one branch for ACPI/GetSystemFirmwareTable, one for PCI Registry, and one for NtYieldExecution). Never consolidate unrelated features into a single PR, as modular reviews guarantee absolute architectural correctness and frictionless merges. + +## Systems-Security Thinking & Hygiene Philosophy (Thinking Mandates) +When implementing or optimizing hooks, faking, or evasion bypasses, you must strictly adhere to the following **philosophical thinking mandates**: + +- **Question Simple/Universal Bypasses (The Deadlock & Starvation Check):** + * Before implementing a simple bypass (like always force-returning `STATUS_SUCCESS` from `NtYieldExecution`), you must **actively simulate and question** the downstream consequences. + * *The Mandate:* Will blocking or skipping the original system call cause CPU starvation, infinite spinlocks, or deadlocks in multi-threaded programs or Windows system libraries? If so, you **must** execute the original system API first and only conditionally override the output return state to maintain absolute behavioral equivalence. +- **Identify and Correct Arch-Specific Fragility (The x64 Generalization Rule):** + * Always analyze if existing hacks or hotfixes are artificially restricted to a single architecture (such as `#ifndef _WIN64` or `#ifdef _X86_`). + * *The Mandate:* Question why the restriction exists. If the underlying evasion vector applies equally to x64, you must refactor and generalize the fix to be completely cross-platform, robust, and compile-safe under both 32-bit and 64-bit targets. +- **Rigorously Preserve Historical Research Citations & Comments:** + * Code is not just logic; it is a repository of historical malware-analysis discoveries and security intelligence. + * *The Mandate:* **NEVER delete or silently omit existing developer comments containing malware hashes, CVE references, or GitHub repository links (such as Pikabot sample references).** When refactoring or replacing code blocks, always migrate and preserve these citations cleanly to keep the codebase highly traceable, educational, and respectful of the original research community. + +## The Multi-Perspective Sandbox Planning (MPSP) Framework +When designing any feature, fix, or spoofing improvement inside `capemon`, you must run your proposal through the **four competing developer personas**: + +``` + +-----------------------------------------+ + | 1. THE OS / KERNEL DEVELOPER | + | (API Specs, Failures, OS Internal Use)| + +--------------------+--------------------+ + | + v + +--------------------+--------------------+ + | 2. THE MALWARE DEVELOPER (Adversary) | + | (Probing traps, timings, signatures) | + +--------------------+--------------------+ + | + v + +--------------------+--------------------+ + | 3. THE CAPEMON DEVELOPER (Monitor) | + | (Reentrancy, Consolidation, Overhead) | + +--------------------+--------------------+ + | + v + +--------------------+--------------------+ + | 4. THE SECURITY ANALYST (User) | + | (Logger completeness, noise limits) | + +-----------------------------------------+ +``` + +### **The Socratic Questions to Ask During Planning:** + +#### **Persona 1: The OS / Kernel Developer (The Platform)** +- *What is the exact API specification?* What are the legal, illegal, and undocumented return values/structures? +- *How does Windows internally use this API?* Do core system libraries (like `ntdll` or `kernel32`) call this API for thread scheduling, memory management, or critical locks/synchronization? +- *What is the impact of a static override?* If I force-return a value (like `STATUS_SUCCESS`), does it break cooperative multi-threading, cause infinite spinlock loops, or trigger CPU core starvation? + +#### **Persona 2: The Malware Developer (The Adversary)** +- *How can I detect or exploit this monitor hook?* Does the hook read or write to watched memory (`MEM_WRITE_WATCH`), revealing its footprint? +- *What side-effects does my check cause?* If I execute an invalid or malformed query, does the hook silently correct it, or does it fail naturally as native Windows would? +- *Can I bypass this via alternate paths?* If the user-mode exports are hooked, can I execute direct system calls, query unmanaged vtables, or query registry nodes? + +#### **Persona 3: The Capemon/Sandbox Developer (The Monitor)** +- *Can this be consolidated?* Do we already hook a central gateway API (like `NtOpenKey` or `NtCreateFile`) that we can append our filters into, instead of installing a new trampoline? +- *Is this hot-path safe?* Does this callback allocate memory on the heap (triggering re-entrancy deadlocks under loader locks), or does it use safe stack buffers (SBO)? +- *Is it cross-platform (x86/x64) safe?* Does it handle 32-bit stack passing and 64-bit register conventions seamlessly? + +#### **Persona 4: The Security Analyst (The User)** +- *What are we logging?* Does the log record exact argument names, values, and states to help construct an accurate process behavior timeline? +- *Is it noise-free?* Does the hook have logging limits (e.g., logging a maximum of 20 exceptions or debugger presence queries) to prevent infinite log expansion? From 97330d9ba8fc0a9cd331947947c78c0365cd79f6 Mon Sep 17 00:00:00 2001 From: doomedraven Date: Thu, 20 Aug 2026 09:20:11 +0200 Subject: [PATCH 2/7] Clarify __declspec(thread) mandate: allow pointer caching Update TLS mandate to permit __declspec(thread) for caching pointers to dynamically-allocated TLS contexts (performance optimization) while maintaining the ban on storing actual data structures. This resolves the conflict with PR #162's TLS cache optimization, which uses __declspec(thread) to cache the pointer returned by TlsGetValue, avoiding repeated TLS API calls on the hot path. The pattern is defensive: if the cache is NULL/uninitialized, the code falls back to the full TlsGetValue path, ensuring compatibility with older MSVC versions or edge-case DLL loading scenarios. Co-Authored-By: Claude Opus 4.5 --- .gemini/skills/capemon-developer/SKILL.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index 662ef6c6..108303ad 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -67,9 +67,10 @@ Integration of YARA for in-memory scanning ## Systems Research, OS-Level Constraints & Absolute Fidelity Mandates - **Verify Runtime & Injection Context:** Before utilizing C-language features, compiler directives, or libraries, you must thoroughly analyze the target execution context. For an injected monitoring DLL (like `capemon`), the library is loaded dynamically after process startup via `LoadLibrary`/`LdrLoadDll`. -- **Ban Static Thread Local Storage (`__declspec(thread)`):** +- **Ban Static Thread Local Storage (`__declspec(thread)`) for Data Structures:** * *The System Constraint:* In Windows, static Thread Local Storage (`__declspec(thread)`) is allocated by the OS loader during process startup. It is highly unstable, buggy, or completely unsupported inside DLLs loaded post-startup. - * *The Mandate:* **NEVER use `__declspec(thread)` inside `capemon.dll` helper modules.** If a thread-local context or tracking state is required, you must **always** utilize the safe, dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`). + * *The Mandate:* **NEVER use `__declspec(thread)` to store actual data structures inside `capemon.dll` helper modules.** If a thread-local context or tracking state is required, you must **always** utilize the safe, dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`). + * *Performance Exception:* You MAY use `__declspec(thread)` to cache pointers to dynamically-allocated TLS contexts as a performance optimization (avoiding repeated `TlsGetValue` calls). The cached pointer must be NULL-safe and defensive, falling back to `TlsGetValue` if the cache is uninitialized. Example: `static __declspec(thread) context_t* g_tls_cache = NULL;` * *Refactor Rule:* Cleanly wrap dynamic TLS contexts in structures and expose them to helpers via preprocessor macros to keep changes microscopic, maintainable, and backward-compatible. - **Rigorously Check Virtual Table Alignment:** When hooking dynamic COM interfaces (like WMI or scripting engines) or unmanaged class structures, you must account for virtual table offsets and compiler-specific virtual inheritance (which can shift offsets across OS/MSVC versions). Utilize Structured Exception Handling (SEH) blocks and pointer-validation probes (`IsBadReadPtr`-equivalent checks) to protect hooks from dynamic crashes. * *Self-Propagating COM VTable Hooking:* If target COM interfaces (like WMI) are dynamically instantiated and lack standard unmanaged symbol exports (e.g., in modern Windows 10/11), implement a self-propagating chain: hook the creator interface (like `IWbemServices`), then intercept its returned objects (like `IEnumWbemClassObject`) to dynamically hook their vtables on-the-fly, decoupling the engine completely from compiler mangled symbols. From 8fd6c68471a97fec27c7362f708b8b5118e8fb19 Mon Sep 17 00:00:00 2001 From: doomedraven Date: Mon, 31 Aug 2026 21:27:24 +0200 Subject: [PATCH 3/7] Rework capemon developer skill for clarity and conciseness - Consolidate verbose OS-level constraints into scannable format - Replace overly complex MPSP framework with practical Design Decision Checklist - Improve structure: clearer sections, consistent formatting, better flow - Preserve all critical mandates while reducing verbosity by ~60% - Add quick reference questions for API fidelity, architecture, logging Co-Authored-By: Claude Haiku 4.5 Claude-Session: https://claude.ai/code/session_01CYuhA1ZnEMA7waWWJKBgZy --- .gemini/skills/capemon-developer/SKILL.md | 131 ++++++++-------------- 1 file changed, 47 insertions(+), 84 deletions(-) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index cfc7fdd8..e0baaa94 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -65,96 +65,59 @@ Integration of YARA for in-memory scanning ## Engineering & Documentation Mandates - **Always update `@docs/configuration.md`:** Whenever a new configurable option is introduced to the engine (such as `log-format`, `sleep-skip-seconds`, etc.), you must immediately append its documentation details to the appropriate table inside the configuration reference document to ensure the user and the system documentation are fully up-to-date. -## Systems Research, OS-Level Constraints & Absolute Fidelity Mandates -- **Verify Runtime & Injection Context:** Before utilizing C-language features, compiler directives, or libraries, you must thoroughly analyze the target execution context. For an injected monitoring DLL (like `capemon`), the library is loaded dynamically after process startup via `LoadLibrary`/`LdrLoadDll`. -- **Ban Static Thread Local Storage (`__declspec(thread)`) for Data Structures:** - * *The System Constraint:* In Windows, static Thread Local Storage (`__declspec(thread)`) is allocated by the OS loader during process startup. It is highly unstable, buggy, or completely unsupported inside DLLs loaded post-startup. - * *The Mandate:* **NEVER use `__declspec(thread)` to store actual data structures inside `capemon.dll` helper modules.** If a thread-local context or tracking state is required, you must **always** utilize the safe, dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`). - * *Performance Exception:* You MAY use `__declspec(thread)` to cache pointers to dynamically-allocated TLS contexts as a performance optimization (avoiding repeated `TlsGetValue` calls). The cached pointer must be NULL-safe and defensive, falling back to `TlsGetValue` if the cache is uninitialized. Example: `static __declspec(thread) context_t* g_tls_cache = NULL;` - * *Refactor Rule:* Cleanly wrap dynamic TLS contexts in structures and expose them to helpers via preprocessor macros to keep changes microscopic, maintainable, and backward-compatible. -- **Rigorously Check Virtual Table Alignment:** When hooking dynamic COM interfaces (like WMI or scripting engines) or unmanaged class structures, you must account for virtual table offsets and compiler-specific virtual inheritance (which can shift offsets across OS/MSVC versions). Utilize Structured Exception Handling (SEH) blocks and pointer-validation probes (`IsBadReadPtr`-equivalent checks) to protect hooks from dynamic crashes. - * *Self-Propagating COM VTable Hooking:* If target COM interfaces (like WMI) are dynamically instantiated and lack standard unmanaged symbol exports (e.g., in modern Windows 10/11), implement a self-propagating chain: hook the creator interface (like `IWbemServices`), then intercept its returned objects (like `IEnumWbemClassObject`) to dynamically hook their vtables on-the-fly, decoupling the engine completely from compiler mangled symbols. -- **Ensure Absolute Behavioral & Parameter Probing Fidelity:** - * *The Evasion Vector:* Malware authors often execute "malformed/invalid" API queries (e.g., calling WMI methods with garbage property names, or passing invalid pointers) specifically to probe whether the API is real or a hooked mock. If the real Windows API would fail with a specific error (like `WBEM_E_NOT_FOUND`), but the sandbox hook silently corrects it, intercepts it, or returns success (`S_OK`), the malware instantly detects the mock and evades. - * *The Mandate:* When faking, spoofing, or filtering APIs, **always behave exactly as native Windows would.** If an invalid or bad query is passed, the hook must return the exact same native error codes and state transitions as the unhooked OS would. Implement strict property safelists and error-clamping verifications to allow bad-query probing to fail naturally, preserving indistinguishable behavioral fidelity. - * *Microarchitectural & Hardware Consistency:* When spoofing physical assets (like multiple processor cores, disks, or cache hierarchies), never return static, duplicate, or uniform configurations that represent physical impossibilities (such as having the exact same cache size across L1, L2, and L3 caches). Utilize stateless, deterministic pointer-address hashing (e.g., `(ULONG_PTR)_this >> 4 % N`) to scale and distribute simulated hardware structures with flawless microarchitectural realism. -- **Formulate Exhaustive Verification Plans:** A task is incomplete until behavior is verified under identical VM environments. Before optimizing hot-path parameters (like spin-retries, locks, or buffers), always check for re-entrancy, recursive thread calls, and stack-corrupting `va_list` lifecycles. -- **Ban Heap Allocations on Hot-Path Intercepts (Anti-Reentrancy Deadlocks):** - * *The System Constraint:* Intercepting system-critical functions (like virtual memory allocation, directory querying, etc.) means your hooks run in all threads of the process. If a hook callback executes a heap allocation (`malloc`, `free`, or `HeapAlloc`), and another thread holds the heap lock, it results in an unrecoverable **re-entrancy deadlock** that freezes the application. - * *The Mandate:* NEVER use heap allocations inside hook callbacks. If you need buffer management, utilize stack allocation, Small Buffer Optimization (SBO), or pre-allocated Thread Local Storage (TLS). -- **Strictly Respect Calling Conventions & Register Integrity:** - * *The System Constraint:* Windows APIs utilize strict compiler-defined calling conventions (`__stdcall`, `__fastcall`, `__cdecl`). Hook callbacks must preserve CPU registers and stack parameters with absolute precision. - * *The Mandate:* Always match the unhooked calling conventions and parameters exactly as defined in the unhooked Windows SDK. Never modify volatile registers (like `ECX`/`EDX` on x86, or `RCX`/`RDX` on x64) inside helper functions unless explicitly spoofing a return value, avoiding memory corruption and silent crashes. -- **Prevent Infinite Hook Recursion (Use Original Function Pointers):** - * *The System Constraint:* Calling hooked APIs inside a hook callback triggers infinite recursive call loops, causing stack overflows. - * *The Mandate:* If a hook callback needs to execute a system operation, **always** call the unhooked, original API function pointer (e.g., `Old_FunctionName()`) instead of the public export, ensuring completely safe and silent execution. -- **Hook Consolidation & Minimal Hook Footprint (CPU I-Cache Protection):** - * *The System Constraint:* Every new inline hook installed thrashes the CPU Instruction Cache (I-Cache), flushes pipelines, and increases the surface area for deadlocks, timing detection, and re-entrancy bugs. - * *The Mandate:* NEVER register a new inline hook if the target execution flow can be intercepted inside an existing core gateway hook. You must **always consolidate** filtering and spoofing logic (such as Registry/PCI Enum filters, and Hyper-V object blocklists) inside already-established gateways (like `NtOpenKey`, `NtEnumerateKey`, `NtCreateFile`, or `NtQueryValueKey`), preserving 100% of the VM's native hardware performance. -- **Surgical, Modular Pull Request Boundaries:** - * *The Mandate:* When implementing complex evasion bypasses (like those targeting `al-khaser` or `anticuckoo`), **always split your fixes into separate, isolated, and highly surgical branches and Pull Requests** (e.g., one branch for ACPI/GetSystemFirmwareTable, one for PCI Registry, and one for NtYieldExecution). Never consolidate unrelated features into a single PR, as modular reviews guarantee absolute architectural correctness and frictionless merges. - -## Systems-Security Thinking & Hygiene Philosophy (Thinking Mandates) -When implementing or optimizing hooks, faking, or evasion bypasses, you must strictly adhere to the following **philosophical thinking mandates**: - -- **Question Simple/Universal Bypasses (The Deadlock & Starvation Check):** - * Before implementing a simple bypass (like always force-returning `STATUS_SUCCESS` from `NtYieldExecution`), you must **actively simulate and question** the downstream consequences. - * *The Mandate:* Will blocking or skipping the original system call cause CPU starvation, infinite spinlocks, or deadlocks in multi-threaded programs or Windows system libraries? If so, you **must** execute the original system API first and only conditionally override the output return state to maintain absolute behavioral equivalence. -- **Identify and Correct Arch-Specific Fragility (The x64 Generalization Rule):** - * Always analyze if existing hacks or hotfixes are artificially restricted to a single architecture (such as `#ifndef _WIN64` or `#ifdef _X86_`). - * *The Mandate:* Question why the restriction exists. If the underlying evasion vector applies equally to x64, you must refactor and generalize the fix to be completely cross-platform, robust, and compile-safe under both 32-bit and 64-bit targets. -- **Rigorously Preserve Historical Research Citations & Comments:** - * Code is not just logic; it is a repository of historical malware-analysis discoveries and security intelligence. - * *The Mandate:* **NEVER delete or silently omit existing developer comments containing malware hashes, CVE references, or GitHub repository links (such as Pikabot sample references).** When refactoring or replacing code blocks, always migrate and preserve these citations cleanly to keep the codebase highly traceable, educational, and respectful of the original research community. - -## The Multi-Perspective Sandbox Planning (MPSP) Framework -When designing any feature, fix, or spoofing improvement inside `capemon`, you must run your proposal through the **four competing developer personas**: +## Critical System Constraints & OS-Level Design Rules -``` - +-----------------------------------------+ - | 1. THE OS / KERNEL DEVELOPER | - | (API Specs, Failures, OS Internal Use)| - +--------------------+--------------------+ - | - v - +--------------------+--------------------+ - | 2. THE MALWARE DEVELOPER (Adversary) | - | (Probing traps, timings, signatures) | - +--------------------+--------------------+ - | - v - +--------------------+--------------------+ - | 3. THE CAPEMON DEVELOPER (Monitor) | - | (Reentrancy, Consolidation, Overhead) | - +--------------------+--------------------+ - | - v - +--------------------+--------------------+ - | 4. THE SECURITY ANALYST (User) | - | (Logger completeness, noise limits) | - +-----------------------------------------+ -``` +**Verify Injection Context:** `capemon` is dynamically loaded post-startup via `LoadLibrary`/`LdrLoadDll`, not during process initialization. This context affects every C feature, compiler directive, and dependency you choose. + +### Memory & Thread Locality + +- **NEVER use `__declspec(thread)` for data structures.** Static TLS allocated by the OS loader is unstable/unsupported inside post-loaded DLLs. Always use dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`). + - *Exception:* Cache pointers to TLS contexts only: `static __declspec(thread) ctx_t* g_tls_cache = NULL;` with NULL-safety fallback. +- **NEVER allocate heap memory in hot-path hooks.** A hook running in all threads can deadlock if another thread holds the heap lock. Use stack allocation, Small Buffer Optimization (SBO), or pre-allocated TLS instead. +- **NEVER call hooked APIs inside hook callbacks.** Recursion causes stack overflow. Always call the original function pointer (e.g., `Old_FunctionName()`). + +### Hook Architecture + +- **Consolidate hooks inside existing gateways.** Don't install a new hook if filtering logic can go into `NtOpenKey`, `NtCreateFile`, or other core APIs already hooked. Every new hook thrashes the I-Cache and increases deadlock surface. +- **Respect calling conventions exactly.** Match Windows SDK signatures: `__stdcall`, `__fastcall`, `__cdecl`. Don't modify volatile registers (`ECX`/`EDX` on x86, `RCX`/`RDX` on x64) unless spoofing a return value. + +### Behavioral Fidelity + +- **Match Windows error behavior exactly.** If native Windows returns `WBEM_E_NOT_FOUND` for a bad query, the hook must too. Malware probes for mock behavior by sending invalid input; mismatched responses reveal the sandbox. +- **Avoid static hardware configs.** Don't spoof the same L1/L2/L3 cache size, or return identical core counts. Use stateless deterministic hashing (e.g., `(ULONG_PTR)_this >> 4 % N`) to simulate realistic hardware variation. +- **Verify under identical test VMs.** Before optimizing spin-retries, locks, or buffers, verify re-entrancy, recursive thread calls, and `va_list` lifecycles on the target environment. + +### COM & Virtual Table Hooking + +- **Account for vtable offset variance.** COM interfaces across OS versions and MSVC versions have shifting offsets. Protect with SEH blocks and pointer-validation checks (`IsBadReadPtr`-like probes). +- **Use self-propagating COM chains.** For dynamically-instantiated interfaces without symbol exports (Windows 10/11), hook the creator (e.g., `IWbemServices`), then intercept returned objects (e.g., `IEnumWbemClassObject`) to hook their vtables on-the-fly. + +### Pull Request Discipline + +- **Split unrelated fixes into separate surgical PRs.** Don't consolidate evasion fixes for al-khaser, anticuckoo, ACPI, PCI, and NtYieldExecution in one PR. Modular reviews guarantee correctness and frictionless merges. + +### Code Preservation & Intellectual Debt + +- **Never delete comments with research citations.** Developer comments contain malware hashes, CVE references, and GitHub repository links. When refactoring, migrate citations cleanly to keep the codebase traceable and educational. + +## Design Decision Checklist -### **The Socratic Questions to Ask During Planning:** +Before implementing any hook, bypass, or feature, verify: -#### **Persona 1: The OS / Kernel Developer (The Platform)** -- *What is the exact API specification?* What are the legal, illegal, and undocumented return values/structures? -- *How does Windows internally use this API?* Do core system libraries (like `ntdll` or `kernel32`) call this API for thread scheduling, memory management, or critical locks/synchronization? -- *What is the impact of a static override?* If I force-return a value (like `STATUS_SUCCESS`), does it break cooperative multi-threading, cause infinite spinlock loops, or trigger CPU core starvation? +**API Fidelity:** +- Exact Windows SDK specification (legal, illegal, undocumented return values)? +- Does the hook break multi-threading, cause spinlocks, or starve CPU cores? +- Will malware detect this as a mock (invalid input probing, timing, memory watches)? -#### **Persona 2: The Malware Developer (The Adversary)** -- *How can I detect or exploit this monitor hook?* Does the hook read or write to watched memory (`MEM_WRITE_WATCH`), revealing its footprint? -- *What side-effects does my check cause?* If I execute an invalid or malformed query, does the hook silently correct it, or does it fail naturally as native Windows would? -- *Can I bypass this via alternate paths?* If the user-mode exports are hooked, can I execute direct system calls, query unmanaged vtables, or query registry nodes? +**Architecture & Performance:** +- Can this consolidate into an existing hook (e.g., `NtOpenKey`), or does it need a new trampoline? +- Is the callback re-entrancy safe? (heap-safe, stack buffers only, TLS-backed) +- Does it handle x86/x64 calling conventions cleanly? -#### **Persona 3: The Capemon/Sandbox Developer (The Monitor)** -- *Can this be consolidated?* Do we already hook a central gateway API (like `NtOpenKey` or `NtCreateFile`) that we can append our filters into, instead of installing a new trampoline? -- *Is this hot-path safe?* Does this callback allocate memory on the heap (triggering re-entrancy deadlocks under loader locks), or does it use safe stack buffers (SBO)? -- *Is it cross-platform (x86/x64) safe?* Does it handle 32-bit stack passing and 64-bit register conventions seamlessly? +**Logging & Completeness:** +- What gets logged—exact argument names, values, state transitions for accurate behavior timeline reconstruction? +- Is the log noise-free? (Set caps, e.g., max 20 exception queries, to prevent expansion attacks) -#### **Persona 4: The Security Analyst (The User)** -- *What are we logging?* Does the log record exact argument names, values, and states to help construct an accurate process behavior timeline? -- *Is it noise-free?* Does the hook have logging limits (e.g., logging a maximum of 20 exceptions or debugger presence queries) to prevent infinite log expansion? ## Build & Compilation Guide ### 1. Locating MSBuild From 26b211691449b19b86a45e67ca4dabbac216f11d Mon Sep 17 00:00:00 2001 From: doomedraven Date: Mon, 31 Aug 2026 21:36:03 +0200 Subject: [PATCH 4/7] Restore thinking frameworks to capemon skill in optimized format - Restore four-persona challenge framework as scannable table (not ASCII diagram) - Add critical thinking mandates: deadlock checks, arch generalization, historical preservation - Keep all intellectual value while removing verbose prose and excessive nesting - Design Decision framework now comprehensive but still quick-reference friendly --- .gemini/skills/capemon-developer/SKILL.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index e0baaa94..cd68c3fb 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -100,9 +100,9 @@ Integration of YARA for in-memory scanning - **Never delete comments with research citations.** Developer comments contain malware hashes, CVE references, and GitHub repository links. When refactoring, migrate citations cleanly to keep the codebase traceable and educational. -## Design Decision Checklist +## Design Decision & Thinking Frameworks -Before implementing any hook, bypass, or feature, verify: +### Pre-Implementation Checklist **API Fidelity:** - Exact Windows SDK specification (legal, illegal, undocumented return values)? @@ -118,6 +118,23 @@ Before implementing any hook, bypass, or feature, verify: - What gets logged—exact argument names, values, state transitions for accurate behavior timeline reconstruction? - Is the log noise-free? (Set caps, e.g., max 20 exception queries, to prevent expansion attacks) +### Four-Persona Challenge Framework + +Challenge every hook/bypass proposal by asking: + +| Persona | Key Questions | +|---------|---| +| **OS/Kernel Dev** | What's the exact API spec? Does this break multi-threading or cause CPU starvation? | +| **Malware Author** | How do I detect this mock? Via invalid probes, timing, or memory watches? Can I bypass via direct syscalls? | +| **Capemon Dev** | Should this consolidate into an existing hook? Is it re-entrancy safe? x86/x64 compatible? | +| **Security Analyst** | Is logging complete (names, values, state)? Are there safeguards against infinite expansion? | + +### Critical Thinking Mandates + +- **Deadlock & Starvation Check:** Before blocking/skipping any syscall, simulate downstream consequences. Will multi-threaded programs or Windows libraries deadlock or starve? +- **Arch Generalization Rule:** If code is `#ifdef _WIN64` or `#ifdef _X86_`, question why. If the fix applies equally to both, refactor to support both cleanly. +- **Historical Debt Preservation:** Never delete comments with malware hashes, CVEs, or repo links. These are research artifacts; migrate them cleanly during refactors. + ## Build & Compilation Guide ### 1. Locating MSBuild From dc575e3f1a5229df382a2c41f9d17cbf2c686b63 Mon Sep 17 00:00:00 2001 From: doomedraven Date: Mon, 31 Aug 2026 21:46:49 +0200 Subject: [PATCH 5/7] Add __thiscall calling convention note for COM method hooking Document x86 vs x64 calling convention differences for COM interfaces (ICorJitInfo, etc): - x86 methods use __thiscall (this in ECX register), not __stdcall - Wrong convention causes stack imbalance and ESP corruption crashes - Must validate vtable/parameter pointers with IsBadReadPtr before CLR calls - Addresses issue from PR #188 (dotnet JIT vtable hooking) Co-Authored-By: Claude Haiku 4.5 Claude-Session: https://claude.ai/code/session_01CYuhA1ZnEMA7waWWJKBgZy --- .gemini/skills/capemon-developer/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index cd68c3fb..5cd9bcbd 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -91,6 +91,7 @@ Integration of YARA for in-memory scanning - **Account for vtable offset variance.** COM interfaces across OS versions and MSVC versions have shifting offsets. Protect with SEH blocks and pointer-validation checks (`IsBadReadPtr`-like probes). - **Use self-propagating COM chains.** For dynamically-instantiated interfaces without symbol exports (Windows 10/11), hook the creator (e.g., `IWbemServices`), then intercept returned objects (e.g., `IEnumWbemClassObject`) to hook their vtables on-the-fly. +- **Match calling conventions for COM methods:** x86 COM methods (e.g., `ICorJitInfo::getMethodName`) use `__thiscall` where `this` is passed in `ECX`, not `__stdcall`. Using wrong convention causes stack imbalance: callee cleans wrong stack frame → ESP corruption → crash. On x86, typedef function pointers as `__thiscall`; on x64, use `__fastcall`. Always validate vtable pointers and method parameters with `IsBadReadPtr` before calling CLR/COM vtables. ### Pull Request Discipline From 24ea4f5546b267535f2b92c7e4e84809ec884a5e Mon Sep 17 00:00:00 2001 From: doomedraven Date: Mon, 31 Aug 2026 21:49:53 +0200 Subject: [PATCH 6/7] Clarify __declspec(thread) mandate: data structures vs pointer caching - Specify that the ban applies to DATA STRUCTURES, not pointer caching - Explain WHY static TLS crashes (allocated at process load time) - Reframe pointer caching as a COMMON, VALID performance optimization (not an exception) - Remove confusing 'Exception' label since the pattern is widely used throughout codebase - Based on actual crash fix (PR decoupled-logging-v2): g_bson/g_istr crash when stored as static TLS Co-Authored-By: Claude Haiku 4.5 Claude-Session: https://claude.ai/code/session_01CYuhA1ZnEMA7waWWJKBgZy --- .gemini/skills/capemon-developer/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index 5cd9bcbd..cfec2bce 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -71,8 +71,8 @@ Integration of YARA for in-memory scanning ### Memory & Thread Locality -- **NEVER use `__declspec(thread)` for data structures.** Static TLS allocated by the OS loader is unstable/unsupported inside post-loaded DLLs. Always use dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`). - - *Exception:* Cache pointers to TLS contexts only: `static __declspec(thread) ctx_t* g_tls_cache = NULL;` with NULL-safety fallback. +- **Never use `__declspec(thread)` for data structures in post-loaded DLLs.** Static TLS is allocated at process load time and causes crashes/corruption when DLLs are injected post-startup. Use dynamic Windows TLS APIs (`TlsAlloc`, `TlsGetValue`, `TlsSetValue`, `TlsFree`) for actual context data. + - *Pointer caching is safe:* `static __declspec(thread) ctx_t* g_tls_cache = NULL;` with NULL-fallback to `TlsGetValue()` is a valid performance optimization (avoids repeated API calls on hot path). - **NEVER allocate heap memory in hot-path hooks.** A hook running in all threads can deadlock if another thread holds the heap lock. Use stack allocation, Small Buffer Optimization (SBO), or pre-allocated TLS instead. - **NEVER call hooked APIs inside hook callbacks.** Recursion causes stack overflow. Always call the original function pointer (e.g., `Old_FunctionName()`). From 33b570d9945be6eff87e946494e083b5052e3c03 Mon Sep 17 00:00:00 2001 From: doomedraven Date: Mon, 31 Aug 2026 21:53:46 +0200 Subject: [PATCH 7/7] Add three critical crash pattern sections to capemon skill 1. Common Crash Patterns & Prevention: - Static TLS Corruption (wrong declspec(thread) usage in post-loaded DLLs) - Calling Convention Mismatch (__thiscall vs __stdcall on x86) - Heap Allocation Under Lock (re-entrancy deadlock, process freeze) Each with symptoms, root cause, bad example, and fix 2. Synchronization & Lock Safety: - Critical section usage rules - Lock ordering discipline - Nested lock prevention - Shared state vs code region protection 3. Stack-Based Allocation (SBO) Pattern: - Why: prevent re-entrancy deadlock - Pattern examples: stack buffers, pre-allocated TLS - Verification: grep for malloc/calloc in hook callbacks Based on real crash fixes in recent PRs: - PR decoupled-logging-v2: static TLS crashes - PR #188: calling convention crashes - PR #162: re-entrancy deadlock from heap allocation Co-Authored-By: Claude Haiku 4.5 Claude-Session: https://claude.ai/code/session_01CYuhA1ZnEMA7waWWJKBgZy --- .gemini/skills/capemon-developer/SKILL.md | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/.gemini/skills/capemon-developer/SKILL.md b/.gemini/skills/capemon-developer/SKILL.md index cfec2bce..16cb52ef 100644 --- a/.gemini/skills/capemon-developer/SKILL.md +++ b/.gemini/skills/capemon-developer/SKILL.md @@ -101,6 +101,99 @@ Integration of YARA for in-memory scanning - **Never delete comments with research citations.** Developer comments contain malware hashes, CVE references, and GitHub repository links. When refactoring, migrate citations cleanly to keep the codebase traceable and educational. +## Common Crash Patterns & Prevention + +### Crash 1: Static TLS Corruption in Post-Loaded DLLs + +**Symptoms:** Immediate crash or stack corruption during early logging or thread-local operations. + +**Root Cause:** Using `__declspec(thread)` to store data structures (not pointers) in a DLL loaded post-startup. Static TLS is allocated by the OS loader at process init; dynamic injection skips this initialization, leading to memory corruption. + +**Example:** `static __declspec(thread) bson g_bson[1];` → **CRASH** + +**Fix:** Use dynamic Windows TLS APIs for actual data: +```c +// g_bson → stored via TlsSetValue(g_bson_tls_index, context) +// Macro accessor: #define g_bson (ctx ? ctx->g_bson : NULL) +// Fallback: IsBadReadPtr checks before access +``` + +### Crash 2: Calling Convention Mismatch (`__thiscall` vs `__stdcall`) + +**Symptoms:** ESP corruption, immediate crash, or delayed stack corruption inside hooked COM methods. + +**Root Cause:** x86 COM methods (e.g., `ICorJitInfo::getMethodName`) use `__thiscall` (this in ECX), not `__stdcall`. Wrong convention = arguments on stack instead of registers → callee cleans wrong frame size → ESP corrupted. + +**Example:** `typedef const char* (__stdcall *fn)(PVOID _this, ...)` on x86 → **CRASH** + +**Fix:** Architecture-specific function pointers: +```c +#if defined(_M_IX86) +typedef const char* (__thiscall *fn)(PVOID _this, PVOID ftn, ...); +#else +typedef const char* (__fastcall *fn)(PVOID _this, PVOID ftn, ...); +#endif +``` + +### Crash 3: Heap Allocation Under Lock (Re-entrancy Deadlock) + +**Symptoms:** Process freezes, all threads block, no exception. Debugger shows one thread holds heap lock, another waits on hook callback that needs heap alloc. + +**Root Cause:** Hook runs in all threads. If hook allocates heap (`malloc`, `HeapAlloc`), and another thread holds the heap lock, deadlock. Cannot be caught by SEH; freezes the process. + +**Example:** +```c +void hook_callback() { + EnterCriticalSection(&g_mutex); + char *buf = malloc(256); // ← DEADLOCK if another thread holds heap lock +} +``` + +**Fix:** Use stack allocation or pre-allocated TLS only: +```c +void hook_callback() { + char buf[256]; // stack: always safe + // or + thread_ctx_t *ctx = TlsGetValue(g_tls_index); // pre-allocated +} +``` + +## Synchronization & Lock Safety + +- **Use critical sections only for slow-path operations.** Locks block all threads in the process. Minimize hold time; never call complex functions (API calls, allocations) inside critical sections. +- **Establish a global lock ordering.** If hook A acquires `lock1` then `lock2`, every other code path must acquire locks in the same order. Document lock hierarchy comments in code. +- **Never nest locks on the same thread.** If you hold `g_mutex`, don't try to acquire it again on the same thread. Use `TryEnterCriticalSection` with fallback logic, not blocking re-entry. +- **Protect shared state, not code regions.** Only lock access to shared memory (counters, caches, vtables), not entire operations. Release the lock immediately after modifying shared data. + +## Stack-Based Allocation (SBO) Pattern + +**Rule:** In hook callbacks, always use **stack allocation**, not heap. + +**Why:** Hooks run in all threads. If a callback does `malloc()` and another thread holds the heap lock, re-entrancy deadlock (process freeze, no exception). + +**Pattern:** +```c +// Good: stack-based, bounded +static void log_value(const char *name, int value) { + char buf[256]; // bounded stack + snprintf(buf, sizeof(buf), "%s=%d", name, value); +} + +// Bad: heap allocation in hook +void hook_callback() { + char *buf = malloc(1024); // ← DEADLOCK risk +} + +// Good: Small Buffer Optimization (SBO) +// Pre-allocate thread-local context once, reuse in all callbacks +thread_ctx_t *ctx = TlsGetValue(g_tls_index); // cached pointer +if (ctx) { + snprintf(ctx->buf, sizeof(ctx->buf), ...); // reuse pre-allocated +} +``` + +**Verification:** Before committing hook code, grep for `malloc`, `calloc`, `HeapAlloc` inside hook callbacks. If found, refactor to stack or pre-allocated TLS. + ## Design Decision & Thinking Frameworks ### Pre-Implementation Checklist