Dezasamblare - kildekode

Sandbox →

Cunoașterea structurii comenzilor mașinilor de mulți ani nu este obligatorie, astfel încât o persoană să se poată numi un programator. Firește, acest lucru nu a fost întotdeauna cazul. Înainte de apariția primilor asamblori, programarea a fost efectuată direct în codul mașinii. Munca grea, cuplată cu un număr mare de erori. Asamblorii moderni permit (într-o măsură rezonabilă) abstractizarea fierului, metoda de comenzi de codare. Ce putem spune despre compilatorii de limbi de nivel înalt. Ei uimesc cu complexitatea implementării lor și cu simplitatea cu care programatorul este permis să transforme codul sursă într-o secvență de instrucțiuni de mașină (și să transforme, suficient, optim). De la programator, aveți nevoie doar de cunoașterea limbii / IDE preferate. Știind ce compilator se traduce la listarea sursei nu este necesar.
Pentru cei care sunt interesați să privească o scurtă descriere a structurii codării instrucțiunilor mașinii, un exemplu de implementare și codul sursă al disassemblerului pentru arhitectura x86, bine ai venit.

Crearea unui dezasamblator pentru arhitectura x86 este, deși sarcina nu este deosebit de complicată, dar totuși destul de specifică. De la programator este nevoie de un anumit tip de cunoștințe - cunoașterea modului în care microprocesorul recunoaște succesiunea "mușcăturilor" din codul mașinii. Nu toate universitățile pot obține astfel de cunoștințe în cantitate suficientă pentru a scrie un dezasamblator modern funcțional - este necesar să îl căutați singur (de obicei în limba engleză). Această postare nu intenționează să acopere în totalitate problema creării unui dezasamblator, ci doar pe scurt, cum a fost scris disassemblerul pentru arhitectura x86, modul de execuție a comenzii pe 32 de biți. De asemenea, aș dori să menționez probabilitatea posibilelor inexactități în traducerea anumitor concepte din specificația oficială.

Structura de comandă pentru intel x86

Structura echipei este după cum urmează:
• Prefixe opționale (fiecare prefix este de 1 octet în mărime)
• Opcode de comandă obligatorie (1 sau 2 octeți)
• Mod_R / M - octet, care determină structura operanzilor comenzii - opțional.
• Byte opționale ocupate de operanții instrucțiunii (uneori împărțite ca un octet al câmpului SIB [Scale, Index, Base], valoare compensată și imediată).

Există următoarele prefixe:
Primele șase schimbă registrul de segmente utilizat de comandă atunci când accesează locația de memorie.
• 0x26 - Prefixul de înlocuire a segmentului ES
• Prefixul de înlocuire pentru segmentul 0x2E - CS
• 0x36 - prefixul de înlocuire a segmentului SS
• 0x3E - prefixul de înlocuire a segmentului BS
• prefixul de înlocuire pentru segmentul 0x64 - FS
• Prefix de înlocuire segment 0x65 - GS

• 0x0F - prefix comenzi suplimentare (uneori, nu conta ca un prefix real, - în acest caz, se crede că comanda Opcode este format din doi octeți, primul dintre care 0x0F)

Fiecare dintre aceste prefixe modifică semantica și (sau) structura instrucțiunii mașinii (de exemplu, lungimea sau alegerea mnemonicilor).

Comandă opcodes.
Opcodul comenzii este uneori unic, uneori cu prefixul (ele) definește în mod unic numele (mnemonic) al comenzii. Sunt multe echipe. Și cu sofisticarea microprocesoarelor moderne, numărul lor nu scade - apar comenzi noi, iar cele învechite nu dispar (compatibilitate înapoi). Lista de opcode și comenzile asociate cu acestea, de regulă, pot fi descărcate pe site-urile oficiale ale producătorilor de microprocesoare.

Bitul Mod_R / M constă din următoarele câmpuri:

• Mod - primii doi biți (valoarea de la 0 la 3)
• R / M reprezintă următorii trei biți (valoarea de la 0 la 7)
• Valoarea ModR / M - următorii trei biți (o valoare de la 0 la 7)

Primul lucru pe care trebuie să-l faceți este să mutați primele două tabele în structuri de date care sunt convenabile pentru lucru. Pe același site puteți descărca versiuni xml ale acestor tabele și ele se transformă deja în structuri frumoase de sishnye. Am făcut ceva greșit - am încărcat tabela html în Excel și deja acolo, scriind un script simplu pe VBA, am primit codul original, care, după reparații manuale, era structurile de date necesare.

Algoritmul de dezasamblare este foarte simplu:

• Obține o listă de prefixe utilizate în instrucțiunile actuale ale mașinii
• Câmpul corespunzător este căutat în unul din cele două tabele, în funcție de opcod, prefixele și generarea (modelul) microprocesorului țintă (căutat).
• am găsit înregistrarea se caracterizează printr-o listă de domenii, cum ar fi generarea (model) a microprocesorului, de la care există suport pentru această comandă, sau, de exemplu, lista de steaguri pe care această echipă se poate schimba. Noi, în principiu, sunt doar interesele mnemonicii (numele) comenzii și lista operanzilor. După analizarea tuturor operanților găsiți și a câmpului octet Mod_R / M, putem afla reprezentarea textului și lungimea comenzii.

Numărul de operanzi poate varia de la zero la trei. Tabelele sursă conțin mai mult de o sută de tipuri de operanzi. Unele operanzi sunt duplicate - au nume diferite, dar secvența operațiilor de procesare a bytelor Mod_R / M (și eventual octeții ulteriori) pentru ele este aceeași.

PS:
Nu faptul că cineva care citește acest post va avea vreodată nevoie de informații derivate din el (dezasamblatoarele scriu unități), dar în orice caz, acest dezasamblator a fost testat și chiar inclus într-un protector comercial mai mare. interlocutorii sunt deschise și distribuite în mod liber)

Articole similare