WinAPI z Assemblerem – Część 0

Postanowiłem podjąć się tego niełatwego zadania i w miarę przystępny sposób opisać jak można napisać szybkie i małe aplikacje w języku assembler wykorzystując do tego również WinAPI.

Większość programistów wysokopoziomowych pewnie popuka się w czoło i opuści ten artykuł, ich strata ;). Dobry programista powinien znać wiele języków, nawet te, które pozornie wyszły już z użycia.

Artykuł przeznaczony raczej dla osób znających już podstawy programowania w Assemblerze i WinAPI.

Prawda jest taka, że jednak aplikacji biznesowej w ten sposób nie napiszemy, gdyż wiązałoby się to z ogromną ilością czasu i straconej cierpliwości. Z drugiej strony, programy napisane praktycznie od zera dają mnóstwo satysfakcji i w wielu przypadkach działają po prostu szybciej; najczęściej spotykanymi aplikacjami są dobrze znane nam keygeny i cracki.

Środowisko

Skoro WinAPI, to piszemy pod Windowsem ;), a jako assemblera użyjemy FASM, naprawdę bardzo fajny, dobrze opisany i dość często aktualizowany. Ściągnąć go można z podanego linku, nie wymaga instalacji – wystarczy tylko rozpakować i uruchomić.

Pierwsze kroki

Mogę zapewnić, że nie będą łatwe, WinAPI samo w sobie nie należy do łatwych, a co dopiero gdy wymieszamy to jeszcze z assemblerem, ale żeby nie straszyć zbytnio, na początku napiszemy prostą aplikację wyświetlającą prosty Message Box. Co najpierw? Uruchamiamy FASMW.EXE.

Można się trochę zdziwić, bo program nie wygląda okazale, ot okienko z miejscem na wpisanie kodu i paroma przyciskami w menu, ale to nam zupełności wystarczy.

Ponieważ dziś kod jest krótki, wkleję od razu całość i będę omawiał zadania jakie wykonują poszczególne elementy. Program jest najprostszy z możliwych, nie ma podziału na sekcje, ani żadnych elementów interfejsu graficznego, typowe „Hello World”.

Na początku programu należy zdefiniować format wyjściowy, do wyboru mamy kilka: COM, MZ, Portable Executable czy też ELF. Zgodnie z 1. linijką, nasza aplikacja będzie formatu PE z graficznym interfejsem (można wybrać wersję konsolową). Szczegółowy opis każdego formatu można przeczytać tutaj.

Gdy format został już ustalony, możemy dołączyć pomocne nagłówki (tak jak w językach wysokiego poziomu) zawierające makrodefinicje, deklaracje struktur, stałych i innych rzeczy. Na początku będziemy używać nagłówka win32a.inc, który definiuje podstawowe typy WinAPI na architekturę 32-bitową.

I teraz główna część programu, tylko 2 linijki składające się z wywołania tajemniczego makra invoke… No właśnie, co to jest? Będziemy tego używać niemalże w każdym programie, jest to niezwykle przydatna makrodefinicja, która ułatwia wywoływanie funkcji. Dla przykładu, aby bez użycia invoke wywołać funkcję z linijki 5., należałoby wpisać poniższy kod:

W efekcie wychodzi na to samo, ale jakże przyjemniej i czytelniej jest mieć to wszystko w jednej linii, no i mamy pewność, że argumenty umieścimy we właściwej kolejności. Szczegółowy opis wszystkich funkcji WinAPI można znaleźć na MSDN (chyba jedyna rzecz jaka naprawdę Microsoftowi wyszła), w artykułach będę linkował do odpowiednich stron co by oszczędzić wam nieco czasu.

Gdy okienko dialogowe zostanie zamknięte, wywołana zostanie funkcja ExitProcess, która po prostu zamknie nasz program z kodem 0.

Teraz musimy jeszcze ustalić czym są zmienne title i caption, dokonuje się tego praktycznie tak samo jak w Turbo Assemblerze, najpierw etykieta, potem typ, a na końcu dane.

Ostatnia rzecz jaką musimy wykonać, to wskazać z jakich bibliotek oraz funkcji systemowych korzystaliśmy, czyli budujemy tablicę importów. Informacje o przynależności poszczególnych funkcji do bibliotek można zaczerpnąć ze stron MSDN, na końcu opisu każdej funkcji jest podane w jakiej bibliotece się mieści. Wszystkie te czynności robimy w bloku data import.

Na początku zawsze należy wymienić używane biblioteki systemowe, do tego celu używamy makra library, po którym umieszczamy dowolną ilość par składających się z etykiety biblioteki oraz z nazwy biblioteki umieszczonej w apostrofach. Nie jest wymagane aby każda była w nowej linii, jednak niewątpliwie zwiększa to czytelność.

Backslash oznacza złamanie wiersza, bez niego nowa linia zostałaby potraktowana jako nowa instrukcja.

Pozostaje jeszcze kwestia funkcji, robi się to w podobny sposób jak z bibliotekami, z tą różnicą, że bezpośrednio po import umieszczamy etykietę biblioteki, a dopiero potem pary składające się z etykiety i nazwy funkcji.

Uruchomienie

Kod jest gotowy, pozostało go jedynie uruchomić klawiszem F9 albo poprzez menu Run ->Run.

hello_world

Efekt naszej pracy

I tym pozytywnych akcentem kończymy część zerową, kolejna pojawi się niebawem, a wraz z nią ambitniejsze zadania.

[guest@itachi.pl:~]$

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *