Hello world мои очумелые ручки добрались до самого маленького исполняемого файла и нашли на просторах сети аж 268-ми байтный пример для Win7x64. Но вот на моей Win10x64 не работает, когда смотрю в отладчике(x64dbg), ловлю исключение ACCESS_VIOLATION, а потом оказалось, что User32 не загружена, а вот Kernel с какого-то перепугу подгружен - может быть это отладчик с ума сходит и не понимает такие файлы. По переставлял всё, попробовал добавлять ".dll" и в верхнем регистре писал, указатели местами менял, нулевые элементы добавлял - ничего не помогает. Так вот вопрос, не изменилось ли на 10-ке какая-нибудь важная деталь? Может есть рабочие примеры? а может это вообще даже на 7-ке не запускается? FASM: Код (ASM): format binary as 'exe' IMAGE_DOS_SIGNATURE equ 5A4Dh IMAGE_NT_SIGNATURE equ 00004550h PROCESSOR_AMD_X8664 equ 8664h IMAGE_SCN_CNT_CODE equ 00000020h IMAGE_SCN_MEM_READ equ 40000000h IMAGE_SCN_MEM_WRITE equ 80000000h IMAGE_SCN_CNT_INITIALIZED_DATA equ 00000040h IMAGE_SUBSYSTEM_WINDOWS_GUI equ 2 IMAGE_NT_OPTIONAL_HDR64_MAGIC equ 20Bh IMAGE_FILE_RELOCS_STRIPPED equ 1 IMAGE_FILE_EXECUTABLE_IMAGE equ 2 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h include 'win64a.inc' org 0 use64 IMAGE_BASE = 400000h Signature: dw IMAGE_DOS_SIGNATURE,0 ntHeader dd IMAGE_NT_SIGNATURE;'PE' ;image_header-------------------------- .Machine dw PROCESSOR_AMD_X8664 .Count_of_section dw 0;2 .TimeStump dd 0 .Symbol_table_offset dd 0;ntHeader .Symbol_table_count dd 0 .Size_of_optional_header dw EntryPoint-optional_header .Characteristics dw 0x20 or IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_EXECUTABLE_IMAGE ;20h Handle >2Gb addresses ;------------------------------------- optional_header: .Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC .Linker_version_major_and_minor dw 9 .Size_of_code dd 0 .Size_of_init_data dd 0;xC0 .Size_of_uninit_data dd 0 .entry_point dd EntryPoint .base_of_code dd ntHeader .image_base dq IMAGE_BASE .section_alignment dd 4 .file_alignment dd 4 .OS_version_major_minor dw 5,2 .image_version_major_minor dd 0 .subsystem_version_major_minor dw 5,2 .Win32_version dd 0 .size_of_image dd EndOfImage .size_of_header dd EntryPoint .checksum dd 0 .subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI .DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE .Stack_allocation dq 0x100000 .Stack_commit dq 0x1000 .Heap_allocation dq 0x100000 .Heap_commit dq 0x1000 .loader_flag dd 0 .number_of_dirs dd (EntryPoint-export_RVA_size)/8 export_RVA_size dq 0 .import_RVA dd import_ .import_size dd end_import-import_ ;------------------------------------------------ EntryPoint: enter 20h,0 ; space for 4 arguments + 16byte aligned stack xor ecx, ecx ; 1. argument: rcx = hWnd = NULL mov r9, rcx ; 4. argument: r9d = uType = MB_OK = 0 mov edx,MsgCaption+IMAGE_BASE ; 2. argument: edx = window text mov r8,rdx ; 3. argument: r8 = caption call [MessageBox] leave ret ;------------------------------------------------ MsgCaption db "Iczelion's tutorial #2a",0 ;------------------------------------------------- Import_Table: user32_table: MessageBox dq _MessageBox import_: dd 0,0,0,user32_dll,user32_table dd 0 user32_dll db "user32",0,0 dw 0 _MessageBox db 0,0,"MessageBoxA" end_import: times 268-end_import db 0 ;filling up to 268 bytes EndOfImage:
Ruins007, на просторах сети говоришь? Могу и на первоистоичник указать Сказки дядюшки Римуса, "Глава вторая. Как Братец Кролик уменьшал размер программы". По шагам, с комментариями. Попробуй повторить самостоятельно
Вангую, что все 16 data directories в заголовке надо указать. Вряд ли загрузчик проверяет поля SizeOfOptionalHeader и NumberOfDirectories.
rmn, предельный размер в 268 байт как раз и задается 16 data directories в заголовке, то есть код и данные находятся том на месте, где должны были бы быть все 16 data directories хотя используется только импорт
Но если поля Size забиты опкодами, лоадер будет думать, что соответствующая директория есть и попытается ее считать. Нет?
Код (ASM): rq 14 перед началом кода, не дало результатов, проверил PE Tools, остальные директории, кроме import'а - пусты.
Ruins007, просто повторите по-шагам, то что описано во второй главе: с ключом /ALIGN, объединением сегментов кода и данных, DOS-стабом, удалением ExitProcess и т.д. Так можно будет понять ЧТО можно делать в Win10, а ЧЕГО нельзя
Ruins007, чтобы собрать нестандартный PE-заголовок я использовал FASM, можно было то же сделать через NASM, еще раньше я использовал ML.EXE (Masm) когда создавал СОМ-файл и переименовывал его в ЕХЕ, но сейчас ml64.exe не дает возможности создавать бинарные файлы (или я об этом не знаю). Но начать нужно с ml64, я выдернул его и link.exe из VS2014
Ух неожиданно, эксперимент удался. Судя по всему win10 не принимает файлы с нулевым количеством секций. Точнее не подгружает к ним dll из таблицы импорта. Достаточно добавить одну общую секцию и задать количество секций больше нуля, так всё сразу заработало. Более того, там где я брал исходники, было написано, что файлы меньше 268'ми байт не читаются, однако удалив текст сообщения и задав адрес названия секции(".code ") вместо него, программа запустилась и вывела сообщение, хотя получилось 247 байт.
Ещё заметил, что отладчик показывает сразу 3 либы: ntdll.dll, kernel32.dll, kernelbase.dll. Так вот вопрос - это отладчик их по умолчанию подгружает? или всё-таки они и так есть в адресном пространстве процесса? вроде ntdll.dll и так должен там быть, но вот наличие kernel32 - удивляет. Через какую функцию лучше проверить, есть идеи?
Опять чудеса, программа без таблицы импорта спокойно выполняет CreateFile2() из Kernel32 и создаёт файл, правда пока кракозябры в названии, видимо кодировка не сходится. Код (ASM): format binary as 'exe' IMAGE_DOS_SIGNATURE equ 5A4Dh IMAGE_NT_SIGNATURE equ 00004550h PROCESSOR_AMD_X8664 equ 8664h IMAGE_SCN_CNT_CODE equ 00000020h IMAGE_SCN_MEM_READ equ 40000000h IMAGE_SCN_MEM_WRITE equ 80000000h IMAGE_SCN_CNT_INITIALIZED_DATA equ 00000040h IMAGE_SUBSYSTEM_WINDOWS_GUI equ 2 IMAGE_NT_OPTIONAL_HDR64_MAGIC equ 20Bh IMAGE_FILE_RELOCS_STRIPPED equ 1 IMAGE_FILE_EXECUTABLE_IMAGE equ 2 IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE equ 8000h include 'win64a.inc' org 0 use64 IMAGE_BASE = 400000h Signature: dw IMAGE_DOS_SIGNATURE,0 ntHeader dd IMAGE_NT_SIGNATURE;'PE' ;image_header-------------------------- .Machine dw PROCESSOR_AMD_X8664 .Count_of_section dw 0;2 .TimeStump dd 0 .Symbol_table_offset dd 0;ntHeader .Symbol_table_count dd 0 .Size_of_optional_header dw EntryPoint-optional_header .Characteristics dw 0x20 or IMAGE_FILE_RELOCS_STRIPPED or\ IMAGE_FILE_EXECUTABLE_IMAGE ;20h Handle >2Gb addresses ;------------------------------------- optional_header: .Magic_optional_header dw IMAGE_NT_OPTIONAL_HDR64_MAGIC .Linker_version_major_and_minor dw 9 .Size_of_code dd 0 .Size_of_init_data dd 0;xC0 .Size_of_uninit_data dd 0 .entry_point dd EntryPoint .base_of_code dd ntHeader .image_base dq IMAGE_BASE .section_alignment dd 4 .file_alignment dd 4 .OS_version_major_minor dw 5,2 .image_version_major_minor dd 0 .subsystem_version_major_minor dw 5,2 .Win32_version dd 0 .size_of_image dd EndOfImage .size_of_header dd EntryPoint .checksum dd 0 .subsystem dw IMAGE_SUBSYSTEM_WINDOWS_GUI .DLL_flag dw IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE .Stack_allocation dq 0x100000 .Stack_commit dq 0x1000 .Heap_allocation dq 0x100000 .Heap_commit dq 0x1000 .loader_flag dd 0 .number_of_dirs dd (EntryPoint-export_RVA_size)/8 export_RVA_size dq 0 .import_RVA dd 0 .import_size dd 0 EntryPoint: enter 20h,0 ; space for 4 arguments + 16byte aligned stack mov rcx, name_ + IMAGE_BASE mov rdx, 1 mov r8, 1 mov r9, 2 mov qword[rsp+68h-48h], 0 call [file_] leave ret Import_Table: file_ dq 0x00007FF8F59A42F0 dq 0,0,0,0 name_ db 0x41,0x42,0x41,0x2E,0x74,0x78,0x74,0,0 end_import: times 268-end_import db 0 ;filling up to 268 bytes EndOfImage:
Kernel32 подгружен по умолчанию, а вот user32 можно догрузить через LoadLibrary http://masm32.com/board/index.php?topic=4190.msg64268#msg64268
Так это же отлично, можно остальные библиотеки в отдельном потоке подгружать, пока к примеру в основном распаковываешь сжатый код. Тут ещё треугольник на Vulkan API научился выводить, без всяких макросов - чувствую вот-вот руки выпрямятся. p.s. мне бы такие руки, когда я егэ заваливал