Я попробовал написать программу которая просто создает текстовый файл и запоминает его хендл для дальнейших действий. Посмотрев в OllyDbg я увидел что CreateFile возврашает не хендл созданного файла а просто цифру 10. Файл создается а вот хендла нету(( От чего может быть такая ошибка? Помогите пожалуйста. Вот код самой программы. Код (Text): include 'C:\fasm\include\win32ax.inc' section '.data' data readable writeable X db '123.txt',0 hFileR dd ? section '.code' code readable executable start: invoke CreateFile,X,GENERIC_WRITE,\ FILE_SHARE_READ,\ 0,CREATE_ALWAYS,\ FILE_ATTRIBUTE_NORMAL,\ 0 mov [hFileR],eax invoke ExitProcess,0 .end start
Охо-хо-хо-хо, горюшко, с чего ты взял, что "10" - это не хендл созданного файла? Что ты ожидал там увидеть???
jaga а с чего ты взял что хендл будет выглядеть как то по другому? )) если CreateFile не срабатывает она возвращает INVALID_HANDLE_VALUE = -1, тогда вызывай GetLastError и смотри почему, а у тебя всё нормально
Код (Text): dwStored dd 0 ... invoke WriteFile, [hFileR], X, 7, dwStored, 0 invoke CloseHandle, [hFileR] И потом открой файл в NOTEPAD-е.
Научите меня WriteFile ??? Вот как эта прога работает в первом посте? Нафига "mov [hFileR],eax" регистр помещается в ячейку памяти, что это даёт ? Я просто хотел по этому исходнику чтонить сочинить чтоб запись в файл было. Но ничего не получается, нипойму я эти WinAPI. Код (Text): include '%SystemRoot%\Apps\Fasm\include\win32ax.inc' section '.data' data readable writeable X db 'C:\123.txt',0 section '.code' code readable executable start: invoke WriteFile,X,X,X,X,X invoke ExitProcess,0 .end start Почему никакой реакции? Нафиг мне хендлы, мнеб примитивно хотяб, и нагуглить ничего не могу, все умные чтоль сразу горы кода век неразгести! А гдеж для маленьких примерчиги? Мож закрыть чё " INVOKE CloseHandle, fileHandle " типа? Ох опять эти хендлы =) Надо ли сначала CreateFile ? Или сразу можно WriteFile ? ...я имею ввиду как можно вывести хоть какой-то код из программы в некий файл? Типа Хело Ворлд, тока не на экран
Semiono охохохохохо!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Рано ты за кодинг взялся. Чтобы читать или писать в файл нужен хэндл файла, по сути это число. Хэндл можно получить вызовом CreateFile. Это не просто цифра, после вызова CreateFile, в таблице описателей процесса будет этот описатель, который будет ассоциирован с открытым файлом. Указывая эту цифру (10) в параметре WriteFile ты говоришь винде работать именно с этим файлом который ты открыл CreateFile'ом. И кстати после вызова (CALL) CreateFile в регистре EAX будет этот хэндл. Он сохраняется в ячейке памяти, чтобы потом его использовать. Кстати полезно пользоваться MSDN - там описываются параметры всех функций Windows. В том числе и WriteFile. Ты ему хрень передал в посл. примере, конечно ничего не заработает. Первый параметр это как раз число которое вернул CreateFile. Хэндл (Handle) в переводе - "ручка". Т.е. по этой цифре функции работы с файлами (ReadFile, WriteFile) поймут какой файл используется, в какой файл ты хочешь счиать, из какого записать. Т.е. не надо в каждом вызове указывать имя файла, надо один раз указать имя в вызове CreateFile. Более того хэндлы обладают правами доступа. Это тоже важная часть описателя. Через один описатель(хэндл) ты можешь и читать и писать, через другой только читать и т.д. Для образовательных целей советую скачать Process Explorer и глянуть список хэндлов (описателей) процесса какого-нибудь. Кстати бывают хэндлы не только файлов, но и многих других объектов. Кароче бери Рихтера и читай. Это книжка такая. Это можно нагуглить.
Значится всётаки надо Create создать сначала! У мну тут пример был, но я его замучился в фасм перекраивать =) Код (Text): TITLE Using WriteFile (WriteFile.asm) ; This program writes text to an output file. ; Last update: 1/30/02 INCLUDE Irvine32.inc .data buffer BYTE "This text is written to an output file.",0dh,0ah bufSize = ($-buffer) errMsg BYTE "Cannot create file",0dh,0ah,0 filename BYTE "output.txt",0 fileHandle DWORD ? ; handle to output file bytesWritten DWORD ? ; number of bytes written .code main PROC INVOKE CreateFile, ADDR filename, GENERIC_WRITE, DO_NOT_SHARE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 mov fileHandle,eax ; save file handle .IF eax == INVALID_HANDLE_VALUE mov edx,OFFSET errMsg ; Display error message call WriteString jmp QuitNow .ENDIF INVOKE WriteFile, ; write text to file fileHandle, ; file handle ADDR buffer, ; buffer pointer bufSize, ; number of bytes to write ADDR bytesWritten, ; number of bytes written 0 ; overlapped execution flag INVOKE CloseHandle, fileHandle QuitNow: exit main ENDP END main Я сначала по поводу хендлов подумал, что раз CreateFile не требует хендла, то может и WriteFile аналогично? Хм. почему бы и нет, ведь передаётся же дата с чем работать X db 'C:\123.txt',0 Но я не против хендлов как таковых, просто хочеться вникнуть =) 8-)
Semiono Я очень рад что вы поняли про описатели =) Вообще это фундаментальные вещи которые пишут в книгах, поэтому возьмите книгу и прочитайте.
Код (Text): section '.data' data readable writeable X db '123.txt',0 hFile dd ? Msg db 'Hello' zzzz dd ? section '.code' code readable executable start: invoke CreateFile,X,GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 mov [hFile],eax invoke WriteFile,[hFile],Msg,5,zzzz,0 invoke ExitProcess,0 .end start А почему поле " __out_opt LPDWORD lpNumberOfBytesWritten " нельзя цыфрой сразу указать? или NULL ? Вообще что я накатал хоть правильно или можно проще было? Почему всётаки eax помещать в [hFile] нужно было? Даже логичнее наоборот какойнить указатель в регистр загрузить, что тут за фитча таиться?
Semiono Может стоить потрассировать код под олей, дабы видеть что и для чего. hFile это переменная, которая хранит то магическое число.
Semiono Инфу про любой параметр можно узнать в MSDN. Это единственный источник знаний на который надо опираться. Все правильно, но описатели надо закрывать CloseHandle.
Semiono Функция WriteFile возвращает два значения - результат записи (получилось/не получилось) и количество реально записанных байт, поэтому и нужно обязательно сказать адрес ей куда девать второе возвращаемое значение (NumberOfBytesWritten). Сделать так чтобы просто в eax возвращалость NumberOfBytesWritten (а 0 значит ошибка) нельзя потому, что возможна ситуация - удалось записать только часть информации, тогда нужно вернуть и сообщение об ошибке в eax и ненулевое количество байт которые удалость записать.
Semiono Потому, что регистр eax затирается при вызове функций и его значение нужно сохранить в переменной hFile для дальнейшего использования. В твоем примере в WriteFile можно и само значение eax передать, но после WriteFile значение в eax уже будет другим, поэтому в CloseHandle (или в последующие вызовы WriteFile) нужно будет передавать не eax, а сохраненное значение [hFile]
Спасиб, пацаны! Загрузить в OllyGbg это само собой, я просто наспех методом тыка начал решить, хотя "неправильный" код мнеб сразу тоже правду не сказал бы кажись. msdn скачал по теме уже давно, признаться они флудят там, вернее им бы на fasm луче б писать, было бы правильней тогда, у них там систем-администраторский язык повествования, трудно усваиваимый мозг =) * Да про CloseHandle забыл! Y_Mur, leo очень по делу, большое спасибо!
Пожалуй "хорошим тоном" будет коментировать winapi-код так Код (Text): invoke WriteFile,\ ; BOOL WINAPI WriteFile [hFile],\ ; __in HANDLE hFile Msg,\ ; __in LPCVOID lpBuffer 5,\ ; __in DWORD nNumberOfBytesToWrite bWrtn,\ ; __out_opt LPDWORD lpNumberOfBytesWritten 0 ; __inout_opt LPOVERLAPPED lpOverlapped сразу же бросается то что имеют место всякие типы данных 0_o поглядев на DWORD я сразу же подумал об LPCSTR, но не тут-то было! Оказывается это CString::operator Может стоит в таком случае создать "справочник" или таблицу всего такого для Fasm. Или не стоит? Я бы сам зделал, но пока не знаю в какие дебри это уходит и насколько. Всмысле, msdn это понятно, но было бы лучше иметь сразу механический перевод в db dw dd всех типов для асма? Ещё не понятно почему запись функций различается, о чём это вообще говорит? - HANDLE WINAPI CreateFile BOOL WINAPI WriteFile разве bool и handle вещи одного порядка? как будто сравнивать снег с телевизором =)
Semiono это у тебя всё с непривычки к асму ) и судя по тому что ты написал к программированию вообще ) Для начала пиши как тебе удобнее, а потом сам сравнив разные варианты записи поймёшь что удобнее всего в строку invoke имя_функции, аргументы. А если вдруг с большого перекуру мануалов забыл тип или назначение какого нибудь аргумента заглянул в msdn и порядок ) И с чего это тебя вдруг удивляет что одна функция возвращает handle, другая bool, третья integer, четвёртая errorcode, и т.д. ))
Semiono В третий раз говорю, MSDN единственный надежный источник. Если ты ламер не надо вот только кричать это по сто раз. Тошнить начинает.