Gcc Obj File Symbols
自用
測試環境
1 2 3 4 5 6 7 8 9 10 11 12 |
|
目錄
- gcc7
- /usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginT.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtend.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtfastmath.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadbegin.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadend.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadtable.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtprec32.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtprec64.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtprec80.o
- /usr/lib/gcc/x86_64-linux-gnu/7/libasan_preinit.o
- glibc6
- /usr/lib/x86_64-linux-gnu/crt1.o
- /usr/lib/x86_64-linux-gnu/crti.o
- /usr/lib/x86_64-linux-gnu/crtn.o
- /usr/lib/x86_64-linux-gnu/gcrt1.o
- /usr/lib/x86_64-linux-gnu/grcrt1.o
- /usr/lib/x86_64-linux-gnu/libtsan_preinit.o
- /usr/lib/x86_64-linux-gnu/Mcrt1.o
- /usr/lib/x86_64-linux-gnu/rcrt1.o
- /usr/lib/x86_64-linux-gnu/Scrt1.o
gcc 7
/usr/lib/gcc/x86_64-linux-gnu/7/crtbegin.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginT.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtend.o:
1 2 3 4 5 6 7 8 9 10 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o:
1 2 3 4 5 6 7 8 9 10 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtfastmath.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadbegin.o:
1 2 3 4 5 6 7 8 9 10 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadend.o:
1 2 3 4 5 6 7 8 9 10 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtoffloadtable.o:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtprec32.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtprec64.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/crtprec80.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
/usr/lib/gcc/x86_64-linux-gnu/7/libasan_preinit.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
glibc6
/usr/lib/x86_64-linux-gnu/crt1.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
/usr/lib/x86_64-linux-gnu/crti.o:
1 2 3 4 5 6 7 8 9 10 |
|
/usr/lib/x86_64-linux-gnu/crtn.o:
1
|
|
/usr/lib/x86_64-linux-gnu/gcrt1.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
/usr/lib/x86_64-linux-gnu/grcrt1.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
/usr/lib/x86_64-linux-gnu/libtsan_preinit.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
/usr/lib/x86_64-linux-gnu/Mcrt1.o:
1
|
|
/usr/lib/x86_64-linux-gnu/rcrt1.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
/usr/lib/x86_64-linux-gnu/Scrt1.o:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Hello World 反組譯輸出
單純以後剪貼用的。有興趣的朋友可以注意以下觀察重點
_init
sectiontext
section 開頭symbol 為_start
_start
呼叫__libc_start_main
__libc_csu_init
section__libc_csu_fini
section_fini
section
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
|
Load_elf_binary Trace
田野調查:Ubuntu 18.04.2 產生執行檔細節
本篇旨在從command line角度拆解 gcc hello.c -o hello
中間gcc
幫你執行了哪些指令,以及這些執行指令大概在做什麼。每個指令光要分析都要花不少時間,當作以後的作業吧。
目錄
測試環境
1 2 3 4 5 6 |
|
1 2 3 4 5 |
|
(不)完整的gcc 編譯步驟
除了hello.o以外偷塞的object files以及liked libraries
這部份是在連結的時候 gcc
做的事。記得 gcc
全名是 GNU Compiler Collection
,也就是說他不是編譯器,是一個通包的程式。直接列出多連結的檔案,要注意的是在連結時似乎有個順序,所以會多次出現--push-state
-> --as-needed
-> 指定連結函式庫 -> --pop-state
的參數,以後有空再來看這部份。
- /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o
- /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
- /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
- /lib64/ld-linux-x86-64.so.2
- /usr/lib/gcc/x86_64-linux-gnu/7/32/libgcc.a
- /lib/x86_64-linux-gnu/libc.so.6
- /usr/lib/x86_64-linux-gnu/libc.a
- /usr/lib/gcc/x86_64-linux-gnu/7/libgcc_s.so.1
- /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
- /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
- /lib/x86_64-linux-gnu/libc.so.6
附錄
cc
指令拆解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
as
指令拆解
1
|
|
collect2
指令拆解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
ld
指令拆解
要注意的是ld
是由collect2
呼叫的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
用 strace
觀察 gcc hello.c -o hello
會呼叫哪些執行檔
1 2 3 4 5 6 7 8 9 10 |
|
完整的 gcc -v -o hello hello.c
輸出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
collect2 說明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
|
觀察編譯glibc的產出
這次介紹編譯glibc 並安裝後的一些發現
目錄
測試環境
1 2 3 4 5 6 |
|
安裝步驟
- 下載套件
1 2 3 |
|
- 在新的目錄編譯 glibc,你可以自行指定安裝路徑,一定要指定安裝路徑,以免發生嚴重悲劇。
本次設定主要是針對除錯最佳化,以及避免覆蓋系統原本的 glibc
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
觀察與結論
本來想說 libc
用來提供 C 標準函式庫的 binary,那麼了不起就是 libc.so
和 libc.a
以及對應的 header files。安裝完畢後先看一下目錄,事情果然沒有像本組裝工想的那麼簡單。列出第一層目錄如下,除了預期中的lib
和include
以外,竟然還有不少預期以外的目錄。
1 2 3 4 5 6 7 8 9 10 |
|
那麼我們來看一下這些目錄下面有什麼東西吧。
/lib
先來看目錄結構,多了和多國語言相關的函式庫目錄還有 trace shared object PLT (Procedure linkage table) 工具會用到的audio目錄
1 2 3 4 |
|
接下來看/lib
的檔案
列出幾個我有興趣的檔案
*.o
- 在
/lib
裏面會發現幾個object file,它們檔名都有crt
,crt全名是C runtime
,顯然和執行的時候有關。我有空會再找時間了解。先列出來介紹幾個如下
- 在
Scrt1.o
: 這邊我們可以看到T _start
以及U main
,望文生義按圖說故事我們可以猜測執行程式的起始點其實是_start
,做了一些事情後才會去呼叫你寫的main()
,我做了一個實驗,想知道一個應用程式會連結哪些系統上的object檔案請參考這邊
1 2 3 4 5 6 7 8 9 10 |
|
crtn.o
: 用nm
去看會發現沒有symbol
,不過反組譯後會發現有兩個section
,看起來和main啟動前和使用者程式結束後會有關係。有空會再探討。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
ld-linux-x86_64.so.2
- 就是
ld.so
,這個檔案有趣的點是他是一個shared object,但是同時又是可以執行。如果我的懶病沒有發作以後會常常看到這個東西。
- 就是
libc.*
:- 直接看symbol就知道,
T
,U
的定義請翻前面文章,我懶得找。
- 直接看symbol就知道,
1 2 3 4 5 6 7 8 9 10 11 12 |
|
libm.*
: 一樣看symbol節錄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
libdl
- 動態載入函式庫相關函數如
dlvsym
,dlsym
,
- 動態載入函式庫相關函數如
完整檔案如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
/bin
是除了 ldd
以外,我全部沒印象。有些甚至不在Ubuntu的預設安裝中。使用者需要另外安裝,如xtrace
等。
列出幾個我有興趣的工具
- pldd: 列出process使用的shared library。奇怪的是我自己用卻只有列出process的執行檔名稱而已。
- sotruss: 經由PLT (Procedure Linkage Table) trace shared library calls
- sprof: share object 的profile 工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
/sbin
- 除了
ldconfig
外其他的不認識
1 2 3 4 5 6 7 8 9 10 11 |
|
/etc
很有趣,竟然有rpc
(remote procedure call)的檔案,紀錄rpc通訊協定的資訊。
1 2 3 |
|
/share
- 存放時區以及多國語言相關檔案
/var
跳過
/libexec
跳過
/include
跳過
參考資料
- Linux x86 Program Start Up
- ELF: From The Programmer’s Perspective: The .init and .fini Sections (1995)
- Stackoverflow: What is the use of _start() in C?
- Stackoverflow: Executing init and fini
附錄
- 編譯hello.c 囉唆資訊節錄
1
|
|
- 會連結系統提供的object檔案列出如下
- crtn.o
- Scrt1.o
- crti.o
- crtendS.o
- crtbeginS.o
在Ubuntu 18.04.2 Trace 程式呼叫 Glibc 函數
不囉唆,直接上懶人包。
環境設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
使用方式
1
|
|
範例
程式
1 2 3 4 5 6 7 8 |
|
示範操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
參考資料
從gdb Dump Process 記憶體資料
無聊在trace vdso 找到的技巧。整理如下
方法說明
gdb 你要的程式
gdb
設常用的system call
如open
- 執行程式
- 中斷後
info proc mappings
dump memory 檔名 開始位址 結束位址
- 離開
- 剩下看你拿要dump 的檔案做啥了
範例: dump process中的vdso記憶體區塊,觀察vdso symbol
gdb 你要的程式
1 2 3 4 5 |
|
gdb
設常用的system call
如open
1 2 |
|
- 執行程式
1 2 3 4 5 6 |
|
info proc mapings
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
dump memory 檔名 開始位址 結束位址
1 2 3 4 5 6 7 |
|
- 看dump 檔案 symbol
1 2 3 4 5 6 7 8 9 10 11 12 |
|
加碼,觀察ASLR
懶的說明ASLR,請自行參考連結。
另外請自行比較下面兩個 cat
的記憶體區塊位址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Linux Binary 縮寫和連結
整理目前看過的資料縮寫以及網路連結,可能會更新。
ELF header
hdr
: headerEhdr
: ELF headerEI
: ELF identET
: ELF typeEM
: ELF machine
Program header
Phdr
: Program headerPT
: Program header typePF
: Prgram header flag
Section header
Shdr
: Section headerSHN
: Section header indexsh_
: Section headerSHT
: Section header typeSHF
: Section header flag
Symbol table
st
: Symbol tableSTT
: Symbol table typeSTV
: Symbol table visibility
Dynamic section
DT
: Dynamic section type
Note section
NT
: Note type
Auxiliary vector
AT
: auxiliary vector type
資源
Ubuntu 16.04更新到Ubuntu 18.04後Octopress 環境變動
本來想要寫一些東西,結果發現rake
在Ubuntu 無法執行,只好先處理了。
主要的問題是更新後Ruby
版本從16.04使用的2.3
升級成2.5
了。以下是我紀錄過的測試指令,必須承認這是網路上的東西剪貼,我不想知道後面的原理,後果自行負責。寫這篇文章另一個目的是確定上傳到網路上後可以正常發佈才證明真的解決問題了。
預安裝套件
1
|
|
Ruby 相關更新,完全不知道做啥
1 2 3 |
|
更新Octopress Gemfile
由於更新後rake
版本也從10.5.0
變成12.3.1
,所以一跑rake
就會出現版本不合的錯誤,因此我把Gemfile
rake
的版本檢查改成12
,diff 檔案如下
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|