6日目 メモリのセグメント化その2

↑育毛の広告がおおいですね

 

前回に引き続きメモリを詳しく見ていくぞい

参考にしてる本がx86向けなのでレジスタの名前とか所々変かもしれません。

 

f:id:simauma1203:20180115194603j:image

単純なプログラムです。

これについて詳しく調べていきます。

 

main関数と定義した関数をそれぞれ逆アセンブルします。結果は以下の通り。

f:id:simauma1203:20180115194700j:image

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の値をコピーします。

新しいフレームポインタを作って

局所変数を参照するためらしい。

f:id:simauma1203:20180115204207p:image

イメージ図。

字が酷いやが。

上がスタックの先頭(積んでくところ)

先頭の方は低位アドレス。

 

どうやったら画像大きく出来るんじゃろ

 

これで本の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もやってみたいので、本があったら買って、同時進行でやりたいです。

 

おやすみなせ

4日目 変数のスコープとメモリ

今日やったのは変数のスコープ、コンテキストという呼称もあるらしい。

簡潔にまとめると関数内でjとかやると局所変数のが優先されるってこと。

メモリのアドレスも別の場所に確保される

 

あと静的変数

staticで定義されるやつ。

1回しか初期化されない

メモリはずっと同じアドレスをとる。

関数呼び出した後もあどれすと値を保持する

 

f:id:simauma1203:20180114212908j:image

(Static2.c)

本曰く、局所変数は高位、大域変数は低位のアドレスをとってるとのこと

なんでだろ、メモリを分割して分業してんのかな?

 

次はメモリのセグメント、めっちゃ難しそうなんですが、

 

3日目 GDBでデバッグ

今日はデバッガというのを使ってみた。

Linuxに標準で付属してる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ページくらいまではこんな感じの基本的事項。

結構じみなところだけどがんばります

 

 

 

2日目 ほぼ環境構築

明日はセンター試験ですね

受験生のみなさん頑張って下さい

 

今日は環境構築をちょっとしました

f:id:simauma1203:20180113012000j:image

UbuntuVScode入れて、日本語入力できるようにしました。

日本語うつ機会ないので要らなかったかもしれませんが。

 

MacWindowsだとGNUじゃないからgdbとかコマンドが使えないみたいですね。

たぶんこれからこのOSをメインで使うことになると思います

あと、少し重かったのでVMwareに多くメモリ割りふるつもりです

 

明日は沢山本の方も読み進めて、できるだけ先に進みたいです

おやすみ

1日目 ubuntuと逆アセンブルを試す

今日はmacbookのBootcamp(win10)にVMwareをインストールしてUbuntuをいれた。

f:id:simauma1203:20180111232936j:image

VScode入れようと思ったらdebパッケージのインスコでエラー。

ググッたとこ、このバージョンは不具合が多いみたい。

 

これはこれでおいといて、逆アセンブルというのを試してみた。

f:id:simauma1203:20180111233216j:image

これはMacのほうからやってる

HelloWorldとforを混ぜたソースのアセンブリ

 

本曰く、-M Intel オプションでアセンブリシンタックスIntelに出来るみたいだが、出来なかった。環境の差異かな?

 

アセンブリは調べて少しわかった、レジスタとメモリの値を移動したりする命令があるみたい

文法が単純で明解。

まだ分からない命令は莫大なので要勉強です

 

地道だけどしっかり理解したい

 

てかコマンドのオプションの仕様とかよく知らない

勉強はじめます

初投稿。

これからひっそりブログを書いていこうと思います。

日記みたいなものを書き散らかしていくことになるとおもいます。

 

今日は本を買いました。

ハッキング美しき策謀というやつ。

名前が中二感あってかっこいい。

f:id:simauma1203:20180111003337j:image

この本はプログラムの脆弱性やらシェルコードについての本みたいです。暗号学についても書かれてますがよくわらなかった、、。

 

だいたい500頁くらいあります。読破できる気がせん。

 

というわけでこの本を(できれば)毎日読みつつプログラムを弄りつつ、学んだことを定期的にブログに吐いていきます。

 

どうか三日坊主にはなりませんように。

がんばります。

 

 

1/22追記

使うプログラムはこの本の公式ページからダウンロードできます。