1
DELPHI
Część 3.ASM i Pascal
Delphi Offline 4Programmers : Zadania i wypracowania, oraz zbiory lekcyjne delphi
wersje faq napisane przez wielu programistów znajdują się w tej ogromnej książce, składającej się z wielu stron o bardzo wnikliwie napisanej treści.
Autorzy : minn,. Adam Boduch,iinni.
Podziękowania dla wszystkich autorów faq, bo to oni stworzyli tą książkę.
Książka ta nie jest , nie była i nie będzie wydana na rynku, jedynie może się ukazać w wersji pirackiej na stronach i z innych żródeł, jest ona prawnie nieprawna i prawnie łamie chyba wszystkie prawa dotyczące praw prawa prawowitego właściciela i autora oraz plagiat jak cholera . Uehhhhh, ;) prawo w Polsce jest pOkRęCoNe,
IRCc2003
Ps : w rzyciu jeszcze niewidziałem tak wielkiej kopii danych tak wielu autorów i to zklepana całkiem bez ich zgody ! czy to może tak być? Nie, Dla tego proszę wnikliwie nie doszukiwać się autorów tej oto wielkiej 2 tomowej księgi, i potraktować to jako wielkie uznanie, iż wasze Faq mogło się ukazać wraz z najlepszymi, nik nie będzie pokszywdzony, dane nie są zmienione, brakuje tylko podpisów autorów, z powodu takiego, że, naprawdę ich nie znałem: Dlaczego ją napisałem ? bo wasze nauki poprostu się marnowały !
Dlaczego by tego nie zapakować w jedno. Nigdy nie myślałem o tym że ta książka będzie wirowała po internecie, nawet teraz, jak ją piszę , niewiem o tym, co dzieje się w czasie gdy ty ją czytasz. Jeżeli jednak coś się dzieje i z nie mojego powodu dostałą się ona w wasze oblicze, bądż zbyt wielu autorów tych faq się z czymś tutaj zawartym nie zgadza, proszę zmieniać treść DOWOLI ! NIC TUTAJ NIE MUSI ZOSTAC W TAKIEJ FORMIE W JAKIEJ JEST wszystko to dotyczy każdej mojej książki, która w jakiś sposób kogoś lub wielu WAS crackerów i hakerów i Hakerów uraziła. Wiele danych pochodzi ze strony :
4programmers.net i to Właśnie A.B powinien mieć o to największy żal, no ale cóż zrobię.
PA.
TP w 32-bitowym opakowaniu
Czyli jak zmusić 16-bitowy kompilator tp do 32-bitowych operacji. Pozornie rzecz niemożliwa, a jednak...Część tematu jest już zaprezentowana w artykule pt.: efektywne programowanie w turbo pascalu, więc się będę nieco powtarzać. Ponadto zakładam, że znasz podstawy asemblera, bo to dzięki niemu będziemy czarować w 32 bitach. (Będziemy używać tylko asemblera wbudowanego w kompilator, więc jeśli używasz asemblera zewnętrznego, to nie ma sensu żebyś czytał dalej ten artykuł.)
Co nam daje działanie na 32 bitach? Przede wszystkim operacje takie są szybsze w porównaniu do ich 16-bitowych odpowiedników, ponadto wyniki naszych działań nie są ograniczone rozmiarem 16-bitowego rejestru a rozmiarem rejestru 32-bitowego, czyli że bez nadmiernego kombinowania możemy sobie działać na wielokrotnie większych liczbach - przy zachowaniu tej samej, a nawet wyższej szybkości.Same plusy :)
Ale jest i minus: jak? Jak zmusić kompilator tp do przełknięcia czegoś, do czego nie był przewidziany? Popatrzmy na wbudowany asembler: nie zna takich rejestrów, jak EAX,EBX itp, nie zna FS ani GS, w ogóle zero zrozumienia dla naszych 32-bitowych aspiracji. Ale zna on coś takiego, jak DB, DW i DD. I to nas urządza. :)
Jak się buduje 32-bitową instrukcję? Jeśli by za pośrednictwem debuggera (np.: Turbo Debugger) pownikać w kod jakiegoś 32-bitowego programu, to zobaczymy śmiesznie prostą prawidłowość: każda taka operacja jest poprzedzona bajtem o wartości 66h (102d). Tak! To jest naprawdę aż takie proste! Więc zaczynamy rzeźbienie...
Na pierwszy ogień najczęściej używana operacja - zerowanie rejestru.
asm
mov ax,0 {można tak}
xor ax,ax {można też tak; tak jest lepiej, bo operacje
wykonywane na samych rejestrach, bez odwołania
do pamięci, są szybsze}
db $66; mov ax,0 {tu już mamy 32 bity: mov eax,0}
db $66; xor ax,ax {i druga wersja 32-bitowa: xor eax,eax
ta wersja jest najlepsza i najszybsza}
end;
W ten sam sposób możemy sobie dzielić, mnożyć, dodawać, odejmować, przesuwać bity, wrzucać na stos i z niego zdejmować - teoretycznie cokolwiek!W praktyce pojawia się kilka problemów, ale o tym za chwilę.
Może kilka przykładów:
{szybkie c=a*b, gdzie a i b są typu word, wynik
jest też typu word, czyli w zasadzie nic nowego}
mov ax,a
mov bx,b
db 66; mul bx
mov c,ax
Teraz mnożenie word*word z wynikiem dword (tzn. longint). Strach patrzeć w debuggerze na to, co robi TP z c := longint(a)*longint(b)...
db $66; xor ax,ax; {na wszelki wypadek eax = 0}
mov ax,a {ax = a}
mov bx,b {bx = b}
db $66; mul bx {eax = eax * ebx}
db $66; mov word ptr c,ax {c = eax}
Powyższa instrukcja jest wykonywana o ponad 60% szybciej.A może by tak zaryzykować 64 bity?... Mnożenie dword*dword z wynikiem qword (2*longint)!!! Wynik zrzucany do dwóch zmiennych - poniżej $FFFFFFFF do c, a to co wyżej - to do d.
db $66; mov ax, word ptr a
db $66; mov bx, word ptr b
db $66; mul bx
db $66; mov word ptr c,ax
db $66; mov word ptr d,dx
W analogiczny sposób można dzielić dword przez dword, otrzymując w wyniku też dwa dwordy (tzn. c = a div b; d = a mod b):
db $66; div bx
Jak szybko zwiększyć zmienną typu longint?
asm {tak TP interpretuje inc(a): dwie operacje dodawania}
add word ptr a,0001
adc word ptr a+2,0000
asm {tak my zrobimy: jedna operacja inkrementacji}
db $66; inc word ptr a
Nie trzeba dodawać, że inc jest dużo szybsze od add?A dodawanie? Proszę bardzo:
asm {dodawanie stałych: niech stała będzie równa np. $0F0F1010}
db $66; add word ptr a,$1010; DW $0F0F;
{przy dodawaniu stałej, której dolna część będzie mniejsza
od $100, pojawi się problem, bo kompilator się nabierze,
że to bajt; wtedy trzeba mocno czarować:}
db $66; mov ax,$0010; DW $000F;
db $66; add word ptr a,ax
end; { co i tak generuje szybszy kod niż inc(a,$000F0010)}
Jeśli porównasz któryś z powyższych kodów z jego odpowiednikiem generowanym w wyniku zwykłego mnożenia, dzielenia itp., to zobaczysz jak wiele zyskujesz.
Możemy też dopalić najbardziej czasochłonną procedurę w TP: move (nota bene - ona jest 8-bitowa!!!). Napiszemy własną wersję, która będzie prawie cztery razy szybsza.A w ogóle jak działa ta procedura? Szybki rzut oka:
procedure move(var src;var dest;count : word); assembler;
mov cx,count
push ds
lds si,src
les di,dest
cld
rep movsb {!!!}
pop ds
Spójrz na linijkę z trzema wykrzyknikami: rep movsb. movsb to operacja przenoszenia bajtu ze stosu ds:si na stos es:di. Przenosimy po bajcie! (Jeśli nie wierzysz, to odpal program, który używa tej procedury, pod debuggerem i sam sprawdź.)Przecież to jest bez sensu, bo kompilator bez żadnego rzeźbienia pozwala na napisanie procedury, która będzie przenosić po słowie, czyli w tym samym czasie skopiuje dwa razy więcej!Ale po co się ograniczać do słowa? Poniższa procedura będzie zrzucać od razu cztery bajty, osiągając graniczną prędkość działania równą prędkości zegara pamięci...
procedure move32(var src;var dest;count : word); assembler;
mov ax,count
db $66; xor dx,dx {xor ecx,ecx}
mov bx,4
div bx {ax = count div 4; dx = count mod 4}
mov cx,ax
db $66; rep movsw {rep movsd}
cmp dx,0
jz @@1
db $66; mov cx,dx
rep movsb
@@1:
Chyba już łąpiesz, o co chodzi? Wtykasz db $66; wszędzie, gdzie się da, i już możesz być szczęśliwy. Uważaj na jedno: operacje na pamięci - zrzucanie i pobieranie ze stosu; pamiętaj, że operujesz naraz czterema bajtami, a nie dwoma czy jednym. Jeśli nie jesteś pewien, czy poprawnie zrobiłeś to, co chciałeś, a masz do dyspozycji Turbo Debuggera albo jakiś inny debugger, to nie wahaj się i sprawdzaj.Jeżeli masz jeszcze jakieś pytania lub chcesz coś dodać - pisz do mnie.
FAQ CrackPL - Asm dla badaczy kodu – Wprowadzenie
Chyba nikogo nie musze uswiadamiac jak wazna jest znajomoscassemblera dla badaczy kodu. Jezyk ten bedacy mnemonika kodumaszynowego procesorow ulega zatraceniu w dzisiejszych czasach wdobie pakietow typu Visual Microsoftu, Borlanada i innych.Nowoczesni (czytaj. nowi -:)) programisci nie maja nawet pojeciaczym jest assebler i jak go ugrysc a przeciez kod asemblera jestesencja programowania i dlatego kazdy badacz kodu musi go poznać.Postanowilem przedstawic wam maly guide wprowadzajacy do asembleradla wszystkich poczatkujacych crackerów i pod ich kierunkiempisany. Jest to jedynie schematyczny przeglad podstawowych pojec iinstrukcji, który mam nadzieje rozwine w przyszlosci. W ZADNYWYPADKU NIE JEST TO TUTOR programowania w asm, jedynie przedstawiazagadnienia na ktore nalezy zwrocic uwage podczas analizy kodu. Noale mam nadzieje :-) ze kazdy kto to przeczyta wezmie sie za asm'aporzadnie i bedzie pisal w nim programy w razie potrzeby.Wszelkie sugestie i pomysly kierowac na gcrkpl@friko6.onet.pl.Co powinien wiedziec cracker o asmInDeX[PODSTAWOWE INFORMACJE]1. Rejestry [REGISTERS]1.a. [Specyfikacja architektury Intela - Rejestry]2. [Flagi - Rejestr znacznikow]2.a. [Flagi - Rejestr znacznikow - specyfikacja Intel 8086]3. [Stos - STACK ]4. [Call i Ret - wywolania funkcji i procedur]5. [MOV - instrukcja przeniesienia]6. [CMP i skoki warunkowe]6.a. [Specyfikacja skokow warunkowy][CIEKAWOSTKI]7. TEST EAX,EAX - co to znaczy ?___________________________________________________________________1. Rejestry [REGISTERS]Rejestry sa podstawowym miejscem przechowywania danych. Sa to16-bitowe komorki procesora. Jest 14 rejestrów i w tym 12 rejestrowdanych i adresowych, rejestr wskaznika instrukcji (IP) i rejestrznacznikow. Rejestry danych i adresowych mozemy podzielic na kilkagrup i tak:AX (akumulator) --------+BX (bazowy) |----- Rejestry ogólnegoprzenzaczeniaCX (licznik) | DX (danych) --------+SP (wskaznik stosu) --------+BP (wskaznik bazy) |-----Rejestrywskaznikowe iindeksoweSI (index zrodla) |DI (indeks przeznaczenia) --------+CS (programu) --------+DS (danych) |----- Rejstry segmentoweSS (stosu) |ES (dodatkowy) --------+IP (wskaznik instrukcji)I Rejestr ZnacznikowJak oczywiscie kazdy sie zorientowal przy pracy w Win32 rejestryokreslane sa jak EAX, EAX itd, oznacza to ze sa to odpowiednikipowyzszych rejestrow, tyle, ze 32-bitowe.Chwila wyjasnienia z tymi bitami. Wezmy rejestr AX, ktoryjest 16bitowy i dzieli sie na dwa podrejestry 8 bitowe AH i AL. Jak wiemy8 bitow tworzy bajt, ktory przyjumuje wartosc od 0 do 255, czylirejestr AH i AL moze miec najwieksza wartosc FFh. Logicznie myslac-:) rejestr 16 bitowy moze przyjac maksymalna wartosc FFFFh itd.(32 bit EAX mam max FFFFFFFFh ups-:)). Chyba kazdy lapie co daja 32bitowe rejestry i jak zwiekszaja sie mozliwosci.Warto zapoznac sie z charakterystykami rejestrow, gdzyz kazdy maswoje wlasne konkretne zastowsowanie. Przegladajac kod programumozemy zauazyc pewne prawidlowosci, np.EIP - debugujac pod SoftIce 32bit widzimy, ze rejestr ten wskazujena aktualny kod instrukcji i mozemy go uzyc np do zalozenia pulapkina danej lini czyli bpx EIP lub dokladniej CS:EIP.CS - wskazuje segment kodu, czyli jak mamy jakac linie kodu oadresie np. 14F:04033232 to mozemy ja zapisac jako CS:04033232poniewaz w rejestrze CS jest zachowana wartosc 014F.DS - podobnie jak powyzej, zawiera adres segmentu dany, jezeli wokienku danych pod SoftIce mamy jakis adres np. 0145:03055555 to DSwskazuje segment 0145.ESI i EDI sa wskaznikami danych np. do porownan tekstow itp. Wezmynp. instrukcje porownywania w bibliotekach VB - reps cmpsw dla,ktorych w w ds:esi i es:edi zawarte sa adresy tekstow (np. numerowseryjnych) do porwnania. To samo tyczy sie wielu instrukcjiprzesylania i porownnywania danych, gdzie przeznaczenie i celzawarte sa w rejesteach SI i DI np:LEA SI, ZRODLo ;Zaladowanie adresu zrodlaLEA DI, ES:PRzesznaczenie ;Zaladowanie adresuprzezanczeniaMOV CX,100 ;Zaladowanie licznika elementowMOVS Przeznaczenie,Zrodlo ;Kopiowanie tekstu z jednegomiejsca w innne.___________________________________________________________________1.a. [Specyfikacja architektury Intela - Rejestry]Rejestry ogolnego przeznaczenia RejestrysegmentoweAH/AL AX (EAX) Akumulator CS ProgramuBH/BL BX (EBX) Bazowy DS DanychCH/CL CX (ECX) Licznik SS StosuDH/DL DX (EDX) Danych ES Dodatkowy(Exx) znaczy 386+ 32 bit rejestr Rejestry wskaznikowe Rejestry stosuSI (ESI) Indeks zrodla SP (ESP) Wskaznik stosuDI (EDI) Indeks przeznaczenia BP (EBP) Wskaznik bazyIP Wskaznik instrukcjiFLAGI Rejestr Znacznikow (zobacz FLAGI)Specjalne rejestry (386+)CR0 Control Register 0 DR0 Debug Register 0 CR2 Control Register 2 DR1 Debug Register 1 CR3 Control Register 3 DR2 Debug Register 2 DR3 Debug Register 3TR4 Test Register 4 DR6 Debug Register 6TR5 Test Register 5 DR7 Debug Register 7TR6 Test Register 6TR7 Test Register 7Rejestry ogolnego przeznaczenia sa przeznaczzone do przechowywaniadowolnych danych i wykonywania roznych operacji (arytmetycznych,logicznych itp) , pelnia takze funkcje specjalne odpowiadajace ichnazwom. AX (accumulator) - rejestr ten jest najczesciej uzywany przyoperacjach mnozenia i dzielenia, a takze w operacjach logicznych,arytmetycznych i odkladania wynikow wielu operacji.8 dolnych bitow tego rejstru okresla sie jako rejestr AL, a 8gornych bitow jako AH BX (basis) - rejestr bazowy moze byc uzywany jako dwa 8-bitowerejestry BH i BL, a np. jako 16-bit mozemy go uzyc do utworzeniaadresu pamieci, tworzac z rejestrem segmentowym pelny adres -Segmennt:Offset - DS:BX CX (count) - rejestr zliczajacy jest wykorzystywany oproczzliczania takze do przesylania danych. Moze byc takze uzywany jakodwa rejestry 8-bitowe CH i CL.DX (data) - rejestr danych wykorzystuje sie przy dzieleniu imnozeniu. Jest takze jedynym rejestrem, w korym mozna podac adresportu w rozkazach wejscia-wyjscia. Rejestry segmentowe sluza do adresowania pamieci operacyjnej. CS (code segment) - rejestr wskazuje poczatek segmentu koduprogramu, tworzy pelny adres wraz z rejestrem IP - CS:IP. Rozkazyprogramu, skoki, powroty pobierane sa w odniesieniu do tegorejestru. DS (data segment) - rejestr wskazujacy poczatek segmentu danych SS (stack segment) - rejestr stosu wskazuje poczatek segmentu stosu ES (extra segment) - rejestr dodatkowu wskazujacy dodatkowy segmentdanych Rejestry wskaznikow. Dostep do danych adresowany jest przezpolaczenie adresu z rejestru segmentu z przesunieciem pobieranym zinnego rejestru min. rejestru wskaznikowego.SI (source index) - rejestr indeksowy zrodla, najczesciej stosowanyprzy adresowaniu w innstrukcjach przetwarzajacych lancuchy znakow,tworzy wowczas pelny adres DS:SI DI (destination index) - rejestr indeksowy przeznaczenia, podobnydo SI uzywany w adresowaniu danych przy przetwarzaniu lancuchowznakow, tworzy wowczas pelny adres ES:DI SP (stack pointer) - wskaznik stosu tworzy wraz z SS - SS:SP adresdanej odeslanej na stos i jest wykorzystywany przy pobieraniu izapisywaniu danych na stos. BP (base pointer) - wskaznik bazy uzywany jest podczas operacjiniestandardowych np. przy pobieraniu parametrow przekazywanych nastos. IP (instruction pointer) - wskaznik instrukcji wskazuje naaktualnie wykonywana instrukcje i wraz z rejestrem segmentu kodutworzy pelny adres - CS:IP. IP wskazuje offset (przesuniecie)wzgledem poczatku segmentu programu. ___________________________________________________________________2. [Flagi - Rejestr znacznikow]Falgi sa komorkami, ktore moga przyjmowac wartosc 0 lub 1 i sazawarte w rejestrze znacznikow. Odpowiednie ustawienieposzczegolnych flag decyduje o wykonaniu innych instrukcji aszczegolnie instrukci warunkowych. Najszybciej zrozumiec flagimozna na przykladzie :CMP AX,BX - Porownaj rejestry AX z BX, jezeli rowne to flagazerowa Z ustawiona na 1JZ 0401233 - Jezeli flaga Z ustawiona na 1 to wykonaj skok doadrsu 0401233Oczywiscie intrukcja CMP ustawia takze inne flagi z zaleznosci odwyniku porownania i podobnie inne instrukcje warunkowych skokowmoga sprawdzac takze inne flagi. Szczegolowiej przedstawie to przyomowieniu skokow warunkowych....
alef01