Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <stdio.h>
- #define OBJ_CASE_INSENSITIVE 0x00000040
- #define DB(_val_) __asm __emit (_val_)
- #define INVALID_SYSCALL (DWORD)(-1)
- #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
- // code selectors
- #define CS_32 0x23
- #define CS_64 0x33
- #define RAX 0
- #define RCX 1
- #define RDX 2
- #define RBX 3
- #define RSP 4
- #define RBP 5
- #define RSI 6
- #define RDI 7
- #define R8 8
- #define R9 9
- #define R10 10
- #define R11 11
- #define R12 12
- #define R13 13
- #define R14 14
- #define R15 15
- #define X64_PUSH(_r_) DB(0x48 | ((_r_) >> 3)) DB(0x50 | ((_r_) & 7))
- #define X64_POP(_r_) DB(0x48 | ((_r_) >> 3)) DB(0x58 | ((_r_) & 7))
- // Switch processor to long mode
- #define X64_ENTER_CS(_cs_) \
- { \
- DB(0x6a) DB(_cs_) /* push @cs */ \
- DB(0xe8) DB(0x00) DB(0x00) DB(0x00) DB(0x00) /* call $+5 */ \
- DB(0x83) DB(0x04) DB(0x24) DB(0x05) /* add dword [esp], 5 */ \
- DB(0xcb) /* retf */ \
- }
- // Switch processor to WOW64 mode
- #define X64_EXIT_CS(_cs_) \
- { \
- DB(0xe8) DB(0x00) DB(0x00) DB(0x00) DB(0x00) /* call $+5 */ \
- DB(0xc7) DB(0x44) DB(0x24) DB(0x04) DB(_cs_) /* mov dword [rsp + 4], @cs */ \
- DB(0x00) DB(0x00) DB(0x00) \
- DB(0x83) DB(0x04) DB(0x24) DB(0x0d) /* add dword [rsp], 0xD */ \
- DB(0xcb) /* retf */ \
- }
- #define X64_SYSCALL() \
- { \
- DB(0x0f) DB(0x05) \
- }
- // 64-bit assembly helpers
- #define X64_ENTER() X64_ENTER_CS(CS_64)
- #define X64_EXIT() X64_EXIT_CS(CS_32)
- #define GET_NEXT_ARG() i < ArgsCount ? Args[i++] : 0
- #define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
- DWORD x64_Syscall(DWORD dwSyscallNumber, PDWORD64 Args, DWORD ArgsCount)
- {
- DWORD Status = 0, OldStack = 0, i = 0;
- if (dwSyscallNumber == INVALID_SYSCALL)
- {
- return STATUS_UNSUCCESSFUL;
- }
- DWORD64 _rcx = GET_NEXT_ARG();
- DWORD64 _rdx = GET_NEXT_ARG();
- DWORD64 _r8 = GET_NEXT_ARG();
- DWORD64 _r9 = GET_NEXT_ARG();
- DWORD64 StackArgs = NULL;
- DWORD64 StackArgsCount = 0;
- if (ArgsCount > 4)
- {
- StackArgs = (DWORD64)&Args[3];
- StackArgsCount = ArgsCount - 4;
- }
- __asm
- {
- push ebx
- push esi
- push edi
- /**
- * Stack align for 64-bit mode.
- */
- mov OldStack, esp
- and esp, 0xfffffff0
- /**
- * Swith to the long mode.
- */
- X64_ENTER()
- /**
- * Copy register arguments.
- */
- push _rcx
- X64_POP(RCX)
- push _rdx
- X64_POP(RDX)
- push _r8
- X64_POP(R8)
- push _r9
- X64_POP(R9)
- /**
- * Push stack arguments.
- */
- push StackArgs
- X64_POP(RDI)
- push StackArgsCount
- X64_POP(RSI)
- test esi, esi
- jz _call
- _loop_push :
- push[edi + esi * 8]
- sub esi, 1
- jnz _loop_push
- _call :
- /**
- * Perform a system call.
- */
- push _rcx
- X64_POP(R10)
- mov eax, dwSyscallNumber
- sub esp, 0x28
- X64_SYSCALL()
- add esp, 0x28
- /**
- * Save returned status code.
- */
- mov Status, eax
- /**
- * Remove syscall arguments from the stack.
- */
- push StackArgsCount
- X64_POP(RSI)
- test esi, esi
- jz _end
- _loop_pop :
- pop edi
- sub esi, 1
- jnz _loop_pop
- _end :
- /**
- * Swith back to the 32-bit mode.
- */
- X64_EXIT()
- mov esp, OldStack
- pop edi
- pop esi
- pop ebx
- }
- return Status;
- }
- #define TEB64_ProcessEnvironmentBlock 0x60
- typedef DWORD64 PTR64;
- #include <pshpack8.h>
- typedef struct _LIST_ENTRY_64
- {
- PTR64 Flink;
- PTR64 Blink;
- } LIST_ENTRY_64;
- typedef struct _STRING_64
- {
- USHORT Length;
- USHORT MaximumLength;
- PTR64 Buffer;
- } ANSI_STRING_64,
- * PANSI_STRING_64;
- typedef struct _UNICODE_STRING_64
- {
- USHORT Length;
- USHORT MaximumLength;
- PTR64 Buffer;
- } UNICODE_STRING64,
- * PUNICODE_STRING64;
- #include <poppack.h>
- #include <pshpack8.h>
- typedef struct _OBJECT_ATTRIBUTES_64
- {
- ULONG Length;
- PTR64 RootDirectory;
- PTR64 ObjectName;
- ULONG Attributes;
- PTR64 SecurityDescriptor;
- PTR64 SecurityQualityOfService;
- } OBJECT_ATTRIBUTES_64,
- * POBJECT_ATTRIBUTES_64;
- typedef struct _IO_STATUS_BLOCK_64
- {
- union
- {
- NTSTATUS Status;
- PTR64 Pointer;
- };
- PTR64 Information;
- } IO_STATUS_BLOCK_64,
- * PIO_STATUS_BLOCK_64;
- #include <poppack.h>
- __declspec(align(16))
- typedef struct _NT_OPEN_FILE_PARAMS
- {
- PTR64 FileHandle;
- IO_STATUS_BLOCK_64 IoStatusBlock;
- UNICODE_STRING64 usName;
- OBJECT_ATTRIBUTES_64 ObjectAttributes;
- WCHAR Name[MAX_PATH];
- } NT_OPEN_FILE_PARAMS,
- * PNT_OPEN_FILE_PARAMS;
- int main(int argc, CHAR* argv[])
- {
- PNT_OPEN_FILE_PARAMS Params = (PNT_OPEN_FILE_PARAMS)VirtualAlloc(
- NULL, sizeof(NT_OPEN_FILE_PARAMS),
- MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE
- );
- if (Params == NULL)
- {
- return -1;
- }
- ACCESS_MASK DesiredAccess = FILE_GENERIC_READ;
- ULONG ShareAccess = FILE_SHARE_READ;
- ULONG OpenOptions = 0;
- wcscpy_s(Params->Name, L"\\??\\C:\\Windows\\system32\\ntdll.dll");
- Params->usName.Buffer = (PTR64)&Params->Name;
- Params->usName.Length = Params->usName.MaximumLength = (USHORT)wcslen(Params->Name) * 2;
- Params->ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES_64);
- Params->ObjectAttributes.RootDirectory = NULL;
- Params->ObjectAttributes.ObjectName = (PTR64)&Params->usName;
- Params->ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
- Params->ObjectAttributes.SecurityDescriptor = Params->ObjectAttributes.SecurityQualityOfService = NULL;
- DWORD64 Args[] =
- {
- (DWORD64)&Params->FileHandle,
- (DWORD64)DesiredAccess,
- (DWORD64)&Params->ObjectAttributes,
- (DWORD64)&Params->IoStatusBlock,
- (DWORD64)ShareAccess,
- (DWORD64)OpenOptions
- };
- while (true) {
- DWORD Status = x64_Syscall(0x33, Args, 6);
- printf("NtOpenFile: Status = 0x%.8x, FileHandle = 0x%.8x\n", Status, (HANDLE)Params->FileHandle);
- DWORD64 Args2[1];
- Args2[0] = Params->FileHandle;
- Status = x64_Syscall(0xF, Args2, 1);
- printf("NtClose: Status = 0x%.8x\n", Status);
- Sleep(100);
- }
- VirtualFree(Params, 0, MEM_RELEASE);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment