Здравствуйте. при написании такого кода на ФАСМе крейт файл ругается на параметры и выдает C000000D:
Но при этом код из студии работает хорошо:
я залез в отладчик и увидел, что компиляторы выравнивают поля в структурах по-разному, приложу пикчи заполненной структуры unicode_string в фасме и в visual studio.
почему так? visual studio меняет смещение полей в структуре? как сделать так, чтобы системный вызов крейт файла возвращал status_success? спасибо за внимание.
Код:
format PE64 Console 5.0
entry Start
include 'win64ax.inc'
struct _OBJECT_ATTRIBUTES
Length dd 0
RootDirectory dq 0
ObjectName dq 0
Attributes dd 0
DSecurityDescriptor dq 0
SecurityQualityOfService dq 0
ends
struct _UNICODE_STRING
Length dw 0
MaximumLength dw 0
Buffer dq 0
ends
section '.text' code readable executable
Start:
push rsi
mov rsi, rsp
and rsp, 0FFFFFFFFFFFFFFF0h
sub rsp, 020h
call main
mov rsp, rsi
pop rsi
ret
filename db '\',0,'?',0,'?',0,'\',0,'C',0,':',0,'\',0,'X',0,'e',0,'r',0,'o',0,'x',0,'\',0,'g',0,'a',0,'g',0,'a',0,'.',0,'e',0,'x',0,'e',0,0,0
namelenmax = $-filename
proc main
local objattrproc2:_OBJECT_ATTRIBUTES
local unistring:_UNICODE_STRING
local handlefile dq 0
local iostatus dq 2 dup(0)
mov bx, namelenmax
mov [unistring.MaximumLength], bx
sub bx, 2
mov [unistring.Length], bx
lea rbx, [filename]
mov [unistring.Buffer], rbx
mov [objattrproc2.Length], 48
mov [objattrproc2.Attributes], 0
mov [objattrproc2.RootDirectory], 0
mov [objattrproc2.DSecurityDescriptor], 0
mov [objattrproc2.SecurityQualityOfService],0
lea rbx, [unistring]
mov [objattrproc2.ObjectName], rbx
lea rcx, [handlefile]
mov rdx, 80000h
lea r8, [objattrproc2]
lea r9, [iostatus]
sub rsp, 58h
mov qword [rsp+20h], 0
mov qword [rsp+28h], 0
mov qword [rsp+30h], 0
mov qword [rsp+38h], 1
mov qword [rsp+40h], 0
mov qword [rsp+48h], 0
mov qword [rsp+50h], 0
call NtCreateFile
ret
endp
proc NtCreateFile PHANDLEFileHandle,\
ACCESS_MASKDesiredAccess, \
POBJECT_ATTRIBUTESObjectAttributes, \
PIO_STATUS_BLOCKIoStatusBlock, \
PLARGE_INTEGERAllocationSize, \
ULONGFileAttributes, \
ULONGShareAccess, \
ULONGCreateDisposition, \
ULONGCreateOptions, \
PVOIDEaBuffer, \
ULONGEaLength
mov r10, rcx
mov rax, 55h
syscall
ret
endp
C:
#include <Windows.h>
#include <stdio.h>
struct IO_STATUS {
ULONG_PTR a;
ULONG_PTR b;
};
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
#ifdef MIDL_PASS
[size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT* Buffer;
#else // MIDL_PASS
_Field_size_bytes_part_opt_(MaximumLength, Length) PWCH Buffer;
#endif
} UNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
UNICODE_STRING* ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES* POBJECT_ATTRIBUTES;
typedef DWORD(WINAPI* NtCreateFile)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, IO_STATUS* IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength);
int main()
{
IO_STATUS iobl = { 0 };
HANDLE flhnd = 0;
HMODULE nt = LoadLibraryW(L"ntdll.dll");
NtCreateFile crtfl = (NtCreateFile)GetProcAddress(nt, "NtCreateFile");
UNICODE_STRING unistr = { 0 };
unistr.Buffer = (PWSTR)L"\\??\\C:\\Xerox\\gaga.exe";
unistr.Length = 42;
unistr.MaximumLength = 44;
OBJECT_ATTRIBUTES objattr = { 0 };
objattr.Length = sizeof(objattr);
objattr.RootDirectory = 0;
objattr.ObjectName = &unistr;
objattr.Attributes = 0;
objattr.SecurityDescriptor = 0;
objattr.SecurityQualityOfService = 0;
DWORD status = crtfl(&flhnd, WRITE_OWNER, &objattr, &iobl, 0, 0, 0, 1, 0, 0, 0);
printf("%x status", status);
getchar();
return(0);
}
почему так? visual studio меняет смещение полей в структуре? как сделать так, чтобы системный вызов крейт файла возвращал status_success? спасибо за внимание.
Вложения
Последнее редактирование: