2009-09-01 18 views
97

Ho deciso di imparare il linguaggio Assembly. La ragione principale per farlo è essere in grado di capire il codice smontato e magari essere in grado di scrivere parti di codice più efficienti (ad esempio, attraverso C++), fare cose come code caves, ecc. Ho visto che ci sono un migliaio di differenti sapori di assemblaggio , quindi, per gli scopi che ho menzionato, come dovrei iniziare? Che tipo di montaggio dovrei imparare? Voglio imparare facendo in primo luogo alcuni programmi facili (cioè una calcolatrice), ma l'obiettivo stesso sarà quello di essere accostato ad esso in modo da poter capire il codice mostrato, ad esempio, da IDA Pro.Learning assembly

Sto usando Windows (se questo fa alcuna differenza).

modifica: Quindi, sembra che tutti puntino verso MASM. Anche se capisco che ha capacità di alto livello, tutte buone per il programmatore del codice assembly, non è quello che sto cercando. Sembra avere istruzioni if, invoke, ecc non mostrate nei comuni deassembler (come IDA). Quindi quello che mi piacerebbe sentire, se possibile, è l'opinione di chiunque utilizzi ASM per gli scopi che sto chiedendo (leggendo il codice exe deassemblato in IDA), non solo i programmatori di assembly "generali".

modifica: OK. Sto già imparando l'assemblea. Sto imparando MASM, non usando le cose di alto livello che non mi importano. Quello che sto facendo in questo momento è provare il mio codice sulle direttive __asm ​​in C++, così posso provare le cose più velocemente che se dovessi fare tutto da zero con MASM.

+0

domanda simile a http://stackoverflow.com/questions/1355524/which-syntax-and-architecture-of-assembly-is-most-useful-to-know – TrueWill

+0

Sì, stavo leggendo anche quello. Ma la mia domanda è un po 'più "focalizzata", direi. –

+0

Se sei su Windows, il target (cioè il processore, e quindi il set di istruzioni) è x86 o x86-64. A meno che non si ottenga un'altra macchina o una scheda MCU o si usi un emulatore. Quindi, è la domanda che * assemblatore * dovrei usare? O stai davvero chiedendo quale architettura scegliere come target? Personalmente adoro il bel set di istruzioni ortogonali sui chip della serie m68k, ahimè, alack. – dmckee

risposta

38

Inizia con MASM32 e da lì guarda FASM. Ma ti divertirai con MASM.

+0

Ho sentito dal MASM. Se non sbaglio, ha molte caratteristiche "di alto livello", che non vedo quando guardo il codice non modificato. Mi piacerebbe dover programmare in qualcosa che è esattamente come la maggior parte del codice di output dei disassemblatori, se questo ha senso. –

+1

Questo sarebbe fondamentalmente come scrivere codici op, che non ha molto senso. Imparare MASM32 ti aiuterà a capire come appare il codice in un debugger. Potresti anche provare OllyDbg: http://www.ollydbg.de/ –

+0

Un sacco di quelle caratteristiche "di alto livello" ci sono per un motivo. Non è facile scrivere in linguaggio assembly, quindi ogni piccolo aiuto. Si potrebbe anche imparare a scrivere in codice macchina, emettendo 32 bit int in un file EXE invece di usare linguaggio assembly e un compilatore/linker, ma non c'è davvero alcun motivo per farlo. MASM (o TASM, se riesci a trovare una copia di esso) sono buoni posti per iniziare. –

32

L'assemblaggio che si scrive a mano e l'assieme generato da un compilatore sono spesso molto diversi se visti da un livello elevato. Ovviamente, l'interno del programma sarà molto simile (ci sono solo tanti modi diversi di codificare a = b + c, dopotutto), ma non sono il problema quando stai provando a decodificare qualcosa. Il compilatore aggiungerà un ton di codice boilerplate anche a semplici eseguibili: l'ultima volta che ho confrontato, "Hello World" compilato da GCC era di circa 4kB, mentre se scritto a mano in assembly è di circa 100 byte. È peggio su Windows: l'ultima volta che ho confrontato (certamente, questo era l'ultimo secolo) il più piccolo "Hello World" che potevo ottenere il mio compilatore Windows di scelta allora per generare era 52kB! Di solito questo boilerplate viene eseguito solo una volta, se non del tutto, quindi non influisce molto sulla velocità del programma - come ho detto sopra, il nucleo del programma, la parte in cui viene speso il maggior tempo di esecuzione, di solito è abbastanza simile sia compilato che scritto a mano.

Alla fine della giornata, ciò significa che un esperto di montaggio programmatore e un esperto disassemblatore sono due specialità diverse. Comunemente si trovano nella stessa persona, ma sono davvero separati, e imparare a diventare un ottimo codificatore di assiemi non ti aiuterà molto a imparare il reverse engineering.

Quello che vuoi fare è prendere i manuali di architettura IA-32 e AMD64 (entrambi sono coperti insieme) da Intel e AMD, e guardare attraverso le prime sezioni su istruzioni e opcode. Magari leggi un tutorial o due sul linguaggio assembly, solo per ottenere le basi del linguaggio assembly. Quindi prendi uno piccolo programma di esempio che ti interessa e smontalo: passa attraverso il suo flusso di controllo e prova a capire cosa sta facendo. Vedi se riesci a correggerlo per fare qualcos'altro. Quindi riprova con un altro programma e ripeti finché non ti senti abbastanza a tuo agio per cercare di raggiungere un obiettivo più utile. Potresti essere interessato a cose come "crackmes", prodotto dalla comunità del reverse engineering, che sono sfide per le persone interessate al reverse engineering per cimentarsi in qualcosa, e si spera che imparino qualcosa lungo il percorso. Si trovano in difficoltà da base (inizio qui!) A impossibile.

Soprattutto, è sufficiente pratica. Come in molte altre discipline, con il reverse engineering, la pratica rende perfetti ... o almeno meglio.

+0

So che quando si compila qualcosa con un linguaggio di alto livello, si otterrà un sacco di codice "garbage" che non sarebbe necessario è stato codificato direttamente in assemblea. Capisco anche che c'è una differenza tra un programmatore di assemblaggio esperto e un disassemblatore esperto. Ma lo stesso si può dire su quasi tutto il resto. –

+3

La mia preoccupazione è che, in teoria, potrei leggere i giornali e capire cosa significano, fino a quando non inizierò a scrivere le cose da solo, non credo che lo capirò veramente. Dici che posso iniziare cambiando piccole parti di codice, ma per farlo devo prima sapere quale tipo di assembly "flavor" IDA pro, ad esempio, usa. –

+0

Inoltre, che cosa usa MSVC++ per il codice assembly inline? MASM? –

8

Ho trovato Hacking: The Art of Exploitation un modo interessante e utile in questo argomento ... non posso dire di aver mai usato la conoscenza direttamente, ma non è davvero il motivo per cui l'ho letto. Ti dà un apprezzamento molto più ricco delle istruzioni a cui il tuo codice viene compilato, che a volte è stato utile per capire i bug più sottili.

Non lasciatevi scoraggiare dal titolo. La maggior parte della prima parte del libro è "Hacking" nel senso della parola di Eric Raymond: modi creativi, sorprendenti, quasi subdoli per risolvere i problemi più difficili. Io (e forse tu) ero molto meno interessato agli aspetti di sicurezza.

2

Penso che vogliate imparare i mnemonici opcode ASCII (e i loro parametri), che vengono emessi da un disassemblatore e che sono compresi da (può essere usato come input per) un assemblatore.

Qualsiasi assemblatore (ad esempio MASM) farebbe.

E/o potrebbe essere meglio per voi leggere un libro a riguardo (ci sono stati libri consigliati su SO, non ricordo quale).

3

Ho iniziato a studiare MIPS che è un'architettura a 32 bit molto compatta. È un set di istruzioni ridotto, ma è ciò che rende facile da afferrare per i principianti. Sarai ancora in grado di capire come funziona l'assemblaggio senza essere sopraffatto dalla complessità. Puoi anche scaricare un piccolo IDE, che ti permetterà di compilare il tuo codice MIPS: clicky Una volta capito, penso che sarebbe molto più facile passare ad architetture più complesse. Almeno questo è quello che pensavo :) A questo punto avrete le conoscenze essenziali di allocazione e gestione della memoria, flusso logico, debug, test ed ecc.

7

Non mi concentrerei sul tentativo di scrivere programmi in assembly, in almeno non all'inizio. Se sei su x86 (che presumo tu lo sia, dal momento che stai usando Windows), ci sono un sacco di strani casi speciali che è quasi inutile da imparare. Ad esempio, molte istruzioni presuppongono che tu stia operando su un registro a cui non si fa esplicitamente un nome e che altre istruzioni funzionino su alcuni registri ma non su altri.

Vorrei solo conoscere l'architettura desiderata per capire le nozioni di base, quindi limitarsi a saltare e provare a capire l'output del compilatore. Armati con the Intel manuals e tuffati proprio nell'output del tuo compilatore. Isolare il codice di interesse in una piccola funzione, in modo da essere sicuri di comprendere l'intera cosa.

vorrei prendere in considerazione le nozioni di base per essere:

  • registri: quanti sono, quali sono i loro nomi, e quali sono le loro dimensioni?
  • ordine operando: add eax, ebx significa "Aggiungi ebx a eax e salva il risultato in eax".
  • FPU: impara le basi della pila a virgola mobile e come converti in/da fp.
  • modalità di indirizzamento: [base + offset * moltiplicatore], ma il moltiplicatore può essere solo 1, 2 o 4 (o forse 8?)
  • convenzioni di chiamata: come vengono passati i parametri a una funzione?

Un sacco di tempo sarà sorprendente ciò che il compilatore emette. Rendilo un puzzle per capire perché diavolo il compilatore pensava che sarebbe stata una buona idea. Ti insegnerà molto.

Probabilmente aiuterà anche ad armarsi di Agner Fog's manuals, in particolare l'istruzione che elenca uno. Vi dirà approssimativamente quanto sia costosa ogni istruzione, anche se questo è più difficile da quantificare direttamente sui processori moderni. Ma aiuterà a spiegare perché, ad esempio, il compilatore si spinge così lontano da evitare di rilasciare un'istruzione idiv.

L'unico altro consiglio è di utilizzare sempre la sintassi Intel anziché AT & T quando si ha una scelta. Ero abbastanza neutrale su questo punto, fino al giorno in cui ho capito che alcune istruzioni sono totalmente diverse tra loro (ad esempio, movslq in AT & sintassi T è movsxd in sintassi Intel). Dal momento che i manuali sono tutti scritti usando la sintassi Intel, basta attenervisi.

Buona fortuna!

43

L'ho fatto molte volte e continuo a farlo. In questo caso, dove il tuo obiettivo principale è leggere e non scrivere assembler, ritengo che questo sia valido.

Scrivi il tuo disassemblatore. Non allo scopo di creare il prossimo miglior disassemblatore, questo è strettamente per te. L'obiettivo è imparare il set di istruzioni. Se sto imparando l'assemblatore su una nuova piattaforma, ricordando l'assemblatore per una piattaforma che conoscevo una volta. Inizia con solo poche righe di codice, aggiungendo registri per esempio e ping pong tra smontare l'output binario e aggiungendo istruzioni sempre più complicate sul lato input:

1) apprendere il set di istruzioni per processore specifico

2) imparare le sfumature di come scrivere codice in assemblare per detto processore in modo tale che si può muovere ogni bit di codice operativo in ogni istruzione

3) si impara il set di istruzioni meglio che la maggior parte ingegneri che utilizzano tale set di istruzioni per sopravvivere

Nel tuo caso ci sono un paio di problemi, di solito raccomando il set di istruzioni ARM per iniziare, ci sono più prodotti basati su ARM spediti oggi rispetto a qualsiasi altro (computer x86 inclusi). Ma la probabilità che tu stia usando ARM ora e non conosci abbastanza assemblatore per scrivere codice di avvio o altre routine sapendo che ARM può o non può aiutare quello che stai cercando di fare. La seconda e più importante ragione per la prima ARM è perché le lunghezze delle istruzioni sono fisse e allineate. Disassemblare istruzioni di lunghezza variabile come x86 può essere un incubo come il tuo primo progetto, e l'obiettivo qui è quello di imparare il set di istruzioni per non creare un progetto di ricerca. Il terzo ARM è un set di istruzioni ben fatto, i registri sono uguali e non hanno sfumature particolari.

Quindi dovrete capire quale processore volete iniziare. Suggerisco prima msp430 o ARM, poi ARM prima o seconda poi il caos di x86. Indipendentemente dalla piattaforma, qualsiasi piattaforma che valga la pena di utilizzare ha fogli dati o manuali di riferimento dei programmatori liberi dal fornitore che includono il set di istruzioni e la codifica degli opcode (i bit e i byte del linguaggio macchina). Allo scopo di apprendere cosa fa il compilatore e come scrivere codice che il compilatore non deve fare a meno, è bene conoscere alcuni set di istruzioni e vedere come viene implementato lo stesso codice di alto livello su ogni set di istruzioni con ogni compilatore con ogni ottimizzazione ambientazione.Non vuoi entrare nell'ottimizzazione del tuo codice solo per scoprire che lo hai reso migliore per un compilatore/piattaforma ma molto peggio per tutti gli altri.

Oh per smontare insiemi di istruzioni di lunghezza variabile, invece di iniziare semplicemente dall'inizio e smontare ogni parola di quattro byte in modo lineare attraverso la memoria come faresti con l'ARM o ogni due byte come msp430 (Il msp430 ha istruzioni di lunghezza variabile ma tu può ancora andare in modo lineare attraverso la memoria se si inizia dai punti di ingresso dalla tabella vettoriale di interrupt). Per lunghezza variabile, si desidera trovare un punto di ingresso basato su una tabella vettoriale o una conoscenza su come il processore si avvia e seguire il codice nell'ordine di esecuzione. Devi decodificare completamente ogni istruzione per sapere quanti byte sono usati, quindi se l'istruzione non è un ramo incondizionato, supponiamo che il prossimo byte dopo quell'istruzione sia un'altra istruzione. È necessario memorizzare anche tutti gli indirizzi di ramo possibili e assumere quelli sono gli indirizzi di byte di partenza per ulteriori istruzioni. L'unica volta che ho avuto successo ho fatto diversi passaggi attraverso il binario. Partendo dal punto di ingresso ho contrassegnato quel byte come l'inizio di un'istruzione decodificato in modo lineare attraverso la memoria fino a colpire un ramo incondizionato. Tutti gli obiettivi delle diramazioni sono stati contrassegnati come indirizzi iniziali di un'istruzione. Ho fatto più passaggi attraverso il binario fino a quando non avessi trovato nuovi bersagli di ramo. Se in qualsiasi momento trovi dire un'istruzione a 3 byte ma per qualche motivo hai taggato il secondo byte come inizio di un'istruzione hai un problema. Se il codice è stato generato da un compilatore di alto livello questo non dovrebbe accadere a meno che il compilatore non stia facendo qualcosa di male, se il codice ha assembler scritto a mano (come ad esempio un vecchio gioco arcade) è possibile che ci siano dei rami condizionali che non possono mai accadere come r0 = 0 seguito da un salto se non zero. Potrebbe essere necessario modificare manualmente quelli fuori dal binario per continuare. Per i tuoi obiettivi immediati che presumo saranno su x86, non penso che avrai un problema.

Raccomando gli strumenti gcc, mingw32 è un modo semplice per utilizzare gli strumenti gcc su Windows se x86 è il vostro obiettivo. In caso contrario, mingw32 plus msys è un'ottima piattaforma per la generazione di un cross-compilatore da sorgenti binutils e gcc (in genere piuttosto semplice). mingw32 ha alcuni vantaggi rispetto a cygwin, come programmi significativamente più veloci e si evita l'inferno cygwin dll. gcc e binutils ti permetteranno di scrivere in C o assemblatore e disassemblare il tuo codice e ci sono più pagine web di quelle che puoi leggere mostrandoti come eseguire uno o tutti i tre. Se lo farai con un set di istruzioni a lunghezza variabile, ti consiglio vivamente di utilizzare un set di strumenti che include un disassemblatore. Ad esempio, un disassemblatore di terze parti per x86 sarà una sfida da utilizzare, in quanto non si sa mai se è stato smontato correttamente. Alcuni di questi sono dipendenti dal sistema operativo, l'obiettivo è compilare i moduli in un formato binario che contiene istruzioni di marcatura delle informazioni dai dati in modo che il disassemblatore possa svolgere un lavoro più accurato. L'altra scelta per questo obiettivo primario è quella di avere uno strumento che possa essere compilato direttamente sull'assemblatore per l'ispezione, quindi sperare che quando si compila in un formato binario crei le stesse istruzioni.

La risposta breve (okay leggermente più breve) alla tua domanda. Scrivi un disassemblatore per imparare un set di istruzioni. Vorrei iniziare con qualcosa di RISCY e facile da imparare come ARM. Una volta che si conosce un set di istruzioni, gli altri diventano più facili da raccogliere, spesso in poche ore, dal terzo set di istruzioni è possibile iniziare a scrivere il codice quasi immediatamente utilizzando il foglio dati/il manuale di riferimento per la sintassi. Tutti i processori che vale la pena utilizzare hanno una scheda tecnica o un manuale di riferimento che descrive le istruzioni fino ai bit e ai byte degli opcode. Impara un processore RISC come ARM e un CISC come x86 abbastanza per avere un'idea delle differenze, cose come dover passare attraverso i registri per tutto o essere in grado di eseguire operazioni direttamente sulla memoria con meno o nessun registro. Tre istruzioni per l'operando contro due, ecc. Quando si sintonizza il codice di alto livello, si compila per più di un processore e si confronta l'output. La cosa più importante che imparerai è che non importa quanto sia buono il codice di alto livello scritto la qualità del compilatore e le scelte di ottimizzazione fatte fanno una grande differenza nelle istruzioni reali. Raccomando llvm e gcc (con binutils), né producono codice ottimo, ma sono multi piattaforma e multiobiettivo e entrambi hanno ottimizzatori.Ed entrambi sono gratuiti e puoi facilmente creare compilatori incrociati da fonti per vari processori di destinazione.

+0

Grazie per la risposta. Ma non so nemmeno come scrivere un disassemblatore. –

+8

"Scrivi il tuo disassemblatore" - Sono d'accordo, è come l'ho imparato meglio. (Che succede con "Ma non so nemmeno come scrivere un disassemblatore"?) LOL. – slashmais

+0

Vengo con te! Ho appena comprato un MSP430 e un libro sopra ... :) – Pepe

15

I'll go contro the grain of most answer e raccomandare la variante MMIX di Knuth dell'architettura MIPS RISC. Non sarà tanto utile quanto i linguaggi assembly x86 o ARM (non che siano così cruciali nella maggior parte dei lavori reali in questi giorni ... ;-), ma sbloccherà per te la magia dell'ultima versione di Knuth versione del più grande capolavoro di una profonda conoscenza di basso livello di algoritmi e strutture dati - TAOCP, "The Art of Computer Programming". I link dei due URL che ho citato sono un ottimo modo per iniziare a esplorare questa possibilità!

12

(non so voi, ma io era eccitato con montaggio)

Un semplice strumento per la sperimentazione di montaggio è già installato sul PC.

Andare in Start menu-> Esegui e digitare debug

debug (command)

di debug è un comando in DOS, MS-DOS, OS/2 e Microsoft Windows (solo le versioni x86, non x64) che esegue il programma debug.exe (o DEBUG.COM nelle versioni precedenti del DOS ). Debug può fungere da assembler, disassemblatore o dump esadecimale del programma che consente agli utenti di esaminare interattivamente il contenuto della memoria (in linguaggio assembly, esadecimale o ASCII), apportare modifiche ed eseguire selettivamente COM, EXE e altri tipi di file. Dispone inoltre di diversi sottocomandi che consentono l'accesso a specifici settori del disco , porte I/O e indirizzi di memoria. Il debug di MS-DOS viene eseguito a livello di processo a 16 bit e pertanto è limitato ai programmi per computer a 16 bit. FreeDOS Debug ha una versione "DEBUGX" che supporta anche programmi DPMI a 32 bit.

Tutorial:


Se si vuole capire il codice che vedi nell'immagine IDA Pro (o OllyDbg), si bisogno di t o impara come è strutturato il codice compilato. Raccomando il libro Reversing: Secrets of Reverse Engineering

Ho sperimentato un paio di settimane con debug quando ho iniziato a studiare l'assemblaggio (15 anni fa).
Nota che debug funziona al livello della macchina base, non ci sono comandi di assemblaggio di alto livello.

E ora un semplice esempio:

Dare a per iniziare a scrivere codice assembly - digitare il programma qui sotto - e, infine, dare g per eseguirlo.

alt text


(INT 21 visualizzazione sullo schermo il carattere ASCII memorizzato nel registro DL se il registro AH è impostato su 2-INT 20 termina il programma)

+0

Ho dovuto premere ctrl-c, prima che potessi inserire "g". – ericp

+2

@ericp, non è necessario premere ctrl-c. Ad esempio, si digita 'a' e [invio] per iniziare a scrivere codice assembly. Se premi [invio] due volte, esci dalla modalità di assemblaggio. 'g' e [enter] per eseguirlo (offset 100 per impostazione predefinita). –

+0

effettivamente provoca uno stack overflow o lo scrive semplicemente sullo schermo? –

2

Stai facendo altri lavori di sviluppo su Windows? Su quale IDE? Se si tratta di VS, non è necessario un IDE aggiuntivo solo per leggere il codice smontato: eseguire il debug dell'applicazione (o collegarlo a un'app esterna), quindi aprire lo disassembly window (nelle impostazioni predefinite, ovvero Alt + 8). Passa e guarda la memoria/i registri come faresti con il normale codice. Si potrebbe anche voler mantenere aperta una finestra dei registri (Alt + 5 per impostazione predefinita).

Intel fornisce gratuitamente manuals, che fornisce sia una panoramica dell'architettura di base (registri, unità di elaborazione, ecc.) Sia un riferimento completo alle istruzioni. Man mano che l'architettura matura e diventa più complessa, i manuali di "architettura di base" diventano sempre meno leggibili. Se riesci a mettere le mani su una versione precedente, probabilmente avresti un posto migliore per iniziare (anche i manuali P3 - spiegano meglio lo stesso ambiente di esecuzione di base).

Se ti interessa investire in un libro, here è un bel testo introduttivo. Cerca Amazon per 'x86' e ne otterrai molti altri. È possibile ottenere diverse altre direzioni da un'altra domanda here.

Infine, è possibile beneficiare un bel po 'da readingsomelow - level blog. Questi bit di informazioni in formato byte funzionano meglio per me, personalmente.

2

Questo non ti aiuterà necessariamente a scrivere codice efficiente!

I codici op i86 sono più o meno un formato "legacy" che persiste a causa del volume puro di codice e binari eseguibili per Windows e Linux.

È un po 'come i vecchi studiosi che scrivono in latino, un oratore italiano come Galileo scriverebbe in latino e la sua carta potrebbe essere capita da un oratore polacco come Copernico. Questo era ancora il modo più efficace per comunicare anche se nient'altro era particolarmente buono in latino, e il latino è un linguaggio spazzatura per esprimere idee matematiche.

Quindi i compilatori generano il codice x86 per impostazione predefinita e, i chip moderni leggono i codici op anceint e fanno transalizzare ciò che vedono in istruzioni di risc di parallelo, con esecuzione riordinata, esecuzione speculativa, pipelining ecc. Inoltre fanno pieno uso del 32 o 64 registri che il processore ha effettivamente (in contrasto con il patetico 8 che vedi nelle istruzioni x86)

Ora tutti i compilatori ottimizzanti sanno che questo è ciò che realmente accade, quindi codificano sequenze di codici OP che sanno che il chip può ottimizzare efficientemente - anche se alcune di queste sequenze sembrerebbero inefficienti per un programmatore del .asm circa del 1990.

Ad un certo punto è necessario accettare che gli anni '10 di migliaia di anni impiegati dai compilatori di compilatori hanno pagato e, fidati di loro.

Il modo più semplice e semplice per ottenere un runtime più efficiente è acquistare il compilatore Intel C/C++. Hanno un mercato di nicchia per i compilatori di efficeint e, hanno il vantaggio di poter chiedere ai progettisti di chip cosa succede all'interno.

+0

La tua storia suggerisce in qualche modo che i processori CISC siano internamente diventati processori RISC. Potrei aver frainteso, ma questo semplicemente non è vero. E il patetico 8? I processori moderni (ad esempio, dal 1999) includono molti altri: 10 gpr: EAX-EFLAGS, 80 bit FP0-FP7, 64 bit MMX0-MMX7, 128 bit XMM0-XMM7, segmento: CS-GS, speciali: CR0-CR4 , DR0-DR7, TR3-TR7, GDTR, IDTR, LDTR, MSR e su x86-64 anche R8-R15. Non tutti sono accessibili da ring-3, ma la maggior parte lo sono e la maggior parte sono usati dai recenti compilatori GCC/VC++ (post-2006). Complessivamente leggermente più del "patetico 8";). – Abel

2

Per fare ciò che si vuole fare, ho appena preso il Intel Instruction Set Reference (potrebbe non essere l'esatto che ho usato, ma sembra sufficiente) e alcuni semplici programmi che ho scritto in Visual Studio e ho iniziato a lanciarli in IDAPro/Windbg. Quando sviluppavo i miei programmi, il software a crackmes era utile.

Suppongo che tu abbia alcune nozioni di base su come i programmi vengono eseguiti su Windows. Ma in realtà, per la lettura dell'assemblaggio, ci sono solo poche istruzioni da imparare e alcuni sapori di queste istruzioni (ad esempio, c'è un'istruzione di salto, il salto ha alcuni sapori come jump-if-equal, jump-if-ecx-is-zero , eccetera). Una volta apprese le istruzioni di base è abbastanza semplice ottenere il succo dell'esecuzione del programma. La vista grafico di IDA aiuta, e se stai tracciando il programma con Windbg, è piuttosto semplice capire che cosa stanno facendo le istruzioni se non sei sicuro.

Dopo aver giocato un po ', ho comprato Hacker Disassembly Uncovered. In generale, sto lontano dai libri con la parola "Hacker" nel titolo, ma mi è davvero piaciuto come questo sia andato veramente in profondità su come il codice compilato sembrava smontato. Egli va anche alle ottimizzazioni del compilatore e ad alcune cose di efficienza che erano interessanti.

Tutto dipende davvero da quanto profondamente si vuole essere in grado di capire anche il programma. Se esegui il reverse engineering su un target in cerca di vulnerabilità, se stai scrivendo codice exploit o analizzi malware confezionati per funzionalità, avrai bisogno di più tempo per accelerare il tutto (in particolare per il malware più avanzato). D'altra parte, se vuoi solo essere in grado di cambiare il livello del tuo personaggio nel tuo videogioco preferito, dovresti stare bene in un tempo relativamente breve.

0

Un sacco di buone risposte qui. Programmazione di basso livello, assemblaggio, ecc. Sono popolari nella comunità della sicurezza, quindi vale la pena cercare suggerimenti e suggerimenti una volta arrivati. Hanno anche un po 'di buono tutorials like this one on x86 assembly.

0

Per raggiungere effettivamente il tuo obiettivo, potresti prendere in considerazione l'idea di iniziare con l'IDE in cui ti trovi. Generalmente è una finestra di disassemblaggio, quindi puoi eseguire un singolo passaggio del codice. Di solito c'è una vista di qualche tipo per farti vedere i registri e guardare nelle aree di memoria.

L'esame di codice c/C++ non ottimizzato consente di creare un collegamento nel tipo di codice generato dal compilatore per le origini. Alcuni compilatori hanno una sorta di parola riservata ASM che consente di inserire le istruzioni della macchina nel codice.

Il mio consiglio sarebbe di giocare con quel tipo di strumenti per un po 'e di bagnarsi i piedi, quindi salire? giù? per montare il codice assembler su qualunque piattaforma stiate correndo.

Ci sono molti ottimi strumenti là fuori, ma potresti trovarlo più divertente, per evitare all'inizio la curva di apprendimento ripida.

0

Abbiamo imparato l'assemblaggio con un kit di sviluppo del microcontrollore (Motorola HC12) e una scheda tecnica spessa.

2

Recentemente ho preso una classe di sistemi informatici. Uno degli argomenti era Assembly come strumento per comunicare con l'hardware.

Per me, la conoscenza dell'assemblaggio non sarebbe stata completa senza comprendere i dettagli di come funzionano i sistemi informatici. Capire questo, introduce una nuova comprensione del perché le istruzioni di assemblaggio su un'architettura di processore siano grandiose ma terribili su un'altra architettura.

Detto questo, io sono incline a raccomandare la mia classe libro di testo:

Computer Systems:A programmer's perspective.

Computer Systems:A programmer's perspective http://csapp.cs.cmu.edu/public/csappcover-medium.jpg

Fa gruppo di copertura x86, ma il libro è molto più ampia di quella. Copre il rivestimento del tubo del processore e la memoria come una cache, il sistema di memoria virtuale e molto altro. Tutto ciò può influire sul modo in cui l'assembly può essere ottimizzato per le funzionalità specificate.

3

Il suggerimento di usare il debug è divertente, si possono fare molti trucchetti. Tuttavia, per un sistema operativo moderno, l'apprendimento dell'assemblaggio a 16 bit potrebbe essere leggermente meno utile. Considerare, invece, l'utilizzo di ntsd.exe. È integrato in Windows XP (è stato strattonato in Server 2003 e versioni successive, purtroppo), il che lo rende uno strumento utile da apprendere in quanto è ampiamente disponibile.

Detto questo, la versione originale in XP soffre di un numero di bug. Se si desidera veramente utilizzarlo (o cdb o windbg, che sono essenzialmente interfacce diverse con la stessa sintassi di comando e debug back-end), è necessario installare il pacchetto gratuito windows debugging tools.

Il file debugger.chm incluso in quel pacchetto è particolarmente utile quando si cerca di capire la sintassi insolita.

La cosa grandiosa di ntsd è che puoi farla apparire su qualsiasi macchina XP che ti è vicina e usarla per assemblare o smontare. Realizza uno/grande/strumento di assemblaggio X86. Per esempio (utilizzando CDB dal momento che è in linea nel prompt di DOS, è altrimenti identico):

(errori simbolo saltati, dato che sono irrilevanti - anche, Spero che funzioni di formattazione, questo è il mio primo post)

C:\Documents and Settings\User>cdb calc 

Microsoft (R) Windows Debugger Version 6.10.0003.233 X86 
Copyright (c) Microsoft Corporation. All rights reserved. 

CommandLine: calc 
Symbol search path is: *** Invalid *** 
Executable search path is: 
ModLoad: 01000000 0101f000 calc.exe 
ModLoad: 7c900000 7c9b2000 ntdll.dll 
ModLoad: 7c800000 7c8f6000 C:\WINDOWS\system32\kernel32.dll 
ModLoad: 7c9c0000 7d1d7000 C:\WINDOWS\system32\SHELL32.dll 
ModLoad: 77dd0000 77e6b000 C:\WINDOWS\system32\ADVAPI32.dll 
ModLoad: 77e70000 77f02000 C:\WINDOWS\system32\RPCRT4.dll 
ModLoad: 77fe0000 77ff1000 C:\WINDOWS\system32\Secur32.dll 
ModLoad: 77f10000 77f59000 C:\WINDOWS\system32\GDI32.dll 
ModLoad: 7e410000 7e4a1000 C:\WINDOWS\system32\USER32.dll 
ModLoad: 77c10000 77c68000 C:\WINDOWS\system32\msvcrt.dll 
ModLoad: 77f60000 77fd6000 C:\WINDOWS\system32\SHLWAPI.dll 
(f2c.208): Break instruction exception - code 80000003 (first chance) 
eax=001a1eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4 
eip=7c90120e esp=0007fb20 ebp=0007fc94 iopl=0   nv up ei pl nz na po nc 
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000    efl=00000202 
ntdll!DbgBreakPoint: 
7c90120e cc    int  3 
0:000> r eax 
eax=001a1eb4 
0:000> r eax=0 
0:000> a eip 
7c90120e add eax,0x100 
7c901213 
0:000> u eip 
ntdll!DbgBreakPoint: 
7c90120e 0500010000  add  eax,100h 
7c901213 c3    ret 
7c901214 8bff   mov  edi,edi 
7c901216 8b442404  mov  eax,dword ptr [esp+4] 
7c90121a cc    int  3 
7c90121b c20400   ret  4 
ntdll!NtCurrentTeb: 
7c90121e 64a118000000 mov  eax,dword ptr fs:[00000018h] 
7c901224 c3    ret 
0:000> t 
eax=00000100 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=001a1f48 edi=001a1eb4 
eip=7c901213 esp=0007fb20 ebp=0007fc94 iopl=0   nv up ei pl nz na pe nc 
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000    efl=00000206 
ntdll!DbgUserBreakPoint+0x1: 
7c901213 c3    ret 
0:000>` 

Inoltre, mentre giochi con IDA, assicurati di controllare l'IDA Pro Book di Chris Eagle (non collegato poiché StackOverflow non mi consente di pubblicare più di due collegamenti per il mio primo post). È senza dubbio la migliore referenza là fuori.

+1

+1 per il libro di Chris Eagle. Devo metterci un po 'd'amore per Sk3wl di r00t;) – mrduclaw

1

Una delle lingue di assemblaggio pedagogico standard disponibili è MIPS. È possibile ottenere simulatori MIPS (spim) e vari materiali didattici per questo.

Personalmente, non sono un fan. Mi piace piuttosto IA32.

+0

MIPS è bello. 68000 lo è, e se impari 68000 puoi scrivere binari che girano in MAME. :-) – Nosredna

0

Off topic Lo so, ma dal momento che sei un programmatore di Windows non posso fare a meno di pensare che potrebbe essere un uso più appropriato e/o migliore del tuo tempo per imparare MSIL. No, non è assemblaggio, ma probabilmente è più rilevante in questa era .NET.

0

Conoscere l'assembly può essere utile per il debug ma non mi entusiasmerei troppo nell'utilizzarlo per ottimizzare il codice. I compilatori moderni di solito sono molto più bravi a ottimizzare quell'essere umano in questi giorni.

+0

Hmm. Puoi ancora strizzare un assembly di codice un po 'extra, ma ci vuole più lavoro per battere il compilatore rispetto a prima. – Nosredna

1

Il mio preferito è NASM, principalmente perché è multipiattaforma e compila MMX, SSE, 64-bit ...

Ho iniziato a compilare un semplice file sorgente C con gcc e "codifica" l'istruzione assembler da gcc-format in formato NASM. Quindi puoi modificare piccole porzioni di codice e verificare il miglioramento delle prestazioni che porta.

La documentazione del NASM è davvero completa, non ho mai avuto bisogno di cercare informazioni da libri o altre fonti.

0

È possibile controllare xorpd x86 Assembly video course. (L'ho scritto io). Il corso stesso viene pagato, ma gli esercizi sono aperti, su github. Se hai qualche esperienza di programmazione, penso che dovresti essere in grado di lavorare solo con gli esercizi e capire tutto.

Si noti che il codice è per la piattaforma Windows e viene scritto utilizzando Fasm assembler. Il corso e gli esercizi non contengono alcun costrutto di alto livello, tuttavia potresti usare Fasm per creare macro molto complicate, se mai lo desideri.