Exetools

Exetools (https://forum.exetools.com/index.php)
-   Source Code (https://forum.exetools.com/forumdisplay.php?f=46)
-   -   [C++] Windows SysCall - NtCreateFile (https://forum.exetools.com/showthread.php?t=19467)

Mahmoudnia 03-24-2020 08:56

[C++] Windows SysCall - NtCreateFile
 
Windows SysCall - NtCreateFile

main.cpp
Code:

#include <Windows.h>
#include <stdio.h>
#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 <Windows.h>

#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

h4sh3m 03-25-2020 06:58

Hi

it's good idea but as you know function indexes is changing in every revisions so you need to have an table and select valid index(0x55 in this case) based on os revision id or get correct value at runtime !



BR,
h4sh3m

Mahmoudnia 03-25-2020 13:40

Quote:

Originally Posted by h4sh3m (Post 119608)
Hi

it's good idea but as you know function indexes is changing in every revisions so you need to have an table and select valid index(0x55 in this case) based on os revision id or get correct value at runtime !



BR,
h4sh3m

Hello

Yes, Exactly.

These links includes all tables based on windows version and their revisions .

Code:

https://github.com/tinysec/windows-syscall-table
https://github.com/j00ru/windows-syscalls


Sir.V65j 03-27-2020 14:29

Thanks Bro
Can you help me for do this in Delphi?

h4sh3m 03-27-2020 17:15

Sample for NtClose in delphi(x86 api), before testing check function index in your system and replace it in array(in my system index value is $0C).

Code:

program Project1;

{$APPTYPE CONSOLE}

uses
  Windows;

var
  Nt_xyz{NtClose} : function(a1 : THandle) : DWORD; Stdcall;
  Nt_xyz_Bytes : array[0..23] of Byte = ($B8, $0C, $00, $00, $00, $33, $C9, $8D, $54, $24, $04, $64, $FF, $15, $C0, $00, $00, $00, $83, $C4, $04, $C2, $04, $00);
  w : DWORD;
  hndl : THandle;

begin
  if not(VirtualProtect(@Nt_xyz_Bytes[0], High(Nt_xyz_Bytes), PAGE_EXECUTE, w)) then
    exit;

  FlushInstructionCache(GetCurrentProcess(), @Nt_xyz_Bytes[0], High(Nt_xyz_Bytes));

  @Nt_xyz := @Nt_xyz_Bytes[0];

  hndl := OpenProcess(PROCESS_VM_READ{PROCESS_ALL_ACCESS}, False, GetCurrentProcessId);
  if hndl <> 0 then
    Nt_xyz(hndl);
    //CloseHandle(hndl);
end.


Fyyre 04-08-2020 07:48

hFiref0x and I solve sysindex problem many many years ago, example:

https://github.com/Fyyre/directntapi...ster/usage.txt


All times are GMT +8. The time now is 00:51.

Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2020, vBulletin Solutions, Inc.
Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX