3 Building
Watersrc-stack edited this page 2026-10-11 17:55:06 +02:00

Building

Rules

Rule What it does
make Builds ./netotter (Linux) with -W -Wall -Wextra -Werror and no optimisation.
make re Full rebuild.
make clean / make fclean Remove the objects / the objects and the binaries.
make release Optimised and hardened build (below). Rebuilds this target's objects.
make asan Clean rebuild with -g3 and AddressSanitizer + UndefinedBehaviorSanitizer, for memory checks (works with gdb).
make install / make uninstall Linux: /usr/bin/netotter with cap_net_raw, through sudo. Windows: see below.
make cap Sets cap_net_raw on the local ./netotter, rebuilding it first if needed.
make windows Cross-compiles NetOtter.exe from Linux with x86_64-w64-mingw32-gcc.
make windows-re / make windows-release Full Windows rebuild / Windows release build.
make docs Generates the function explorer and the wiki's Functions-* pages.

Things to know:

  • No header dependencies: after changing a struct in a header, run make re, or objects compiled with the old layout will be linked with the new one.
  • Every warning breaks the build (-Werror).
  • The file list is explicit: when you add a .c file, add it to SRCS in the Makefile, or to ADDSRCS for an OS-specific file.
  • No test suite, no linter: test by running NetOtter (live, or with -I on sample captures), under make asan for memory errors.
  • Mixed builds: asan and release reuse the normal object paths, so run make re afterwards to go back to a normal build.

The release build

make release follows the OpenSSF compiler hardening guide.

Flags Why
-O2 -flto=auto -DNDEBUG Optimisation, with link-time optimisation across files. -O2 rather than -O3: it's what distributions ship and what the hardening options are validated with.
-D_FORTIFY_SOURCE=3 Bounds-checked memcpy, read... where sizes are known.
-fstack-protector-strong Stack canaries.
-fstack-clash-protection Stack probes, so a big allocation can't jump over the guard page.
-fcf-protection=full Intel CET: endbr64 landing pads and shadow-stack compatibility.
-ftrivial-auto-var-init=zero Uninitialised local variables start at zero.
-fzero-call-used-regs=used-gpr Clears used registers on return (harder ROP).
-fno-strict-overflow -fno-strict-aliasing -fno-delete-null-pointer-checks No optimisations based on undefined behaviour.
-fstrict-flex-arrays=3 Only real [] flexible arrays are unbounded, which helps the fortify checks.
-fPIE -pie (Linux) Position-independent executable, for full ASLR.
-Wl,-z,relro,-z,now (Linux) Full RELRO: the GOT is read-only after startup.
-Wl,-z,noexecstack (Linux) Non-executable stack.
-Wl,--as-needed,--no-copy-dt-needed-entries (Linux) Links only the libraries actually used.
-Wl,--dynamicbase,--nxcompat,--high-entropy-va (Windows) ASLR with 64-bit entropy, non-executable data (DEP).
-s Strips the symbols.

To check a Linux release binary:

readelf -hW netotter | grep Type          # DYN (Position-Independent Executable file)
readelf -lW netotter | grep -E 'RELRO|STACK'   # GNU_RELRO present, GNU_STACK RW (not RWE)
readelf -dW netotter | grep FLAGS         # BIND_NOW, FLAGS_1 NOW PIE
readelf -nW netotter | grep feature       # x86 feature: IBT, SHSTK
readelf --dyn-syms -W netotter | grep _chk   # __memcpy_chk, __read_chk, __stack_chk_fail

For Windows, run x86_64-w64-mingw32-objdump -p NetOtter.exe and look for DYNAMIC_BASE, HIGH_ENTROPY_VA and NX_COMPAT under DllCharacteristics.

make release only cleans its own target's objects, so make windows-release leaves the Linux build alone, and the other way round.

Windows

The Windows build links against OpenSSL's libcrypto-3-x64.dll, which ships in libs/windows/ with its headers (libs/windows/include/openssl/), so cross-compiling needs nothing but mingw-w64-gcc.

  • DLLs next to the exe: the build copies libcrypto-3-x64.dll and libssp-0.dll (which libcrypto needs) next to NetOtter.exe. Windows has no rpath: it only looks for DLLs next to the exe, in the system folders and in PATH. So wine ./NetOtter.exe ... works from the repository root.
  • Separate objects: the Windows objects go to obj/windows/, so they never mix with the Linux ones.
  • Updating the bundled OpenSSL: the DLLs and headers are copies of the system MinGW files (/usr/x86_64-w64-mingw32/bin and include/openssl). Refresh them together, because the headers must match the DLL version.
  • Npcap isn't linked: it's loaded at runtime (see OS backends), so the build needs no Npcap SDK.

On Windows itself, use a 64-bit MinGW-w64 toolchain (WinLibs or MSYS2 UCRT64) with mingw32-make from cmd or PowerShell. The Makefile's Windows rules use cmd.exe syntax.

Rule (Windows) Effect
install / uninstall %LOCALAPPDATA%\Programs\NetOtter (WIN_INSTALL_DIR), no admin rights, PATH untouched.
install-admin / uninstall-admin C:\Program Files\NetOtter (WIN_ADMIN_DIR), admin rights checked with fltmc. The folder is added to / removed from the machine PATH by libs/windows/machine_path.ps1.

machine_path.ps1 edits the registry value itself, so the %SystemRoot% entries stay unexpanded: [Environment]::SetEnvironmentVariable would write them back expanded. It then broadcasts the change so new terminals see it. From a cross build, the install rules only print that they must run on Windows.

Documentation

make docs builds the Linux and the Windows objects with GCC's -fcallgraph-info in obj/codemap/, then runs tools/codemap/codemap.py. It writes:

  • docs/build/pages/index.html: the interactive explorer, a single static page to open in a browser or publish on any web server. The pages branch holds the published copy, served at fg.water-source.ovh/pages/NetOtter.
  • docs/build/wiki/: Function-Explorer.md and one Functions-<module>.md per source folder, for this wiki.

The text comes from the comments above each function definition, or above its prototype in a header. To improve the documentation, improve those comments. The script warns when a flow diagram in tools/codemap/template.html names a function that no longer exists. It needs Python 3 and mingw-w64-gcc.

Two variables set the links: FORGE_URL (the repository's web page, for the source and wiki links, https://fg.water-source.ovh/Watersrc-stack/NetOtter by default) and PAGES_URL (where the explorer is published, https://fg.water-source.ovh/pages/NetOtter/ by default, linked from Function explorer; set it empty and the page says to open it locally instead).