とある京大生の作業ログと日々の雑記

コンピュータサイエンスについて学んだことを可視化したり日々の雑記をまとめてます。

低レベルプログラミングの書評

こんにちは、コミさん(@komi_edtr_1230 )です。




今回は低レベルプログラミングという本の書評です。




前回のエントリーがLinuxカーネル本の書評だったんですけど、たったの前回の投稿日が3日前らしい....




ここ3日くらい12時間以上ずっと本読んではコード書きまくるって生活をしてたおかげでなんか時間感覚が狂っちゃってて、前回のエントリーがこんな数日前ってのが信じられないです....




なんかあんまりこんなハイペースで本読み進めてたら「こいつ実は読んでないんじゃね?」って思われそうでアレなんですけど、ちゃんと読んでますからねw




ただまぁここ数日についてはスイスに来てから最強にハードな日々を過ごしてて、ちょうど授業が休講になっててガチで12時間くらいぶっ通しでやるみたいな感じでした。




おかげさまでエナジードリンクにはだいぶお世話になったんですけど、そんなこんなで今回は低レベルプログラミングを読み切ったので書評をしていきます。



本の紹介






f:id:komi1230:20181104031815j:plain




まず最初に、多分この本のことを割と知ってる人は結構多いると思うんですよね。




低レベルプログラミングという名前は決して初心者向けという意味ではないんだけどこの名前のせいでBOOK-OFFではプログラミング初心者向けコーナーに鎮座してあった、というのが前にツイッターでネタになってたんです。




この本の著者はロシア人の方で、ロシアのサンクトペテルブルク(?)とかの大学の助教さんが書いた本なんです。




なので原著はロシア語で書いてあります。




あ、上の画像は英語版なんですけどもちろん和訳版もありますのでご安心ください。




ロシアではこの先生の授業が非常に人気で、その人気さと本の完成度の高さから英語に翻訳されたものが出て、そうして和訳版も存在するわけです。




内容としては「アセンブリ言語C言語を触ってメモリやスタックなどの低レイヤーをしっかり理解しようという」ような感じです。




ということで名前の通り、低レベルなプログラミングというわけです。




コンピュータは低レイヤーになればなるほど難解だと言われており、つまりプログラミング初心者にはしんどすぎる一冊なんですよねw




まあそんなこんなで世界的な名著を今回読んだので、早速レビューに入っていきましょう。



感想






今回は低レベルプログラミングを読んだわけですが、感想としては




低レイヤーの入門には完璧な一冊




という感じです!




もうほんとに読んでて楽しかったですね。




特に良かったと思ったのが「コードの丁寧さと解説の細かさ」です。




本書の構成としてはPart 1でアセンブリ言語の解説とアセンブリ視点でのメモリやスタックの解説、Part 2でC言語の解説とC言語視点でのメモリやスタックの解説、Part 3ではC言語コンパイルする際のメモリ構造や最適化、マルチスレッドへの対応などを見ていく感じとなります。




低レイヤーをアセンブリ視点とC言語視点で見つめるという構成のおかげで無限にメモリへの理解が進んだような気がしました。




あとこの本を読む直前にLinuxカーネル本を読んだということもあってかなりサクサク読めたので、OS周りの知識をつけた上でこの本を読むと楽しさは倍増すると思います。




それでは各パートの感想を述べていきましょう。



Part 1 : アセンブリ言語






そもそもアセンブリ言語ってなんぞやということから始まります。




よく「コンピュータは0と1の塊だ」というのは聞くと思います。




でも実際のところ人間は0と1という形ではコンピューターに命令を出さず、人が理解できる形でコンピュータに命令を出します。




これがいわゆるコンピュータプログラムというやつで、プログラミング言語の文法という形で命令規則を作ってコンピュータに命令を出すわけです。




例えばコンピュータに"Hello World!"という文字列を表示させるときにはC言語では



#include <stdio.h>

int main(void){
    printf("Hello World !\n");

    return 0;
}






という形で命令を出します。




でもこれがコンピュータが命令として理解するには最終的に0と1のバイナリに落とし込む必要があるわけです。




ただ、このような人間にもわかるような物をバイナリに落とし込むために一旦中間となる言語を挟むことになります。




これがアセンブリ言語です。




f:id:komi1230:20181104040644p:plain




一般的に、普通のウェブアプリ開発をしたり機械学習をやっていたりしていたらこのアセンブリ言語というのは触ることはないんですよね。




ただ、コンピュータの動作原理を知るためだったりプロダクトのパフォーマンスをあげようとすると低レイヤまでしっかり見て最適化する必要が出てきたりするわけなんです。




ということで前置きが長くなりましたが低レベルプログラミングのPart 1ではそんなアセンブリ言語をガチャガチャ書いていきます。




内容として、まず1章ではメモリ構造の解説を行い、2章ではアセンブリ言語Hello Worldをはじめとして関数定義など色々やります。




1章のメモリの解説で、ここでしっかり読んでrsiとかedxが何を意味してどんな構造を持ってるのかを理解しておかないと2章以降で何も理解が進まないのでちゃんと読んでおきましょう。(自分はなかなか頭に入ってこず少し手こずった)




3章ではプロセッサのモードについての話で、ユーザースペースでのメモリ構造がどのように発展してきたのかをコードとともに解説していきます。




4章では仮想メモリの話が、5章ではコードにおけるデータ処理の流れやELFファイルなどのファイルのリンクの話が行われます。




ELFファイルヤオブジェクトファイルはよく名前を聞くけどわからない、という感じだったんですけど今回これを読んである程度理解ができたと思います(完全に理解したとは言ってない)




6章ではデータの入出力やシステムコールを扱います。




そしてPart 1の最後の7章ではオートマトンの解説です。




6章までは正直なところ解説の流れが読めてたんですけど、7章で有限オートマトンでの計算フローの解説が行われるのはびっくりしましたね....(アセンブリの解説ならそれはそうという感じだが)




以上がPart 1です。




ぼくは前にオライリージャパンから出てる策謀本を読んでアセンブリやスタック周りを触ったことがあったんですけど、そのときはC言語サイドからスタック操作をしただけでアセンブリ言語についてはobjdumpで眺めるだけという感じだったので、今回アセンブリ言語をゴリゴリ触るのは初めてだったので非常に勉強になりました。




ではPart 2へ。



Part 2 : C言語






Part 2は正直なところ普通のC言語の解説という感じです。




基本文法やポインタを中心とした型システムの解説、マクロやヘッダファイルの意味をざざっと見ていきます。




ただ、これらは内容は普通ですがPart 1でアセンブリ言語をゴリゴリ触ったということで値渡しと参照渡しをアセンブリ言語で見直すというようなアプローチもあり、C言語でのポインタや配列周りは無限に理解が進むと思います。




Part 2はC言語の章ですが、Part 1で見たようにPart 2でもメモリの解説が入ります。




もうこれでもかと言わんばかりにメモリの解説を行います....w




まあそんなこんななのですが、個人的にびっくりしたのはPart 2最後の13章で「いいコードの書き方」を解説した章が設けられている点でした。




内容としてはリーダブルコードに書いてありそうな内容(リーダブルコードを読んだことがないので細かくは言及できないが)で、命名法やオブジェクト指向でよく言及されるカプセル化などについて書いてあります。




低レベルプログラミングという題名の本でありながらそういうことも書いてあるのか、と笑ってしまいましたね...w



Part 3 : C言語アセンブリ言語のつながり






一般に、C言語を書いて実行しようとするときはgccコンパイルして実行ファイルを作成します。




14章, 15章ではC言語からアセンブリコンパイルしたものをlldなどのコマンドでリンクさせた上でアセンブルする、というようなことを行うなどしてコンパイル家庭でのメモリ構造を解説していきます。




16章ではコンパイル時における最適化とパフォーマンスの向上、17章ではマルチスレッド化を議論していきます。




ここらへんは読んでて1番楽しかった部分かもしれません。




というのも、Part 1ではアセンブリ言語に焦点を当て、Part 2ではC言語に焦点を当ててきましたが、Part 3ではそれらの知識をフル活用して全体の流れを触っていくのがなんとも快感でした。




特にマルチスレッドの章で、ぼくは今まで並列処理に興味があったものの中身は得体の知れないものという認識だったのですが、今回勉強してかなり理解できたような気がします。



まとめ






以上、かなり長くなってしまいましたが低レベルプログラミングはホントにいい本でした。




ここらへんの低レイヤの話はリバースエンジニアリングなどの話にも直結していくので、最近セキュリティに興味ある勢としては読んでよかった本だと思います。




本当に勉強になるので、おすすめの一冊です。



今後の予定






さて、スイスに来てから爆速でいろんな分野を勉強してきたんですけど、これで一応やりたかったことはひと通り回れたんですよね。




特に気にしていた低レイヤの分野も勉強できました。




ただ、これらのことを知識として持ってるだけで実際のところはまだそこまで手を動かせてないというのが現状です。




最終的な目標は「CTFで勝てるようにする」という感じなんですよね。




日本にいた頃はずっと機械学習をやってて、これは個人的な意見なんですけど機械学習はどうもマシンパワーでゴリ押してる印象があって、あんまり美しくないなぁって思うようになったんですよね。




Kaggleとかでも最近は画像系のタスクが多くて、GeForceGPUを持ってないぼくは人権すらないわけです。(Google Colabはあまり使いたくない)




ということで機械学習を今後突き詰めるよりかは機械学習の理論と実装経験をあくまで一つのスキルとして持っておいて、その上でセキュリティの分野に走ろうと考えたりしてる今日この頃です。




何かプロダクトを作ることよりも出来上がってるシステムを眺めたりするのが好きな身としてはあまりアプリ制作をやりたい気持ちがなく、だからCTFは今後の自分にとっていい目標かなぁって考えてます。




そんなわけで、明日からはマルウェア解析の本から勉強しようと思います!




PDFはすでに用意してあって、Practical Malware Analysisというのがググったら良さげだったので、明日からはそれを読もうかと。




今回は1000ページ以上あってかなり骨の折れる量なんですけど、今まで通り根気よく勉強していこうと思います!




では、ちょっと今回は長くなっちゃいましたけどここら辺で。




お疲れ様でした〜