Rakitan pembelajaran [ditutup]

102

Saya memutuskan untuk belajar bahasa Assembly. Alasan utama untuk melakukannya adalah untuk dapat memahami kode yang dibongkar dan mungkin dapat menulis bagian kode yang lebih efisien (misalnya, melalui c ++), melakukan sesuatu seperti gua kode, dll. Saya melihat ada jutaan rasa perakitan yang berbeda Jadi, untuk tujuan yang saya sebutkan, bagaimana saya harus memulainya? Perakitan seperti apa yang harus saya pelajari? Saya ingin belajar dengan terlebih dahulu melakukan beberapa program mudah (yaitu kalkulator), tetapi tujuannya sendiri adalah untuk membiasakan diri dengannya sehingga saya dapat memahami kode yang ditampilkan, misalnya, oleh IDA Pro.

Saya menggunakan windows (jika itu membuat perbedaan).

sunting: Jadi, tampaknya semua orang mengarah ke MASM. Meskipun saya mendapatkan poin bahwa ia memiliki kemampuan tingkat tinggi, semuanya baik untuk programmer kode assembly, bukan itu yang saya cari. Tampaknya instruksi if, invoke, dll tidak ditampilkan di deassembler populer (seperti IDA). Jadi yang ingin saya dengar jika memungkinkan, adalah pendapat dari siapa saja yang menggunakan ASM untuk tujuan yang saya tanyakan (membaca kode exe yang sudah di-deassembled di IDA), bukan hanya programmer assembly "umum".

edit: OK. Saya sudah belajar perakitan. Saya belajar MASM, tidak menggunakan hal-hal tingkat tinggi yang tidak penting bagi saya. Apa yang saya lakukan sekarang adalah mencoba kode saya pada arahan __asm ​​di c ++, jadi saya dapat mencoba berbagai hal dengan lebih cepat daripada jika saya harus melakukan semuanya dari awal dengan MASM.

melahap elysium
sumber
Pertanyaan serupa dengan stackoverflow.com/questions/1355524/…
TrueWill
Ya, saya juga membaca yang itu. Tapi pertanyaan saya sedikit lebih "terfokus", menurut saya.
melahap elysium
Jika Anda menggunakan windows, targetnya (yaitu prosesor, dan set instruksi) adalah x86 atau x86-64. Kecuali Anda mendapatkan mesin lain atau papan MCU atau menggunakan emulator. Jadi, apakah pertanyaan assembler mana yang harus saya gunakan? Atau apakah Anda benar-benar bertanya arsitektur apa yang akan ditargetkan? Secara pribadi saya suka instruksi ortogonal yang bagus yang diatur pada chip seri m68k, sayangnya, alack.
dmckee --- mantan moderator anak kucing
2
"Tampaknya memiliki instruksi if, invoke, etc" - Itu adalah makro ('M' dalam "MASM") dan Anda tidak perlu menggunakannya bahkan jika assembler mendukungnya.
ChrisW
3
Merupakan keputusan yang sulit untuk memberikan pertanyaan tersebut upvote ke-65, 64 adalah angka yang sangat indah. . .
735Tesla

Jawaban:

40

Mulailah dengan MASM32 dan dari sana lihat FASM . Tapi Anda akan bersenang-senang dengan MASM.

Sutra Siang
sumber
Saya telah mendengar dari MASM. Jika saya tidak salah, ia memiliki banyak fitur "tingkat tinggi", yang tidak saya lihat ketika saya melihat kode yang dibongkar. Saya ingin memprogram sesuatu yang persis seperti kebanyakan kode keluaran disassembler, jika ini masuk akal.
melahap elysium
1
Itu pada dasarnya akan seperti menulis kode op, yang tidak terlalu masuk akal. Mempelajari MASM32 akan membantu Anda memahami bagaimana kode terlihat di debugger. Anda mungkin juga ingin melihat OllyDbg: ollydbg.de
Noon Silk
7
Anda tidak mengerti perakitan. Anda perlu memahaminya. Opcode adalah angka. Debugger akan mencoba menyelesaikan opcode sesuai instruksi mereka (terkadang sulit). Anda perlu memahami instruksi dasar. Belajar MASM akan membantu Anda melakukan ini. Tidak ada lagi yang perlu dikatakan.
Noon Silk
5
Anda tidak harus menggunakan semua fitur MASM hanya karena fitur tersebut ada; Anda dapat membuat hal-hal sesulit yang Anda inginkan, jika menurut Anda Anda akan belajar lebih banyak dengan cara itu.
JasonTrue
3
MASM, dengan keunikan, bug, dan apa yang disebut fitur-fitur tingkat tinggi telah berbuat lebih banyak untuk membingungkan pemrogram perakitan — pemula dan ahli — lebih dari apa pun yang dapat saya pikirkan.
IJ Kennedy
44

Saya telah melakukan ini berkali-kali dan terus melakukan ini. Dalam hal ini di mana tujuan utama Anda adalah membaca dan bukan menulis assembler, saya rasa ini berlaku.

Tulis pembongkaran Anda sendiri. Bukan untuk tujuan membuat pembongkaran terhebat berikutnya, yang ini hanya untuk Anda. Tujuannya adalah mempelajari set instruksi. Apakah saya sedang mempelajari assembler di platform baru, mengingat assembler untuk platform yang pernah saya kenal. Mulailah dengan hanya beberapa baris kode, tambahkan register misalnya, dan ping pong-ing antara membongkar keluaran biner dan menambahkan instruksi yang semakin rumit di sisi masukan Anda:

1) pelajari set instruksi untuk prosesor tertentu

2) pelajari nuansa bagaimana menulis kode dalam assemble untuk prosesor tersebut sehingga Anda dapat menggoyangkan setiap bit opcode dalam setiap instruksi

3) Anda mempelajari set instruksi lebih baik daripada kebanyakan insinyur yang menggunakan set instruksi itu untuk mencari nafkah

Dalam kasus Anda ada beberapa masalah, saya biasanya merekomendasikan set instruksi ARM untuk memulai, ada lebih banyak produk berbasis ARM yang dikirim hari ini daripada yang lain (termasuk komputer x86). Tetapi kemungkinan Anda menggunakan ARM sekarang dan tidak cukup mengetahui assembler untuk menulis kode startup atau rutinitas lain yang mengetahui ARM mungkin atau mungkin tidak membantu apa yang Anda coba lakukan. Alasan kedua dan yang lebih penting untuk ARM pertama adalah karena panjang instruksi berukuran tetap dan selaras. Membongkar instruksi panjang variabel seperti x86 bisa menjadi mimpi buruk sebagai proyek pertama Anda, dan tujuannya di sini adalah untuk mempelajari set instruksi untuk tidak membuat proyek penelitian. ARM ketiga adalah set instruksi yang dilakukan dengan baik, register dibuat sama dan tidak memiliki nuansa khusus individu.

Jadi, Anda harus mencari tahu prosesor apa yang ingin Anda gunakan. Saya sarankan msp430 atau ARM pertama, lalu ARM pertama atau kedua kemudian x86 chaos. Apa pun platformnya, platform apa pun yang layak digunakan memiliki lembar data atau manual referensi pemrogram yang bebas dari vendor yang menyertakan set instruksi serta pengkodean opcode (bit dan byte dari bahasa mesin). Untuk tujuan mempelajari apa yang dilakukan compiler dan bagaimana menulis kode yang tidak harus dipermasalahkan oleh compiler, ada baiknya untuk mengetahui beberapa set instruksi dan melihat bagaimana kode tingkat tinggi yang sama diimplementasikan pada setiap set instruksi dengan setiap compiler dengan setiap optimasi pengaturan. Anda tidak ingin mengoptimalkan kode Anda hanya untuk mengetahui bahwa Anda telah membuatnya lebih baik untuk satu kompiler / platform tetapi jauh lebih buruk untuk yang lainnya.

Oh untuk membongkar set instruksi panjang variabel, alih-alih hanya memulai dari awal dan membongkar setiap kata empat byte secara linier melalui memori seperti yang Anda lakukan dengan ARM atau setiap dua byte seperti msp430 (msp430 memiliki instruksi panjang variabel tetapi Anda masih bisa mendapatkannya akan linier melalui memori jika Anda mulai dari titik masuk dari tabel vektor interupsi). Untuk panjang variabel, Anda ingin mencari titik masuk berdasarkan tabel vektor atau pengetahuan tentang bagaimana prosesor melakukan booting dan mengikuti kode dalam urutan eksekusi. Anda harus mendekode setiap instruksi sepenuhnya untuk mengetahui berapa banyak byte yang digunakan, maka jika instruksi tersebut bukan cabang tanpa syarat, anggap byte berikutnya setelah instruksi itu adalah instruksi lain. Anda harus menyimpan semua alamat cabang yang mungkin juga dan menganggap itu adalah alamat byte awal untuk instruksi lebih lanjut. Satu kali saya berhasil, saya membuat beberapa lintasan melalui biner. Mulai dari titik masuk, saya menandai byte itu sebagai awal instruksi kemudian diterjemahkan secara linier melalui memori sampai mengenai cabang tanpa syarat. Semua target cabang ditandai sebagai alamat awal dari sebuah instruksi. Saya membuat beberapa lintasan melalui biner sampai saya tidak menemukan target cabang baru. Jika suatu saat Anda menemukan mengatakan instruksi 3 byte tetapi karena alasan tertentu Anda telah menandai byte kedua sebagai awal instruksi, Anda mengalami masalah. Jika kode dibuat oleh kompilator tingkat tinggi, ini seharusnya tidak terjadi kecuali kompilator melakukan sesuatu yang jahat, jika kode memiliki assembler yang ditulis tangan (seperti misalnya game arcade lama), sangat mungkin bahwa akan ada cabang bersyarat yang tidak akan pernah terjadi seperti r0 = 0 diikuti dengan lompatan jika bukan nol. Anda mungkin harus mengeditnya dari biner untuk melanjutkan. Untuk tujuan langsung Anda yang saya asumsikan berada di x86, saya rasa Anda tidak akan mendapat masalah.

Saya merekomendasikan alat gcc, mingw32 adalah cara mudah untuk menggunakan alat gcc di Windows jika x86 adalah target Anda. Jika tidak mingw32 plus msys adalah platform yang sangat baik untuk menghasilkan kompilator silang dari binutils dan sumber gcc (umumnya cukup mudah). mingw32 memiliki beberapa keunggulan dibandingkan cygwin, seperti program yang jauh lebih cepat dan Anda menghindari cygwin dll neraka. gcc dan binutils akan memungkinkan Anda untuk menulis dalam C atau assembler dan membongkar kode Anda dan ada lebih banyak halaman web daripada yang dapat Anda baca yang menunjukkan kepada Anda bagaimana melakukan salah satu atau semua dari ketiganya. Jika Anda akan melakukan ini dengan set instruksi panjang variabel, saya sangat menyarankan Anda menggunakan set alat yang menyertakan disassembler. Pembongkaran pihak ketiga untuk x86 misalnya akan menjadi tantangan untuk digunakan karena Anda tidak pernah benar-benar tahu apakah itu telah dibongkar dengan benar. Beberapa di antaranya juga bergantung pada sistem operasi, tujuannya adalah untuk mengkompilasi modul ke format biner yang berisi petunjuk penandaan informasi dari data sehingga disassembler dapat melakukan pekerjaan yang lebih akurat. Pilihan Anda yang lain untuk tujuan utama ini adalah memiliki alat yang dapat dikompilasi langsung ke assembler untuk pemeriksaan Anda, lalu berharap bahwa ketika dikompilasi ke format biner, alat itu membuat instruksi yang sama.

Jawaban singkat (oke sedikit lebih pendek) untuk pertanyaan Anda. Menulis pembongkaran untuk mempelajari set instruksi. Saya akan mulai dengan sesuatu yang RISIKO dan mudah dipelajari seperti ARM. Setelah Anda mengetahui satu set instruksi yang lain menjadi lebih mudah untuk diambil, seringkali dalam beberapa jam, pada set instruksi ketiga Anda dapat mulai menulis kode hampir seketika dengan menggunakan lembar data / manual referensi untuk sintaks. Semua prosesor yang layak digunakan memiliki lembar data atau manual referensi yang menjelaskan instruksi hingga bit dan byte dari opcode. Pelajari prosesor RISC seperti ARM dan CISC seperti x86 cukup untuk merasakan perbedaannya, hal-hal seperti harus melalui register untuk semuanya atau dapat melakukan operasi secara langsung pada memori dengan register yang lebih sedikit atau tanpa register. Tiga instruksi operan versus dua, dll. Saat Anda menyetel kode tingkat tinggi, kompilasi untuk lebih dari satu prosesor dan bandingkan hasilnya. Hal terpenting yang akan Anda pelajari adalah bahwa betapapun baiknya kode tingkat tinggi ditulis, kualitas kompiler dan pilihan pengoptimalan membuat perbedaan besar dalam instruksi yang sebenarnya. Saya merekomendasikan llvm dan gcc (dengan binutils), keduanya tidak menghasilkankode yang bagus , tetapi mereka multi platform dan multi target dan keduanya memiliki pengoptimal. Dan keduanya gratis dan Anda dapat dengan mudah membuat kompiler silang dari sumber untuk berbagai prosesor target.

old_timer
sumber
Terima kasih balasannya. Tapi saya bahkan tidak tahu bagaimana menulis disassembler.
melahap elysium
8
"Tulis pembongkaran Anda sendiri" - Saya setuju, begitulah cara saya mempelajarinya dengan sebaik-baiknya. (Ada apa dengan "Tapi aku bahkan tidak tahu cara menulis disassembler"?) LOL.
slashmais
Aku pergi denganmu! Baru saja membeli MSP430 dan buku tentangnya ... :)
Pepe
1
Saya punya beberapa contoh msp430 github.com/dwelch67 ditambah beberapa simulator set instruksi untuk bereksperimen dengan termasuk belajar ASM, dll.
old_timer
Saya sangat, sangat menyukai ide ini.
Millie Smith
33

Rakitan yang akan Anda tulis dengan tangan dan rakitan yang dihasilkan oleh kompiler seringkali sangat berbeda jika dilihat dari level tinggi. Tentu saja, bagian dalam program akan sangat mirip ( a = b + clagipula hanya ada begitu banyak cara berbeda untuk menyandikan ), tetapi itu bukan masalah ketika Anda mencoba merekayasa balik sesuatu. Kompiler akan menambahkan satu ton kode boilerplate bahkan ke executable sederhana: terakhir kali saya membandingkan, "Hello World" yang dikompilasi oleh GCC adalah sekitar 4kB, sedangkan jika ditulis secara manual dalam assembly sekitar 100 byte. Ini lebih buruk di Windows: terakhir kali saya membandingkan (memang, ini abad terakhir) "Halo Dunia" terkecil yang bisa saya hasilkan kompiler Windows saya saat itu adalah 52kB! Biasanya boilerplate ini hanya dijalankan sekali, jika ada, jadi tidak banyak mempengaruhi kecepatan program - seperti yang saya katakan di atas, inti program, bagian di mana sebagian besar waktu eksekusi dihabiskan, biasanya sangat mirip baik dikompilasi atau ditulis dengan tangan.

Pada akhirnya, ini berarti bahwa programmer ahli perakitan dan ahli disassembler adalah dua spesialisasi yang berbeda. Biasanya mereka ditemukan pada orang yang sama, tetapi mereka benar-benar terpisah, dan mempelajari bagaimana menjadi pembuat kode perakitan yang sangat baik tidak akan banyak membantu Anda untuk mempelajari rekayasa balik.

Yang ingin Anda lakukan adalah mengambil manual arsitektur IA-32 dan AMD64 (keduanya tercakup bersama) dari Intel dan AMD , dan melihat melalui bagian awal tentang instruksi dan opcode. Mungkin membaca satu atau dua tutorial tentang bahasa assembly, hanya untuk memahami dasar-dasar bahasa assembly. Lalu ambil yang kecilcontoh program yang Anda minati dan bongkar: ikuti alur kontrolnya dan coba pahami apa yang dilakukannya. Lihat apakah Anda dapat menambalnya untuk melakukan sesuatu yang lain. Kemudian coba lagi dengan program lain, dan ulangi sampai Anda merasa cukup nyaman untuk mencoba mencapai tujuan yang lebih berguna. Anda mungkin tertarik pada hal-hal seperti "crackmes", yang diproduksi oleh komunitas reverse engineering, yang merupakan tantangan bagi orang-orang yang tertarik dengan reverse engineering untuk mencoba, dan mudah-mudahan mempelajari sesuatu di sepanjang jalan. Mereka berkisar dalam kesulitan dari dasar (mulai di sini!) Hingga tidak mungkin.

Yang terpenting, Anda hanya perlu berlatih . Seperti di banyak disiplin ilmu lainnya, dengan rekayasa terbalik, latihan membuat sempurna ... atau setidaknya lebih baik .

kquinn
sumber
Saya tahu bahwa ketika Anda mengkompilasi sesuatu dengan bahasa tingkat tinggi, Anda akan mendapatkan banyak kode "sampah" yang tidak akan diperlukan itu dikodekan langsung dalam perakitan. Saya juga mengerti bahwa ada perbedaan antara programmer expert assembly dan expert disassembler. Tetapi hal yang sama dapat dikatakan tentang hampir semua hal lainnya.
melahap elysium
3
Kekhawatiran saya adalah bahwa sementara secara teori saya bisa membaca koran dan memahami apa artinya, sampai saya mulai menulis sendiri, saya tidak percaya saya akan benar-benar memahaminya. Anda mengatakan saya bisa mulai dengan mengubah bagian-bagian kecil dari kode, tetapi untuk melakukan itu saya pertama-tama harus tahu jenis perakitan "rasa" IDA pro, misalnya, gunakan.
melahap elysium
Selain itu, apa yang digunakan MSVC ++ untuk kode perakitan sebaris? MASM?
melahap elysium
15

Saya akan menentang sebagian besar jawaban dan merekomendasikan varian MMIX Knuth dari arsitektur MIPS RISC. Ini tidak akan berguna secara praktis seperti bahasa rakitan x86 atau ARM (bukan karena semuanya itu sangat penting di sebagian besar pekerjaan kehidupan nyata hari ini ... ;-), tetapi AKAN membuka bagi Anda keajaiban dari Knuth terbaru versi karya terbesar yang pernah ada tentang pemahaman mendalam tentang algoritme dan struktur data - TAOCP , "Seni Pemrograman Komputer". Tautan dari dua URL yang saya kutip adalah cara yang bagus untuk mulai menjelajahi kemungkinan ini!

Alex Martelli
sumber
12

(Saya tidak tahu tentang Anda tapi saya senang dengan perakitan)

Alat sederhana untuk bereksperimen dengan perakitan sudah terpasang di pc Anda.

Buka menu Mulai-> Jalankan, dan ketikdebug

debug (perintah)

debug adalah perintah di DOS, MS-DOS, OS / 2 dan Microsoft Windows (hanya versi x86, bukan x64) yang menjalankan program debug.exe (atau DEBUG.COM di versi DOS yang lebih lama). Debug dapat bertindak sebagai assembler, disassembler, atau program hex dump yang memungkinkan pengguna untuk secara interaktif memeriksa isi memori (dalam bahasa assembly, heksadesimal atau ASCII), membuat perubahan, dan secara selektif menjalankan COM, EXE, dan jenis file lainnya. Ia juga memiliki beberapa sub-perintah yang digunakan untuk mengakses sektor disk tertentu, port I / O dan alamat memori. MS-DOS Debug berjalan pada tingkat proses 16-bit dan oleh karena itu terbatas pada program komputer 16-bit . FreeDOS Debug memiliki versi "DEBUGX" yang mendukung program DPMI 32-bit juga.

Tutorial:


Jika Anda ingin memahami kode yang Anda lihat di IDA Pro (atau OllyDbg ), Anda harus mempelajari bagaimana kode yang dikompilasi disusun. Saya merekomendasikan buku Reversing: Secrets of Reverse Engineering

Saya bereksperimen beberapa minggu dengan debugsaat saya mulai belajar perakitan (15 tahun lalu).
Perhatikan bahwa debugbekerja di tingkat mesin dasar, tidak ada perintah perakitan tingkat tinggi.

Dan sekarang contoh sederhana:

Berikan auntuk mulai menulis kode assembly - ketik program di bawah ini - dan terakhir berikan guntuk menjalankannya.

teks alt


( INT 21tampilkan di layar karakter ASCII yang disimpan dalam DLregister jika AHregister diatur ke 2- INT 20menghentikan program)

Nick Dandoulakis
sumber
Saya harus menekan ctrl-c, sebelum saya bisa memasukkan "g."
ericp
2
@ericp, Anda tidak perlu menekan ctrl-c. Misalnya, Anda mengetik a& [enter] untuk mulai menulis kode assembly. Jika Anda menekan [enter] dua kali Anda keluar dari mode perakitan. g& [enter] untuk menjalankannya (diimbangi 100 secara default).
Nick Dandoulakis
apakah itu benar-benar menyebabkan tumpukan meluap atau apakah itu hanya menulisnya ke layar?
Janus Troelsen
1
@user, itu hanya menulis nama situs ini :-)
Nick Dandoulakis
@JanusTroelsen nomor tersebut (53, 74, 61, dll) adalah kode ASCII untuk 'S' 't' 'a' ... Setiap panggilan Int21 mencetak satu karakter dalam satu waktu! Inilah sebabnya mengapa perakitan TIDAK lebih cepat :)
doug65536
8

Saya menemukan Hacking: The Art of Exploitation menjadi cara yang menarik dan berguna untuk topik ini ... tidak bisa mengatakan bahwa saya pernah menggunakan pengetahuan secara langsung, tapi bukan itu alasan saya membacanya. Ini memberi Anda apresiasi yang lebih kaya atas instruksi yang dikompilasi kode Anda, yang terkadang berguna dalam memahami bug yang lebih halus.

Jangan takut dengan judulnya. Sebagian besar bagian pertama buku ini adalah "Hacking" dalam arti kata Eric Raymond: cara kreatif, mengejutkan, hampir licik untuk memecahkan masalah yang sulit. Saya (dan mungkin Anda) kurang tertarik pada aspek keamanan.

mblackwell8
sumber
7

Saya tidak akan fokus mencoba menulis program dalam perakitan, setidaknya tidak pada awalnya. Jika Anda menggunakan x86 (yang saya asumsikan, karena Anda menggunakan Windows), ada banyak kasus khusus aneh yang tidak ada gunanya untuk dipelajari. Misalnya, banyak instruksi mengasumsikan Anda beroperasi pada register yang tidak Anda beri nama secara eksplisit, dan instruksi lain berfungsi pada beberapa register tetapi tidak pada yang lain.

Saya akan belajar cukup tentang arsitektur yang Anda maksudkan sehingga Anda memahami dasar-dasarnya, lalu langsung saja masuk dan mencoba memahami output kompiler Anda. Persenjatai diri Anda dengan manual Intel dan selami langsung output kompiler Anda. Pisahkan kode yang diminati menjadi fungsi kecil, sehingga Anda dapat yakin untuk memahami semuanya.

Saya akan menganggap dasar-dasarnya adalah:

  • register: berapa jumlahnya, apa namanya, dan berapa ukurannya?
  • operand order: add eax, ebxartinya "Tambahkan ebx ke eax dan simpan hasilnya di eax".
  • FPU: pelajari dasar-dasar stack floating-point dan cara Anda mengonversi ke / dari fp.
  • mode pengalamatan: [base + offset * multiplier], tapi multiplier hanya bisa 1, 2, atau 4 (atau mungkin 8?)
  • konvensi panggilan: bagaimana parameter diteruskan ke suatu fungsi?

Seringkali akan mengejutkan apa yang dipancarkan oleh kompilator. Buatlah menjadi teka-teki untuk mencari tahu mengapa penyusun menganggap ini ide yang bagus. Itu akan mengajarimu banyak hal.

Mungkin juga akan membantu untuk mempersenjatai diri Anda dengan manual Agner Fog , terutama instruksi yang mencantumkan satu. Ini akan memberi tahu Anda secara kasar seberapa mahal setiap instruksi, meskipun ini lebih sulit untuk diukur secara langsung pada prosesor modern. Tetapi ini akan membantu menjelaskan mengapa, misalnya, kompilator berusaha keras untuk menghindari penerbitan idivinstruksi.

Satu-satunya saran saya yang lain adalah selalu menggunakan sintaks Intel daripada AT&T ketika Anda punya pilihan. Saya dulu cukup netral dalam hal ini, sampai hari saya menyadari bahwa beberapa instruksi sama sekali berbeda di antara keduanya (misalnya, movslqdalam sintaks AT&T ada movsxddalam sintaks Intel). Karena manual semuanya ditulis menggunakan sintaks Intel, tetap gunakan itu.

Semoga berhasil!

Josh Haberman
sumber
3

Saya mulai mempelajari MIPS yang merupakan arsitektur 32-bit yang sangat ringkas. Ini adalah set instruksi yang dikurangi, tapi itulah yang membuatnya mudah dipahami untuk pemula. Anda masih akan dapat memahami cara kerja perakitan tanpa kewalahan dengan kerumitan. Anda bahkan dapat mengunduh IDE kecil yang bagus, yang memungkinkan Anda untuk mengkompilasi kode MIPS Anda: clicky Setelah Anda memahaminya, saya pikir akan jauh lebih mudah untuk beralih ke arsitektur yang lebih kompleks. Setidaknya itulah yang saya pikirkan :) Pada titik ini Anda akan memiliki pengetahuan penting tentang alokasi dan manajemen memori, aliran logika, debugging, pengujian, dll.


sumber
3

Saran untuk menggunakan debug itu menyenangkan, banyak trik rapi yang bisa dilakukan dengan itu. Namun, untuk sistem operasi modern, mempelajari perakitan 16bit mungkin sedikit kurang berguna. Pertimbangkan, sebagai gantinya, menggunakan ntsd.exe. Itu dibangun ke dalam Windows XP (sayangnya ditarik di Server 2003 dan di atasnya), yang membuatnya menjadi alat yang nyaman untuk dipelajari karena tersedia secara luas.

Meskipun demikian, versi asli di XP mengalami sejumlah bug. Jika Anda benar-benar ingin menggunakannya (atau cdb, atau windbg, yang pada dasarnya adalah antarmuka yang berbeda dengan sintaks perintah yang sama dan proses debug back-end), Anda harus menginstal paket alat debugging windows gratis .

File debugger.chm yang disertakan dalam paket itu sangat berguna saat mencoba mencari tahu sintaks yang tidak biasa.

Hal terbaik tentang ntsd adalah Anda dapat mem-pop-upnya di mesin XP mana pun yang dekat dengan Anda dan menggunakannya untuk merakit atau membongkar. Itu membuat alat pembelajaran perakitan / hebat / X86. Misalnya (menggunakan cdb karena inline di prompt dos, sebaliknya identik):

(kesalahan simbol dilewati karena tidak relevan - juga, saya harap pemformatan ini berfungsi, ini adalah posting pertama saya)

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>`

Juga - saat Anda bermain dengan IDA, pastikan untuk memeriksa Buku IDA Pro oleh Chris Eagle (tidak ditautkan karena StackOverflow tidak ingin saya memposting lebih dari dua tautan untuk posting pertama saya). Ini adalah referensi terbaik di luar sana.

Yordania
sumber
1
1 untuk buku Chris Eagle. Harus menaruh cinta di sana untuk Sk3wl dari r00t;)
mrduclaw
3

Saya baru-baru ini mengambil kelas sistem komputer. Salah satu topiknya adalah Assembly sebagai alat untuk berkomunikasi dengan perangkat keras.

Bagi saya, pengetahuan tentang perakitan tidak akan lengkap tanpa memahami detail cara kerja sistem komputer. Memahami itu, membawa pemahaman baru tentang mengapa instruksi perakitan pada satu arsitektur prosesor bagus tetapi buruk pada arsitektur lain.

Mengingat ini, saya cenderung merekomendasikan buku teks kelas saya:

Sistem Komputer: Perspektif programmer .

Sistem Komputer: Perspektif programmer
(sumber: cmu.edu )

Itu mencakup perakitan x86 tetapi bukunya jauh lebih luas dari itu. Ini mencakup lapisan pipa prosesor dan memori sebagai cache, sistem memori virtual, dan banyak lagi. Semua ini dapat memengaruhi bagaimana perakitan dapat dioptimalkan untuk fitur yang diberikan.

Frank V
sumber
2

Saya pikir Anda ingin mempelajari mnemonik opcode ber-ASCII (dan parameternya), yang dikeluarkan oleh disassembler dan yang dipahami oleh (dapat digunakan sebagai masukan untuk) assembler.

Assembler apa pun (misalnya MASM) bisa melakukannya.

Dan / atau mungkin lebih baik Anda membaca buku tentangnya (ada buku yang direkomendasikan tentang SO, saya tidak ingat yang mana).

ChrisW
sumber
2

Apakah Anda melakukan pekerjaan dev lainnya di windows? Di IDE yang mana? Jika VS, maka tidak perlu IDE tambahan hanya untuk membaca kode yang dibongkar: debug aplikasi Anda (atau lampirkan ke aplikasi eksternal), lalu buka jendela pembongkaran (dalam pengaturan default, yaitu Alt + 8). Langkah dan perhatikan memori / register seperti yang Anda lakukan melalui kode normal. Anda mungkin juga ingin membiarkan jendela register terbuka (Alt + 5 secara default).

Intel memberikan manual gratis , yang memberikan survei arsitektur dasar (register, unit prosesor, dll.) Dan referensi instruksi lengkap. Ketika arsitektur semakin matang dan semakin kompleks, manual 'arsitektur dasar' semakin tidak dapat dibaca. Jika Anda bisa mendapatkan versi yang lebih lama, Anda mungkin memiliki tempat yang lebih baik untuk memulai (bahkan manual P3 - mereka menjelaskan dengan lebih baik lingkungan eksekusi dasar yang sama ).

Jika Anda ingin berinvestasi dalam sebuah buku, berikut adalah teks pengantar yang bagus. Cari amazon untuk 'x86' dan Anda akan mendapatkan banyak lainnya. Anda bisa mendapatkan beberapa petunjuk arah lain dari pertanyaan lain di sini .

Akhirnya, Anda bisa mendapatkan keuntungan sedikit dari membaca beberapa rendah - tingkat blog. Bit info ukuran byte ini bekerja paling baik untuk saya, secara pribadi.

Ofek Shilon
sumber
2

Ini tidak selalu membantu Anda menulis kode yang efisien!

Kode op i86 kurang lebih merupakan format "warisan" yang bertahan karena banyaknya kode dan binari yang dapat dieksekusi untuk Windows dan Linux di luar sana.

Ini seperti sarjana tua yang menulis dalam bahasa latin, penutur bahasa Italia seperti Galileo akan menulis dalam bahasa latin dan makalahnya dapat dipahami oleh penutur bahasa Polandia seperti Copernicus. Ini masih merupakan cara yang paling efektif untuk berkomunikasi meskipun niether sangat mahir dalam bahasa Latin, dan Latin adalah bahasa sampah untuk mengekspresikan ide-ide matematika.

Jadi kompiler menghasilkan kode x86 secara default, dan, chip modern membaca kode Op anceint dan mentransalasikan apa yang mereka lihat menjadi instruksi risc paralel, dengan eksekusi yang diatur ulang, eksekusi spekulatif, pipelining, dll. Selain itu, mereka memanfaatkan sepenuhnya register prosesor 32 atau 64 sebenarnya memiliki (berlawanan dengan 8 menyedihkan yang Anda lihat di instruksi x86.)

Sekarang semua penyusun pengoptimalan tahu bahwa inilah yang sebenarnya terjadi, jadi mereka membuat kode urutan kode OP yang mereka tahu dapat dioptimalkan oleh chip secara efisien - meskipun beberapa urutan ini akan terlihat tidak memadai bagi programmer sekitar tahun 1990.

Pada titik tertentu Anda perlu menerima bahwa 10-an dari ribuan tahun kerja penulis kompiler telah terbayar, dan, percayalah.

Cara termudah dan termudah untuk mendapatkan runtime yang lebih efisien adalah dengan membeli kompiler Intel C / C ++. Mereka memiliki ceruk pasar untuk penyusun efficeint, dan, mereka memiliki keuntungan karena dapat bertanya kepada perancang chip tentang apa yang terjadi di dalamnya.

James Anderson
sumber
Cerita Anda agak menunjukkan bahwa prosesor CISC secara internal telah menjadi prosesor RISC. Saya mungkin salah paham, tetapi ini sama sekali tidak benar. Dan yang menyedihkan 8? Prosesor modern (katakanlah, sejak 1999) mencakup lebih banyak lagi: 10 gpr: EAX-EFLAGS, 80 bit FP0-FP7, 64-bit MMX0-MMX7, 128-bit XMM0-XMM7, segmen: CS-GS, spesial: CR0-CR4 , DR0-DR7, TR3-TR7, GDTR, IDTR, LDTR, MSRs dan pada x86-64 juga R8-R15. Tidak semua ini dapat diakses dari ring-3, tetapi sebagian besar dan sebagian besar digunakan oleh kompiler GCC / VC ++ terbaru (pasca-2006). Secara keseluruhan sedikit lebih dari "menyedihkan 8";).
Abel
2

Untuk melakukan apa yang ingin Anda lakukan, saya hanya mengambil Referensi Set Instruksi Intel (mungkin bukan yang persis seperti yang saya gunakan, tetapi kelihatannya cukup) dan beberapa program sederhana yang saya tulis di Visual Studio dan mulai melemparkannya ke IDAPro / Windbg . Ketika saya mengembangkan program saya sendiri, perangkat lunak di crackmes sangat membantu.

Saya berasumsi bahwa Anda memiliki pemahaman dasar tentang bagaimana program dijalankan di Windows. Tapi sungguh, untuk membaca perakitan, hanya ada beberapa instruksi untuk dipelajari dan beberapa rasa dari instruksi itu (misalnya, ada instruksi lompat, jump memiliki beberapa rasa seperti jump-if-equal, jump-if-ecx-is-zero , dll). Setelah Anda mempelajari instruksi dasar, cukup mudah untuk mendapatkan inti dari eksekusi program. Tampilan grafik IDA membantu, dan jika Anda menelusuri program dengan Windbg, cukup mudah untuk mengetahui apa yang dilakukan instruksi jika Anda tidak yakin.

Setelah sedikit bermain seperti itu, saya membeli Hacker Disassembly Uncovered . Secara umum, saya menghindari buku-buku dengan kata "Hacker" di judulnya, tetapi saya sangat menyukai bagaimana buku ini membahas secara mendalam tentang bagaimana kode yang dikompilasi tampak dibongkar. Ia juga masuk ke dalam optimasi kompiler dan beberapa hal efisiensi yang menarik.

Itu semua sangat tergantung pada seberapa dalam Anda ingin dapat memahami program juga. Jika Anda merekayasa balik target yang mencari kerentanan, jika Anda menulis kode exploit, atau menganalisis malware yang dikemas untuk kemampuan, Anda akan membutuhkan lebih banyak waktu peningkatan untuk benar-benar menjalankan semuanya (terutama untuk malware yang lebih canggih ). Di sisi lain, jika Anda hanya ingin mengubah level karakter Anda di video game favorit, Anda harus melakukannya dengan baik dalam waktu yang relatif singkat.

mrduclaw.dll
sumber
1

Salah satu bahasa rakitan pedagogik standar di luar sana adalah MIPS. Anda bisa mendapatkan simulator MIPS (spim) dan berbagai bahan ajar untuk itu.

Secara pribadi, saya bukan penggemar. Saya lebih suka IA32.

Paul Nathan
sumber
MIPS bagus. 68000 juga, dan jika Anda mempelajari 68000 Anda dapat menulis binari yang berjalan di MAME. :-)
Nosredna
1

Favorit pribadi saya adalah NASM, sebagian besar karena multi-platform, dan mengkompilasi MMX, SSE, 64-bit ...

Saya mulai mengkompilasi beberapa file sumber C sederhana dengan gcc, dan "mentrans-coding" instruksi assembler dari gcc-format ke format NASM. Kemudian Anda dapat mengubah sebagian kecil kode, dan memverifikasi peningkatan kinerja yang dihasilkannya.

Dokumentasi NASM benar-benar lengkap, saya tidak pernah perlu mencari informasi dari buku, atau sumber lain.

GB
sumber
0

Banyak jawaban bagus di sini. Pemrograman tingkat rendah, perakitan, dll. Populer di komunitas keamanan, jadi ada baiknya mencari petunjuk dan tip di sana begitu Anda memulai. Mereka bahkan memiliki beberapa tutorial bagus seperti ini pada perakitan x86 .

Brian Lyttle
sumber
0

Untuk benar-benar mencapai tujuan Anda, Anda dapat mempertimbangkan untuk memulai dengan IDE tempat Anda berada. Umumnya adalah jendela disassembler, sehingga Anda dapat melakukan satu langkah melalui kode. Biasanya ada pandangan untuk membiarkan Anda melihat register dan melihat ke dalam area memori.

Pemeriksaan kode c / c ++ yang tidak dioptimalkan akan membantu membangun tautan ke jenis kode yang dihasilkan kompilator untuk sumber Anda. Beberapa kompiler memiliki semacam kata khusus ASM yang memungkinkan Anda memasukkan instruksi mesin ke dalam kode Anda.

Saran saya adalah bermain-main dengan alat semacam itu untuk sementara waktu dan membuat kaki Anda basah, lalu melangkah? turun? ke kode assembler langsung pada platform apa pun yang Anda jalankan.

Ada banyak alat hebat di luar sana, tetapi Anda mungkin akan merasa lebih menyenangkan, untuk menghindari kesulitan belajar pada awalnya.

EvilTeach
sumber
0

Kami belajar perakitan dengan kit pengembangan mikrokontroler (Motorola HC12) dan lembar data yang tebal.

engkau
sumber
0

Di luar topik Saya tahu, tetapi karena Anda adalah pemrogram Windows, saya tidak bisa tidak berpikir bahwa ini mungkin lebih tepat dan / atau lebih baik menggunakan waktu Anda untuk belajar MSIL. Tidak, ini bukan perakitan, tetapi mungkin lebih relevan di era .NET ini.

slf
sumber
0

Mengetahui perakitan dapat berguna untuk debugging tetapi saya tidak akan terlalu bersemangat menggunakannya untuk mengoptimalkan kode Anda. Kompiler modern biasanya jauh lebih baik dalam mengoptimalkan manusia saat ini.

Adam Pierce
sumber
Hmm. Anda masih bisa memeras sedikit lebih banyak perakitan pengkodean sendiri, tetapi dibutuhkan lebih banyak pekerjaan untuk mengalahkan kompiler daripada sebelumnya.
Nosredna
0

Anda dapat melihat kursus video Perakitan xorpd x86 . (Saya menulisnya). Kursusnya sendiri berbayar, tetapi latihannya bersumber terbuka, di github. Jika Anda memiliki pengalaman pemrograman, saya pikir Anda harus bisa bekerja hanya dengan latihan dan memahami segalanya.

Perhatikan bahwa kode ini untuk platform Windows, dan ditulis menggunakan assembler Fasm . Kursus dan latihan tidak berisi konstruksi tingkat tinggi, namun Anda dapat menggunakan Fasm untuk membuat makro yang sangat rumit, jika Anda ingin melakukannya.

xorpd
sumber