Skip to content

Instantly share code, notes, and snippets.

@gavz
Forked from MEhrn00/CMakeLists.txt
Created March 7, 2025 23:20
Show Gist options
  • Save gavz/b4d42aebf45abed586d9a4e92982c593 to your computer and use it in GitHub Desktop.
Save gavz/b4d42aebf45abed586d9a4e92982c593 to your computer and use it in GitHub Desktop.
Building Stardust with CMake

CMake will automatically generate a compilation database compile_commands.json that many IDEs will hook into for intellisense.
Visual Studio does not support comple_commands.json but will instead use the generated VS solution file for sourcing symbols.

This will build the Stardust project without linking it into shellcode. Passing the -DSTARDUST_BUILD_SHELLCODE=ON flag during configuration will include the final shellcode generation.

The project source code will not build using MSVC/Clang since there is some undefined/implementation-defined behavior that MSVC/Clang will error on but not GCC. This can be fixed if desired but, regardless, the compilation database from CMake can be used for intellisense without needing to build the project.

Usage

For generating a compile_commands.json file.

cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build -G Ninja

Ninja is required on Windows if using an IDE other than Visual Studio. If using Visual Studio, omit the -G Ninja.

Either point your IDE to the generated build/compile_commands.json file to get intellisense or copy/symlink that file to the project root so that it gets detected.

This should add intellisense to the project.

Building the shellcode requires MinGW and can be enabled using the -DSTARDUST_BUILD_SHELLCODE=ON flag.

CXX=x86_64-w64-mingw32-g++ cmake -DSTARDUST_BUILD_SHELLCODE=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_SYSTEM_NAME=Windows -DCMAKE_BUILD_TYPE=MinSizeRel -B build
cmake --build build
cmake_minimum_required(VERSION 3.24)
project(Stardust
LANGUAGES CXX
)
# Build option for generating the final shellcode.bin file
option(STARDUST_BUILD_SHELLCODE "Build the final shellcode.bin file" OFF)
# Add nasm for the Stardust.asm source if building shellcode
if(${STARDUST_BUILD_SHELLCODE})
enable_language(ASM_NASM)
endif()
# Anything that includes 'Common.h' needs to be treated as C++ since the `ExprHashStringA`
# function is constexpr.
# The function definitions in the header files are not marked extern C which will cause
# linking issues so just treat everything as C++ for convenience.
set_source_files_properties(
src/Ldr.c
src/Main.c
src/PreMain.c
src/Utils.c
PROPERTIES
LANGUAGE CXX
)
# Only build the code as an object library by default. Linking requires symbols from the
# linker script.
add_library(stardust-objs OBJECT)
# Add sources
target_sources(stardust-objs
PRIVATE
src/Ldr.c
src/Main.c
src/PreMain.c
src/Utils.c
# Add headers. Not necessary but useful for IDEs
PUBLIC
FILE_SET HEADERS
BASE_DIRS include
FILES
include/Common.h
include/Constexpr.h
include/Defs.h
include/Ldr.h
include/Macros.h
include/Native.h
include/Utils.h
)
# Just picked a random C++ standard
target_compile_features(stardust-objs PRIVATE cxx_std_17)
# Set the include directory
target_include_directories(stardust-objs PRIVATE include)
# Ensure objects are position independent
set_property(TARGET stardust-objs PROPERTY POSITION_INDEPENDENT_CODE ON)
# Add compile flags
target_compile_options(stardust-objs
PRIVATE
# GCC only flags
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:
-falign-jumps=1
-falign-labels=1
>
# GCC and Clang flags
$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:
-fno-ident
-fpermissive
-fpack-struct=8
-falign-functions=1
-masm=intel
-mrdrnd
-fno-asynchronous-unwind-tables
-ffunction-sections
# The 'MinSizeRel' build type will automatically add the '-Os' compile flag but it
# is required since it optimizes out some imported symbols
$<$<NOT:$<CONFIG:MinSizeRel>>:-Os>
# Disable all warnings. The makefile disables all warnings but warnings may be
# helpful during development
-w
>
# MSVC flags
$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:
# Do not include '#pragma comment(lib, ...)' libraries since it is not portable
/Zl
# Disable all warnings
/W0
>
)
# If building the final shellcode file
if(${STARDUST_BUILD_SHELLCODE})
# Add the executable target which the shellcode is built from
add_executable(stardust-exe)
set_property(TARGET stardust-exe PROPERTY POSITION_INDEPENDENT_CODE ON)
# Add the assembly stub and built objects to the executable
target_sources(stardust-exe
PRIVATE
asm/x64/Stardust.asm
$<TARGET_OBJECTS:stardust-objs>
)
# Link options for the executable
target_link_options(stardust-exe
PRIVATE
# GCC/Clang link options
$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:
-nostdlib
"LINKER:--no-seh,--enable-stdcall-fixup"
"LINKER:-T${CMAKE_CURRENT_SOURCE_DIR}/scripts/Linker.ld"
>
)
# Find the python executable for running the build.py script
find_package(Python REQUIRED COMPONENTS Interpreter)
# The build.py script requires pefile. Create a virtualenv in the build dir and install
# it there.
# Python helper variables
set(python-venv-base ${CMAKE_CURRENT_BINARY_DIR}/python-venv)
set(python-venv-bindir ${python-venv-base}/bin)
set(python-venv-libdir ${python-venv-base}/lib)
set(python-venv-site-packages ${python-venv-libdir}/python${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}/site-packages)
set(python-venv-exe ${python-venv-bindir}/python)
set(python-pefile-lib ${python-venv-site-packages}/pefile.py)
# Create 'python-venv' inside the build directory
add_custom_command(
COMMAND ${Python_EXECUTABLE} -m venv ${python-venv-base}
OUTPUT ${python-venv-exe}
COMMENT "Creating python-venv for python dependencies"
)
add_custom_target(python-venv DEPENDS ${python-venv-exe})
# Install pefile into the python virtual environment
add_custom_command(
COMMAND ${python-venv-exe} -m pip install pefile
OUTPUT ${python-pefile-lib}
DEPENDS ${python-venv-exe}
COMMENT "Installing python-pefile into python-venv"
)
add_custom_target(python-pefile DEPENDS ${python-pefile-lib})
# Build the final shellcode file
add_custom_command(
COMMAND
${python-venv-exe} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/build.py
-f $<TARGET_FILE:stardust-exe>
-o stardust.bin
OUTPUT stardust.bin
DEPENDS
stardust-exe
${python-venv-exe}
${python-pefile-lib}
COMMENT "Creating stardust.bin shellcode file"
VERBATIM
)
add_custom_target(stardust-bin ALL DEPENDS stardust.bin)
endif(${STARDUST_BUILD_SHELLCODE})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment