flat assembler
Message board for the users of flat assembler.

Index > Windows > Problem calling NtCreateFile in 64 bit

Author
Thread Post new topic Reply to topic
seapoint



Joined: 25 May 2013
Posts: 8
seapoint 25 May 2013, 01:25
Hi. I'm trying to call NtCreateFile and create a file in 64 bit, but there's some error that I'm unable to find. Can someone help?
The 32 bit code works.

Working 32 bit code:
Code:
format PE GUI
entry start

include 'win32a.inc'

define  OBJ_CASE_INSENSITIVE   0x00000040

FILE_READ_DATA = 0x0001
FILE_READ_ATTRIBUTES = 0x0080
FILE_READ_EA = 0x0008
define FILE_SUPERSEDE 0x00000000
define FILE_NON_DIRECTORY_FILE 0x00000040
define FILE_GENERIC_READ  (STANDARD_RIGHTS_READ or FILE_READ_DATA or FILE_READ_ATTRIBUTES or FILE_READ_EA)

section '.text' code readable executable

start:
mov [attr.Length],              sizeof.OBJECT_ATTRIBUTES
mov [attr.RootDirectory],       0
mov [attr.Attributes],          OBJ_CASE_INSENSITIVE
mov [attr.ObjectName],          fn
mov [attr.SD],                  0
mov [attr.SQOS],                0

mov [fn.Length], FileNameEnd - FileName
mov [fn.MaximumLength], FileNameEnd - FileName
mov [fn.Buffer], FileName

invoke NtCreateFile, hFile,\
[accessMask],\          ;DesiredAccess
attr,\                  ;ObjectAttributes
iosb,\                  ;IoStatusBlock
0,\                     ;AllocationSize
FILE_ATTRIBUTE_NORMAL,\ ;FileAttributes
FILE_SHARE_READ,\       ;ShareAccess
FILE_SUPERSEDE,\        ;CreateDisposition
0,\                     ;CreateOptions
0,\                     ;EaBuffer
0                       ;EaLength
ret

section '.data' data writeable readable
accessMask dd 1F01ffh

struct UNICODE_STRING
        Length          dw ?
        MaximumLength   dw ?
        Buffer          dd ?
ends

struct OBJECT_ATTRIBUTES
        Length          dd ? ;ULONG           Length;
        RootDirectory   dd ? ;HANDLE          RootDirectory;
        ObjectName      dd ? ;PUNICODE_STRING ObjectName;
        Attributes      dd ? ;ULONG           Attributes;
        SD              dd ? ;PVOID           SecurityDescriptor;
        SQOS            dd ? ;PVOID           SecurityQualityOfService;
ends

iosb    dd 2 dup (0)
hFile   dd ?
fn      UNICODE_STRING    ?
attr    OBJECT_ATTRIBUTES ?

FileName du '\??\C:\temp\test32.txt'
FileNameEnd:

section '.idata' import data readable writeable
library ntdll, "ntdll.dll"
import ntdll, NtCreateFile, "NtCreateFile"
    


NOT working 64 bit code - NTSTATUS is 0xC000000D, STATUS_INVALID_PARAMETER - but which one?
Code:
format PE64 GUI 5.0
entry start

include 'win64a.inc'

define  OBJ_CASE_INSENSITIVE   0x00000040

FILE_READ_DATA = 0x0001
FILE_READ_ATTRIBUTES = 0x0080
FILE_READ_EA = 0x0008
define FILE_SUPERSEDE 0x00000000
define FILE_NON_DIRECTORY_FILE 0x00000040
define FILE_GENERIC_READ  (STANDARD_RIGHTS_READ or FILE_READ_DATA or FILE_READ_ATTRIBUTES or FILE_READ_EA)

section '.text' code readable executable

start:
mov [attr.Length],              sizeof.OBJECT_ATTRIBUTES
mov [attr.RootDirectory],       0
mov [attr.Attributes],          OBJ_CASE_INSENSITIVE
mov [attr.ObjectName],          fn
mov [attr.SD],                  0
mov [attr.SQOS],                0

mov [fn.Length], FileNameEnd - FileName
mov [fn.MaximumLength], FileNameEnd - FileName
mov [fn.Buffer], FileName

invoke NtCreateFile, hFile,\
[accessMask],\          ;DesiredAccess
attr,\                  ;ObjectAttributes
iosb,\                  ;IoStatusBlock
0,\                     ;AllocationSize
FILE_ATTRIBUTE_NORMAL,\ ;FileAttributes
FILE_SHARE_READ,\       ;ShareAccess
FILE_SUPERSEDE,\        ;CreateDisposition
0,\                     ;CreateOptions
0,\                     ;EaBuffer
0                       ;EaLength
ret

section '.data' data writeable readable
accessMask dd 1F01ffh

struct UNICODE_STRING
        Length          dw ?
        MaximumLength   dw ?
        Buffer          dq ?
ends

struct OBJECT_ATTRIBUTES
        Length          dd ? ;ULONG           Length;
        RootDirectory   dq ? ;HANDLE          RootDirectory;
        ObjectName      dq ? ;PUNICODE_STRING ObjectName;
        Attributes      dd ? ;ULONG           Attributes;
        SD              dq ? ;PVOID           SecurityDescriptor;
        SQOS            dq ? ;PVOID           SecurityQualityOfService;
ends

align 16
iosb    dd 0
dq 0

align 16
hFile   dq ?
align 16
fn      UNICODE_STRING    ?
align 16
attr    OBJECT_ATTRIBUTES ?

align 16
FileName du '\??\C:\temp\test64.txt'
FileNameEnd:

section '.idata' import data readable writeable
library ntdll, "ntdll.dll"
import ntdll, NtCreateFile, "NtCreateFile"   
    


align 16 is needed, otherwise I get STATUS_DATATYPE_MISALIGNMENT

Related question: are there any debuggers for 64 bit other than windbg?
Post 25 May 2013, 01:25
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 25 May 2013, 02:40
aligning is not enough. you need padding too
Code:
struct UNICODE_STRING
        Length          dw ?
        MaximumLength   dw ?
                        dd ?
        Buffer          dq ?
ends

struct OBJECT_ATTRIBUTES
        Length          dd ? ;ULONG           Length;
                        dd ?
        RootDirectory   dq ? ;HANDLE          RootDirectory;
        ObjectName      dq ? ;PUNICODE_STRING ObjectName;
        Attributes      dd ? ;ULONG           Attributes;
                        dd ?
        SD              dq ? ;PVOID           SecurityDescriptor;
        SQOS            dq ? ;PVOID           SecurityQualityOfService;
ends
    

then acces_mask shoud be accessMask dq FILE_GENERIC_READ, set to only reading and it works fine for me.
combine it with write flags if needed.

note those define please,
Code:
#define FILE_GENERIC_READ         (STANDARD_RIGHTS_READ     |\
                                   FILE_READ_DATA           |\
                                   FILE_READ_ATTRIBUTES     |\
                                   FILE_READ_EA             |\
                                   SYNCHRONIZE)


#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE    |\
                                   FILE_WRITE_DATA          |\
                                   FILE_WRITE_ATTRIBUTES    |\
                                   FILE_WRITE_EA            |\
                                   FILE_APPEND_DATA         |\
                                   SYNCHRONIZE)
    

there is a FILE_READ_EA too, you omit it as optional; but that is free info
Cheers,
Very Happy

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 25 May 2013, 02:40
View user's profile Send private message Visit poster's website Reply with quote
seapoint



Joined: 25 May 2013
Posts: 8
seapoint 25 May 2013, 02:58
Thank you very much!

So the general rule is to make all pointers aligned to qword boundary.
Post 25 May 2013, 02:58
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 25 May 2013, 03:06
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 20:20; edited 1 time in total
Post 25 May 2013, 03:06
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 25 May 2013, 03:20
yes, pointers should be always 8-aligned in or out of a structure.
http://msdn.microsoft.com/en-us/library/aa384264%28v=vs.85%29.aspx
in your case, structures may be 8-aligned too (where you are doing 16 there).
anyway, not all win structures must be 8-aligned, nor 8-padded (example ACCELs in a table).

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 25 May 2013, 03:20
View user's profile Send private message Visit poster's website Reply with quote
seapoint



Joined: 25 May 2013
Posts: 8
seapoint 25 May 2013, 03:34
@HaHaAnonymous
I got it wrong and edited my post before yours, but apparently after you started writing, sorry

hopcode wrote:

then acces_mask shoud be accessMask dq FILE_GENERIC_READ

It's a dword argument so it can be dd, because moving imm32 to reg32 zeroes the upper dword (which I just learned). I guess high dword is also ignored later...

amd64 is interesting
Post 25 May 2013, 03:34
View user's profile Send private message Reply with quote
hopcode



Joined: 04 Mar 2008
Posts: 563
Location: Germany
hopcode 25 May 2013, 03:43
seapoint wrote:
It's a dword argument so it can be dd, because moving imm32 to reg32 zeroes the upper dword (which I just learned). I guess high dword is also ignored later...

yes, you learned right Smile
99% of people tell me it is a wasting of 4 bytes... and i continue to say it is a matter of design. Wink

_________________
⠓⠕⠏⠉⠕⠙⠑
Post 25 May 2013, 03:43
View user's profile Send private message Visit poster's website Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
HaHaAnonymous 25 May 2013, 03:47
[ Post removed by author. ]


Last edited by HaHaAnonymous on 28 Feb 2015, 20:20; edited 1 time in total
Post 25 May 2013, 03:47
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 25 May 2013, 15:03
seapoint wrote:
So the general rule is to make all pointers aligned to qword boundary.
In general, every field should be aligned to its natural boundary (which is often address divisible by field size; notable exception is 10-byte extended double that needs to be qword-aligned). Proper padding inside struct is a half of a way to success: entire structure must be properly aligned too (i.e. any struct with qword field should start at qword boundary, at least; substitute any simple type instead of qword, it'll hold true; C compilers do it automagically, they also pad entire struct in order to achieve the same result within arrays).

----8<----
⠓⠕⠏⠉⠕⠙⠑ wrote:
anyway, not all win structures must be 8-aligned, nor 8-padded (example ACCELs in a table).
Yep, ACCEL should (in RFC 2119 sense) be only word-aligned (since it doesn't contain anything larger than word fields).
Post 25 May 2013, 15:03
View user's profile Send private message Reply with quote
FlatSwede



Joined: 22 May 2013
Posts: 4
FlatSwede 16 Jun 2013, 20:23
A quick question!
Why do we have to align and add padding?
What's the reason behind all this?
Post 16 Jun 2013, 20:23
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4020
Location: vpcmpistri
bitRAKE 16 Jun 2013, 20:51
The only practical explanation is the use of aligned access to data resulting from the increase in pointer size. It might even be a HL language convention? Or improve performance in some instances? (rarely) Once the structures are defined correctly for 64-bit this added memory use will happen almost transparent to the programmer.

Brevity is the source of all errors. Wink

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 16 Jun 2013, 20:51
View user's profile Send private message Visit poster's website Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 07 Jan 2017, 16:08
Hello Wink

Ive tried to write something to the created file, but i always have 0 bytes written.
NtWriteFile returns 8 in the EAX register, but i can't seem to find out what it means.

Code:
include 'win32ax.inc'
entry main

define  OBJ_CASE_INSENSITIVE   0x00000040
define  OBJ_KERNEL_HANDLE      0x00000200
define  FILE_SUPERSEDE         0x00000000


struct UNICODE_STRING
        Length          dw ?
        MaximumLength   dw ?
        Buffer          dd ?
ends

struct OBJECT_ATTRIBUTES
        Length          dd ? ;ULONG           Length;
        RootDirectory   dd ? ;HANDLE          RootDirectory;
        ObjectName      dd ? ;PUNICODE_STRING ObjectName;
        Attributes      dd ? ;ULONG           Attributes;
        SD              dd ? ;PVOID           SecurityDescriptor;
        SQOS            dd ? ;PVOID           SecurityQualityOfService;
ends

struct IO_STATUS_BLOCK
        Status          dd ?
        Pointer         dd ?
        Information     dd ?
ends


FileName du '\??\C:\temp\test32.txt'
FileNameEnd:

main:
     mov [attr.Length],              sizeof.OBJECT_ATTRIBUTES
     mov [attr.RootDirectory],       0
     mov [attr.Attributes],          OBJ_KERNEL_HANDLE;OBJ_CASE_INSENSITIVE
     mov [attr.ObjectName],          fn
     mov [attr.SD],                  0
     mov [attr.SQOS],                0

     mov [fn.Length], FileNameEnd - FileName
     mov [fn.MaximumLength], FileNameEnd - FileName
     mov [fn.Buffer], FileName

     invoke NtCreateFile, hFile,\
     [accessMask],\          ;DesiredAccess
     attr,\                  ;ObjectAttributes
     ioStatusBlock,\         ;IoStatusBlock
     0,\                     ;AllocationSize
     FILE_ATTRIBUTE_NORMAL,\ ;FileAttributes
     FILE_SHARE_READ,\       ;ShareAccess
     FILE_SUPERSEDE,\        ;CreateDisposition
     0,\                     ;CreateOptions
     0,\                     ;EaBuffer
     0                       ;EaLength

     invoke NtWriteFile,eax,0,0,0,ioStatusBlock,STR_HELLO,12,0,0


     mov ebx,[ioStatusBlock.Information]



     invoke ExitProcess,0

 section '.idata' import data readable writeable
    library kernel32,'kernel32.dll',user32,'user32.dll',\
        ntdll,'ntdll.dll'

    import ntdll,\
       NtCreateFile, 'NtCreateFile',\
       NtWriteFile,'NtWriteFile'


    include "%include%/api/kernel32.inc"
    include "%include%/api/user32.inc"

accessMask dd 1F01ffh

STR_HELLO           DB      "Hello World!",0,0,0,0

iosb    dd 2 dup (0)
hFile   dd ?
fn      UNICODE_STRING    ?
attr    OBJECT_ATTRIBUTES ?
ioStatusBlock IO_STATUS_BLOCK ?
    
Post 07 Jan 2017, 16:08
View user's profile Send private message MSN Messenger Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 07 Jan 2017, 22:22
The NT functions are not officially documented. Why not just use the normal well documented functions?
Post 07 Jan 2017, 22:22
View user's profile Send private message Visit poster's website Reply with quote
jochenvnltn



Joined: 15 Jul 2011
Posts: 96
jochenvnltn 08 Jan 2017, 14:18
revolution wrote:
The NT functions are not officially documented. Why not just use the normal well documented functions?


Hi Revolution Smile

Its just because i find the NT functions interesting and im wondering why it is that this NtWriteFile is not working. I just want to learn about it, thats all Wink
Post 08 Jan 2017, 14:18
View user's profile Send private message MSN Messenger Reply with quote
Jerry



Joined: 24 Dec 2016
Posts: 18
Location: Zeist, Netherlands
Jerry 08 Jan 2017, 22:13
seapoint wrote:
Related question: are there any debuggers for 64 bit other than windbg?


I'm starting to learn windbg as i think it is a powerful debugger for windows, i like the ability to script it.
In fact i was just now reading the help file, which is really helpful as it does have a learning curve, not sure how steep though at this point.
For a while i have been using x64dbg ( http://x64dbg.com/ ), an open source debugger for windows which looks like ollydbg, it really helpes me a lot in learning assembly (and checking the results) at this time.

Hope it helps [/url]
Post 08 Jan 2017, 22:13
View user's profile Send private message Reply with quote
Trinitek



Joined: 06 Nov 2011
Posts: 257
Trinitek 10 Jan 2017, 01:26
Jerry wrote:
seapoint wrote:
Related question: are there any debuggers for 64 bit other than windbg?


I'm starting to learn windbg as i think it is a powerful debugger for windows, i like the ability to script it.
In fact i was just now reading the help file, which is really helpful as it does have a learning curve, not sure how steep though at this point.
For a while i have been using x64dbg ( http://x64dbg.com/ ), an open source debugger for windows which looks like ollydbg, it really helpes me a lot in learning assembly (and checking the results) at this time.

Hope it helps [/url]
I can't help but think that's a really slick looking website, especially for a GPL project. Laughing
Post 10 Jan 2017, 01:26
View user's profile Send private message Reply with quote
Jerry



Joined: 24 Dec 2016
Posts: 18
Location: Zeist, Netherlands
Jerry 10 Jan 2017, 18:16
Yes it is, but the product works Wink

There is one option by the way that i must mention if one tries it out, since i mentioned it in the first place.
If you use an int3 yourself somewhere in your program, then by default it keeps breaking on that, not allowing one to continue, sadly.
Under the options menu you'll find the preferences dialog and there you will find the engine tab with the "skip int3 stepping" check-box, for my purposes it would rather see it turned on by default.

Can't imagine anyone here not finding it, but perhaps it saves a small annoyance.
Post 10 Jan 2017, 18:16
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.