Всем привет. Пишу небольшую програмку, и столкнулся с такой проблемой: исходник проги: Код (Text): format PE GUI 4.0 include 'win32a.inc' include 'Win32Structures.inc' include 'Win32Import.inc' section '.code' code readable executable start: push sr push FileName call [FindFirstFileA] push 0 ; тип сообщения (MB_OK) push 0 ; заголовок push sr.cFileName ; сообщение push 0 ; дескриптор окна - владельца call [MessageBoxA] exit: invoke ExitProcess,0 data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ winmm,'WINMM.DLL' import kernel32,\ ExitProcess,'ExitProcess' ;import user32,\ ; MessageBoxA,'MessageBoxA' import winmm,\ mciSendString,'mciSendStringA' FileName db '*.*',0 sr WIN32_FIND_DATA end data компилируется без ошибок. Загружаю в ollydbg и вижу такую картину начиная со стартового кода: Код (Text): ADD BYTE PTR DS:[EAX],AL ADD BYTE PTR DS:[EAX],AL ADD BYTE PTR DS:[EAX],AL ADD BYTE PTR DS:[EAX],AL ADD BYTE PTR DS:[EAX],AL Сердцем понимаю что что-то с памятью намудрил, но сам ни хрена понять не могу. Сверяю с другими исходниками - все нормально. Остальное тоже компилится без проблем. Где я накосячил?
мой кодес думаю что дважды импорты прописываются - include 'Win32Import.inc' - вот здесь у меня все прописано Так что зря это : data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ winmm,'WINMM.DLL' import kernel32,\ ExitProcess,'ExitProcess' ;import user32,\ ; MessageBoxA,'MessageBoxA' import winmm,\ mciSendString,'mciSendStringA'
Код (Text): format PE GUI 4.0 entry start ; <-- include 'win32a.inc' include 'Win32Structures.inc' include 'Win32Import.inc'
При [entry start] Olly вообще сообщила, что мол entry point outside the code. После этого все-таки вывела дизасм. листинг, но в нем ф-ция findfirstfile не определена! Хотя exitprocess висит на своем месте... Если удаляю весь импорт, то компилятор не опознает вызовы процедур, и компилить не хочет.
Перенес. Пишу так: Код (Text): format PE GUI 4.0 entry start section '.code' code readable executable include 'win32a.inc' include 'Win32Structures.inc' include 'Win32Import.inc' start: push sr push FileName call FindFirstFileA push 0 push 0 push sr.cFileName push 0 call MessageBoxA exit: invoke ExitProcess,0 data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' import kernel32,\ ExitProcess,'ExitProcess' FileName db '*.*',0 sr WIN32_FIND_DATA end data Олька выдает листинг: Код (Text): 0040111C > $ 68 9A114000 PUSH BEER.0040119A 00401121 . 68 96114000 PUSH BEER.00401196 ; ASCII "*.*" 00401126 . E8 11FFFFFF CALL BEER.0040103C 0040112B . 6A 00 PUSH 0 0040112D . 6A 00 PUSH 0 0040112F . 68 C6114000 PUSH BEER.004011C6 00401134 . 6A 00 PUSH 0 00401136 . E8 25FFFFFF CALL BEER.00401060 0040113B . 6A 00 PUSH 0 ; /ExitCode = 0 0040113D . FF15 80114000 CALL DWORD PTR DS:[<&KERNEL32.ExitProces>; \ExitProcess 00401143 . 78110000 DD 00001178 ; Struct 'IMAGE_IMPORT_DESCRIPTOR' 00401147 . 00000000 DD 00000000 0040114B 00 DB 00 0040114C > 0000 ADD BYTE PTR DS:[EAX],AL 0040114E 00 DB 00 0040114F . 6B110000 DD 0000116B 00401153 80 DB 80 00401154 > 1100 ADC DWORD PTR DS:[EAX],EAX 00401156 00 DB 00 00401157 00 DB 00 ; Struct 'IMAGE_IMPORT_DESCRIPTOR' 00401158 00 DB 00 00401159 > 0000 ADD BYTE PTR DS:[EAX],AL 0040115B 00 DB 00 0040115C > 0000 ADD BYTE PTR DS:[EAX],AL 0040115E 00 DB 00 0040115F . 00000000 DD 00000000 00401163 . 00000000 DD 00000000 00401167 . 00000000 DD 00000000 0040116B > 4B DEC EBX 0040116C 45 DB 45 ; CHAR 'E' 0040116D 52 DB 52 ; CHAR 'R' 0040116E > 4E DEC ESI 0040116F 45 DB 45 ; CHAR 'E' 00401170 4C DB 4C ; CHAR 'L' 00401171 33 DB 33 ; CHAR '3' 00401172 32 DB 32 ; CHAR '2' 00401173 2E DB 2E ; CHAR '.' 00401174 44 DB 44 ; CHAR 'D' 00401175 4C DB 4C ; CHAR 'L' 00401176 > 4C DEC ESP 00401177 00 DB 00 00401178 . 88110000 DD 00001188 ; Import lookup table for 'KERNEL32.DLL' 0040117C 00 DB 00 0040117D > 0000 ADD BYTE PTR DS:[EAX],AL 0040117F 00 DB 00 00401180 > . 372A5D77 DD kernel32.ExitProcess 00401184 00 DB 00 00401185 00 DB 00 00401186 00 DB 00 00401187 > 0000 ADD BYTE PTR DS:[EAX],AL 00401189 00 DB 00 0040118A . 45 78 69 74 50>ASCII "ExitProcess",0 00401196 . 2A 2E 2A 00 ASCII "*.*",0 Упорно не хочет видеть вызов FindFirstFile и MessageBox. Самое интересное, что эта хрень после запуска висит в памяти, не прекращая процесс!
вообще лучше забейте тогда на include 'Win32Structures.inc' include 'Win32Import.inc' и юзайте фасмовские макросы и пр.
пишу так: Код (Text): format PE GUI 4.0 entry start section '.code' code readable executable include 'win32a.inc' include 'struc.h' ;include 'Win32Structures.inc' ;include 'Win32Import.inc' FileName db '*.*',0 sr WIN32_FIND_DATA start: push sr push FileName call FindFirstFileA push 0 ; òèï ñîîáùåíèÿ (MB_OK) push 0 ; çàãîëîâîê push sr.cFileName ; ñîîáùåíèå push 0 ; äåñêðèïòîð îêíà - âëàäåëüöà call MessageBoxA exit: invoke ExitProcess,0 data import library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' import kernel32,\ ExitProcess,'ExitProcess',\ FindFirstFileA,'FindFirstFileA' import user32,\ MessageBoxA,'MessageBoxA' end data В struc.h -> Код (Text): struc FILETIME { .dwLowDateTime dd 0 .dwHighDateTime dd 0 } struc WIN32_FIND_DATA { .dwFileAttributes dd 0 .ftCreationTime FILETIME .ftLastAccessTime FILETIME .ftLastWriteTime FILETIME .nFileSizeHigh dd 0 .nFileSizeLow dd 0 .dwReserved0 dd 0 .dwReserved1 dd 0 .cFileName rb 100h .cAlternateFileName rb 14 } Компилируется без ошибок. Запускаю Ольку: Код (Text): 0040113E >/$ 68 04104000 PUSH BEER.00401004 00401143 |. 68 00104000 PUSH BEER.00401000 ; ASCII "*.*" 00401148 |. E8 7D000000 CALL <&KERNEL32.FindFirstFileA> 0040114D |. 6A 00 PUSH 0 0040114F |. 6A 00 PUSH 0 00401151 |. 68 30104000 PUSH BEER.00401030 00401156 |. 6A 00 PUSH 0 00401158 |. E8 9D000000 CALL <&USER32.MessageBoxA> 0040115D |. 6A 00 PUSH 0 ; /ExitCode = 0 0040115F \. FF15 C6114000 CALL DWORD PTR DS:[<&KERNEL32.ExitProces>; \ExitProcess 00401165 . BA110000 DD 000011BA ; Struct 'IMAGE_IMPORT_DESCRIPTOR' 00401169 . 00000000 DD 00000000 0040116D . 00000000 DD 00000000 00401171 . A1110000 DD 000011A1 00401175 . C6110000 DD 000011C6 00401179 . F2110000 DD 000011F2 ; Struct 'IMAGE_IMPORT_DESCRIPTOR' 0040117D . 00000000 DD 00000000 00401181 . 00000000 DD 00000000 00401185 . AE110000 DD 000011AE 00401189 . FA110000 DD 000011FA 0040118D . 00000000 DD 00000000 ; Struct 'IMAGE_IMPORT_DESCRIPTOR' 00401191 . 00000000 DD 00000000 00401195 . 00000000 DD 00000000 00401199 . 00000000 DD 00000000 0040119D . 00000000 DD 00000000 004011A1 . 4B 45 52 4E 45>ASCII "KERNEL32.DLL",0 004011AE . 55 53 45 52 33>ASCII "USER32.DLL",0 004011B9 00 DB 00 004011BA . D2110000 DD 000011D2 ; Import lookup table for 'KERNEL32.DLL' 004011BE . E0110000 DD 000011E0 004011C2 . 00000000 DD 00000000 004011C6 > . 372A5D77 DD kernel32.ExitProcess 004011CA > $ 96 XCHG EAX,ESI 004011CB . F2: PREFIX REPNE: ; Superfluous prefix 004011CC . 5D POP EBP 004011CD . 77 00 JA SHORT BEER.004011CF 004011CF > 0000 ADD BYTE PTR DS:[EAX],AL 004011D1 . 0000 ADD BYTE PTR DS:[EAX],AL 004011D3 00 DB 00 004011D4 . 45 78 69 74 50>ASCII "ExitProcess",0 004011E0 . 0000 DW 0000 004011E2 . 46 69 6E 64 46>ASCII "FindFirstFileA",0 При отладке FindFirstFileA прыгает на адрес 004011CF, и срабатывает исключение. Вот это да! Я уже охренел ошибки искать. Что это за хрень? Может, я неправильно объявил вызов ф-ции?
мда, подозреваю, что и MessageBoxA не определена. Короче, не знаю чей там кодес, но... судя по всему за основу взят один из примеров к фасму. 1. Закомментировать надо все-таки mciSendString, поскольку не используется. 2. Инклуды с макросами до секции кода, все так. Инклуды с импортом(если там есть такие) - в строго отведенное место. 3. В импорте необходимо иметь MessageBoxA, как и другие используемые функции. 4. Прежде чем использовать неведомо кем сделанные инклуды (если они не входят в пакет), неплохо заглянуть внутрь, на предмет "какая криворукая обезьяна их писала?". Если вроде правильно - обезьяну умалчиваешь. Если не понимаешь чего там - лучше не использовать. Ну и про последнее: есть разница между Call [MessageBoxA] и Call MessageBoxA Теоретически оба варианта валидны, и могут быть использованы в зависимости от способа оформления импорта. Практически - пока не въехал, пробуй со скобками и без что-то одно должно сработать.
Спасибо. Скомпилировал так: Код (Text): format PE console entry start include 'win32a.inc' section '.code' code import writeable readable executable include 'Win32Structures.inc' include 'Win32Import.inc' FileName db '*.*',0 sr WIN32_FIND_DATA start: push sr push FileName call [FindFirstFileA] push 0 ; òèï ñîîáùåíèÿ (MB_OK) push 0 ; çàãîëîâîê push sr.cFileName ; ñîîáùåíèå push 0 ; äåñêðèïòîð îêíà - âëàäåëüöà call [MessageBoxA] exit: invoke ExitProcess,0 mciSendString удалил, в импорт добавил MessageBoxA. Наконец-то компиляция! Но... при запуске показывает точку вместо имени файла. Что это такое? Секцию text заменил на code.
Я дико извиняюсь, но есть еще один вопрос. Новую тему создавать не хочу, спрошу в старой. Код (Text): format PE console entry start include 'win32a.inc' section '.code' code import writeable readable executable include 'Win32Structures.inc' include 'Win32Import.inc' FileName db '*.exe',0 sr WIN32_FIND_DATA start: push sr push FileName call [FindFirstFileA] push 0 ; òèï ñîîáùåíèÿ (MB_OK) push 0 ; çàãîëîâîê push sr.cFileName ; ñîîáùåíèå push 0 ; äåñêðèïòîð îêíà - âëàäåëüöà call [MessageBoxA] invoke CreateFile, sr.cFileName, GENERIC_WRITE or GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 cmp eax, INVALID_HANDLE_VALUE je exit exit: invoke ExitProcess,0 В инклудах CreateFile определен: ... CreateFile dd RVA _CreateFileA ... _CreateFileA dw 0 db 'CreateFile',0 При запуске пишет The procedure entry point CreateFile could not be located in the dll kernel32.dll Определил ф-цию вроде бы правильно. Остальные функции определены так же, и все работает. Почему не видит ф-цию в kernel32.dll??
Потому что в kernel32.dll есть две ф-ии: CreateFileA (ASCII версия) и CreateFileW (Unicode версия). В высокоуровневых языках проект управляется define'ами UNICODE и _UNICODE, которые заменяют макрос CreateFile на CreateFileA или на CreateFileW.