学習アセンブリ[終了]


102

アセンブリ言語を学ぶことにしました。そうする主な理由は、逆アセンブルされたコードを理解し、コードのより効率的な部分を(たとえば、C ++を介して)書けるようになること、コードケーブなどの処理を実行できることです。アセンブリにはさまざまな種類のアセンブリがあることがわかりました、だから、私が言及する目的のために、私はどのように始めるべきですか?どのようなアセンブリを学ぶべきですか?最初にいくつかの簡単なプログラム(電卓など)を実行して学習したいのですが、目標自体は、IDA Proなどのコードを理解できるように、それに慣れることです。

私はウィンドウを使用しています(違いがある場合)。

編集:それで、誰もがMASMに向かっているようです。高レベルの機能を備えているという点はわかりますが、アセンブリコードプログラマーにとってはすべて良いですが、それは私が探しているものではありません。一般的な逆アセンブラー(IDAなど)に示されていないif、invokeなどの命令があるようです。だから、もし私が聞きたいのは、単に「一般的な」アセンブリプログラマーではなく、私が求めている目的(逆アセンブルされたexeのコードをIDAで読む)にASMを使用する人の意見です。

編集:OK。私はすでに集会を学んでいます。私はMASMを学習していますが、私にとって重要ではない高レベルのものを使用していません。私が今行っているのは、c ++の__asmディレクティブでコードを試すことです。そのため、MASMで最初からすべてを実行しなければならなかった場合よりもずっと速く試すことができます。



はい、私もそれを読んでいました。しかし、私の質問はもう少し「焦点を絞った」ものだと思います。
貪欲なエリジウム2009

Windowsを使用している場合、ターゲット(つまり、プロセッサ、つまり命令セット)はx86またはx86-64です。別のマシンやMCUボードを入手したり、エミュレータを使用したりしない限り。では、どのアセンブラを使用すればよいのでしょうか。それとも、本当にどのアーキテクチャを対象とするのですか?個人的に、私はm68kシリーズチップに設定されたすてきな直交命令が大好きです。
dmckee ---元モデレーターの子猫

2
「if、invokeなどの命令があるようです」-これらはマクロ(「MASM」の「M」)であり、アセンブラーがサポートしていても、使用する必要はありません。
ChrisW、2009

3
その65番目の賛成票に質問をするのは難しい決定でした、64はとても美しい数字です。。。
735テスラ2014年

回答:


40

始まるMASM32とでそちらからFASM。しかし、MASMを楽しむことができます。


MASMから聞いたことがあります。私が誤解していない場合は、「高レベル」の機能がたくさんあり、解読されたコードを見るとわかりません。これが理にかなっている場合、私はほとんどの逆アセンブラー出力コードとまったく同じものでプログラムする必要があります。
貪欲なエリジウム2009

1
これは基本的にはオペコードを書くようなものですが、実際には意味がありません。MASM32の学習は、デバッガーでコードがどのように見えるかを理解するのに役立ちます。こちらもOllyDbgをチェックアウトしたい:ollydbg.de
正午シルク

7
あなたはアセンブリを理解していません。あなたはそれを理解する必要があります。オペコードは数値です。デバッガーは、オペコードをその命令に解決しようとします(難しい場合もあります)。基本的な手順を理解する必要があります。MASMの学習は、これを行うのに役立ちます。これ以上言う必要はありません。
正午シルク

5
MASMの機能があるからといって、MASMの機能をすべて使用する必要はありません。そうすればもっと読みたいと思うなら、好きなだけ読みにくくすることができます。
JasonTrue 2009

3
MASMは、その癖、バグ、およびいわゆる高レベルの機能を備えているため、アセンブリプログラマー(初心者とエキスパートの両方)を混乱させるために、私が考えている以上に多くのことを行ってきました。
IJケネディ

44

私はこれを何度もやってきて、これを続けています。あなたの主な目的がアセンブラーを読むことでなく書くことであるこの場合、私はこれが当てはまると思います。

独自の逆アセンブラーを作成します。次に大きい逆アセンブラを作成するためではなく、これは厳密にあなたのためです。目標は、命令セットを学ぶことです。新しいプラットフォームでアセンブラーを学習しているかどうかは、以前知っていたプラットフォームのアセンブラーを思い出します。ほんの数行のコードから始めて、たとえばレジスタを追加し、バイナリ出力を逆アセンブルすることと、入力側にますます複雑な命令を追加することとの間にピンポンを実行します。

1)特定のプロセッサの命令セットを学ぶ

2)上記のプロセッサ用にアセンブルでコードを記述する方法のニュアンスを学び、すべての命令のすべてのオペコードビットを小刻みに動かせるようにする

3)その命令セットを使用して生計を立てているほとんどのエンジニアよりも、命令セットをよりよく学ぶ

あなたの場合、いくつかの問題がありますが、通常ARM命令セットから始めることをお勧めします。今日出荷されているARMベースの製品は他のどの製品よりも多くなっています(x86コンピュータを含む)。しかし、現在ARMを使用していて、スタートアップコードやARMを認識している他のルーチンを作成するのに十分なアセンブラーを知らない可能性は、実行しようとしていることに役立つ場合とそうでない場合があります。ARMが最初に重要になる2番目の理由は、命令の長さが固定サイズで整列されているためです。x86のような可変長命令を分解することは、最初のプロジェクトとして悪夢になる可能性があり、ここでの目標は、研究プロジェクトを作成しないように命令セットを学ぶことです。3番目のARMはよくできた命令セットであり、レジスターは同等に作成され、個々の特別なニュアンスはありません。

したがって、どのプロセッサから始めたいかを理解する必要があります。まずmsp430またはARM、次にARMが最初または2番目、次にx86の混乱をお勧めします。どのプラットフォームを使用する場合でも、使用する価値のあるプラットフォームには、命令セットとオペコード(機械語のビットとバイト)のエンコードを含むデータシートまたはプログラマーリファレンスマニュアルがベンダーから無料で提供されています。コンパイラーが何をするか、またコンパイラーが苦労する必要のないコードをどのように書くかを学ぶために、いくつかの命令セットを理解し、各最適化を行う各コンパイラーで各命令セットに同じ高レベルのコードがどのように実装されるかを確認するのは良いことです。設定。コードを最適化したくはなく、1つのコンパイラ/プラットフォームでは改善されたが、他のコンパイラ/プラットフォームでは改善されたことがわかるだけです。

ああ、可変長の命令セットを逆アセンブルするために、単に最初から始めて、ARMのように4バイトワードごとに、またはmsp430のように2バイトごとに線形にメモリを逆アセンブルするのではなく(msp430には可変長命令がありますが、割り込みベクトルテーブルのエントリポイントから開始すると、メモリを直線的に移動します)。可変長の場合、ベクトルテーブルまたはプロセッサの起動方法に関する知識に基づいてエントリポイントを見つけ、コードを実行順に追跡する必要があります。使用されているバイト数を知るには、各命令を完全にデコードする必要があります。その後、命令が無条件分岐でない場合は、その命令の次のバイトが別の命令であると想定します。また、可能なすべての分岐アドレスを格納し、それらがより多くの命令の開始バイトアドレスであると想定する必要があります。一度成功したとき、バイナリを何度か通過しました。エントリポイントから始めて、そのバイトを命令の開始としてマークし、無条件分岐に到達するまでメモリを介して線形にデコードしました。すべての分岐ターゲットは、命令の開始アドレスとしてタグ付けされました。新しいブランチターゲットが見つからなくなるまで、バイナリを何度も通過しました。いつでも3バイトの命令を見つけたが、何らかの理由で2番目のバイトに命令の先頭としてタグ付けした場合は、問題があります。コードが高レベルのコンパイラーによって生成された場合、コンパイラーが何か悪しくない限り、これは起こらないはずです。コードに手書きのアセンブラ(古いアーケードゲームなど)が含まれている場合、条件付き分岐が発生し、r0 = 0の後にゼロでない場合はジャンプが続くなど、決して発生しない可能性があります。続行するには、バイナリから手動で編集する必要がある場合があります。私の想定しているあなたの当面の目標はx86になると思いますが、問題はないと思います。

x86がターゲットの場合、mingw32はWindowsでgccツールを使用する簡単な方法です。そうでない場合は、mingw32とmsysは、binutilsとgccソースからクロスコンパイラを生成するための優れたプラットフォームです(通常は非常に簡単です)。mingw32には、大幅に高速なプログラムのようなcygwinに比べていくつかの利点があり、cygwin dllの地獄を回避できます。gccとbinutilsを使用すると、Cまたはアセンブラーで記述してコードを逆アセンブルできます。また、3つのうちいずれか1つまたはすべてを実行する方法を示すWebページが読める数よりも多くなっています。可変長の命令セットでこれを行う場合は、逆アセンブラを含むツールセットを使用することを強くお勧めします。たとえばx86用のサードパーティの逆アセンブラは、正しく逆アセンブルされているかどうか本当にわからないため、使用するのが難しいでしょう。これの一部はオペレーティングシステムにも依存します。逆アセンブラがより正確な作業を実行できるように、データからの情報マーキング指示を含むバイナリ形式にモジュールをコンパイルすることが目標です。この主な目的の他の選択肢は、検査のためにアセンブラーに直接コンパイルできるツールを用意し、バイナリ形式にコンパイルすると同じ命令が作成されることを期待することです。

あなたの質問への短い(大丈夫少し短いER)答え。逆アセンブラを記述して、命令セットを学習します。ARMのようなRISCyで簡単に習得できるものから始めます。1つの命令セットがわかったら、多くの場合数時間で、3番目の命令セットを使用すると、構文がデータシート/リファレンスマニュアルを使用してコードをすぐに書き始めることができます。使用に値するすべてのプロセッサには、オペコードのビットおよびバイトまでの命令を説明するデータシートまたはリファレンスマニュアルがあります。ARMのようなRISCプロセッサとx86のようなCISCについて、違いを感じ取れるように十分に学びます。2つの命令に対する3つのオペランド命令など。高レベルのコードを調整すると、複数のプロセッサ用にコンパイルして、出力を比較します。あなたが学ぶ最も重要なことは、高レベルのコードがどれほど上手く書かれていても、コンパイラの品質と、行われた最適化の選択が実際の命令に大きな違いをもたらすということです。llvmとgcc(binutilsを使用)をお勧めします。どちらも作成できません。優れたコードですが、それらはマルチプラットフォームとマルチターゲットであり、どちらもオプティマイザを備えています。どちらも無料で、さまざまなターゲットプロセッサのソースからクロスコンパイラを簡単に構築できます。


返信いただきありがとうございます。しかし、逆アセンブラの書き方すらわかりません。
貪欲なエリジウム2009

8
「独自の逆アセンブラーを作成する」-同意します。それが、私が最もよく学んだ方法です。(しかし、「逆アセンブラの書き方すら知らない」とはどういうことですか?)LOL。
slashmais

一緒に行きます!MSP430とその本を購入したばかりです... :)
Pepe

1
私はいくつかのMSP430の例を持ってgithub.com/dwelch67など、ASMを学習含めて実験用のプラスいくつかの命令セットシミュレータを
old_timer

私は本当に、このアイデアが本当に好きです。
ミリースミス

33

手作業で作成するアセンブリとコンパイラによって生成されるアセンブリは、多くの場合、上位レベルから見ると大きく異なります。もちろん、プログラムの内部は非常によく似ています(a = b + c結局のところ、エンコードする方法は非常に多くあります)が、何かをリバースエンジニアリングしようとしても問題はありません。コンパイラが追加されますトンであっても、単純な実行ファイルに定型コードのを:アセンブリ内の手によって書かれた場合、それは約100バイトですが、私は比較最後の時間を、GCCでコンパイルの「Hello World」は、4kBの程度でした。Windowsではさらに悪い:前回比較したとき(確かに、これは前世紀でした))当時選択したWindowsコンパイラで生成できる最小の「Hello World」は52kBでした。通常、このボイラープレートは一度でも1回しか実行されないので、プログラムの速度にはあまり影響しません-上で述べたように、プログラムのコア、ほとんどの実行時間が費やされる部分は、コンパイルされているか手で書かれました。

結局のところ、これはエキスパートアセンブリプログラマーとエキスパートディスアセンブラーが2つの異なる専門分野であることを意味します。通常、それらは同じ人物に存在しますが、実際には別々であり、優れたアセンブリコーダーになる方法を学習しても、リバースエンジニアリングを学ぶのにそれほど役立ちません。

やりたいことは、IntelAMDのIA-32とAMD64(どちらも一緒にカバーされています)のアーキテクチャマニュアルを入手し、命令とオペコードの初期のセクションを確認することです。アセンブリ言語の基本を理解するためだけに、アセンブリ言語に関するチュートリアルを1、2度読んでください。次に、小さな興味のあるサンプルプログラムとそれを逆アセンブルする:プログラムの制御フローをステップ実行し、それが何をしているかを理解しようとします。パッチを適用して他のことを実行できるかどうかを確認してください。次に、別のプログラムでもう一度試し、より有用な目標を達成するために十分に快適になるまで繰り返します。リバースエンジニアリングコミュニティによって作成された「クラックメ」のようなものに興味があるかもしれません。これらは、リバースエンジニアリングに興味がある人が実際に試してみて、うまくいけば途中で何かを学べるようにするための課題です。難易度は、基本的なもの(ここから開始!)から不可能までさまざまです。

何よりも、練習するだけです。他の多くの分野と同様に、リバースエンジニアリングを使用することで、練習は完璧になります...または少なくともそれ以上


高級言語で何かをコンパイルすると、アセンブリで直接コーディングされた場合には不要な大量の「ガベージ」コードが生成されることを知っています。また、エキスパートアセンブリプログラマーとエキスパートディスアセンブラーには違いがあることも理解しています。しかし、他のほとんどすべてについて同じことが言えます。
貪欲なエリジウム2009

3
私の懸念は、理論的には論文を読んでそれらの意味を理解することはできましたが、自分で書き始めるまでは、本当に理解できるとは思えません。コードの小さな部分を変更することから始められるとおっしゃっていますが、そのためにはまず、たとえばIDAプロが使用するアセンブリの「フレーバー」の種類を知る必要があります。
貪欲なエリジウム2009

また、MSVC ++はインラインアセンブリコードに何を使用しますか?MASM?
貪欲なエリジウム

15

私はほとんどの答えの粒度に逆らって、MIPS RISCアーキテクチャのKnuthのMMIXバリアントを推奨します。x86やARMアセンブリ言語ほど実用的ではありませんが(最近の現実の仕事では、それら自体が非常に重要であるわけではありません... ;-)、Knuthの最新の魔法のロックを解除しますアルゴリズムとデータ構造の深い低レベル理解に関する史上最高の傑作のバージョン-TAOCP、「The Art of Computer Programming」。私が引用した2つのURLからのリンクは、この可能性を探るのに最適な方法です。


12

(あなたのことは知りませんが、私は組み立てに興奮していました)

アセンブリを試すための簡単なツールがすでにPCにインストールされています。

[スタート]メニュー-> [ファイル名を指定して実行]に移動し、次のように入力しますdebug

デバッグ(コマンド)

debugは、DOS、MS-DOS、OS / 2およびMicrosoft Windows(x64ではなくx86バージョンのみ)のコマンドで、プログラムdebug.exe(または古いバージョンのDOSのDEBUG.COM)を実行します。デバッグは、アセンブラー、逆アセンブラー、または16進ダンププログラムとして機能し、ユーザーがインタラクティブにメモリの内容(アセンブリ言語、16進またはASCII)を調べ、変更を加え、COM、EXE、およびその他のファイルタイプを選択的に実行できます。また、特定のディスクセクター、I / Oポート、メモリアドレスにアクセスするために使用されるいくつかのサブコマンドがあります。MS-DOSデバッグは 16ビットプロセスレベルで実行されるため、16ビットコンピュータプログラムに限定されます。FreeDOS Debugには、32ビットDPMIプログラムもサポートする「DEBUGX」バージョンがあります。

チュートリアル:


IDA Pro(またはOllyDbg)に 表示されるコードを理解したい場合は、コンパイルされたコードの構造を理解する必要があります。私は本「Reversing:Secrets of Reverse Engineering」をお勧めします

debugアセンブリの学習を始めたとき(15年前)に数週間実験しました。は基本マシンレベル
debug機能することに注意してください。高レベルのアセンブリコマンドはありません。

そして今、簡単な例:

与えるaアセンブリコードを書き始めるために-プログラムの下に入力し-そして最終的に与えg、それを実行します。

代替テキスト


(レジスタが設定されている場合、レジスタにINT 21格納されているASCII文字を画面に表示します- プログラムを終了します)DLAH2INT 20


「g」を入力する前に、ctrl-cを押す必要がありました。
ericp 2009

2
@ ericp、ctrl-cを押す必要はありません。たとえば、aアセンブリコードの記述を開始するには、&と入力します。[Enter]キーを2回押すと、アセンブリモードが終了します。g&[入力]して実行します(デフォルトではオフセット100)。
Nick Dandoulakis

それは実際にスタックオーバーフローを引き起こしますか、それとも単にそれを画面に書き込みますか?
Janus Troelsen

1
@user、それはこのサイトの名前を書き込むだけです:-)
Nick Dandoulakis

@JanusTroelsenこれらの数値(53、74、61など)は、「S」「t」「a」のASCIIコードです...各Int21呼び出しは、一度に1文字を印刷します!これが、アセンブリが速くない理由です:)
doug65536

8

私はハッキング:搾取の芸術がこのトピックへの興味深く有用な方法であることに気づきました...私がこれまで直接知識を使用したことがあるとは言えませんが、それが本当に私がそれを読んだ理由ではありません。それはあなたのコードがコンパイルする命令のより豊かな感謝をあなたに与える、それは時々微妙なバグを理解するのに有用であった。

タイトルに気を取られないでください。この本の最初の部分のほとんどは、エリックレイモンドという言葉の意味での「ハッキング」です。難しい問題を解決するための創造的で、驚くほど、卑劣な方法です。私(そして多分あなたも)は、セキュリティの側面にそれほど関心がありませんでした。


7

私は、少なくとも最初は、プログラムをアセンブリで記述しようとすることに焦点を当てません。x86(Windowsを使用しているため、そうだと思います)を使用している場合、奇妙な特殊なケースがたくさんあり、学ぶのは無意味です。たとえば、多くの命令は、明示的に指定しないレジスタを操作していることを想定しており、他の命令は一部のレジスタでは機能しますが、他のレジスタでは機能しません。

私はあなたが基本を理解しているあなたの意図されたアーキテクチャについて十分に学び、それからただ飛び込んであなたのコンパイラの出力を理解しようとするでしょう。自分の腕のIntelのマニュアルコンパイラの出力に、ちょうどダイビングの権利。対象のコードを小さな関数に分離して、全体を確実に理解できるようにします。

基本は次のように考えます。

  • レジスタ:そこにはいくつありますか、それらの名前は何ですか、そしてそれらのサイズは何ですか?
  • オペランドの順序:add eax, ebx「eaxにebxを追加して結果をeaxに保存する」ことを意味します。
  • FPU:浮動小数点スタックの基本と、FPとの変換方法を学びます。
  • アドレッシングモード:[ベース+オフセット*乗数]、ただし乗数は1、2、または4(またはおそらく8?)
  • 呼び出し規約:パラメータは関数にどのように渡されますか?

多くの場合、コンパイラーが何を出力するかは意外です。コンパイラが一体これが良いアイデアだと思った理由を理解するパズルにしてください。それはあなたにたくさん教えます。

また、Agner Fogのマニュアル、特に取扱説明書が記載されているマニュアルを身に付けると役立つでしょう。最新のプロセッサで直接定量化するのは困難ですが、各命令の概算コストがわかります。しかし、たとえば、コンパイラーがidiv命令の発行を回避するために、これまでにない方法を説明するのに役立ちます。

私の他の唯一のアドバイスは、選択肢がある場合は常にAT&TではなくIntel構文を使用することです。私はこの点でかなり中立でした。その日までに、2つの命令が完全に異なることに気づきました(たとえば、movslqAT&T構文はmovsxdIntel構文です)。マニュアルはすべてIntel構文を使用して記述されているため、そのまま使用してください。

幸運を!


3

私は非常にコンパクトな32ビットアーキテクチャであるMIPSの学習を始めました。これは簡略化された命令セットですが、初心者にはわかりやすいものです。複雑さに煩わされることなく、アセンブリの仕組みを理解することができます。あなたも、あなたはMIPSのコードをコンパイルすることができます素敵なの少しのIDEをダウンロードすることができます:clickyを あなたはそれのこつを得れば、私はより複雑なアーキテクチャに移行する方がはるかに簡単になると思います。少なくとも私はそう思っていました:)この時点で、メモリの割り当てと管理、ロジックフロー、デバッグ、テストなどの基本的な知識が身に付きます。


3

デバッグを使用するという提案は楽しいものです。これを使用すると、多くの巧妙なトリックを実行できます。ただし、最新のオペレーティングシステムの場合、16ビットアセンブリを学習することは、あまり役に立ちません。代わりに、ntsd.exeの使用を検討してください。これはWindows XPに組み込まれています(残念ながら、Server 2003以降で使用されていました)。これは、非常に広く利用されているため、学ぶのに便利なツールです。

とはいえ、XPの元のバージョンには多くのバグがあります。本当にそれを使用したい場合(または、cdb、またはwindbg、これらは本質的に同じコマンド構文とデバッグバックエンドを持つ異なるインターフェースです)、無料のWindowsデバッグツールパッケージをインストールする必要があります。

そのパッケージに含まれているdebugger.chmファイルは、異常な構文を理解しようとするときに特に役立ちます。

ntsdの素晴らしい点は、近くにあるどのXPマシンにもそれをポップアップし、それを使用してアセンブリまたは逆アセンブルできることです。/ great / X86アセンブリ学習ツールを作成します。たとえば(dosプロンプトでインラインなのでcdbを使用しますが、それ以外は同じです):

(シンボルエラーは無関係なのでスキップされました-また、この書式設定が機能することを願っています。これが私の最初の投稿です)

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

また、IDAで遊んでいる間は、Chris EagleによるIDA Pro Bookを必ずチェックしてください(StackOverflowでは、最初の投稿に3つ以上のリンクを投稿させたくないため、リンクを解除しています)。それはそこに最高のリファレンスです。


1
クリスイーグルの本の+1。Gottaは、r00tのSk3wlに愛を込めました;)
mrduclaw

3

私は最近コンピュータシステムのクラスを受講しました。トピックの1つは、ハードウェアと通信するツールとしてのアセンブリでした。

私にとって、コンピューターシステムがどのように機能するかの詳細を理解しなければ、組み立ての知識は完全ではなかったでしょう。これを理解すると、あるプロセッサアーキテクチャでのアセンブリ命令が優れているが、別のアーキテクチャではひどい理由が新たに理解されます。

これを踏まえて、私はクラスの教科書を勧める傾向があります。

コンピュータシステム:プログラマの視点

コンピュータシステム:プログラマの視点
(ソース:cmu.edu

それはx86アセンブリをカバーしますが、本はそれよりはるかに広いです。プロセッサのパイプライン処理とキャッシュとしてのメモリ、仮想メモリシステムなどをカバーしています。これはすべて、特定のフィーチャー用にアセンブリを最適化する方法に影響を与える可能性があります。


2

逆アセンブラーによって出力され、アセンブラーによって理解される(入力として使用できる)ASCII化されたオペコードニーモニック(およびそのパラメーター)を学びたいと思います。

任意のアセンブラ(MASMなど)で実行できます。

そして/またはあなたはそれについての本を読む方が良いかもしれません(SOで推薦された本がありました、私はどれを覚えていません)。


2

Windowsで他の開発作業をしていますか?どのIDEで?VSの場合、逆アセンブルされたコードを読み取るだけの追加のIDEは必要ありません。アプリをデバッグ(または外部アプリにアタッチ)してから、逆アセンブリウィンドウを開きます(デフォルトの設定では、Alt + 8です)。通常のコードの場合と同じように、メモリ/レジスタをステップアンドウォッチします。また、レジスタウィンドウを開いたままにすることもできます(デフォルトではAlt + 5)。

Intelは、基本的なアーキテクチャ(レジスタ、プロセッサユニットなど)の調査と完全な命令リファレンスの両方を提供する無料のマニュアルを提供しています。アーキテクチャが成熟し、より複雑になるにつれて、「基本アーキテクチャ」のマニュアルはますます読みにくくなります。古いバージョンを手に入れることができる場合は、開始するのに最適な場所があるはずです(P3のマニュアルでさえ基本的な実行環境は同じです)。

あなたが本に投資したいと思っているなら、ここに素敵な紹介文があります。アマゾンで「x86」を検索すると、他にも多くのものが得られます。ここで別の質問から他のいくつかの指示を得ることができます

最後に、あなたはからかなり恩恵を受けることができます読んで いくつかの ロー - レベルのブログを。これらのバイトサイズの情報ビットは、個人的には私にとって最適です。


2

これは必ずしも効率的なコードの作成に役立つとは限りません。

i86 opコードは多かれ少なかれ「レガシー」フォーマットであり、そこには膨大な量のコードとそこにあるWindowsとLinuxの実行可能なバイナリのために存続しています。

それはラテン語で書く古い学者のようで、ガリレオのようなイタリア人の話者はラテン語で書くでしょうし、彼の論文はコペルニクスのようなポーランド人の話者でも理解できるでしょう。nietherは特にラテン語が得意でしたが、これは依然として最も効果的なコミュニケーション方法であり、ラテン語は数学的なアイデアを表現するためのゴミ言語です。

そのため、コンパイラはデフォルトでx86コードを生成し、最新のチップはanceint Opコードを読み取って、並べ替えられた実行、投機的実行、パイプライン処理などを使用して、並列risc命令に変換し、さらに32または64レジスタをフルに活用します。実際には(x86の手順で見られる哀れな8とは対照的です。)

すべての最適化コンパイラはこれが実際に起こることを知っているので、チップが効率的に最適化できることがわかっているOPコードのシーケンスをコード化します-これらのシーケンスの一部は、1990年頃の.asmプログラマにとって非効率に見えるかもしれません。

ある時点で、コンパイラ作成者が費やした数万人年の努力が報われたことを受け入れ、それらを信頼する必要があります。

より効率的なランタイムを実現する最も簡単で最も簡単な方法は、インテルC / C ++コンパイラーを購入することです。彼らはefficeintコンパイラーのためのニッチな市場を持っています、そして彼らは内部で何が起こっているかについてチップ設計者に尋ねることができるという利点を持っています。


あなたの話は、CISCプロセッサが内部的にRISCプロセッサになったことを幾分示唆しています。私は誤解しているかもしれませんが、これは単に真実ではありません。そして哀れな8?最新のプロセッサー(たとえば、1999年以降)には、さらに多くのものが含まれています:10 gpr:EAX-EFLAGS、80ビットFP0-FP7、64ビットMMX0-MMX7、128ビットXMM0-XMM7、セグメント:CS-GS、スペシャル:CR0-CR4 、DR0-DR7、TR3-TR7、GDTR、IDTR、LDTR、MSR、およびx86-64ではR8-R15。これらすべてがring-3からアクセスできるわけではありませんが、ほとんどは最近(2006年以降)のGCC / VC ++コンパイラーで使用されています。完全に「哀れな8」よりも少し多い;)。
アベル

2

あなたがやりたいことをするために、私はIntel Instruction Set Reference(私が使用したものとは正確ではないかもしれませんが、十分に見える)とVisual Studioで記述したいくつかの単純なプログラムを取り、IDAPro / Windbgに投げ始めました。自分のプログラムを拡張したときcrackmesのソフトウェアは役に立ちました。

Windowsでのプログラムの実行方法について、ある程度の基本的な知識があることを前提としています。しかし、実際には、アセンブリを読み取るために、学習する必要がある命令とそれらの命令のいくつかのフレーバーしかありません(たとえば、jump命令があり、jumpには、jump-if-equal、jump-if-ecx-is-zeroのようないくつかのフレーバーがあります、など)。基本的な手順を学ぶと、プログラム実行の要点を取得するのは非常に簡単です。IDAのグラフビューが役立ちます。Windbgを使用してプログラムをトレースしている場合は、不明な場合に命令が何を行っているかを理解するのは非常に簡単です。

そのように少し遊んだ後、私はHacker Disassembly Uncoveredを購入しました。一般に、タイトルに「ハッカー」という言葉が含まれる本は避けますが、コンパイルされたコードが逆アセンブルされているように見える方法について、これが本当に詳細に説明されているのがとても気に入りました。彼はまた、コンパイラーの最適化と興味深いいくつかの効率性についても説明します。

それはすべて、プログラムをどれだけ深く理解したいかにもよります。脆弱性を探すターゲットをリバースエンジニアリングしている場合、エクスプロイトコードを記述している場合、または機能についてパックされたマルウェアを分析している場合は、実際に物事を進めるために、特により高度なマルウェアの場合、より多くの立ち上げ時間が必要になります。 )。一方、お気に入りのビデオゲームでキャラクターのレベルを変更できるようにしたいだけの場合は、比較的短時間で問題なく動作するはずです。


1

MIPSは、標準的な教育用アセンブリ言語の1つです。MIPSシミュレーター(スピム)とそのためのさまざまな教材を入手できます。

個人的に、私はファンではありません。IA32が好きです。


MIPSは素晴らしいです。68000も同様です。68000を習得すれば、MAMEで実行するバイナリを作成できます。:-)
Nosredna

1

私の個人的なお気に入りは、主にマルチプラットフォームであり、MMX、SSE、64ビットをコンパイルするため、NASMです...

簡単なCソースファイルをgccでコンパイルし、アセンブラー命令をgcc形式からNASM形式に「トランスコーディング」し始めました。次に、コードの小さな部分を変更し、それによってもたらされるパフォーマンスの向上を確認できます。

NASMのドキュメントは本当に完全です。本やその他のソースから情報を検索する必要はありませんでした。




0

実際に目標を達成するには、現在のIDEから始めることを検討してください。通常は逆アセンブラーウィンドウなので、コードを1ステップで実行できます。通常、レジスタを表示してメモリ領域を調べるための何らかのビューがあります。

最適化されていないc / c ++コードの調査は、コンパイラーがソース用に生成する種類のコードへのリンクを構築するのに役立ちます。一部のコンパイラには、コードに機械語命令を挿入できるようにするASMの予約語があります。

私のアドバイスは、しばらくの間、この種のツールをいじって、足を濡らしてから、ステップアップすることです。ダウン?あなたが実行しているプラ​​ットフォームでのアセンブラコードにまっすぐに。

すばらしいツールはたくさんありますが、最初は急な学習曲線を避けるために、もっと楽しいかもしれません。


0

マイクロコントローラー開発キット(Motorola HC12)と厚いデータシートを使用してアセンブリを学びました。


0

オフトピックですが、あなたはWindowsプログラマーなので、MSILを学ぶための時間をより適切に使用したり、時間を有効に活用したりすることはできません。いいえ、それはアセンブリではありませんが、おそらくこの.NET時代にはより関連性があります。


0

アセンブリーを知ることはデバッグに役立ちますが、コードを最適化するためにそれを使用することにそれほど興奮しません。最近のコンパイラは通常、最近の人間の最適化にはるかに優れています。


うーん。自分でかなり多くの追加のコーディングアセンブリを作成することもできますが、コンパイラーを使用するには、以前よりも多くの作業が必要です。
Nosredna 2009

0

xorpd x86 Assemblyビデオコースをチェックしてください。(私はそれを書きました)。コース自体は有料ですが、演習はgithubのオープンソースです。プログラミングの経験があれば、演習だけで作業してすべてを理解できるはずです。

コードはWindowsプラットフォーム用であり、Fasmアセンブラを使用して記述されていることに注意してください。コースと演習には高レベルの構成は含まれていませんが、必要に応じて、Fasmを使用して非常に複雑なマクロを作成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.