私はアセンブリ言語を学ぶことにしました。これを行う主な理由は、逆アセンブルされたコードを理解できることと、コードのより効率的な部分を(たとえば、c ++を介して)作成できること、コードケーブなどの操作を行うことができることです。 、だから、私が言及する目的のために、どのように始めるべきですか?どのようなアセンブリを学ぶ必要がありますか?最初に簡単なプログラム(電卓など)を実行することで学習したいのですが、IDA Proなどで表示されるコードを理解できるように、目標自体はそれに慣れることです。
私はウィンドウを使用しています(違いがあれば)。
編集:だから、誰もがMASMに向かっているようです。高度な機能を備えているという点は理解できますが、すべてアセンブリコードプログラマーに適していますが、それは私が探しているものではありません。人気のあるデアセンブラー(IDAなど)に表示されないif、invokeなどの命令があるようです。したがって、可能であれば、私が聞きたいのは、「一般的な」アセンブリプログラマーだけでなく、私が求めている目的(IDAで逆アセンブルされたexeのコードを読む)にASMを使用する人の意見です。
編集:OK。私はすでにアセンブリを学んでいます。私はMASMを学んでいますが、私にとって重要ではない高レベルのものを使用していません。私が今していることは、c ++の__asmディレクティブでコードを試すことです。そのため、MASMを使用してすべてをゼロから実行する必要がある場合よりもずっと速く試すことができます。
MASM32 で開始し、そこから [〜#〜] fasm [〜#〜] を見てください。しかし、MASMを楽しんでください。
私はこれを何度も行ってきましたが、これを続けています。あなたの主な目標がアセンブラーを読んで書くことではないこの場合、私はこれが当てはまると思います。
独自の逆アセンブラを作成します。次に優れた逆アセンブラを作成するためではなく、これは厳密にあなたのためです。目標は、命令セットを学習することです。新しいプラットフォームでアセンブラーを学んでいるかどうか、かつて知っていたプラットフォームのアセンブラーを覚えているかどうか。ほんの数行のコードから始めて、たとえばレジスタを追加し、バイナリ出力を逆アセンブルし、入力側にますます複雑な命令を追加することの間でピンポンを実行します。
1)特定のプロセッサの命令セットを学ぶ
2)すべての命令のすべてのオペコードビットを小刻みに動かすことができるように、前述のプロセッサのアセンブルでコードを記述する方法のニュアンスを学ぶ
3)その命令セットを使用して生計を立てているほとんどのエンジニアよりも、命令セットをよく学習します。
あなたの場合、いくつかの問題があります。通常、ARM命令セットを開始することをお勧めします。他のどの製品よりも多くのARM (x86コンピューターを含む)。しかし、あなたがARMを使用しており、起動コードまたはARMを知っている他のルーチンを書くのに十分なアセンブラーを知らないARM最初の2番目の重要な理由は、命令の長さが固定サイズで整列しているためです。x86のような可変長命令の分解は悪夢になる可能性があります最初のプロジェクトとして、ここでの目標は、研究プロジェクトを作成しないように命令セットを学習することです。3番目のARMはよくできた命令セットで、レジスタは等しく作成され、個々の特別なニュアンスはありません。
そのため、どのプロセッサを使用するかを把握する必要があります。私は、msp430またはARM最初、次にARM最初または2番目、次にx86のカオスを推奨します。どのプラットフォームでも、使用する価値のあるプラットフォームにはデータシートまたはプログラマーは、命令セットおよびオペコード(機械語のビットとバイト)のエンコードを含む、ベンダーから無料のマニュアルを参照します。いくつかの命令セットを知って、各最適化設定を使用して各コンパイラで各命令セットに同じ高レベルのコードがどのように実装されているかを確認するのはよいことです。 1つのコンパイラ/プラットフォームではより良いが、他のすべてではより悪い。
ああ、可変長命令セットを逆アセンブルするために、単にARMまたはmsp430のような2バイトごとに可変長命令ですが、割り込みベクトルテーブルのエントリポイントから開始する場合は、メモリを直線的に移動することで取得できます。可変長の場合、ベクトルテーブルまたはプロセッサの起動方法に関する知識に基づいてエントリポイントを検索し、各命令を完全にデコードして、使用されているバイト数を知る必要があり、その命令が無条件分岐でない場合、その命令の後の次のバイトが別の命令であると想定します。よく、それらがより多くの命令のための開始バイトアドレスであると仮定します一度成功したとき、私はバイナリを何度か通過しました。命令の開始としてのtバイトは、無条件分岐に到達するまでメモリを介して線形にデコードされます。すべての分岐ターゲットは、命令の開始アドレスとしてタグ付けされました。新しいブランチターゲットが見つからなくなるまで、バイナリを複数回通過しました。いつでも3バイトの命令を見つけたが、何らかの理由で2番目のバイトを命令の開始としてタグ付けした場合、問題が発生します。コードが高レベルのコンパイラーによって生成された場合、コンパイラーが何か邪悪なことをしない限り、これは起こりません。コードに手書きのアセンブラー(古いアーケードゲームなど)がある場合は、起こりえない条件分岐がある可能性が高いですr0 = 0のような、ゼロでない場合はジャンプが続きます。続行するには、バイナリからこれらを手動で編集する必要がある場合があります。私がx86上にあると思われる当面の目標については、問題があるとは思わない。
Gccツールをお勧めします。x86がターゲットの場合、mingw32はWindowsでgccツールを使用する簡単な方法です。そうでない場合、mingw32とmsysは、binutilsおよびgccソースからクロスコンパイラを生成するための優れたプラットフォームです(一般的に非常に簡単です)。 mingw32にはcygwinに比べていくつかの利点があります。たとえば、プログラムが非常に高速であり、cygwin dllの地獄を回避できます。 gccとbinutilsを使用すると、Cまたはアセンブラーで記述してコードを逆アセンブルできます。また、3つのうちのいずれかまたはすべての実行方法を示すWebページがあります。可変長命令セットを使用してこれを行う場合は、逆アセンブラを含むツールセットを使用することを強くお勧めします。たとえば、x86用のサードパーティの逆アセンブラは、正しく逆アセンブルされたかどうかがわからないため、使用するのが難しいでしょう。これの一部もオペレーティングシステムに依存します。目標は、モジュールをバイナリ形式にコンパイルして、データからの指示情報を含むバイナリ形式にコンパイルし、逆アセンブラがより正確なジョブを実行できるようにすることです。この主な目標の他の選択肢は、検査のためにアセンブラに直接コンパイルできるツールを用意し、バイナリ形式にコンパイルするときに同じ命令を作成することを期待することです。
あなたの質問への短い(まあ少し短い)答え。逆アセンブラを記述して、命令セットを学習します。 ARMのようにRISCyで学びやすいものから始めます。 1つの命令セットを知った後、他の命令セットは数時間ではるかに簡単になります。3番目の命令セットにより、構文のデータシート/リファレンスマニュアルを使用して、すぐにコードの記述を開始できます。使用する価値のあるすべてのプロセッサーには、命令をオペコードのビットとバイトまで説明したデータシートまたはリファレンスマニュアルがあります。 ARMなどのRISCプロセッサーとx86のようなCISCを学習して、すべてのレジスターを通過する必要がある、またはより少ないメモリで直接操作を実行できるなどの違いを感じる3つのオペランド命令と2つのオペランド命令など、高レベルコードを調整するときは、複数のプロセッサ用にコンパイルし、出力を比較します。最も重要なことは、高レベルコードがどれほど優れていてもコンパイラの品質と最適化の選択により、実際の命令に大きな違いが生じます.llvmとgcc(binutilsを使用)、greatコードを生成しないことをお勧めしますが、これらはマルチプラットフォームとマルチターゲットであり、両方とも両方とも無料で、さまざまなターゲットプロセッサのソースからクロスコンパイラを簡単に構築できます。
手作業で作成するアセンブリとコンパイラによって生成されるアセンブリは、高レベルから見ると非常に異なることがよくあります。もちろん、プログラムの内部は非常によく似ています(結局、a = b + c
をエンコードする方法は非常に多くあります)が、何かをリバースエンジニアリングしようとするときの問題ではありません。コンパイラは、ボイラープレートコードのtonを単純な実行可能ファイルに追加します。前回比較したとき、GCCによってコンパイルされた「Hello World」は約4kBでしたが、 Assemblyで手書きで書かれたのは約100バイトです。 Windowsの場合はさらに悪い:前回(確かに、これは最後century)でした。生成する選択は52kBでした!通常、このボイラープレートは1回しか実行されないため、プログラムの速度にはあまり影響しません。前述のように、プログラムのコアは、実行時間の大半を費やしている部分であり、コンパイルされているか手で書かれた。
つまり、エキスパートアセンブリプログラマーとエキスパートディスアセンブラー2つの異なる専門分野です。一般的に同じ人に見られますが、実際には別々であり、優れたアセンブリコーダーになる方法を学習しても、リバースエンジニアリングを学ぶのにそれほど役立ちません。
あなたがやりたいことは、IA-32とAMD64(両方とも一緒に扱われます)アーキテクチャマニュアルを Intel と [〜#〜] amd [〜#〜] から入手することです。命令とオペコードに関する初期のセクションをご覧ください。アセンブリ言語の基本を理解するために、アセンブリ言語のチュートリアルを1つか2つ読んでください。次に、興味のあるsmallサンプルプログラムを取得し、それを逆アセンブルします。その制御フローをステップ実行し、その実行内容を理解してください。他のことをするためにパッチを適用できるかどうかを確認します。その後、別のプログラムで再試行し、より便利な目標を達成するのに十分なほど快適になるまで繰り返します。リバースエンジニアリングコミュニティが作成した「クラック」などに興味があるかもしれません。リバースエンジニアリングに興味のある人にとっては、試してみて、できれば何かを習得することが困難です。難易度は基本的なもの(ここから始めましょう!)から不可能なものまであります。
とりわけ、必要なのはpracticeだけです。他の多くの分野と同様に、リバースエンジニアリングでは、練習が完璧になります...または少なくともbetter。
私はほとんどの答えの粒子に反して、Knuthの [〜#〜] mmix [〜#〜] MIPS RISCアーキテクチャのバリアントを推奨します。 x86やARMアセンブリ言語(最近のほとんどの実際の仕事ではそれほど重要ではない... ;-)ほど実用的ではありませんが、アルゴリズムとデータ構造の深い低レベルの理解に関する史上最高の傑作のKnuthの最新バージョンの魔法を解き放ちます- [〜#〜] taocp [〜#〜] 、 " 「コンピュータプログラミングの芸術」。私が引用した2つのURLからのリンクは、この可能性を模索するための素晴らしい方法です。
Hacking:The Art of Exploitation は、このトピックに興味深く有用な方法であることがわかりました...知識を直接使用したことがあるとは言えませんが、だからといってそれを読んだわけではありません。これにより、コードのコンパイル先の命令をより深く理解でき、微妙なバグを理解するのに役立つことがあります。
タイトルに惑わされないでください。本の最初の部分のほとんどは、エリック・レイモンドの言葉の意味での「ハッキング」です。創造的で、驚くべき、ほとんど巧妙な方法で難しい問題を解決します。私(そしておそらくあなた)は、セキュリティの側面にあまり興味がありませんでした。
少なくとも最初は、アセンブリでプログラムを作成しようとはしません。 x86を使用している場合(Windowsを使用しているため、これを使用していると思われます)、学習するのは無意味な奇妙な特殊なケースがたくさんあります。たとえば、多くの命令は、明示的に名前を付けていないレジスタを操作していることを前提としており、他の命令は一部のレジスタでは機能しますが、他のレジスタでは機能しません。
目的のアーキテクチャについて十分に学び、基本を理解したら、すぐに飛び込んでコンパイラの出力を理解しようとします。 Intelマニュアル で準備を整え、コンパイラの出力に飛び込みます。目的のコードを小さな関数に分離し、全体を確実に理解できるようにします。
基本は次のように考えます。
add eax, ebx
は、「ebxをeaxに追加し、結果をeaxに保存する」ことを意味します。多くの場合、コンパイラが出力するものは驚くでしょう。なぜコンパイラがこれが良いアイデアだと思ったのかを理解するパズルにしましょう。それは多くを教えてくれます。
また、おそらく Agner Fogのマニュアル で自分自身を武装するのに役立つでしょう。各命令がどれほど高価かを教えてくれますが、最新のプロセッサで直接定量化するのは難しいです。しかし、たとえば、コンパイラがidiv
命令の発行を回避するために道を遠ざけている理由を説明するのに役立ちます。
私の他の唯一のアドバイスは、選択肢がある場合は常にAT&TではなくIntel構文を使用することです。私はこの点についてはかなり中立でしたが、2つの間でいくつかの命令がまったく異なることに気がつく日まで(たとえば、AT&T構文のmovslq
はIntel構文のmovsxd
です)。マニュアルはすべてIntel構文を使用して作成されているため、そのままにしてください。
がんばろう!
デバッグを使用するという提案は楽しいもので、多くの巧妙なトリックをそれで行うことができます。ただし、最新のオペレーティングシステムの場合、16ビットアセンブリの学習はあまり役に立たない場合があります。代わりに、ntsd.exeの使用を検討してください。これはWindowsに組み込まれていますXP(残念ながらServer 2003以降ではヤンクされました)。これは非常に広く利用されているため、学ぶのに便利なツールです。
とはいえ、XPの元のバージョンには多くのバグがあります。本当に使用したい場合(またはcdb、windbg、これらは本質的に同じコマンド構文とデバッグの異なるインターフェースです)バックエンド)、無料の windows debugging tools パッケージをインストールする必要があります。
そのパッケージに含まれている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では、最初の投稿で2つ以上のリンクを投稿できないため、リンクは解除されています)。そこから最高のリファレンスを手に入れることができます。
私は最近、コンピューターシステムのクラスを取りました。トピックの1つは、ハードウェアと通信するためのツールとしてのアセンブリでした。
私にとって、アセンブリの知識は、コンピューターシステムがどのように機能するかの詳細を理解しなければ、完全ではなかったでしょう。それを理解すると、あるプロセッサアーキテクチャでのアセンブリ命令が優れているが、別のアーキテクチャではひどい理由が新たに理解できるようになります。
これを考えると、私は私のクラスの教科書をお勧めします:
(ソース: cmu.ed )
それはx86アセンブリをカバーしますが、本はそれよりもはるかに広いです。プロセッサのパイプライン処理、キャッシュとしてのメモリ、仮想メモリシステムなどをカバーしています。これらはすべて、特定の機能に対してアセンブリを最適化する方法に影響を与える可能性があります。
私は、非常にコンパクトな32ビットアーキテクチャであるMIPSを学び始めました。これは命令セットの削減ですが、初心者にとっては簡単に理解できるものです。複雑さに圧倒されることなく、アセンブリの動作を理解することができます。素敵な小さなIDEをダウンロードすることもできます。これにより、MIPSコードをコンパイルできます: clicky より複雑なアーキテクチャに簡単に移行できます。少なくともそれは私が考えたものです:)この時点で、メモリの割り当てと管理、論理フロー、デバッグ、テストなどの基本的な知識が得られます。
Windowsで他の開発作業を行っていますか?どのIDEで? VSの場合、追加のIDEだけで逆アセンブルされたコードを読む必要はありません。アプリをデバッグ(または外部アプリにアタッチ))してから、 逆アセンブリウィンドウ =(デフォルト設定では、Alt + 8です。通常のコードと同じように、メモリ/レジスタをステップアンドウォッチします。レジスタウィンドウを開いたままにしておくこともできます(デフォルトではAlt + 5)。
Intelは無料で manuals を提供し、基本アーキテクチャ(レジスタ、プロセッサユニットなど)の調査と完全な命令リファレンスの両方を提供します。アーキテクチャが成熟し、より複雑になるにつれて、「基本アーキテクチャ」のマニュアルはどんどん読みにくくなります。古いバージョンを手に入れることができれば、おそらく開始するのに良い場所があるでしょう(P3マニュアルでも-彼らはより良い説明と同じです基本実行環境)。
本に投資したいなら、 here はニースの入門テキストです。 Amazonで「x86」を検索すると、他の多くのものが見つかります。別の質問から他のいくつかの指示を得ることができます こちら 。
最後に、 readingsomelow - level ブログからかなりの利益を得ることができます。これらのバイトサイズの情報ビットは、個人的には私にとって最適です。
これは必ずしも効率的なコードを書くのに役立つとは限りません!
i86 opコードは、多かれ少なかれ「レガシー」フォーマットであり、WindowsとLinuxのコードと実行可能なバイナリの膨大な量のために存続しています。
古い学者がラテン語で書いているように、ガリレオのようなイタリア語の話者はラテン語で書き、彼の論文はコペルニクスのようなポーランド語話者が理解できるでしょう。ニーザーはラテン語が特に得意でしたが、これは依然として最も効果的なコミュニケーション方法でした。ラテン語は数学的なアイデアを表現するためのごみの言語です。
そのため、コンパイラはデフォルトでx86コードを生成し、最新のチップはanceint Opコードを読み取り、並べ替えられた実行、投機的実行、パイプライン化などを使用して、それらを並列risc命令に変換します。プロセッサが実際に持っている32または64レジスタの使用(x86命令で見られる哀れな8とは対照的)
現在、すべての最適化コンパイラはこれが実際に起こることを知っているので、チップが効率的に最適化できることを知っているOPコードのシーケンスをコーディングします-これらのシーケンスの一部は1990年頃の.asmプログラマにとって非効率に見えますが。
ある時点で、コンパイラ作成者が費やした数万人の努力が報われたことを受け入れ、それらを信頼する必要があります。
より効率的なランタイムを実現する最も簡単で簡単な方法は、Intel C/C++コンパイラを購入することです。 efficeintコンパイラーのニッチ市場があり、チップ設計者に内部で何が起こっているのかを尋ねることができるという利点があります。
あなたがしたいことをするために、私は Intel Instruction Set Reference (私が使用したものとは異なるかもしれませんが、それは十分に見えます)とVisual Studioで書いたいくつかの簡単なプログラムを取りましたIDAPro/Windbgにそれらを投げ始めました。自分のプログラムを大きくしたとき、 crackmes のソフトウェアが役に立ちました。
Windowsでプログラムがどのように実行されるかについての基本的な理解があることを前提としています。しかし、実際には、アセンブリを読むために、学ぶべき少数の命令とそれらの命令のいくつかのフレーバーがあります(例えば、ジャンプ命令があり、ジャンプは、等しい場合はジャンプ、ecxがジャンプする場合はゼロのようないくつかのフレーバーを持っていますなど)。基本的な手順を学べば、プログラム実行の要点を取得するのは非常に簡単です。 IDAのグラフビューは役立ちます。Windbgを使用してプログラムをトレースしている場合、不明な場合は指示が何をしているのかを簡単に把握できます。
そのように少し遊んだ後、私は Hacker Disassembly Uncovered を購入しました。一般に、タイトルに「Hacker」という単語が含まれる本には近づきませんが、コンパイルされたコードが逆アセンブルされたように見える方法について、この本が本当に詳細に進んだことはとても気に入りました。彼はまた、コンパイラーの最適化と、興味深いいくつかの効率化についても調べています。
それはすべて、プログラムをどれだけ深く理解したいかにもよります。脆弱性を探してターゲットをリバースエンジニアリングしている場合、エクスプロイトコードを記述している場合、または機能を求めてパックマルウェアを分析している場合は、実際に物事を進めるためにより多くの時間を必要とします(特に、より高度なマルウェアの場合) )。一方、お気に入りのビデオゲームでキャラクターのレベルを変更したいだけの場合は、比較的短時間で問題なく実行できるはずです。
逆アセンブラーによって出力され、アセンブラーによって理解される(入力として使用できる)ASCII化されたオペコードニーモニック(およびそのパラメーター)を学習したいと思います。
任意のアセンブラー(MASMなど)が行います。
そして/またはそれについてあなたがそれについて本を読む方が良いかもしれません(SOで推薦された本がありました、私はどれを覚えていません)。
私の個人的なお気に入りはNASMです。これは主にマルチプラットフォームであり、MMX、SSE、64ビットをコンパイルするためです...
私はいくつかの単純なCソースファイルをgccでコンパイルし始め、アセンブラー命令をgcc形式からNASM形式に「トランスコーディング」しました。その後、コードの小さな部分を変更し、それがもたらすパフォーマンスの改善を検証できます。
NASMのドキュメントは本当に完全で、書籍やその他のソースから情報を検索する必要はありませんでした。
標準的な教育用アセンブリ言語の1つにMIPSがあります。 MIPSシミュレーター(spim)とさまざまな教材を入手できます。
個人的には、私はファンではありません。 IA32が好きです。
マイクロコントローラ開発キット(Motorola HC12)と厚いデータシートを使用してアセンブリを学習しました。
xorpd x86 Assembly video course を確認できます。 (私はそれを書きました)。コース自体は有料ですが、演習はgithubでオープンソースです。プログラミングの経験がある場合は、演習だけで作業し、すべてを理解できるはずです。
コードはWindowsプラットフォーム用であり、 Fasmアセンブラー を使用して記述されていることに注意してください。コースと演習には高レベルの構造は含まれていませんが、Fasmを使用して非常に複雑なマクロを作成することもできます。
オフトピックは知っていますが、あなたはWindowsプログラマであるため、MSILを学習するのにあなたの時間をより適切に使用することをお勧めします。いいえ、アセンブリではありませんが、この.NETの時代にはおそらくより関連性があります。
デバッグについてアセンブリを知っていると便利ですが、コードを最適化するためにアセンブリを使用することにあまり興奮しません。最近のコンパイラは、通常、人間を最適化するのに非常に優れています。
ここにはたくさんの良い答えがあります。低レベルのプログラミング、アセンブリなどはセキュリティコミュニティで人気がありますので、始めたらヒントやヒントを探す価値があります。優れた機能もあります x86アセンブリに関するこのようなチュートリアル 。
実際に目標を達成するには、IDEから開始することを検討してください。一般的には逆アセンブラウィンドウなので、コードをシングルステップ実行できます。通常、何らかのビューがあります。レジスタを確認し、メモリ領域を調べることができます。
最適化されていないc/c ++コードを調べると、コンパイラがソース用に生成するコードの種類へのリンクを構築するのに役立ちます。一部のコンパイラには、コードにマシン命令を挿入できるASMの予約語があります。
私のアドバイスは、これらの種類のツールでしばらく遊んで、足を濡らしてからステップアップすることです。ダウン?実行中のプラットフォームでのアセンブラーコードのストレート化。
すばらしいツールはたくさんありますが、最初は急な学習曲線を避けるために、もっと楽しくなるかもしれません。