Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ELFバイナリ静的解析入門
Search
segfo
August 17, 2018
0
810
ELFバイナリ静的解析入門
segfo
August 17, 2018
Tweet
Share
More Decks by segfo
See All by segfo
RustでOS作りたい話
segfo
4
1k
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
95
5.2k
Designing for Performance
lara
604
68k
Adopting Sorbet at Scale
ufuk
73
9.1k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Why Our Code Smells
bkeepers
PRO
334
57k
Scaling GitHub
holman
458
140k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
329
21k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
430
Typedesign – Prime Four
hannesfritz
40
2.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Transcript
ELFバイナリ静的解析入門 PIEバイナリの静的シンボル解決 segfo
この資料を読む上で必要な知識 PIEの意味を理解していること(必須) 動的リンクライブラリは何のことか理解していること(必須) IntelCPUのエンディアンを理解していること。(必須) ELFバイナリの各種構造体を理解していること。(必須ではない) ↑大体なんとなく直感でわかればOK。 (構造体で言われても正直抽象的すぎて分からない)
このスライドの目的 32bitアプリケーションがPIE時に動的関数が直接呼び出しされる場合において ローダーがどのようにアプリケーション内のシンボルを解決しているのか。 ということに焦点を当てている。 これを理解することで、動的リンクについての理解を深めることができる。
ソースコード(test.c) #include<stdio.h> #include<stdlib.h> int main(){ char s[128]={0}; printf("hello world"); fgets(s,127,stdin);
exit(-1); return 0; }
コンパイルオプション gcc -m32 -shared test.c -o sharedObject
BinaryNinjaで見たときのmain関数 謎の関数1 printf関数?
BinaryNinjaで見たときのmain関数(続き) 謎の関数2 fgets関数? 謎の関数3 exit関数? _fini関数が赤線以下から開 始している。 BinaryNinjaがうまく解析で きていない _fini関数
ソースを持っているから、なんとなく分かるが... バイナリだけポイって渡されて、手元にBinaryNinjaしか無くて 「静的解析してね♥」とか言われたら? わっかんねーよ バーーーーーーーーーーーカ ってなる、でもIDA使ってるProに負けるのは悔しいから なんとしてでもBinaryNinjaだけで解析したい。
シンボル名解決に必要な3つのセクション 【.dynsym】 シンボルとアドレスの対応表。.rel.dynから参照される。 【.dynstr】 シンボル名が文字列でダーーーーっと書かれている。 stdinとかfgetsとかが書いてある。.dynsymから参照される。 【.rel.dyn】 再配置についての情報がたくさんかかれている 0x5d4をcallしていたら、それは.dynsymの何番を見れば.dynstr(シンボル)がわかるよ みたいな事が書いてある。
それが変数か関数かと言った種類も書いてある
sub_5d4が何の関数呼び出しか解決してみよう これ! 【余談】 赤枠(アドレス0x5d3)の命令は 自身+1のアドレスを呼んでいる。 このままでは命令として意味が成り立っていないため、 動かない。ローダーがこの命令を書き換える(動的リンク する)ことで正しい命令となる。
.rel.dynセクション 種別が02のみ以下の解釈 call対象アドレス call 0x5d4 種別 01=変数 02=関数 06=GOTシンボル解決用 08=共有ライブラリがロード
されたアドレスを加える シンボルのインデックス =6 シンボル(.dyn.sym)のインデック ス=ゼロから始まる
.dynsymセクション 0番目 1番目 2番目 3番目 4番目 5番目 6番目(今回の対象)
.dynsymセクション .dynstr先頭からのオ フセット (文字列へのオフ セットアドレス) サイズ 関数の配置アドレス ・上位8bit=bind 0=Local 1=Global
2=Weak ・下位8bit=Type 0=NOTYPE 1=OBJECT 2=FUNC
.dynstrセクション .dynstr先頭=0x274 0x274+0x8d=0x301 65 78 69 74 00 文字列:“exit”
結果 着目点:.textセクションに存在する、0x5d3の命令(call 0x5d4命令)は共有ライブラリの どの関数を呼ぶのか 0x5d4は.rel.dynセクションの7番目のエントリに存在する .dynsymの6番目のエントリに.dynstrの参照がある .dynstrセクションのオフセット0x8dのアドレスにシンボル名が存在する そのシンボル名は exit だった。 つまり、動的リンク時には、exit関数が0x5d3のcall命令にリンクされる =PLTを経由しない(LD_PRELOADが効かないということもわかる)
おまけ _fini関数が赤線以下から開 始している。 BinaryNinjaがうまく解析で きていない 【余談】 何故_fini関数がmain関数の一部として解析されているか。 gccはexit関数が呼ばれているので ret命令を置かなかったことが一つ。 さらにBNがこの関数をexit関数であることを理解していない。
そのため、バイナリ的に後続する関数である _fini関数の末尾ret命令まで main関数であると解析されてしまっている。
おわり