View difference between Paste ID: vpuH2f0g and UCXbKtbd
SHOW: | | - or go back to the newest paste.
1
#include <iostream> 
2
#include <strsafe.h>
3
#include <wtypes.h>
4
#include <winnt.h>
5
 
6
typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
7
#define NT_SUCCESS(Status) (((NTSTATUS)(Status) >= 0))
8
#define OBJ_CASE_INSENSITIVE                    0x00000040L
9
10
typedef struct _UNICODE_STRING
11
{
12
   USHORT Length;
13
   USHORT MaximumLength;
14
   PWSTR  Buffer;
15
} UNICODE_STRING, * PUNICODE_STRING;
16
17
typedef struct _OBJECT_ATTRIBUTES
18
{
19
   ULONG Length;
20
   HANDLE RootDirectory;
21
   PUNICODE_STRING ObjectName;
22
   ULONG Attributes;
23
   PVOID SecurityDescriptor;
24
   PVOID SecurityQualityOfService;
25
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
26
27
template< typename modHandleType, typename procNameType >
28
auto getProcAddressOrThrow(modHandleType modHandle, procNameType procName) {
29
   auto address = GetProcAddress(modHandle, procName);
30
   if (address == nullptr) throw std::exception{ (std::string{"Error importing: "} + (std::string{procName})).c_str() };
31
   return address;
32
}
33
34
#define CONCAT( id1, id2 ) id1##id2
35
// Notice- the comma operator is used to make sure the dll is loaded, discard the result- then getModuleHandle is used
36
37
#define IMPORTAPI( DLLFILE, FUNCNAME, RETTYPE, ... )                                                                        \
38
   typedef RETTYPE( WINAPI* CONCAT( t_, FUNCNAME ) )( __VA_ARGS__ );                                                        \
39
   template< typename... Ts >                                                                                               \
40
   auto FUNCNAME( Ts... ts ) {                                                                                              \
41
      const static CONCAT( t_, FUNCNAME ) func =                                                                            \
42
       (CONCAT( t_, FUNCNAME )) getProcAddressOrThrow( ( LoadLibrary( DLLFILE ), GetModuleHandle( DLLFILE ) ), #FUNCNAME ); \
43
      return func( std::forward< Ts >( ts )... );                                                                           \
44
   }; 
45
46
IMPORTAPI(L"ntdll.dll", RtlNtStatusToDosError, NTSTATUS, NTSTATUS )
47
IMPORTAPI( L"ntdll.dll", NtCreateSymbolicLinkObject, NTSTATUS, PHANDLE  , ACCESS_MASK  , POBJECT_ATTRIBUTES  , PUNICODE_STRING  )  
48
     
49
void ErrorExit(LPTSTR lpszFunction,NTSTATUS ntstatus)
50
{
51
   LPVOID lpMsgBuf;
52
   LPVOID lpDisplayBuf;
53
   DWORD dw = RtlNtStatusToDosError(ntstatus) ;
54
55
   FormatMessage(
56
      FORMAT_MESSAGE_ALLOCATE_BUFFER |
57
      FORMAT_MESSAGE_FROM_SYSTEM |
58
      FORMAT_MESSAGE_IGNORE_INSERTS,
59
      NULL,
60
      dw,
61
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
62
      (LPTSTR)&lpMsgBuf,
63
      0, NULL);
64
65
   lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
66
   StringCchPrintf( (LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), lpszFunction, dw, lpMsgBuf );
67
  
68
   MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
69
70
   LocalFree(lpMsgBuf);
71
   LocalFree(lpDisplayBuf);
72
   ExitProcess(dw);
73
}
74
75
int main()
76
{
77
   HANDLE SymbolicLinkHandle;
78
   UNICODE_STRING dest{ 8, 8, []() { static auto dest = (wchar_t*)L"\\NUL"; return dest; }() };
79
80
   UNICODE_STRING link{ 28, 28, []() { static auto dest = (wchar_t*)L"\\??\\GLOBALROOT"; return dest; }() };
81
   OBJECT_ATTRIBUTES oa{ sizeof(OBJECT_ATTRIBUTES), 0, &link, OBJ_CASE_INSENSITIVE, nullptr, nullptr };
82
 
83
   auto symlink_status = NtCreateSymbolicLinkObject( &SymbolicLinkHandle, MAXIMUM_ALLOWED, &oa, &dest );
84
   if ( ! (NT_SUCCESS(symlink_status))) { ErrorExit((wchar_t*)L"NtCreateSymbolicLinkObject", symlink_status); };
85
86
   std::cout << "Created \\??\\GLOBALROOT -> \\NUL - Immunity archived" << std::endl;
87
   
88
   system("pause");
89
 }