Slide 1

Slide 1 text

ELFバイナリ静的解析入門 PIEバイナリの静的シンボル解決 segfo

Slide 2

Slide 2 text

この資料を読む上で必要な知識 PIEの意味を理解していること(必須) 動的リンクライブラリは何のことか理解していること(必須) IntelCPUのエンディアンを理解していること。(必須) ELFバイナリの各種構造体を理解していること。(必須ではない)  ↑大体なんとなく直感でわかればOK。  (構造体で言われても正直抽象的すぎて分からない)

Slide 3

Slide 3 text

このスライドの目的 32bitアプリケーションがPIE時に動的関数が直接呼び出しされる場合において ローダーがどのようにアプリケーション内のシンボルを解決しているのか。 ということに焦点を当てている。 これを理解することで、動的リンクについての理解を深めることができる。

Slide 4

Slide 4 text

ソースコード(test.c) #include #include int main(){ char s[128]={0}; printf("hello world"); fgets(s,127,stdin); exit(-1); return 0; }

Slide 5

Slide 5 text

コンパイルオプション gcc -m32 -shared test.c -o sharedObject

Slide 6

Slide 6 text

BinaryNinjaで見たときのmain関数 謎の関数1 printf関数?

Slide 7

Slide 7 text

BinaryNinjaで見たときのmain関数(続き) 謎の関数2 fgets関数? 謎の関数3 exit関数? _fini関数が赤線以下から開 始している。 BinaryNinjaがうまく解析で きていない _fini関数

Slide 8

Slide 8 text

ソースを持っているから、なんとなく分かるが... バイナリだけポイって渡されて、手元にBinaryNinjaしか無くて 「静的解析してね♥」とか言われたら? わっかんねーよ バーーーーーーーーーーーカ ってなる、でもIDA使ってるProに負けるのは悔しいから なんとしてでもBinaryNinjaだけで解析したい。

Slide 9

Slide 9 text

シンボル名解決に必要な3つのセクション 【.dynsym】 シンボルとアドレスの対応表。.rel.dynから参照される。 【.dynstr】 シンボル名が文字列でダーーーーっと書かれている。 stdinとかfgetsとかが書いてある。.dynsymから参照される。 【.rel.dyn】 再配置についての情報がたくさんかかれている 0x5d4をcallしていたら、それは.dynsymの何番を見れば.dynstr(シンボル)がわかるよ みたいな事が書いてある。 それが変数か関数かと言った種類も書いてある

Slide 10

Slide 10 text

sub_5d4が何の関数呼び出しか解決してみよう これ! 【余談】 赤枠(アドレス0x5d3)の命令は 自身+1のアドレスを呼んでいる。 このままでは命令として意味が成り立っていないため、 動かない。ローダーがこの命令を書き換える(動的リンク する)ことで正しい命令となる。

Slide 11

Slide 11 text

.rel.dynセクション 種別が02のみ以下の解釈 call対象アドレス call 0x5d4 種別 01=変数 02=関数 06=GOTシンボル解決用 08=共有ライブラリがロード されたアドレスを加える シンボルのインデックス =6 シンボル(.dyn.sym)のインデック ス=ゼロから始まる

Slide 12

Slide 12 text

.dynsymセクション 0番目 1番目 2番目 3番目 4番目 5番目 6番目(今回の対象)

Slide 13

Slide 13 text

.dynsymセクション .dynstr先頭からのオ フセット (文字列へのオフ セットアドレス) サイズ 関数の配置アドレス ・上位8bit=bind 0=Local 1=Global 2=Weak ・下位8bit=Type 0=NOTYPE 1=OBJECT 2=FUNC

Slide 14

Slide 14 text

.dynstrセクション .dynstr先頭=0x274 0x274+0x8d=0x301 65 78 69 74 00 文字列:“exit”

Slide 15

Slide 15 text

結果 着目点:.textセクションに存在する、0x5d3の命令(call 0x5d4命令)は共有ライブラリの どの関数を呼ぶのか 0x5d4は.rel.dynセクションの7番目のエントリに存在する .dynsymの6番目のエントリに.dynstrの参照がある .dynstrセクションのオフセット0x8dのアドレスにシンボル名が存在する そのシンボル名は exit だった。 つまり、動的リンク時には、exit関数が0x5d3のcall命令にリンクされる  =PLTを経由しない(LD_PRELOADが効かないということもわかる)

Slide 16

Slide 16 text

おまけ _fini関数が赤線以下から開 始している。 BinaryNinjaがうまく解析で きていない 【余談】 何故_fini関数がmain関数の一部として解析されているか。 gccはexit関数が呼ばれているので ret命令を置かなかったことが一つ。 さらにBNがこの関数をexit関数であることを理解していない。 そのため、バイナリ的に後続する関数である _fini関数の末尾ret命令まで main関数であると解析されてしまっている。

Slide 17

Slide 17 text

おわり