Z mojego doświadczenia wynika, że początek nauki assembly, to w zasadzie nie nauka assembly, a:
- próba wyboru kompilatora / assemblera
- nauka stworzenia hello world w pod ten assembler
- stwierdzenie, że kurs jest pod tasm a my mamy nasm
- stwierdzenie, że nasm nie rozumie składni at&t
- stwierdzenie, że w zasadzie na 20 linii programu w masm/fasm tylko 3 to faktycznie instrukcje assembly
- stwierdzenie, że windows nie ma int 21h i assembly 16-bitowy kiepsko na nim działa
- stwierdzenie, że windows nie ma również int 80h
- etc.
Powyższe rzeczy są ofc ważne, ale fajnie by było to uprościć na samym początku do np.:
- jak najmniejszego overhead'a jeśli chodzi o strukturę pliku źródłowego, czyli np. żadnych tablic importów, sekcji, etc
- zunifikowania API - do zrobienia pierwszych kroków wystarczy w zasadzie z 5 funkcji i fajnie by było gdyby było można je tak samo wywołać pod Windowsem jak i "Linuxami"
Oczywiście, zunifikowane API wprowadza nowe API, co też cudowne nie jest (chociaż niby możnaby rozwiązać to implementując np. API Linuxa pod Windowsem, ale nvm).
Wracając do Simplified Assembly Loader aka asmloader - jest to prosta appka której podaje się nazwę pliku zawierającego 32-bitowy kod maszynowy (bez żadnych nagłówków) i która:
1. Alokuje pamięć Read/Write/Execute na podany plik (+- 0x101 bajtów na stub + padding).
2. Ładuje tam kod maszynowy (na offset +0x100).
3. Skacze do niego.
Oraz dodatkowo, udostępnia API (5 funkcji: exit, putchar, getchar, printf, scanf; taak, to są standardowe funkcje ze standardowej biblioteki C, więc bez problemu można znaleźć ich opis).
Jeśli chodzi o warunki początkowe, to nie można czynić żadnych założeń co do wartości rejestrów, oprócz dwóch:
- EBX zawiera pointer na tablicę API (o tym za chwilę)
- ESP wskazuje na prawidłowy stos (tzn nie trzeba ESP inicjować w żaden sposób, można od razu korzystać ze stosu)
Jeśli chodzi o odwołania do API, to robi się to używając call [ebx+NR_FUNKCJI * 4], gdzie * 4 wynika z wielkości pointera (4 bajty aka 32 bity), a NR_FUNKCJI to:
0 - exit
1 - putchar
2 - getchar
3 - printf
4 - scanf
Np. call [ebx+1*4] wywoła putchar.
Funkcje są cdecl, czyli:
1. Argumenty wrzuca się na stos (stos rośnie w stronę niższych adresów, więc przyjmuje się, że argumenty wrzuca się "od tyłu").
2. Caller (programista) musi zdjąć argumenty ze stosu po tym jak funkcja wróci.
3. To co funkcja zwróci jest w EAX.
Np. wypisanie literki 'H' to (w składni nasm):
push dword 'H' ; wrzucenie na stos literki 'H' (kodu ASCII ofc)
call [ebx+1*4] ; wywołanie putchar
add esp, 4 ; wyczyszczenie stosu
Jeśli chodzi o stub i padding, to stub zawiera kod który wrzuca do EBX adres tablicy API, a padding to po prostu 0xCC (int3), czyli jeśli ktoś zapomni o exit lub ret (lepiej użyć exit, ew trzeba zadbać o zachowanie rejestrów które się używa), to program się crashnie.
By the way...
On 22nd Nov'24 we're running a webinar called "CVEs of SSH" – it's free, but requires sign up: https://hexarcana.ch/workshops/cves-of-ssh (Dan from HexArcana is the speaker).
Jeśli chodzi o assembler który polecam do kompletu, to jest nim nasm (Netwide Assembler), ale w zasadzie może być to dowolny assembler który umie wygenerować beznagłówkowy kod maszynowy (np. fasm z format binary i use32 też się nada).
To chyba na tyle. Na koniec linki:
asmloader.c (źródło, licencja MIT)
asmloader.exe (binarka pod Win32)
Programik kompiluje się pod GCC (MinGW, "linuxowe" GCC) i MSVC++ (cl.exe), np.
gcc asmloader.c -o asmloader
Jeśli chodzi o potencjalny rozwój, to raczej za dużo go nie będzie. Co najwyżej planuje dodać tryb 64-bitowy, oraz jakieś proste API do wypisania wszystkich rejestrów i RDTSC.
And that's that :)
Comments:
Szczerze, to już ruszyło (rzuć okiem na moje uploady na YT). Ale wrzucę dzisiaj jeszcze posta o tym ;)
a co za problem pobrac z Youtube? w gruncie rzeczy ladujac film na YT juz go masz na dysku, pewnie nawet o tym nie wiedzac:)
Ja tam żadnego obniżenia jakości nie mam, zależy czym ściągasz. Ja polecam do tego JDownloader, tyle że to bardziej kombajn do ściągania, co może niektórych ucieszyć a dla innych będzie tylko niepotrzebnie zwiększać wagę.
A tak w ogóle to witam, to chyba mój pierwszy komentarz, bloga obserwuję od niecałego miesiąca.
W zasadzie wszystko na temat zostało powiedziane ;)
Natomiast jeśli będzie dużo głosów za downloadem, to postaram się żeby opcja downloadu videocastów również była.
(Zresztą, pisałem o tym w komentarzach w następnym poście)
@olo16
Witam witam ;)
Ad loader i quit(), a raczej exit() - system operacyjny wie dokładnie ile pamięci proces ma zaalokowane, więc, przy wyjściu procesu, może tą pamięć zwolnić. W zasadzie jeśli chodzi o zwykłą alokację pamięci i otwieranie handli, to można ufać systemowi operacyjnemu że tą pamięć zwolni i handle zamknie.
Jakieś 15 lat temu (za czasów Windows 95 i 98) był z tym większy problem afair, i memory leaki faktycznie się zdarzały.
void clean_at_exit() { tutaj dealkoacja, jesli cos jest zaalokowane ofc; }
atexit(clean_at_exit);
Or similar (ofc to wymaga przynajmniej jednej zmiennej globalnej, ale co zrobić). Lib C (w którym jest implementacja tego mechanizmu) zadba o to by clean_at_exit() bylo wywołane.
New to podobno w większości implementacji wrapper na malloc, co byłoby logiczne.
Za to malloc musi wywoływać funkcje systemowe, no bo jak inaczej ma alokować.
Widziałem że po malloc też nie zawsze wywołujesz free, więc rozumiem że jest tak samo - OS wszystko sobie zwolni? Heh, we wszystkich kursach i książkach zawsze straszą wyciekami - w zasadzie to dobrze, wyrabia dobre nawyki, ale widzę że wycieki pamięci to raczej problem jeśli program często alokuje i nie zwalnia, wtedy może mu się wyczerpać pamięć.
http://www.wykop.pl/link/744031/emulator-komputera-napisany-w-js-linux-odpalony-w-przegladarce/
Ciekawe jak to działa :p
P.S. kod cpux86.js bardzo ciekawy :D
Gdy przepisałem słowo w słowo hello world.
To zapisałem i użyłem następujących komend
nasm hell.asm - działa
asmloader hell.asm
Cytuje "Simplified Assembly Loader v0.0.1 by gynvael.coldwind//vx"
"Code loaded at 0x00030100 <334 bytes>"
Pojawienie się błędu "Program asmloader.exe przestał działać."
Debuguj lub zamknij program
Nie działa mi w ogóle ten loader. Gdy wyrzucę wypisz_xyz i wypisz_hello to i tak program się skonfiguruje tylko że wtedy po wpisaniu A,g nie dostaję żadnego efektu.
Podrzuć kod który się wysypuje, to rzucę okiem.
push 'H'
call [ebx + 4]
add esp, 4
push 0x0A
call [ebx + 4]
add esp, 4
push 0
call [ebx]
add esp, 4
Sypie się na pierwszym call'u, próbuje skoczyć do 0x4, w ebx jak już mówiłem jest 0.
Hmm, mógłbyś mi tą binarkę asmloader'a z plikiem core podrzucić?
Żeby wygenerować core zrób tak:
ulimit -c unlimited
<i tutaj odpal asmloader na tym programie co się wysypuje>
Mój e-mail: gynvael@coldwind.pl
nick@domena:~/Folder/C$ gcc asmloader.c -o asmloader
asmloader.c: In function ‘LoadBinary’:
asmloader.c:134:4: error: #error Not implemented.
asmloader.c: In function ‘main’:
asmloader.c:191:4: error: #error Not implemented.
Dodatkowe informacje:
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
Target: x86_64-linux-gnu
sudo apt-get install libc6-dev-i386
i kompilować:
gcc -m32 -o asmloader asmloader.c
*clap* *clap* *clap*
zrobiłeś:
nasm cuź.asm ; Output -> cuź lub cuź.BIN
asmloader cuź.ASMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM ; zamiast . czy .bin
P.S.
Wiem, że to dawny komentarz, ale musiałem coś na ten temat wspomnieć.
.
.
.
.
.
.
.
.
.
.
.
.
.
*clap*
Asmloader jest na licencji MIT, więc rzuć najlepiej okiem na samą licencje (sekcja "-- License Stuff" w kodzie źródłowym: https://github.com/gynvael/asmloader/blob/master/asmloader.c) :)
Ta licencja generalnie pozawala na większość (wszystkie?) ciekawe zastosowania, i stawia jeden wymóg:
"The [..] copyright notice and this permission notice shall be included in all copies or substantial portions of the Software."
Nie, to nie GPL. Po prostu musisz kopię licencji (łącznie z copyright notice) dołączyć do swojego programu (jako plik tekstowy; zazwyczaj dokleja się na koniec swojej licencji albo robi jakiś osobny plik na to).
Add a comment: