IT

アセンブリの勉強法 (1/2)

アセンブリ言語は機械語を人間に読みやすいように変換したもので、機械語と1:1で対応しています。アセンブリ言語を理解することはコンピュータの仕組みを理解する上でかなり大切なことです。そこで今回はアセンブリ言語の勉強方法をご紹介致します。

アセンブリとアセンブラの違い

アセンブリ(アセンブリ言語、assembly language)

アセンブリ言語とは、低級プログラミング言語の1つで、機械語にほぼ直接対応するレベルの命令を人間が読み書きできる形で記述できるプログラミング言語のことである。

アセンブリ言語とは – IT用語辞典 Weblio辞書

 アセンブラ(assembler)

アセンブラとは、アセンブリ言語をCPUが理解できる機械語の形に変換するプログラムのことである。

アセンブラとは – IT用語辞典 Weblio辞書

つまり、アセンブリはプログラミング言語で、アセンブラはアセンブリを機械語をコンパイルするプログラムです!

アセンブリを理解するということは、コンピュータの仕組みを理解するということ

アセンブリはコンピュータのメモリ、レジスタ(CPU内の記憶領域)を直接操作します。従って非常に煩雑な操作が伴います。例えばHello WorldをアセンブリとCで比べてみます。

C言語のHello Worldはこれです

printf("Hello World!\n")

一方でアセンブリでは下記のようになります

global _start

section .data                     
message: db 'hello, world!', 10

section .text 
_start:                           
    mov     rax, 1          ; system call number should be stored in rax 
    mov     rdi, 1          ; argument #1 in rdi: where to write (descriptor)?
    mov     rsi, message    ; argument #2 in rsi: where does the string start? 
    mov     rdx, 14         ; argument #3 in rdx: how many bytes to write? 
    syscall                 ; this instruction invokes a system call

出典:low-level-programming/hello.asm at master · Apress/low-level-programming · GitHub

今は分かる必要はありませんが、簡単に説明するとアセンブリではメッセージ(Hello World)をメモリに保存したあとレジスタに移動し、システムコール番号をレジスタに移動し、書き込むバイト数をセットしてからシステムコールをするという煩雑な処理になります。

これをいきなり理解するのは難しいので、

  1. Cの簡単な構文をコンパイルして実行ファイルにする
  2. 逆アセンブルして実行ファイルをアセンブリにする
  3. それを参考にアセンブリを自分でも書けるようにしていく

という3ステップがおすすめの勉強法になります。

これができる本を2冊ご紹介したいと思います。今回は入門編として1冊目をご紹介します

アセンブリ入門におすすめの本

おすすめ本その1:コンピュータハイジャッキング

[éäºåå]ã®ã³ã³ãã¥ã¼ã¿ãã¤ã¸ã£ãã­ã³ã°

この本は下記のような構成になっています

  • 第1章:不正アクセス概要
  • 第2章:準備
  • 第3章:基礎知識
  • 第4章:シェルコード
  • 第5章:バッファオーバーフロー
  • 第6章:コントロールハイジャッキング
  • 第7章:リモートコード実行
  • 第8章:ファイヤーウォールの突破
  • 付録

この本はアセンブリとCを用いて不正アクセスの手法を勉強する本です。この本は大学の教授が書かれており、アセンブリやCを知らない人向けに非常に丁寧に書かれております。アセンブリのコードも1行ずつ何をやっているのかを説明してくれていますし、第3章のところでメモリの構造(テキスト領域、データ領域、ヒープ、スタック)、レジスタの構造についても全く知らない人向けの説明があります。これは今まで読んだ中で最もわかりやすい本の一つです。

第4章以降では、アセンブリとCを用いた不正アクセスについて解説されています。ここでは実際に使えるコードを書きながらアセンブリの知識を深めることができます。Cで実装された脆弱性のあるTCPサーバーを、アセンブリで書いたコードで攻撃する例を学びます。

そして、これは最も重要なことなのですが、アセンブリはPythonなどの高級言語よりも遥かに環境に依存します。つまり、LinuxとMacの差、そしてアセンブラ(NASMなど)のバージョンの差によって結果が違うことがよく起こります。私が最初に勉強したときもこれで大変苦しみました。しかし、この本は第2章の準備のところで、Kali linuxというLinuxOSをVMwareかVirtualBoxを使ってインストールします。著者と同じ仮想環境を使うことで手元での実行結果を本とかなり近づけることができます。なので初心者にも本当に優しいです。

まとめ

この本では次のことが学べます。

  • コンピュータの仕組みの基礎(メモリ、レジスタ)
  • gdbを用いたC言語のデバッグ
  • 実行ファイルがメモリとCPU上で何をしているのかの深い理解
  • アセンブリの書き方
  • バッファオーバーフローという有名な脆弱性の仕組み
  • リモートコード実行の手法(Cでの脆弱性とアセンブリでのコード注入)

そして仮想環境を使うので、本に書かれているコードが手元でもしっかり動きます。

おすすめ本その2:低レベルプログラミング(次回)

f:id:rustacean:20181126170812p:plain

ちょっと長くなりそうなのでこちらは次回ご紹介致します!

こちらからお進みください!

アセンブリの勉強法 (2/2)この記事はアセンブリの勉強法の2/2の記事です。 前回の記事(1/2)はこちら アセンブリおすすめ本その1:コンピュータハイ...

POSTED COMMENT

  1. […] これは本当に学習コストが高いと思いますが、そんな人がここの読者にいるのでしょうか…いるのであれば、まずは大手企業のエンジニアの中途者採用などを見るといいと思います。例えば、「応募条件 〇〇による大規模開発経験3年以上」などと書いてあるはずです。それで、入りたい企業などで使われている言語を学習したらいいと思います。 コンピュータの構造を理解するには、Cとアセンブリの勉強が良いと思います。アセンブリは機械語と1:1で対応している低水準言語です。機械語を理解するためには、アセンブリの勉強が近道です。アセンブリはこの記事でも紹介してるので、よければ参考にしてください。 https://media.itkaikei.com/2019/01/25/assembly-1/ […]

COMMENT

メールアドレスが公開されることはありません。