6日目 メモリのセグメント化その2
↑育毛の広告がおおいですね
前回に引き続きメモリを詳しく見ていくぞい
参考にしてる本がx86向けなのでレジスタの名前とか所々変かもしれません。
単純なプログラムです。
これについて詳しく調べていきます。
main関数と定義した関数をそれぞれ逆アセンブルします。結果は以下の通り。
main+0~1をプロシージャプロローグといいます。プロプロです。関数プロローグともいいます。多分。
これらの命令でフレームポインタをスタック上に退避してこの関数で宣言した局所変数のメモリをスタックに確保します。
ということはtest_function関数の関数プロローグは+0~4ですね
私的メモですが、esp、ebpはそれぞれ現在のスタックフレームの局所変数を参照する為のもの、スタックの一番上を指すものです
だからebpがプッシュ、ポップされてるんですね。
さらにmain+4~19に引数を渡してtest_func+8~17でスタックに配置してるっぽいです。
本だとそのままesp+XXに引数をmovしてるけど
違ったみたいですね。
因みにFILO(先入れ後出し)だから逆順で引数が渡されてます。
test_func+35あたりに着目してみると
0x7a69=31337(10)なのでrbp-0x24がflagのアドレスだと気づきます
+42の0x41はAの文字コードと一致&BYTE PTRでcharと同じ1バイトなのでAを配列にぶち込んでるとこだとおもいます。そこから伸びるのがbufferってことですかねー
あとmain+24のcallで0x400546のtest_funcが呼び出されてるみたいです。
callでeipを関数の先頭にしてるんですね。
そのあとtest_funcの関数プロローグがスタックフレームの作成を引き継いでます。
まずebpの現在の値がスタックにプッシュされます。
この値は退避されたフレームポインタ(SFP)といいます。
mainに制御を返す時にebpの値を復元するために使うらしいです。へー
そしてebpに現在のespの値をコピーします。
新しいフレームポインタを作って
局所変数を参照するためらしい。
イメージ図。
字が酷いやが。
上がスタックの先頭(積んでくところ)
先頭の方は低位アドレス。
どうやったら画像大きく出来るんじゃろ
これで本の3ページ分。先が遠いやばいw
5日目 メモリのセグメント化
あー、明日は学校でセンター試験とかなきゃいけないらしいです。特に国語は不可だと思います。
初めに記しますがこの章結構長くなりそう
改めて本題に入ると、
セグメントとは領域という意味らしい
コンパイルされたプログラムを実行するとき、
メモリ空間がテキスト、データ、ヒープ、スタック、bssという5つのセグメントに分割されるとのこと。(bssってなんや
それぞれのセグメントには目的があるらしい
1.テキストセグメント
別名コードセグメント。
機械語が格納される。高水準言語の制御構造とか関数はアセンブリのbranch,jump,call命令にコンパイルされるから、命令処理の実行は非線形になる(日本語でおk。
非線形って直接的な意味は分からんけど、最初から全て決まった順で処理をしないということかな?わかんない
実行時にテキストセグメントの先頭の命令を指すようにeipが設定される
そのあとeipが指すメモリから命令を読み込む、その命令のバイト長をeipに加算、読み込んだ命令を実行の繰り返し。
jump,callのときはeipを書き換えるだけだそう。
因みにテキストセグメントは書き込み禁止で、これは何故かというとセグメントサイズの固定とプロセス間のコード共有のため。
プロセス間のコード共有ってなんじゃろ?
2.データセグメントとbssセグメント
データセグメントは初期化された大域変数や静的変数、一方、bssセグメントには初期化されていない大域、静的変数が格納される。
両方のセグメントは書き込み可能だけど、サイズが固定。
大域変数や静的変数は関数コンテキストに関係なく永続的。これは固有のメモリセグメントに格納されるから。
なるほど納得。
3.ヒープセグメント
プログラマが直接制御できる。
どんな目的にもつかえる。
実行時動的に割り当てられる。
サイズは大きくも小さくもなる。
アロケータとデアロケータというアルゴリズムによって管理されてる。
それぞれ、ヒープ中のメモリを切り出してプログラムで使えるように割り当てる、割り当てたメモリを回収して再利用できるようにするというアルゴリズムです。だからサイズが可変
要するにヒープ割り当て関数でプログラム実行時にメモリを動的に確保、解放できるということ。
あと、ヒープの成長はメモリアドレスの上位に向かう
あー長い。けどそんなに複雑じゃないですね
4.スタックセグメント
局所変数や関数呼び出し中のコンテキストを格納するとこ。一時的なメモ帳。
サイズは可変。
GDBのbacktraceで参照するやつ。
関数が呼び出されるときeipが移行するのと共に呼び出される関数側で使う変数が用意される。
だからスタックセグメントを使って引数の受け渡し、復元するeipの値の保存、関数が使う全ての局所変数の割り当てが行われる。
これらの情報はスタックフレームという纏まりにされて、スタック上に格納される。
余談である抽象的なデータ構造のこともスタックというらしい。
それは先入れ後出し(FILO)という構造で最初にに入れたのは最後にでてくる、その逆もしかるもの。
スタックに値を入れるのをプッシュ、取り出すのをポップという。
スタックセグメントはスタックフレームを保持するスタックを実現するためのもの。
スタックは下位に成長する。
確かに関数が入れ子になってた時に便利そうかも。
スタックの末端アドレスを管理するためのespレジスタというのがある。
プッシュ、ポップの度に値が変わる。
関数の呼び出し時には色んな情報がスタックフレームとしてスタックにプッシュされる。
現在のスタックフレームに格納された局所変数を参照するためにebpレジスタ(フレームポインタ(FP)、ローカルベース(LB)ポインタ)が用いられる。
それぞれのスタックフレームには関数に引き渡すパラメータ、該当関数の局所変数の他、呼び出し元に戻るために必要な、退避されたフレームポインタ(SFP)と戻りアドレスという二つのポインタが保持されている。
SFPは呼び出し元のコンテキストのスタックフレームを復元する、つまりebpレジスタの値を元に戻すために使われる。
これで直前のスタックフレームの関数のコンテキストを復元する。
要約するとスタックセグメントは関数ごとに情報を纏めてスタックにプッシュして、ポップしてコンテキストを復元するという感じですかね。あたまいたい
なんかセグメント同士の作用をまだ理解してない気がします
メモリのセグメントまだまだ続きます
あとはサンプルプログラムをGDBで眺めたり弄ったりするみたいです
この章が終わったらファイルアクセス、uid、構造体、関数ポインタ、擬似乱数やっておさらいやってお終いみたいです。
そこからは脆弱性攻撃です楽しみ。
CTFもやってみたいので、本があったら買って、同時進行でやりたいです。
おやすみなせ
3日目 GDBでデバッグ
今日はデバッガというのを使ってみた。
結構細かくプログラムを弄れる&メモリの書き換えとかできるみたい。
gcc -g XXX.c
これでコンパイル-gは色々デバッグ情報を追加してくれるらしい、よくわからん
gdb -q ./a.out
このコマンドもよくわからんけどデバッガのコマンドラインになる
此処からgdb
break main
mainの直前でbreakする
11とかで行数指定できる
x/xw 変数名
メモリの内容をみれる。xwとかは色々置き換わってデータサイズとか型を示すっぽい?
info register <レジスタ名>
レジスタ覗き見れる。ripとかeip見てふむふむとか云うらしい
コマンドの頭文字だけで省略して書けるのが多い
すごい面倒くさがりというか効率的な開発者だと思った
今日つかったのはこれくらい。
本の方は今56ページで130ページくらいまではこんな感じの基本的事項。
結構じみなところだけどがんばります
1日目 ubuntuと逆アセンブルを試す
今日はmacbookのBootcamp(win10)にVMwareをインストールしてUbuntuをいれた。
VScode入れようと思ったらdebパッケージのインスコでエラー。
ググッたとこ、このバージョンは不具合が多いみたい。
これはこれでおいといて、逆アセンブルというのを試してみた。
これはMacのほうからやってる
HelloWorldとforを混ぜたソースのアセンブリ。
本曰く、-M Intel オプションでアセンブリのシンタックスをIntelに出来るみたいだが、出来なかった。環境の差異かな?
アセンブリは調べて少しわかった、レジスタとメモリの値を移動したりする命令があるみたい
文法が単純で明解。
まだ分からない命令は莫大なので要勉強です
地道だけどしっかり理解したい
てかコマンドのオプションの仕様とかよく知らない
勉強はじめます
初投稿。
これからひっそりブログを書いていこうと思います。
日記みたいなものを書き散らかしていくことになるとおもいます。
今日は本を買いました。
ハッキング美しき策謀というやつ。
名前が中二感あってかっこいい。
この本はプログラムの脆弱性やらシェルコードについての本みたいです。暗号学についても書かれてますがよくわらなかった、、。
だいたい500頁くらいあります。読破できる気がせん。
というわけでこの本を(できれば)毎日読みつつプログラムを弄りつつ、学んだことを定期的にブログに吐いていきます。
どうか三日坊主にはなりませんように。
がんばります。
1/22追記
使うプログラムはこの本の公式ページからダウンロードできます。