Такая вот проблема: есть код на фасм, который на одних ОС работает нормально, а на других почему-то нет (ошибка доступа). В основном, нормально он на 7 (но не на всех), а не работает на ХР. Аналогичный код на Масм работает везде без проблем. В чем может быть сложность с фасм-кодом, может у кого-то есть мысли? Код (Text): format PE GUI entry _start include 'include\win32ax.inc' include 'include\encoding\win1251.inc' section '.code' code readable executable import writeable library ntdll,'ntdll.dll' import ntdll, \ NtCreateFile, 'NtCreateFile',\ NtWriteFile, 'NtWriteFile' struct UNICODE_STRING Length dw ? MaximumLength dw ? Buffer dd ? ends struct OBJECT_ATTRIBUTES Length dd ? RootDirectory dd ? ObjectName dd ? Attributes dd ? SD dd ? SQOS dd ? ends iosb dd 2 dup (0) hFile dd ? fn UNICODE_STRING ? attr OBJECT_ATTRIBUTES ? FileName dw '\','?','?','\','d',':','\','f','a','s','m','i', 't','.','t','x','t', 0 FileNameEnd: Buffer db "some text",13,10,"QQ:",13,10,"Email:fasm at 126 fasm su",13,10,\ "Homepage:http://fasm.it",13,10,0 BufferEnd: _start: mov [attr.Length], sizeof.OBJECT_ATTRIBUTES mov [attr.RootDirectory], 0 mov [attr.Attributes], 40h mov [attr.ObjectName], fn mov [attr.SD], 0 mov [attr.SQOS], 0 mov [fn.Length], FileNameEnd - FileName - 2 mov [fn.MaximumLength], FileNameEnd - FileName mov [fn.Buffer], FileName invoke NtCreateFile, hFile, 1F01ffh, attr, iosb,0,1,0,2,060h,0,0 invoke NtWriteFile, [hFile] ,0, 0, 0, iosb, Buffer, BufferEnd - Buffer - 1,0,0 ret
Код (Text): format PE GUI entry _start include 'win32ax.inc' include '\encoding\win1251.inc' section '.data' data readable writeable struct UNICODE_STRING Length dw ? MaximumLength dw ? Buffer dd ? ends struct OBJECT_ATTRIBUTES Length dd ? RootDirectory dd ? ObjectName dd ? Attributes dd ? SD dd ? SQOS dd ? ends iosb dd 2 dup (0) hFile dd ? fn UNICODE_STRING ? attr OBJECT_ATTRIBUTES ? FileName dw '\','?','?','\','d',':','\','f','a','s','m','i', 't','.','t','x','t', 0 FileNameEnd: Buffer db "some text",13,10,"QQ:",13,10,"Email:fasm at 126 fasm su",13,10,\ "Homepage:http://fasm.it",13,10,0 BufferEnd: section '.code' code readable executable _start: mov [attr.Length], sizeof.OBJECT_ATTRIBUTES mov [attr.RootDirectory], 0 mov [attr.Attributes], 40h mov [attr.ObjectName], fn mov [attr.SD], 0 mov [attr.SQOS], 0 mov [fn.Length], FileNameEnd - FileName - 2 mov [fn.MaximumLength], FileNameEnd - FileName mov [fn.Buffer], FileName invoke NtCreateFile, hFile, 1F01ffh, attr, iosb,0,1,0,2,060h,0,0 invoke NtWriteFile, [hFile] ,0, 0, 0, iosb, Buffer, BufferEnd - Buffer - 1,0,0 ret section '.idata' import data readable library ntdll,'ntdll.dll' import ntdll, \ NtCreateFile, 'NtCreateFile',\ NtWriteFile, 'NtWriteFile' Либо делай выравнивание, если не хочешь другие секции создавать.
M0rg0t Ну в частности, секции executable+writeable сильно не нравятся DEP… Надо или разносить в разные секции, или на конкретном компе вноситься в исключения DEP.
f2065 Если явно указано, что executable, то DEP здесь не причём. Не нравиться секции со смешанным доступом могут разве что эвристике антивирусов. M0rg0t С одной стороны подключаете win1251.inc, а с другой занимаетесь такими же извращениями, что и в masm: Код (Text): FileName dw '\','?','?','\','d',':','\','f','a','s','m','i', 't','.','t','x','t', 0 В fasm'е для объявления юникодных строк есть директива du: Код (Text): FileName du '\??\d:\fasmit.txt',0
Которая например глючит с русскими буквами, и ранее с align вроде был глюк. Я сделал макрос textW (и заодно - он выдаёт size.Metka) с полной таблицей utf8 Код (Text): macro textW [value] { common local .length,.position,.wide virtual at 0 db value .length = $ end virtual .position = 0 while .position < .length virtual at 0 db value load .char byte from .position end virtual if .char <= 0x7F .wide = .char else if (.char >= 0xC0) .wide = .char + 0x350 else if (.char = 0x80) ; Ђ .wide = 0x0402 else if (.char = 0x81) ; Ѓ .wide = 0x0403 else if (.char = 0x82) ; ‚ .wide = 0x201A else if (.char = 0x83) ; ѓ .wide = 0x0453 else if (.char = 0x84) ; „ .wide = 0x201E else if (.char = 0x85) ; … .wide = 0x2026 else if (.char = 0x86) ; † .wide = 0x2020 else if (.char = 0x87) ; ‡ .wide = 0x2021 else if (.char = 0x88) ; ? .wide = 0x20AC else if (.char = 0x89) ; ‰ .wide = 0x2030 else if (.char = 0x8A) ; Љ .wide = 0x0409 else if (.char = 0x8B) ; ‹ .wide = 0x2039 else if (.char = 0x8C) ; Њ .wide = 0x040A else if (.char = 0x8D) ; Ќ .wide = 0x040C else if (.char = 0x8E) ; Ћ .wide = 0x040B else if (.char = 0x8F) ; Џ .wide = 0x040F else if (.char = 0x90) ; ђ .wide = 0x0452 else if (.char = 0x91) ; ‘ .wide = 0x2018 else if (.char = 0x92) ; ’ .wide = 0x2019 else if (.char = 0x93) ; “ .wide = 0x201C else if (.char = 0x94) ; ” .wide = 0x201D else if (.char = 0x95) ; • .wide = 0x2022 else if (.char = 0x96) ; – .wide = 0x2013 else if (.char = 0x97) ; — .wide = 0x2014 else if (.char = 0x98) ; ? .wide = 0x3F else if (.char = 0x99) ; ™ .wide = 0x2122 else if (.char = 0x9A) ; љ .wide = 0x0459 else if (.char = 0x9B) ; › .wide = 0x203A else if (.char = 0x9C) ; њ .wide = 0x045A else if (.char = 0x9D) ; ќ .wide = 0x045C else if (.char = 0x9E) ; ћ .wide = 0x045B else if (.char = 0x9F) ; џ .wide = 0x045F else if (.char = 0xA0) ; NBSP .wide = 0x00A0 else if (.char = 0xA1) ; Ў .wide = 0x040E else if (.char = 0xA2) ; ў .wide = 0x045E else if (.char = 0xA3) ; Ј .wide = 0x0408 else if (.char = 0xA4) ; ¤ .wide = 0x00A4 else if (.char = 0xA5) ; Ґ .wide = 0x0490 else if (.char = 0xA6) ; ¦ .wide = 0x00A6 else if (.char = 0xA7) ; § .wide = 0x00A7 else if (.char = 0xA8) ; Ё .wide = 0x0401 else if (.char = 0xA9) ; © .wide = 0x00A9 else if (.char = 0xAA) ; Є .wide = 0x0404 else if (.char = 0xAB) ; « .wide = 0x00AB else if (.char = 0xAC) ; ¬ .wide = 0x00AC else if (.char = 0xAD) ; ? .wide = 0x3F else if (.char = 0xAE) ; ® .wide = 0x00AE else if (.char = 0xAF) ; Ї .wide = 0x0407 else if (.char = 0xB0) ; ° .wide = 0x00B0 else if (.char = 0xB1) ; ± .wide = 0x00B1 else if (.char = 0xB2) ; І .wide = 0x0406 else if (.char = 0xB3) ; і .wide = 0x0456 else if (.char = 0xB4) ; ґ .wide = 0x0491 else if (.char = 0xB5) ; µ .wide = 0x00B5 else if (.char = 0xB6) ; ¶ .wide = 0x00B6 else if (.char = 0xB7) ; · .wide = 0x00B7 else if (.char = 0xB8) ; ё .wide = 0x0451 else if (.char = 0xB9) ; № .wide = 0x2116 else if (.char = 0xBA) ; є .wide = 0x0454 else if (.char = 0xBB) ; » .wide = 0x00BB else if (.char = 0xBC) ; ј .wide = 0x0458 else if (.char = 0xBD) ; Ѕ .wide = 0x0405 else if (.char = 0xBE) ; ѕ .wide = 0x0455 else if (.char = 0xBF) ; ї .wide = 0x0457 else .wide = 0x3F end if dw .wide .position = .position + 1 end while } struc textW [value] { common align 2 label . word .temp_sz = $ textW value .size = $ - .temp_sz }
l_inc С русскими буквами сейчас не удалось воспроизвести, может уже или исправили или я ранее что-то не так делал… Но по крайней мере у меня макрос сразу определяет .size (для работы с реестром очень полезно), а встроенный du - нет (или я не умею ?). Про align - в смысле du сам не делает align. И потом куча API-функций внезапно перестают работать (но не все). Например вот invoke RegCreateKeyExW, HKEY_CURRENT_USER, t_reg_test, 0, 0, 0, KEY_WRITE or KEY_WOW64_64KEY, 0, h_reg1, 0 Если t_reg_test не выровнено по align 2 - то будет ошибка ERROR_NOACCESS.
f2065 sizeof.stringname - более традиционный вариант. Я его придерживаюсь обычно. Со стандартными заголовками нет. Но для того, чтобы да, таких монстров, как в #6, создавать не обязательно. Достаточно так: Код (Text): struc du [args] { common . du args sizeof.#. = $-. } Ну это из серии "позволяет выстрелить в себе в ногу". Это не глюк. Для fasm вообще позволять выстрелить и себе, и другим в любую часть тела — обычное дело. Это плата за максимально возможную свободу. Сюда же и нулевой размер секции, и отсутствие проверок на число аргументов API, и никакого неявного выравнивания и прочее.