; dhae_marker32.asm - MASM (ml.exe) binding of the Dhaedalida RabbitStart/RabbitEnd
; virtualization markers for 32-bit x86 (PE32). The x64 binding is the sibling
; dhae_marker.asm, assembled with ml64.
;
; A separate file rather than an IFDEF arm because the two assemblers are
; different programs with incompatible dialects: ml.exe REQUIRES .386 + .model
; flat, both of which ml64.exe rejects outright, and there is no predefined
; symbol that distinguishes them. The `32` in the filename is what keeps the two
; from being assembled by the wrong tool.
;
; 32-bit x86 has no 64-bit immediate, so the magic cannot be hidden inside a
; `mov reg, imm64` the way the x64 binding does. It is emitted as inline DATA
; and jumped over:
;
;     EB 08                       jmp short $+10   -> the ret below
;     01 54 76 DE C0 E5 1A D1     DHAE_SIG_RABBITSTART, little-endian
;     C3                          ret              <- the jump target
;
; The 8 magic bytes therefore sit at offset +2, exactly where the x64 binding
; puts them, well inside the scanner's 16-byte window. The DB values MUST equal
; DHAE_SIG_RABBITSTART / DHAE_SIG_RABBITEND in sdk/dhae_marker_sig.h.
;
; `.model flat, C` is what gives the two symbols their i386 COFF cdecl
; decoration, `_RabbitStart` and `_RabbitEnd`, which is the name an MSVC-x86 C caller
; emits. A bare RET is correct because the markers take no arguments - there is
; nothing for a callee-cleanup convention to pop.
;
; Build (from a 32-bit dev prompt - note ml, NOT ml64):
;     ml /c /coff /Fo dhae_marker32.obj dhae_marker32.asm
; then link dhae_marker32.obj into your PE32 program and declare in C:
;     void RabbitStart(void); void RabbitEnd(void);
; (or just #include "dhae_sdk.h").

; ALIGN 4, not 16: under `.model flat` ml.exe gives the code segment DWORD
; alignment and rejects a larger ALIGN with "A2189: invalid combination with
; segment alignment". The x64 sibling can use 16 because ml64's segments are.
; It costs nothing here - the scanner locates a marker by its magic bytes, not by
; its alignment, and the magic sits at offset +2 either way.

.386
.model flat, C

.code

ALIGN 4
PUBLIC RabbitStart
RabbitStart PROC
    DB  0EBh, 008h                                      ; jmp short $+10
    DB  001h, 054h, 076h, 0DEh, 0C0h, 0E5h, 01Ah, 0D1h  ; DHAE_SIG_RABBITSTART
    DB  0C3h                                            ; ret
RabbitStart ENDP

ALIGN 4
PUBLIC RabbitEnd
RabbitEnd PROC
    DB  0EBh, 008h                                      ; jmp short $+10
    DB  002h, 054h, 076h, 0DEh, 0C0h, 0E5h, 01Ah, 0D1h  ; DHAE_SIG_RABBITEND
    DB  0C3h                                            ; ret
RabbitEnd ENDP

ALIGN 4
PUBLIC BearStart
BearStart PROC
    DB  0EBh, 008h                                      ; jmp short $+10
    DB  005h, 054h, 076h, 0DEh, 0C0h, 0E5h, 01Ah, 0D1h  ; DHAE_SIG_BEARSTART
    DB  0C3h                                            ; ret
BearStart ENDP

ALIGN 4
PUBLIC BearEnd
BearEnd PROC
    DB  0EBh, 008h                                      ; jmp short $+10
    DB  006h, 054h, 076h, 0DEh, 0C0h, 0E5h, 01Ah, 0D1h  ; DHAE_SIG_BEAREND
    DB  0C3h                                            ; ret
BearEnd ENDP

END
