Dhaedalida marker SDK
=====================

Tag a function for protection in source: bracket the code you want
protected with RabbitStart() / RabbitEnd(), and the Dhaedalida GUI auto-selects the
enclosing function and hands its address to the CLI. Detection works with or
without a PDB because the markers are found by an embedded byte signature, not
by symbol name.

    #include "dhae_sdk.h"
    int validate_license(const char* key) {
        RabbitStart();
        /* ... sensitive code ... */
        RabbitEnd();
        return ok;
    }

Whole-method granularity: the markers tag the enclosing function; Dhaedalida
protects the ENTIRE function, not just the span between the two calls.

FIVE MARKER PAIRS, one per protection mode - pick per function:
  RabbitStart() / RabbitEnd()        Rabbit, the default VM (--rabbit)   - the faster VM
  BearStart() / BearEnd()            Bear, the strongest VM (--bear)     - approx 5x slower

  TRexStart() / TRexEnd()            T-Rex AVX2 VM (--trex), x64 and PE32
  WolfStart() / WolfEnd()            Wolf SSE2 VM (--wolf), x64 and PE32
  RhinoStart() / RhinoEnd()          Rhino MMX VM (--rhino), x64 and PE32
Rhino requires Pro or Ultimate; Basic and Demo reroute Rhino markers to Rabbit.
Wolf needs SSE2 at runtime and Pro or Ultimate. Basic and Demo reroute Wolf markers to Rabbit.
T-Rex needs AVX2 at runtime and Pro or Ultimate. Pro and Ultimate support optional packing
and protection layers on both bitnesses. Basic and Demo reroute T-Rex markers to Rabbit;
explicit Demo CLI T-Rex requests are refused.

A function may carry only ONE pair. Two pairs on one function is ambiguous about
how to protect it, and Dhaedalida refuses the job rather than choosing for you.
Rabbit and Bear support x64 and PE32. Bear needs a Pro or Ultimate licence; the Demo edition
protects with Rabbit, and a Bear-marked function is virtualized instead.

TWO SERVICE MARKERS - a different KIND of thing. These are REAL CALLABLE
FUNCTIONS, not tags: they select no protection mode and bracket nothing, and
what Dhaedalida replaces is their OWN body. You act on the value they return.
Both are full-version only.

  DhaedalidaIsDebuggerPresent()   1 = a debugger was detected, 0 = not.
  DhaedalidaIsImagePatched()      1 = this image has been modified, 0 = not.

      if (DhaedalidaIsImagePatched()) {
          /* you decide what happens */
      }

In a binary Dhaedalida has not processed BOTH return 0, so your own debug builds
take neither branch. Neither result is cached - every call re-runs the work, which
is what makes a debugger that attaches LATER, or a patch applied LATER, still
detectable. Call them at a decision point, never in a loop.

DhaedalidaIsDebuggerPresent() must NOT be called from DllMain: one of its checks
loads user32.dll, and LoadLibrary under the loader lock deadlocks.
DhaedalidaIsImagePatched() loads nothing and is safe from DllMain - but a software
breakpoint in your own code makes it return 1 (that is the intended answer), and a
program that rewrites its own code should not use it at all.

Core files
----------
  dhae_marker_sig.h   The marker magic constants (shared with the GUI scanner).
  dhae_sdk.h          The marker prototypes (C / C++).
  dhae_sdk.c          The MSVC C/C++ marker definitions.
  dhae_licensing.h    Application-licensing query API and fixed-width structs.
  dhae_licensing.c    Link into the licensed EXE/DLL (x86 or x64).
  dhae_splash.h      DhaedalidaCloseSplash() startup-screen API.
  dhae_splash.c      Link into the EXE/DLL owning the splash (x86 or x64).
Select Misc > Splash screen > Close from code, then call DhaedalidaCloseSplash().
Repeated or early calls are safe. Without a splash the function does nothing.
  dhae_machine_id_impl.h  Shared hardware fingerprint implementation.

Ultimate application licensing queries
-------------------------------------
Compile dhae_licensing.c into your application and include dhae_licensing.h.
DhaedalidaGetMachineId(mask, hex, 65) returns a SHA-256 hexadecimal Machine ID.
Select CPU=1, BIOS=2, MAC=4, HDD=8 by OR-ing flags; zero is invalid.
It works before activation/protection. Link bcrypt.lib and iphlpapi.lib.
Use the same mask when issuing a locked license. Missing hardware fails.
CPU is a processor model identity, not a unique chip serial. Selected hardware
changes require reissuing the license; cloning/spoofing is an offline limit.
Protect that same module with Ultimate application licensing enabled.
DhaedalidaGetLicenseInfo(&info, sizeof(info)) returns 1 for available data.
It exposes status/source, UTF-8 customer fields, trial limits/usage,
remaining days/executions, expiration and configured blocked countries.
Convenience functions: DhaedalidaGetCustomerInfo, DhaedalidaGetTrialDaysRemaining,
DhaedalidaGetTrialExecutionsRemaining and DhaedalidaGetLicenseExpiration.
All return success separately from the value; 0 means unavailable or invalid
arguments. Check it before using the result. No license runtime = unavailable.
Times are UTC FILETIME ticks; expiry is exclusive midnight after the selected
date, zero means unlimited. UINT32_MAX means unlimited remaining days/runs.
Remaining executions exclude this launch. Counts/customer data are a startup
snapshot; days update per query, rounded up. Queries do not consume a run.
The effective expiration is the earliest active trial time limit or license
expiration. A licensed process bypasses trials; trial-only getters return 0.
TLS callbacks before licensing startup return unavailable. Data belongs to
this EXE/DLL, not its host. Installing a new license requires restarting.

Language bindings (bindings\)
-----------------------------
Every binding emits the same 8 magic bytes at a call-reachable site, so the one
GUI scanner detects them all, and every binding supplies all twelve markers - the
five pairs and the two service markers - on both 64-bit and 32-bit x86.

  C / C++ (MSVC)              dhae_sdk.c + dhae_sdk.h
  C (GCC / Clang / MinGW)     bindings\c-gnu\dhae_sdk_gnu.c
  Rust                        bindings\rust\dhae_marker.rs
  Delphi / Object Pascal/FPC  bindings\pascal\DhaeMarker.pas
  Go                          bindings\go\
  Assembly - MASM             bindings\masm\dhae_marker.asm     (ml64, 64-bit)
                              bindings\masm\dhae_marker32.asm   (ml,   32-bit)
  Assembly - FASM             bindings\fasm\dhae_marker.asm     (64-bit)
                              bindings\fasm\dhae_marker32.asm   (32-bit)
  Assembly - NASM / YASM      bindings\nasm\dhae_marker.asm     (64-bit)
                              bindings\nasm\dhae_marker32.asm   (32-bit)
  D                           bindings\d\dhae_marker.d
  Zig                         bindings\zig\dhae_marker.zig
  Nim                         bindings\nim\dhaemarker.nim

Every binding covers both 64-bit and 32-bit x86. For C/C++ that means the build
line never changes - cl /O2 yourapp.c dhae_sdk.c works in either dev prompt.

Any other language with a C FFI can link dhae_sdk.c and declare the externs it needs.
Visual Basic / C# / F# and other .NET languages are not supported (they emit
managed IL, not native machine code).

Requirements
------------
Native x86 - 64-bit or 32-bit; markers statically linked into the image, reached
by a direct call. Dhaedalida protects both, EXE and DLL. On a 32-bit target,
ship the .pdb beside it if you can: a 32-bit image carries no unwind table, so
without symbols the enclosing function has to be worked out from the marker
call, and a worked-out address is flagged as such so you can check it.
