flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Windows > Problem calling NtCreateFile in 64 bit

Author
Thread Post new topic Reply to topic
seapoint



Joined: 25 May 2013
Posts: 8
Problem calling NtCreateFile in 64 bit
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 NtCreateFilehFile,\
[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 ntdllNtCreateFile"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 NtCreateFilehFile,\
[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 ntdllNtCreateFile"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
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
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: 1171
Location: Unknown
Stupid post removed.


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
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
@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

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: 1171
Location: Unknown
Stupid post removed.


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

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
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: 2624
Location: dank orb
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

_________________
The generation of random numbers is too important to be left to chance - Robert R Coveyou
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: 43
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 NtCreateFilehFile,\
     [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: 15164
Location: GW170817
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: 43

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
Re: Problem calling NtCreateFile in 64 bit

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
Re: Problem calling NtCreateFile in 64 bit

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
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


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.