Skip to content

Refactor: Symmetric architecture — shared function discovery for CFF and Junk modes - #22

Merged
sondt99 merged 1 commit into
mainfrom
refactor/symmetric-architecture
Aug 2, 2026
Merged

Refactor: Symmetric architecture — shared function discovery for CFF and Junk modes#22
sondt99 merged 1 commit into
mainfrom
refactor/symmetric-architecture

Conversation

@sondt99

@sondt99 sondt99 commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Summary

Both obfuscation modes now follow the same pipeline pattern, eliminating the asymmetric architecture where Junk mode loaded the PE 2-4 times redundantly.

Before

CFF:  pe64 → pdbparser → obfuscatecff → save  (1 PE load, explicit in main.cpp)
Junk: func2rva(pe64+pdbparser) → filter → LIEF(same file!) → inject → save  (2-4 PE loads, hidden)

After

Both: FunctionDiscovery(path) → [filter/select] → engine-specific work → save

CFF:  FunctionDiscovery → sym_func adapter → pe64 → obfuscatecff → save
Junk: FunctionDiscovery → filter_functions → LIEF → TrampolineInjector → save

New common/ Module (5 files)

File Purpose
function_info.h Shared FunctionInfo struct used by both modes
function_discovery.h/.cpp Single PE+PDB load, returns function list
function_filter.h/.cpp Blacklist filtering, size filtering, interactive selection

Key Changes

  • Junk mode no longer loads PE redundantly — was 2-4 loads (RVAResolver×1-2 + temp TrampolineInjector + real TrampolineInjector), now 1 load (FunctionDiscovery) + 1 load (LIEF for actual injection)
  • main.cpp orchestrates both modes symmetrically — validate → discover → engine → save
  • JunkCodeManager accepts pre-discovered functions instead of creating internal RVAResolver
  • DbgHelp singleton safe — FunctionDiscovery is scoped and destroyed before CFF creates its pe64

Checklist

  • common/function_info.h — shared struct
  • common/function_discovery.h/.cpp — single load, tested
  • common/function_filter.h/.cpp — blacklist + size filter + interactive selection
  • JunkCodeManager::run_auto_injection_mode uses ObfuGuard::filter_functions
  • JunkCodeManager::run_manual_injection_mode uses ObfuGuard::select_functions_interactive
  • main.cpp CFF mode uses FunctionDiscovery in scoped block
  • main.cpp Junk mode uses FunctionDiscovery in scoped block
  • vcxproj and vcxproj.filters updated with new files
  • No RVAResolver created in new code paths
  • LIEF Parser::parse called exactly once (inside TrampolineInjector)
  • Old private methods preserved for backward compatibility

Test plan

  • Build succeeds in Release|x64
  • CFF mode: obfuscate test binary, verify output runs
  • Junk auto mode: obfuscate test binary, verify output runs
  • Junk manual mode: select functions interactively, verify output
  • Run match_check.py on full 60-binary test suite
  • Verify no redundant PE loads (grep confirms)

Extract shared function discovery layer so both obfuscation modes
follow the same pipeline: validate → discover → engine → save.

New common/ module:
- function_info.h: shared FunctionInfo struct (name, pdb_offset, rva, size)
- function_discovery.h/.cpp: single PE+PDB load, returns function list
- function_filter.h/.cpp: blacklist filtering, size filtering, interactive
  selection — moved from JunkCodeManager private methods

Architecture changes:
- Both modes use FunctionDiscovery for function discovery (1 PE load each)
- CFF: FunctionDiscovery → convert to sym_func → pe64 → obfuscatecff → save
- Junk: FunctionDiscovery → filter → LIEF → TrampolineInjector → save
- Junk mode no longer loads PE 2-4 times (was: pe64 via RVAResolver + LIEF)
- JunkCodeManager::run_auto/manual_injection_mode now accept pre-discovered
  function list instead of creating internal RVAResolver instances
- main.cpp orchestrates both modes at the same abstraction level

DbgHelp singleton safety:
- FunctionDiscovery (which owns pdbparser) is scoped in a block and
  destroyed before CFF creates its own pe64 for the VA-mapped buffer
- Neither engine creates a second pdbparser after receiving the function list

Files changed: 5 modified, 5 new (common/ module)
Files unchanged: pe64, pdbparser, obfuscatecff, cfflattening, func2rva
@sondt99
sondt99 merged commit 271a4ae into main Aug 2, 2026
2 of 3 checks passed
@sondt99
sondt99 deleted the refactor/symmetric-architecture branch August 2, 2026 11:32
sondt99 added a commit that referenced this pull request Aug 10, 2026
Refactor: Symmetric architecture — shared function discovery for CFF and Junk modes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant