Statifier » 履歴 » バージョン 1
kanata, 2025/04/13 15:41
1 | 1 | kanata | # Statifier |
---|---|---|---|
2 | |||
3 | {{rawhtml(<canvas id="map"></canvas><script src="/javascripts/pagemap.min.js"></script><script>pagemap(document.querySelector("#map"));</script>)}} |
||
4 | |||
5 | {{toc}} |
||
6 | |||
7 | # 経緯 |
||
8 | |||
9 | とあるコマンドをインストールしようと思った・・・・が・・・・・ 駄目っ・・・・・! |
||
10 | パッケージの依存関係がすごい。つまり、1つコマンドを導入するのに、入れたくないパッケージを山のように入れなければならない。。 |
||
11 | |||
12 | そのコマンド1つだけ実行したいだけなのに・・・ |
||
13 | |||
14 | そこで思いつく悪魔の発想・・・っ! |
||
15 | |||
16 |  |
||
17 |  |
||
18 | |||
19 | 1バイナリで動くようにすれば、他の環境に楽に持っていける。理論上は出来るはず・・・と思い、調べたら出てきた。 |
||
20 | |||
21 | [statifier](http://statifier.sourceforge.net/)というのを使えば可能であることがわかった。 |
||
22 | |||
23 | {{rawhtml(<a class="embedly-card" href="http://statifier.sourceforge.net/">ELF STATIFIER MAIN PAGE</a><script async src="//cdn.embedly.com/widgets/platform.js" charset="UTF-8"></script>)}} |
||
24 | |||
25 | メンテナンスはあまり活発ではないようだが、x86_64にも対応してくれているっぽい。 |
||
26 | |||
27 | >その他の案として、参照している動的リンクライブラリを全部洗い出してコピーし、LD_PRELOAD環境変数に突っ込んだ上で実行すればいけるかなぁ。とか、思ったんだけど、試してはいない。 |
||
28 | |||
29 | # 概要 |
||
30 | |||
31 | 結局、なにがしたいかと言うと、 |
||
32 | |||
33 | ~~~ |
||
34 | $ cat test.c |
||
35 | #include <stdio.h> |
||
36 | |||
37 | int main(){ |
||
38 | printf("Helloworld"); |
||
39 | return 0; |
||
40 | } |
||
41 | $ gcc test.c |
||
42 | $ ldd a.out |
||
43 | linux-vdso.so.1 => (0x00007fffc62d0000) |
||
44 | libc.so.6 => /lib64/libc.so.6 (0x00007f886214a000) |
||
45 | /lib64/ld-linux-x86-64.so.2 (0x00007f8862517000) |
||
46 | ~~~ |
||
47 | |||
48 | この単純なプログラムですら、3つの動的リンクライブラリを必要としている事がわかる。 |
||
49 | このライブラリがシステムに存在しないと、プログラムは動かない。 |
||
50 | だったら・・・プログラム(a.out)の中に、この3つの動的リンクライブラリを取り込んだらいいじゃない。 |
||
51 | という発想。 |
||
52 | |||
53 | # Install |
||
54 | |||
55 | まず、自分はこのソフトのコンパイルのため、コンパイル用の仮想環境を用意した。 |
||
56 | statifierを導入するために、依存関係となっている複数パッケージを導入する・・・のは本末転倒である。 |
||
57 | コンパイル済みのものだけを目的の環境にコピーしてやればよいではないか。 |
||
58 | |||
59 | という訳で、[ここ](https://sourceforge.net/projects/statifier/files/)から最新版のtar.gzをダウンロードする。 |
||
60 | |||
61 | >自分が実施した時は、statifier-1.7.4.tar.gz でした。 |
||
62 | |||
63 | 適当なところに展開しておく。 |
||
64 | |||
65 | ~~~ |
||
66 | $ tar xvfz statifier-1.7.4.tar.gz |
||
67 | ~~~ |
||
68 | |||
69 | コンパイル時に必要となるパッケージをインストール。 |
||
70 | |||
71 | ~~~ |
||
72 | # yum install glibc.i686 glibc-devel.i686 libgcc.x86_64 libgcc.i686 |
||
73 | ~~~ |
||
74 | |||
75 | makeする。 |
||
76 | |||
77 | ~~~ |
||
78 | $ cd xvfz statifier-1.7.4 |
||
79 | $ bash ./configure |
||
80 | $ make |
||
81 | ~~~ |
||
82 | |||
83 | というのが、めんどうな方のために自分がコンパイルしたものをここに置いておく。 |
||
84 | |||
85 | attachment:statifier-1.7.4_for_x86_64.tar.gz |
||
86 | |||
87 | # 実行環境について |
||
88 | |||
89 | さっそく動作確認してみる。 |
||
90 | dateコマンドを静的リンクにしてみよう。 |
||
91 | |||
92 | ~~~ |
||
93 | $ ldd /bin/date |
||
94 | linux-vdso.so.1 => (0x00007fff3432f000) |
||
95 | libc.so.6 => /lib64/libc.so.6 (0x00007f61fcf4f000) |
||
96 | /lib64/ld-linux-x86-64.so.2 (0x00007f61fd31c000) |
||
97 | $ cd statifier-1.7.4 |
||
98 | $ setarch `uname -m` -R src/statifier.sh /bin/date /tmp/date2 |
||
99 | ~~~ |
||
100 | |||
101 | これでstaticなdateコマンドが出来たはず。 |
||
102 | |||
103 | ~~~ |
||
104 | $ setarch `uname -m` -R /tmp/date2 |
||
105 | 2016年 6月 5日 日曜日 17:30:56 JST |
||
106 | $ ldd /tmp/date2 |
||
107 | 動的実行ファイルではありません |
||
108 | ~~~ |
||
109 | |||
110 | うん、たぶんうまく動いてるんだと思われる。 |
||
111 | |||
112 | ## 超注意:ASLRの怪 |
||
113 | |||
114 | なんか、おまじないのようなコマンドがくっついているのが、おわかり頂けただろうか・・・ |
||
115 | |||
116 | ~~~ |
||
117 | $ setarch `uname -m` -R |
||
118 | ~~~ |
||
119 | |||
120 | 実は、これ、LinuxのASLRというセキュリティ機能を一時的に無効にするコマンドになります。 |
||
121 | ASLRについては、ググるか、[[CTF_Pwn]]をみてね。 |
||
122 | なんか、いろいろやってみたけど、動かなくてね~。 |
||
123 | |||
124 | どうやら、「静的リンクの実行体に変換する時」と、「実際に動作させる時」にメモリアドレスが同じになってないといけないっぽい。 |
||
125 | |||
126 | なので、必ず「setarch `uname -m` -R」を頭につけて変換&実行しておくれ。 |
||
127 | |||
128 | # 想定される使い方 |
||
129 | |||
130 | よっしゃー。これで、1バイナリになって、どの環境でも動くぞイヤッッホォォォオオォオウ! |
||
131 | |||
132 | と、ならないのが世の定め。。 |
||
133 | |||
134 | ちょっとLinuxディストリビューションの違うLinuxに持ち込んでみたが動かない。。 |
||
135 | まぁ全部試した訳ではないのだけれど、 |
||
136 | 同じディストリビューションだと動いているっぽい。 |
||
137 | |||
138 | たぶん、kernelのバージョンが違ってたりすると、取り込んだlibcでそれを吸収できないとか、そんな感じになっている気がする。 |
||
139 | 調べてないけど。 |
||
140 | |||
141 | >そう考えると1バイナリになるGo言語って結構考えられてますね。ファイルサイズが大きくなるだろうから、そこらへんトレードオフなんだろうけど。 |
||
142 | |||
143 | なので、自分は同じLinuxディストリビューションで2環境用意して運用している。 |
||
144 | |||
145 | * VMでコンパイル用環境を作る(足りない物は、なんでもかんでもyum install。使い捨て) |
||
146 | * 本番環境。できるだけパッケージを入れない。 |
||
147 | |||
148 | # 補足 |
||
149 | |||
150 | statifier には、こんな記述が |
||
151 | |||
152 | >Recent Linux kernels introduced VDSO (Virtual Dynamic Shared Object) and stack randomization. Those things, while valuable features, don't play well with Statifier. |
||
153 | |||
154 | >>意訳:ASLRとVDSOを使うバイナリは上手く動かないぜ |
||
155 | |||
156 | この statifier を作った方達は、Ermine というソフトを販売しております。 |
||
157 | |||
158 | >Ermine works in a fashion similar to Statifier, creating self-contained executables from dynamically-linked >applications. But Ermine-packed applications are not snapshots: instead they can be thought of as small virtual machines. |
||
159 | >And because of this an Ermine-packed application does not suffer from the problems created by VDSO/stack randomization |
||
160 | |||
161 | >> 意訳:Ermineなら問題ないんだぜ |
||
162 | |||
163 | Ermine |
||
164 | http://www.magicermine.com/ |
||
165 | |||
166 | >15日トライアルもできるらしい。 |
||
167 | |||
168 | # 参考 |
||
169 | |||
170 | bkブログ - statifier で動的リンクの実行ファイルを擬似的に静的リンクにする |
||
171 | http://0xcc.net/blog/archives/000089.html |
||
172 | |||
173 | ELF Statifierを使って実行形式ファイルをシステム間で移動する |
||
174 | https://osdn.jp/magazine/08/12/02/012255 |