View Single Post
  #1  
Old 03-24-2020, 08:56
Mahmoudnia's Avatar
Mahmoudnia Mahmoudnia is offline
Family
 
Join Date: Nov 2012
Posts: 228
Rept. Given: 64
Rept. Rcvd 142 Times in 49 Posts
Thanks Given: 198
Thanks Rcvd at 283 Times in 97 Posts
Mahmoudnia Reputation: 100-199 Mahmoudnia Reputation: 100-199
[C++] Windows SysCall - NtCreateFile

Windows SysCall - NtCreateFile

main.cpp
Code:
#include 
#include 
#include "windows_struct.h"

int createTestFile()
{
    HANDLE hCurtProc = GetCurrentProcess();

#ifdef _WIN64
    BYTE byteNtCreateFile[0x1000]{
        0x4C, 0x8B, 0xD1,                                   // mov r10, rcx
        0xB8, 0x55, 0x00, 0x00, 0x00,                       // mov eax, 55h
        0xF6, 0x04, 0x25, 0x08, 0x03, 0xFE, 0x7F, 0x01,     // test byte ptr [7FFE0308h], 1
        0x75, 0x03,                                         // jne  ELSE 
        0x0F, 0x05,                                         // syscall
        0xC3,                                               // retn
        // ELSE:
        0xCD, 0x2E,                                         // int 2Eh
        0xC3                                                // retn
    };
#else
    BYTE byteNtCreateFile[0x1000]{
        0xB8, 0x55, 0x00, 0x00, 0x00,                       // mov eax, 55h
        0xBA, 0x40, 0x8D, 0x50, 0x77,                       // mov edx, offset j_Wow64Transition
        0xFF, 0xD2,                                         // syscall
        0xC2, 0x2C, 0x00,                                   // retn
        0x90                                                // nop
    };
#endif


    void* pShellcode = VirtualAllocEx(hCurtProc, nullptr, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (pShellcode == NULL)
    {
        printf("VirtualAlloc failed 0x%X\n", GetLastError());
        return false;
    }

    BOOL bWriteMem = WriteProcessMemory(hCurtProc, pShellcode, byteNtCreateFile, sizeof(byteNtCreateFile), nullptr);
    if (bWriteMem == 0)
    {
        printf("WriteProcessMemory failed 0x%X\n", GetLastError());
        VirtualFreeEx(hCurtProc, pShellcode, 0, MEM_RELEASE);
        return false;
    }

    HANDLE hFile = NULL;
    OBJECT_ATTRIBUTES objAttr;
    IO_STATUS_BLOCK ioStatusBlock;

    // Initalize Unicode String
    UNICODE_STRING ucFilepath;
    WCHAR wcFilepath[100] = L"\\??\\\\C:\\dev\\testFile.txt";
    RtlInitUnicodeString(&ucFilepath, wcFilepath);

    // Initialize object
    InitializeObjectAttributes(&objAttr, &ucFilepath, OBJ_CASE_INSENSITIVE, NULL, NULL);


    //NtCreateFile funcNtCreateFile = (NtCreateFile)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateFile");
    NtCreateFile funcNtCreateFile = (NtCreateFile)pShellcode;

    NTSTATUS stat = funcNtCreateFile(&hFile, FILE_GENERIC_WRITE, &objAttr, &ioStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
        FILE_RANDOM_ACCESS | FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
    if (!NT_SUCCESS(stat))
    {
        printf("NtCreateFile failed 0x%X\n", GetLastError());
        VirtualFreeEx(hCurtProc, pShellcode, 0, MEM_RELEASE);
        return false;
    }

    BOOL bClose = CloseHandle(hFile);
    if (bClose == FALSE)
    {
        printf("CloseHandle failed 0x%X\n", GetLastError());
        VirtualFreeEx(hCurtProc, pShellcode, 0, MEM_RELEASE);
        return false;
    }

    bool bFreeMem = VirtualFreeEx(hCurtProc, pShellcode, 0, MEM_RELEASE);
    if (bFreeMem == 0)
    {
        printf("VirutalFreeEx failed 0x%X\n", GetLastError());
        return false;
    }

    return true;
}


int main()
{
    if (createTestFile() == true)
        printf("createTestFile sucess\n");

    return 0;
}
windows_struct.h
Code:
#pragma once
#include 

#define FILE_OPEN 0x00000001
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_RANDOM_ACCESS 0x00000800
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define OBJ_CASE_INSENSITIVE 0x00000040

#define InitializeObjectAttributes(p, n, a, r, s) { \
(p)->Length = sizeof(OBJECT_ATTRIBUTES); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}

typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;

FORCEINLINE VOID RtlInitUnicodeString(
    _Out_ PUNICODE_STRING DestinationString,
    _In_opt_ PWSTR SourceString
)
{
    if (SourceString)
        DestinationString->MaximumLength = (DestinationString->Length = (USHORT)(wcslen(SourceString) * sizeof(WCHAR))) + sizeof(WCHAR);
    else
        DestinationString->MaximumLength = DestinationString->Length = 0;

    DestinationString->Buffer = SourceString;
}

typedef _Success_(return >= 0) LONG NTSTATUS;
typedef NTSTATUS* PNTSTATUS;



typedef struct _IO_STATUS_BLOCK
{
    union
    {
        LONG Status;
        PVOID Pointer;
    };
    ULONG Information;
} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK;

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR;
    PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;

#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)

typedef
NTSYSCALLAPI NTSTATUS
(*NTAPI NtCreateFile)(
    _Out_ PHANDLE FileHandle,
    _In_ ACCESS_MASK DesiredAccess,
    _In_ POBJECT_ATTRIBUTES ObjectAttributes,
    _Out_ PIO_STATUS_BLOCK IoStatusBlock,
    _In_opt_ PLARGE_INTEGER AllocationSize,
    _In_ ULONG FileAttributes,
    _In_ ULONG ShareAccess,
    _In_ ULONG CreateDisposition,
    _In_ ULONG CreateOptions,
    _In_reads_bytes_opt_(EaLength) PVOID EaBuffer,
    _In_ ULONG EaLength
    );
Source : guidedhacking
Reply With Quote
The Following 3 Users Say Thank You to Mahmoudnia For This Useful Post:
niculaita (03-25-2020), nimaarek (04-08-2020), Sir.V65j (03-27-2020)