Įvairūs > Jūsų pačių kurtos pamokos

{ASM} mini disasembleris

(1/1)

vitalikaz:
Iš tikrųjų labai įdomi laabai žemo lygio (procesoriaus lygyje) programavimo kalba.. Čia daugiau kaip pavizdys, negu pamoka. Nors jeigu nors truputuką orentuojasi žmogus šiame reikale, tai iš komentarų viską galima puikiai suprasti. Programa iš EXE arba COM windows executable failų pagauna komandas JMP (jump (pascalinis goto) ) ir ROL (procesoriaus registro dvejetainę reikšmę pastumia į kairę). Tokiu pat būdu darašę likusias komandas (jų yra daug) gautume visą dekompiliatorių ir galėtume stebėti bet kurios programos veiksmus pažingsniui. Tai būtu naujas dviračio išradimas, nes disasmblerių yra parašyta gan daug ;) Jeigu kas domisi assembler'iu ir kažkam įdomu kaip visa tai atrodo, tai vat mano mini disasm'as:


--- Kodas: ---; Gausime JMP ir ROL veiksmus is EXE arba COM failo



.model Small ; programos modelio lygis

.stack 100h  ; stack'o dydis sesioliktaineje skaiciavimo sistemoje


; duomenu segmente isskiriame vietos tam tikrom reiksmem. Kitaip tariant - kintamieji. "10, 13" - windows'u eilutes pabaigos zenklas

.data

welcome db 10, 13, "Programa suranda .com arba .exe faile JMP bei ROL komandas ir isveda rezultat'a i faila", 10, 13, "$" ; welcome tekstas

iveskite db "Iveskite eilute:  $"

eilute db 100, ?, 101 dup(?) ; pirmame baite saugomas eilutes ilgis, i antra interupt'as irashys ivesta ilgi, toliau - turini. (+1 simb. eneteriui)

neivesta db 10,13, "Neivedete eilutes!", 10, 13, "$"

atlikta_lbl db 10,13,"Atlikta. $"

dirbama_lbl db 10,13,"Dirbama...", 10, 13, "$"

sourceprogram db 64 dup(0)

output db 64 dup(0)

help db 10, 13, "Naudojimo taisykles: 3.exe programa.exe failas.txt; kur programa.exe - failas, kuriame ieskosim komandu, failas.txt - rezultatu isvedimo failas.$";

rez db 100 dup(0), "$"

tempas db ?, ?, "$"

notexists db "Pradinis failas neegzistuoja.$"

buf db 128 dup(?)

jmp_lbl db "JMP "

rol_lbl db "ROL "

rol1 db ", 1"

neweil db 13, 10

baitas db ? ; vienas baitukas :)

hex db "0123456789ABCDEF"

; zodzio (2 baitu) ilgio registru pavadinimai

WordRegName db 'AX'

db 'CX'

db 'DX'

db 'BX'

db 'SP'

db 'BP'

db 'SI'

db 'DI'


; baito ilgio registru pavadinimai

ByteRegName db 'AL'

db 'CL'

db 'DL'

db 'BL'

db 'AH'

db 'CH'

db 'DH'

db 'BH'

tarp db " "

kabl db ", "

OutputFileHandle dw ? ; failo deskriptorius



; kodo segmento pradzia !

.code

 

; makro komandos

WriteFileStr macro string, writebytes

.data

@@msg_pos = $

db string,0

.code

mov ah, 40h

mov cx, writebytes

mov bx, OutputFileHandle

mov dx, offset @@msg_pos

int 21h

endm


; parsiname registro pavadinima

proc ByteRegParse

push ax

push bx

push cx



mov cl, 2h

mul cl



xor bx,bx

mov bl,al



mov ah, 40h

mov dx, offset ByteRegName

add dx, bx

mov bx, OutputFileHandle

mov cx, 2

int 21h



pop cx

pop bx

pop ax



ret

endp ByteRegParse

; ....

proc WordRegParse

push ax

push bx

push cx



mov cl, 2h

mul cl



xor bx,bx

mov bl,al



mov ah, 40h

mov dx, offset WordRegName

add dx, bx

mov bx, OutputFileHandle

mov cx, 2

int 21h



pop cx

pop bx

pop ax



ret

endp WordRegParse



; iejimo taskas (kaip pvz C/C++ - main() f-cija, pascalyje - pagrindinis begin).

start:

 

    mov ax, @data

    mov ds, ax ; inicijuojame duomenu segmenta



    lea dx, welcome

    mov ah, 09h

    int 21h ; isvedame welcome teksta



    mov ax, ds                       

    mov ds, ax                         

    mov al, byte ptr ES:[80h] ;   tikrinami pradiniai duomenys (ar yra parametras)

    cmp al,0

    jne yra_param



showhelp:

    ; jeigu nera parametru - isvedame helpa ir iseinam (besalygishkai jump'iname i pabaiga)       

lea dx, help

mov ah, 09h

int 21h

jmp pabaiga

 

yra_param:

xor bh, bh

xor ah, ah

mov di, ax ; parametru eilutes ilgis

dec di ; pirmo tarpo neskaiciuojam

xor si, si ; skaitliukas

mov bl, 82h



; pradedam skaityt parametrus (skaitom pirma)

skaitom_pirma:

cmp di, 0

jle showhelp ; jeigu nera parametru parodom help'a ir iseiname

mov al, byte ptr ES:[bx]

cmp al, 20h ; 20h - tarpas

je antras ; jeigu tarpas - reiskia skaitysim jau antra parametra

mov [sourceprogram+si], al

inc si

dec di

inc bl

jmp skaitom_pirma ; jei cia, reiskia tarpo dar nebuvo - skaitom toliau.



antras:

inc bl ; praeinam tarpa (bl++)

dec di ; di --

; pridedam nuliuka i pabaiga (eilutes pabaiga)

mov [sourceprogram + 2 + si], 0

xor si, si ; registras si = 0

cmp di, 0

je showhelp ; jei parametro ilgis yra 0 - parodom helpa ir iseiname is programos



skaitom_antra:

cmp di, 0

jle toliau ; jeigu jau perskaitem visa parametra ir viskas tvarkoje - einame toliau

mov al, byte ptr ES:[bx]

mov [output+si], al

inc si

dec di

inc bl

jmp skaitom_antra



toliau:

; pridedam nuliuka ir i antrojo parametro pabaiga

mov [output + 2 + si], 0



; bandome atidaryti exe faila

mov ah, 3Dh

mov al, 0

lea dx, sourceprogram

int 21h



; tikriname ar failas egzistuoja, jei ne - isvedame pranesima ir iseinam

cmp ax, 02h

je nofile



mov bx, ax ; bx'e - source failo deskriptorius



lea dx, dirbama_lbl

mov ah, 09h

int 21h







mov dx, offset output

xor ax, ax

mov ah, 3Ch

mov cx, 00h

int 21h

mov dx, ax ; dx - rezultato failo deskriptorius.

mov [OutputFileHandle], dx

jmp loopas ; pradedame darba


; jei nera failo..

nofile:

lea dx, notexists

mov ah, 09h

int 21h

jmp pabaiga


; PRADEDAM DARBA (atidaryto failo deskriptorius - BX)

loopas:
; nuliname registrus

xor si, si

xor di, di

xor ax, ax



push dx

mov cx, 80h ; skaitysime 128 simbolius (toks yra buferis)

lea dx, buf

mov ah, 3Fh

int 21h ; nuskaitom



pop dx

cmp ax, cx

jl pasktmp



cur:

cmp si, 80h ; ar jau daejome iki buferio pabaigos

jge loopas ; jei taip - skaitom i sekanti buferi

xor ax, ax

mov al, [buf + si]

; palyginame komandos koda. Jeigu atitinka jump'ui - pereiname prie jump'u

cmp al, 0E9h

je radom

cmp al, 0EAh

je radom

cmp al, 0EBh

je radom



cmp al, 0D0h ; jeigu rol'as baitu registram (ah, bh, ch, dh)

je rolByteCheck_ ; komanda_ - temp'inis pointas, kad nenushokti per toli kodo segmente

cmp al, 0D1h ; jeigu rol'as zodzio registram (ax, bx, cx, dx)

je rolByteCheck_

cmp al, 0D2h ; jeigu rol'as baitu registram su cl

je rolByteCheck_

cmp al, 0D3h ; jeigu rol'as zodzio registram su cl

je rolByteCheck_



jmp pls

radom:

; irasom i faila

push bx

mov bx, dx



push ax

mov cx, 4h ; rasysim 4 baitus

mov ah, 40h

lea dx, jmp_lbl ; JMP

int 21h ; irasom

pop ax



; adresa...

; zhiurim koks jmp'as ir atitinkamai imam adresa... (1b, 2b arba 4b - isorinis)

cmp al, 0EBh

je trumpasis



cmp al, 0E9h

je artimasis



cmp al, 0EAh

je tolimasis_





jmp nl



pasktmp:

jmp paskutinis



trumpasis: ; - 1 baito adresas

xor ax, ax

mov al, [buf + si + 1]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



jmp nl



tolimasis_:

jmp tolimasis



rolByteCheck_:

jmp rolByteCheck



artimasis: ; - 2 baitu adresas

; pirmas baitas

xor ax, ax

mov al, [buf + si + 1]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

; antras baitas

xor ax, ax

mov al, [buf + si + 2]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



jmp nl





tolimasis: ; - 4 baitu adresas

; pirmas baitas

xor ax, ax

mov al, [buf + si + 1]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

; antras baitas

xor ax, ax

mov al, [buf + si + 2]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



WriteFileStr<':'>, 1 ; <segmento adresas>:<efektyvus adresas>

; trecas baitas

xor ax, ax

mov al, [buf + si + 3]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

; ketvirtas baitas

xor ax, ax

mov al, [buf + si + 4]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



jmp nl



cur_:

jmp cur


; ROL'ai

rolByteCheck:

mov ah, [buf + si + 1]

shl ah, 2

shr ah, 5

cmp ah, 00h

jne pls_

cmp al, 0D0h

je rolByte

cmp al, 0D1h

je rolWord

cmp al, 0D2h

je rolCLByte_

cmp al, 0D3h

je rolCLWord_

jmp pls



pls_:

jmp pls

rolCLByte_:

jmp rolCLByte

rolCLWord_:

jmp rolCLWord

rolByte:

WriteFileStr<'ROL '>, 4

mov al, [buf + si + 1]

shl al, 5

shr al, 5

call ByteRegParse

WriteFileStr<', 1'>, 3

jmp nl



rolWord:

WriteFileStr<'ROL '>, 4

mov al, [buf + si + 1]

shl al, 5

shr al, 5

call WordRegParse

WriteFileStr<', 1'>, 3

jmp nl



rolCLByte:

WriteFileStr<'ROL '>, 4

mov al, [buf + si + 1]

shl al, 5

shr al, 5

call ByteRegParse

WriteFileStr<', CL'>, 4

jmp nl



rolCLWord:

WriteFileStr<'ROL '>, 4

mov al, [buf + si + 1]

shl al, 5

shr al, 5

call WordRegParse

WriteFileStr<', CL'>, 4

jmp nl



nl:

; nauja eilute

mov cx, 2h

mov ah, 40h

lea dx, neweil

int 21h



mov dx, bx

pop bx





pls:

inc si

jmp cur





pabaiga:

jmp ppabaiga ; tempinis



paskutinis:

; ax'e - paskutinio buferio ilgis.

mov si, ax

cmp si, 0

je pabaiga



xor di, di



lloop:

cmp si, 0

jbe pabaiga

mov al, [buf + di]



cmp al, 0E9h

je rradom

cmp al, 0EAh

je rradom

cmp al, 0EBh

je rradom

cmp al, 0D0h ; jeigu rol'as baitu registram (ah, bh, ch, dh)

je rrolByteCheck_

cmp al, 0D1h ; jeigu rol'as zodzio registram (ax, bx, cx, dx)

je rrolByteCheck_

cmp al, 0D2h ; jeigu rol'as baitu registram su cl

je rrolByteCheck_

cmp al, 0D3h ; jeigu rol'as zodzio registram (su cl

je rrolByteCheck_



jmp ppls



rradom:



; irasom i faila

push bx

push ax

mov bx, dx ; deskriptorius



mov cx, 4h ; rasysim 4 baitus

mov ah, 40h

lea dx, jmp_lbl

int 21h ; irasom

pop ax

; adresa...

; zhiurim koks jmp'as ir atitinkamai imam adresa...

cmp al, 0EBh

je ttrumpasis



cmp al, 0E9h

je aartimasis



cmp al, 0EAh

je ttolimasis_



jmp nnl





ttrumpasis: ; - 1 baito adresas



xor ax, ax

mov al, [buf + di + 1]

mov dl, 10h

div dl



push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



jmp nnl



ttolimasis_:

jmp ttolimasis





rrolByteCheck_:

jmp rrolByteCheck

aartimasis: ; - 2 baitu adresas

; pirmas baitas

xor ax, ax

mov al, [buf + di + 1]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

; antras baitas

xor ax, ax

mov al, [buf + di + 2]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



jmp nnl



ttolimasis: ; - 4 baitu adresas

; pirmas baitas

xor ax, ax

mov al, [buf + di + 1]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

; antras baitas

xor ax, ax

mov al, [buf + di + 2]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

WriteFileStr<':'>, 1

; trecas baitas

xor ax, ax

mov al, [buf + di + 3]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

; ketvirtas baitas

xor ax, ax

mov al, [buf + di + 4]

mov dl, 10h

div dl

push bx

xor bx, bx

mov bl, al

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax

push bx

xor bx, bx

mov bl, ah

lea dx, [hex + bx]

pop bx

push ax

mov cx, 1h ; rasysim 1 bita

mov ah, 40h

int 21h ; irasom

pop ax



jmp nnl

lloop_:

jmp lloop



rrolByteCheck:

mov ah, [buf + di + 1]

shl ah, 2

shr ah, 5

cmp ah, 00h

jne ppls_

cmp al, 0D0h

je rrolByte

cmp al, 0D1h

je rrolWord

cmp al, 0D2h

je rrolCLByte_

cmp al, 0D3h

je rrolCLWord_

jmp ppls



ppls_:

jmp ppls

rrolCLByte_:

jmp rrolCLByte

rrolCLWord_:

jmp rrolCLWord

rrolByte:

WriteFileStr<'ROL '>, 4

mov al, [buf + di + 1]

shl al, 5

shr al, 5

call ByteRegParse

WriteFileStr<', 1'>, 3

jmp nnl



rrolWord:

WriteFileStr<'ROL '>, 4

mov al, [buf + di + 1]

shl al, 5

shr al, 5

call WordRegParse

WriteFileStr<', 1'>, 3

jmp nnl



rrolCLByte:

WriteFileStr<'ROL '>, 4

mov al, [buf + di + 1]

shl al, 5

shr al, 5

call ByteRegParse

WriteFileStr<', CL'>, 4

jmp nnl



rrolCLWord:

WriteFileStr<'ROL '>, 4

mov al, [buf + di + 1]

shl al, 5

shr al, 5

call WordRegParse

WriteFileStr<', CL'>, 4

jmp nnl







nnl:

; nauja eilute

mov cx, 2h

mov ah, 40h

lea dx, neweil

int 21h



mov dx, bx

pop bx



ppls:

dec si

inc di

jmp lloop




ppabaiga:

lea dx, atlikta_lbl

mov ah, 09h

int 21h



    mov ah, 4ch

    mov al, 0

    int 21h ; pabaiga

 

end start

--- Baigti kodą ---

Programą rašiau univerui (pirmam kurse, pirmam semestre). Siūlau visiems pasidomėt, kas nesidomėjo, tikrai įdomu :)

Lukas:
niekad neteko susidurti su asemblerio kalba, bet kiek zinau tai su ja parasytos programos labai nedaug resursu rija is pc, nes nenaudoja tarpiniu terpiu kurios kompiliuotu koda, o kreipiasi tiesiai i proca ar kt. dali, ane?

softas windowsams

vitalikaz:
Nu cia jau zhiurint kaip parasysi programa. Su pascaliu, C/C++ ir kitom kalbom irgi laisvai gali gi dinamishkai pats atminti ishskirinet ir pan, kad maziau resursu rytu. Pascalyje irgi yra standartine biblioteka, kad dirbt tiesiai su procesoriaus registrais :) su asm'u parasytos programos tikrai labai mazai uzima, uztat kodo labai daug gaunasi ir dazniausiai jis sunkiai iskaitomas.

Navigacija

[0] Žinučių sąrašas

Eiti į pilną versiją