Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #88, АПРЕЛЬ 2006 г.

Трудовая дисциплина

Крис Касперски aka мыщъх

Хакер, номер #088, стр. 088-114-7


В комплекте с полной версией MASM'а идут inc-файлы, в которых все прототипы объявлены правильно, однако в DDK ничего подобного нет, и поэтому эту работу нам приходится выполнять самостоятельно и писать так: extern MessageBoxA@16:near или так: extern _imp__MessageBoxA@16:dword. В последнем случае функция будет вызвана через переходник. Если слово stdcall в модели памяти не указано и, следовательно, знак подчеркивания транслятором не добавляется, обе конструкции будут выглядеть так: extern _MessageBoxA@16:near и extern __imp__MessageBoxA@16:dword. Чтобы не вызывать каждый раз по длинному имени, создай короткий алиас, обозвав ее хоть msgbox, хоть mb, хотя во избежание путаницы программисты все-таки сохраняют оригинальные API-имена и убирают только "_" и "$x".

Законченный вариант программы будет выглядеть так.

.386

.model flat

extern _ExitProcess@4:near

extern _MessageBoxA@16:near

.data

s0 db 'hello, world',0

.code

_start:

push 0

push 0

push offset s0

push 0

call _MessageBoxA@16

push 0

call _ExitProcess@4

end _start

Программа нормально транслируется и даже работает, но не дает ответа на вопрос: почему же ее создатель не выполнил все эти действия заранее?! Да потому, что программа предназначалась для TASM'а, библиотекарь которого именует функции так, как написано, а не так, как диктует соглашение о stdcall-вызовах. Но почему бы тогда не транслировать программу TASM'ом?! Есть причины. Во-первых, TASM заброшен и уже не развивается (впрочем, MASM не развивается тоже), во-вторых, объектные файлы, сгенерированные TASM'ом, трудно интегрировать в другие проекты. В-третьих, мыщъх'и испытывают к Багдаду стойкую антипатию, непреодолимую даже пивом. Но если кому-то нравится TASM, то компилируйте программу так:

rem ассемблируем

tasm32 /ml h2.asm

rem готовим библиотеки из dll

implib -c user32.lib C:\WINNT\system32\user32.dll

implib -c kernel32.lib C:\WINNT\system32\kernel32.dll

rem линкуем

tlink32 h2.obj -Tpe -aa -L user32.lib -L kernel32.lib

А нельзя ли ассемблировать нашу программу замечательным (и притом совершенно бесплатным) транслятором FASM? Увы! Различия в синтаксисе FASM'а очень значительные, и без капитальной правки листинга здесь не обойтись. Вот только один пример. Широко распространенная конструкция DB 669h DUP(?) приводит FASM в состояние замешательства и ее приходится заменять на rb 669h, что, несомненно, короче, но это же сколько лишней работы по переносу делать приходится! Отсутствие offset'а мы уже отмечали. Привычных директив тоже нет. Макросредства есть, но совсем не те, что в MASM'е, и работают они совсем не так!

После переделки под FASM программа будет выглядеть так:

include 'INCLUDE\win32ax.inc'

.code

start:

push 0

push 0

push s0

push 0

call [MessageBox]

push 0

call [ExitProcess]

.data

s0 db 'hello, world',0

.end start

Как видно, исчезли директивы .386" и .model, а в начале ключевого слова end" появилась точка, которой раньше не было. Включаемый файл "win32ax.inc" содержит все необходимые определения, и поэтому API-функции вызываются по их именам, заключенных в квадратики (косвенный вызов по ссылке, если делать иначе - все рухнет). Ключевое слово offset исчезло из инструкции push s0. Вот, пожалуй, и все. Теперь транслятор пережевывает программу и не давится: fasm hello.asm. Нам же остается только запустить созданный exe-файл на выполнение и порадоваться тому, как хорошо он работает.

Назад на стр. 088-114-6  Содержание  Вперед на стр. 088-114-8