# Project name
PROJECT := PlatinumPick

# The flags given to make
MAKEFLAGS += --no-builtin-rules     # eliminate use of the built-in implicit rules
MAKEFLAGS += --no-builtin-variables # eliminate use of the built-in rule-specific variables

# Program for compiling C++ programs
CXX = gcc

# Extra flags to give to the C preprocessor and programs that use it
CPPFLAGS := $(addprefix -I,Inc)
CPPFLAGS += $(addprefix -I,/mingw64/include/ddk)

# Extra flags to give to the C++ compiler
CXXFLAGS := -c                              # compile the source files, but do not link
CXXFLAGS += -Wall                           # enable all the warnings
CXXFLAGS += -Wextra                         # enable some extra warnings
CXXFLAGS += -Werror                         # turn all warnings into errors
CXXFLAGS += -Wshadow                        # issue a warning when a variable declaration hides a previous declaration
CXXFLAGS += -pedantic-errors                # disable compiler extensions
CXXFLAGS += -Wconversion                    # warn for implicit conversions that may alter a value
CXXFLAGS += -Wundef                         # warn if an undefined identifier is evaluated in an #if directive
CXXFLAGS += -Wpadded                        # warn if padding is added to a structure due to alignment requirements
CXXFLAGS += -fdiagnostics-color=always      # use color in diagnostics
CXXFLAGS += -std=c++20                      # use C++20 standard
CXXFLAGS += -Os                             # optimize for size
CXXFLAGS += -flto                           # enable whole program Link Time Optimization (LTO)
CXXFLAGS += -ffat-lto-objects               # generate a fat LTO object that has both a true object and a discardable IR section
CXXFLAGS += -m64                            # generate code for the x86-64 architecture
CXXFLAGS += -fno-stack-protector            # disable stack protection
CXXFLAGS += -mno-stack-arg-probe            # disable stack probing
CXXFLAGS += -fno-ident                      # do not emit metadata containing compiler name and version
CXXFLAGS += -fno-exceptions                 # disable exception handling
CXXFLAGS += -fno-unwind-tables              # suppress generation of static unwind tables
CXXFLAGS += -fno-asynchronous-unwind-tables # prevent generation of the .pdata section that contains the unwind tables
CXXFLAGS += -fno-builtin                    # don't recognize built-in functions that do not begin with __builtin_ as prefix
CXXFLAGS += -ffunction-sections             # place each function in a separate section in the resulting object file
CXXFLAGS += -fdata-sections                 # place each data item in a separate section in the resulting object file
CXXFLAGS += -fno-jump-tables                # do not use jump tables for switch statements
CXXFLAGS += -fno-toplevel-reorder           # do not reorder top-level functions, variables, and asm statements
CXXFLAGS += -fpack-struct=8                 # specify maximum alignment for structure member packing
CXXFLAGS += -fms-extensions                 # accept some non-standard constructs used in Microsoft header files
CXXFLAGS += -fno-rtti                       # disable run-time type information
CXXFLAGS += -fomit-frame-pointer            # omit the frame pointer in functions that don't need one
CXXFLAGS += -masm=intel                     # output assembly instructions using selected dialect
CXXFLAGS += -v                              # enable verbose mode

# Extra flags to give to the compiler when they are supposed to invoke the linker
LDFLAGS := -fuse-ld=bfd                     # use the bfd linker instead of the default linker
LDFLAGS += -nostdlib                        # do not use the standard system startup files or libraries when linking
LDFLAGS += -Wl,--entry=PicEntry             # specify the program entry point
LDFLAGS += -shared                          # create a DLL instead of a regular executable
LDFLAGS += -Wl,--wdmdriver                  # set the IMAGE_DLLCHARACTERISTICS_WDM_DRIVER bit in the optional header
LDFLAGS += -Wl,--exclude-all-symbols        # specify that no symbols should be automatically exported
LDFLAGS += -Wl,--subsystem=native:6.1       # specify the subsystem and the subsystem version targeted by the executable
LDFLAGS += -Wl,--major-image-version=6      # set the major number of the image version
LDFLAGS += -Wl,--minor-image-version=1      # set the minor number of the image version
LDFLAGS += -Wl,--dynamicbase                # use ASLR
LDFLAGS += -Wl,--high-entropy-va            # use HEASLR
LDFLAGS += -Wl,--image-base=0x180000000     # set the base address for the program
LDFLAGS += -Wl,--nxcompat                   # indicate that the executable is compatible with DEP
LDFLAGS += -Wl,--no-seh                     # the image does not use SEH
LDFLAGS += -Wl,--disable-tsaware            # the image isn't Terminal Server aware
LDFLAGS += -Wl,--no-insert-timestamp        # suppress generation of the PE file header timestamp
LDFLAGS += -Wl,--strip-all                  # remove all symbol table and relocation information from the executable
LDFLAGS += -Wl,--gc-sections                # enable garbage collection of unused input sections
LDFLAGS += -Wl,--oformat=pei-x86-64         # specify the binary format for the output object file
LDFLAGS += -Wl,--major-os-version=6         # set the major number of the OS version
LDFLAGS += -Wl,--minor-os-version=1         # set the minor number of the OS version
LDFLAGS += -Wl,--cref                       # output a cross reference table
LDFLAGS += -Wl,-Map=Temp/$(PROJECT)_x64.map # generate linker map file
LDFLAGS += -Wl,--disable-auto-import        # don't automatically import data symbols from other DLLs without dllimport
LDFLAGS += -Wl,-static                      # do not link against shared libraries
LDFLAGS += -Wl,--verbose                    # enable verbose mode

# Source files
SOURCES := $(wildcard Src/*.cpp)

# Object files
OBJECTS64 := $(patsubst Src/%.cpp, Temp/%_x64.obj, ${SOURCES})

# Default target
.DEFAULT_GOAL := help

# Display help
.PHONY: help
help:
	@ echo "[*] usage: make {pic|clean|help}"

# PIC target
.PHONY: pic
pic: Bin/$(PROJECT)_x64.bin

# Build PIC (x64)
Bin/$(PROJECT)_x64.bin: Bin/$(PROJECT)_x64.sys
	@ echo "[*] extracting .text section from PE file..."
	@ objcopy --target=pei-x86-64 --dump-section .text=$@ $<
	@ xxd -include -u $@ $(dir $@)/Shellcode.h
	@ echo "[+] done."

# Link (x64)
Bin/$(PROJECT)_x64.sys: $(OBJECTS64)
	@ echo "[*] linking COFF file(s) into PE file..."
	@ mkdir -p $(dir $@)
	@ $(CXX) $(LDFLAGS) $^ -o $@
	@ echo "[+] done."

# Compile (x64)
Temp/%_x64.obj: Src/%.cpp
	@ echo "[*] compiling C/C++ code into COFF file..."
	@ mkdir -p $(dir $@)
	@ $(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -o $@
	@ objdump --disassemble --disassembler-options=intel --reloc --wide --no-addresses --no-show-raw-insn $@ > $@.disasm
	@ echo "[+] done."

# Cleanup
.PHONY: clean
clean:
	@ echo "[*] cleaning up..."
	@ find . -name "*.obj" -type f -printf "removed '%f'\n" -delete
	@ find . -name "*.sys" -type f -printf "removed '%f'\n" -delete
	@ find . -name "*.bin" -type f -printf "removed '%f'\n" -delete
	@ find . -name "*.map" -type f -printf "removed '%f'\n" -delete
	@ find . -name "*.disasm" -type f -printf "removed '%f'\n" -delete
	@ find . -name "Shellcode.h" -type f -printf "removed '%f'\n" -delete
	@ echo "[+] done."
