-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
298 lines (257 loc) · 13.1 KB
/
Copy pathCMakeLists.txt
File metadata and controls
298 lines (257 loc) · 13.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
cmake_minimum_required(VERSION 3.21) # 3.21+ required for first-class HIP language support
# ── Project ────────────────────────────────────────────────────────────────
project(FSP.DMRCrack LANGUAGES C CXX)
# ── Options ────────────────────────────────────────────────────────────────
option(USE_HIP "Build with AMD ROCm/HIP instead of NVIDIA CUDA" OFF)
option(USE_CUDA "Build with the NVIDIA CUDA GPU backend" ON)
option(USE_OPENCL "Build with the portable OpenCL GPU backend (NVIDIA/AMD/Intel)" OFF)
option(NO_GUI "Build headless CLI only (no Win32 GUI)" OFF)
option(BUILD_TESTS "Build test utilities" OFF)
# The three GPU back-ends are mutually exclusive. Priority when several are
# requested: HIP > OpenCL > CUDA. OpenCL is the vendor-neutral backend used for
# the Debian/Kali package (free build deps, runs on NVIDIA + AMD + Intel);
# CUDA/HIP remain available as build-from-source options for peak performance.
if(USE_HIP)
set(USE_OPENCL OFF CACHE BOOL "Disabled: HIP backend selected" FORCE)
set(USE_CUDA OFF CACHE BOOL "Disabled: HIP backend selected" FORCE)
elseif(USE_OPENCL)
set(USE_CUDA OFF CACHE BOOL "Disabled: OpenCL backend selected" FORCE)
endif()
# USE_HIP/USE_CUDA compile the single-source CUDA kernel (src/bruteforce.cu).
# USE_OPENCL compiles src/bruteforce_cl.cpp. Otherwise we build the portable
# multi-threaded CPU-only engine (src/bruteforce.c), which needs no toolkit.
if(USE_HIP OR USE_CUDA)
set(GPU_BACKEND ON)
else()
set(GPU_BACKEND OFF)
endif()
# Force CLI on Linux (no Win32 GUI available)
if(UNIX)
set(NO_GUI ON CACHE BOOL "Forced ON: no Win32 GUI on Linux" FORCE)
endif()
# ── Compiler flags ─────────────────────────────────────────────────────────
# GCC/Clang and MSVC take different flag syntax. The GCC-style flags (-O3, -Wall)
# are what nvcc/hipcc/gcc consume on the Linux build paths; MSVC needs /-style
# equivalents or it misparses -W as "/W<next-arg>".
if(MSVC)
set(COMMON_C_FLAGS
/W3
/D_CRT_SECURE_NO_WARNINGS
)
else()
set(COMMON_C_FLAGS
-O3
-W
-Wall
-D_CRT_SECURE_NO_WARNINGS # harmless on GCC/Clang
)
endif()
if(WIN32)
list(APPEND COMMON_C_FLAGS -DWIN32 -D_WINDOWS)
endif()
if(NO_GUI)
list(APPEND COMMON_C_FLAGS -DNO_GUI)
endif()
if(USE_HIP)
list(APPEND COMMON_C_FLAGS -DUSE_HIP)
endif()
# ── Source files ───────────────────────────────────────────────────────────
# bruteforce.cu = GPU kernel (CUDA/HIP); bruteforce.c = portable CPU twin.
# They implement the same engine API — exactly one is compiled in.
if(GPU_BACKEND)
set(BRUTEFORCE_SRC src/bruteforce.cu)
elseif(USE_OPENCL)
set(BRUTEFORCE_SRC src/bruteforce_cl.cpp)
else()
set(BRUTEFORCE_SRC src/bruteforce.c)
endif()
# OpenCL backend: embed the kernel source (src/dmrcrack.cl) into a generated
# header so the runtime has no external .cl file dependency. The C++ raw-string
# wrapper handles arbitrary kernel content (must never contain the delimiter).
if(USE_OPENCL)
set(_cl_embed "${CMAKE_BINARY_DIR}/dmrcrack_cl_embed.h")
file(READ "${CMAKE_SOURCE_DIR}/src/dmrcrack.cl" _cl_src)
file(WRITE "${_cl_embed}"
"/* Auto-generated from src/dmrcrack.cl — do not edit. */\n"
"static const char *DMRCRACK_CL_SRC = R\"DMRCLSRC(\n${_cl_src}\n)DMRCLSRC\";\n")
endif()
set(SOURCES_COMMON
${BRUTEFORCE_SRC}
src/payload_io.c
src/rc4.c
src/lang.c
src/lang_en.c
src/lang_es.c
)
if(NO_GUI)
list(APPEND SOURCES_COMMON src/cli.c)
else()
list(APPEND SOURCES_COMMON
src/gui.c
src/updater.c
src/main.c
)
endif()
# ── GPU back-end ───────────────────────────────────────────────────────────
if(USE_HIP)
# ── AMD ROCm / HIP ─────────────────────────────────────────────────────
# First-class HIP language support (CMake 3.21+). The single-source kernel
# file src/bruteforce.cu is compiled as HIP; gpu_compat.h aliases the cudaXxx
# symbols to their hipXxx equivalents so the same source builds on both back-ends.
#
# GPU targets: RDNA1/2/3 (gfx10xx/gfx11xx) + CDNA (gfx90a) + Vega (gfx906/908).
# Override at configure time with -DCMAKE_HIP_ARCHITECTURES="gfxXXXX;...".
# Set before enable_language(HIP) so the compiler probe uses this list.
if(NOT DEFINED CMAKE_HIP_ARCHITECTURES)
set(CMAKE_HIP_ARCHITECTURES
"gfx906;gfx908;gfx90a;gfx1010;gfx1030;gfx1031;gfx1100;gfx1101;gfx1102")
endif()
enable_language(HIP)
find_package(hip REQUIRED)
# Compile bruteforce.cu as HIP rather than CUDA.
set_source_files_properties(src/bruteforce.cu PROPERTIES LANGUAGE HIP)
add_executable(dmrcrack ${SOURCES_COMMON})
target_compile_options(dmrcrack PRIVATE
$<$<COMPILE_LANGUAGE:HIP>:-O3>
${COMMON_C_FLAGS}
)
target_link_libraries(dmrcrack PRIVATE hip::device)
elseif(USE_CUDA)
# ── NVIDIA CUDA ─────────────────────────────────────────────────────────
enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
# Disable CMake's automatic arch-flag generation; we supply all -gencode
# flags explicitly below, gated on the CUDA version.
set(CMAKE_CUDA_ARCHITECTURES OFF)
add_executable(dmrcrack ${SOURCES_COMMON})
set_target_properties(dmrcrack PROPERTIES
CUDA_SEPARABLE_COMPILATION OFF
CUDA_RESOLVE_DEVICE_SYMBOLS ON
)
# Use -gencode=arch=...,code=... (single token, no space) so CMake does not
# inadvertently quote the flag as one shell word when generating Makefiles
# on Linux, which would make nvcc reject it with "single input file" error.
# sm_75 (Turing) and sm_86 (Ampere) — always included
target_compile_options(dmrcrack PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-O3>
$<$<COMPILE_LANGUAGE:CUDA>:-gencode=arch=compute_75,code=sm_75>
$<$<COMPILE_LANGUAGE:CUDA>:-gencode=arch=compute_86,code=sm_86>
)
# sm_89 (Ada Lovelace, RTX 4xxx) — requires CUDA 11.8+
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.8")
target_compile_options(dmrcrack PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-gencode=arch=compute_89,code=sm_89>
)
endif()
# sm_120 (Blackwell consumer, RTX 50xx) — requires CUDA 12.8+.
# NOTE: consumer Blackwell is sm_120, NOT sm_100 (that is datacenter B100/B200).
# Shipping sm_120 SASS removes the PTX-JIT dependency on the 50-series, which
# can silently fail to launch on some driver/toolkit combos.
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "12.8")
target_compile_options(dmrcrack PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-gencode=arch=compute_120,code=sm_120>
)
endif()
# PTX fallback: JIT-compile for future / other GPU generations. compute_89 PTX
# is forward-compatible with everything >= sm_89 (incl. sm_120), so it covers
# Hopper, datacenter Blackwell and any 50xx built on a pre-12.8 toolkit.
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.8")
target_compile_options(dmrcrack PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-gencode=arch=compute_89,code=compute_89>)
else()
target_compile_options(dmrcrack PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:-gencode=arch=compute_86,code=compute_86>)
endif()
# Windows-only MSVC host-compiler flags — gated to avoid breaking gcc on Linux
target_compile_options(dmrcrack PRIVATE
$<$<AND:$<COMPILE_LANGUAGE:CUDA>,$<BOOL:${WIN32}>>:-Xcompiler /W4,/D_CRT_SECURE_NO_WARNINGS,/DWIN32,/D_WINDOWS>
)
target_link_libraries(dmrcrack PRIVATE CUDA::cudart_static)
elseif(USE_OPENCL)
# ── Portable OpenCL (NVIDIA / AMD / Intel) ──────────────────────────────
# Vendor-neutral GPU backend (src/bruteforce_cl.cpp + embedded src/dmrcrack.cl).
# Build deps are free (opencl-headers + an ICD loader), so this is the
# configuration used for the Debian/Kali package. Falls back to a portable
# multi-threaded CPU scorer at runtime when no OpenCL device is present.
find_package(OpenCL REQUIRED)
add_executable(dmrcrack ${SOURCES_COMMON})
target_compile_options(dmrcrack PRIVATE ${COMMON_C_FLAGS})
target_compile_definitions(dmrcrack PRIVATE USE_OPENCL)
# The generated embed header lives in the build directory.
target_include_directories(dmrcrack PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(dmrcrack PRIVATE OpenCL::OpenCL)
else()
# ── CPU-only (no GPU toolkit) ───────────────────────────────────────────
# Portable multi-threaded engine compiled from src/bruteforce.c. Builds with
# a plain C toolchain and no proprietary dependencies — this is the variant
# shipped in Debian/Kali. GPU users build from source with -DUSE_CUDA=ON.
add_executable(dmrcrack ${SOURCES_COMMON})
target_compile_options(dmrcrack PRIVATE ${COMMON_C_FLAGS})
endif()
# ── Include paths ──────────────────────────────────────────────────────────
target_include_directories(dmrcrack PRIVATE include)
# ── Platform link libraries ────────────────────────────────────────────────
if(WIN32 AND NOT NO_GUI)
target_link_libraries(dmrcrack PRIVATE
user32 gdi32 comdlg32 kernel32 dwmapi shell32 advapi32
${CMAKE_SOURCE_DIR}/vendor/winsparkle/x64/WinSparkle.lib
)
target_include_directories(dmrcrack PRIVATE vendor/winsparkle/include)
elseif(WIN32 AND NO_GUI)
target_link_libraries(dmrcrack PRIVATE
user32 kernel32 advapi32
)
elseif(UNIX)
find_package(Threads REQUIRED)
target_link_libraries(dmrcrack PRIVATE Threads::Threads m)
endif()
# ── Output directory ──────────────────────────────────────────────────────
set_target_properties(dmrcrack PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin
)
# ── Test tools ────────────────────────────────────────────────────────────
if(BUILD_TESTS)
# Host test tools (no GPU toolkit required) -- parity with the Windows
# build_test_*.bat helpers. Each links only the host C sources it needs.
if(UNIX)
find_package(Threads REQUIRED)
endif()
# dmrcrack_add_test(<name> [extra sources...]) compiles tests/<name>.c.
function(dmrcrack_add_test name)
add_executable(${name} tests/${name}.c ${ARGN})
target_include_directories(${name} PRIVATE include)
if(WIN32)
target_link_libraries(${name} PRIVATE user32 gdi32 comdlg32 shell32 advapi32)
else()
target_link_libraries(${name} PRIVATE Threads::Threads m)
endif()
set_target_properties(${name} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
endfunction()
dmrcrack_add_test(test_strict_score src/bruteforce.c src/rc4.c src/payload_io.c)
dmrcrack_add_test(test_score_canonical src/rc4.c src/payload_io.c)
dmrcrack_add_test(test_silence_guard src/payload_io.c)
dmrcrack_add_test(test_hytera_ks)
# test_hytera_ks is a self-contained known-answer test (no external data),
# so it can run unattended in CI via `ctest`. The data-dependent tests
# (test_strict_score, test_score_canonical, test_silence_guard) build here
# but are run manually against a .bin capture (test/ is gitignored).
enable_testing()
add_test(NAME hytera_ks COMMAND test_hytera_ks)
endif()
# ── Install targets (used by cmake --install and Debian packaging) ─────────
include(GNUInstallDirs)
install(TARGETS dmrcrack
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(EXISTS "${CMAKE_SOURCE_DIR}/man/dmrcrack.1")
install(FILES man/dmrcrack.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
)
endif()
if(UNIX AND EXISTS "${CMAKE_SOURCE_DIR}/completions/dmrcrack.bash")
install(FILES completions/dmrcrack.bash
DESTINATION ${CMAKE_INSTALL_DATADIR}/bash-completion/completions
RENAME dmrcrack
)
endif()