成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

萬萬沒想到,一個(gè)可執(zhí)行文件原來包含了這么多信息!

開發(fā) 前端
拿到一個(gè)編譯好的可執(zhí)行文件,你能獲取到哪些信息?文件大小,修改時(shí)間?文件類型?除此之外呢?實(shí)際上它包含了很多信息,這些你都知道嗎?

拿到一個(gè)編譯好的可執(zhí)行文件,你能獲取到哪些信息?文件大小,修改時(shí)間?文件類型?除此之外呢?實(shí)際上它包含了很多信息,這些你都知道嗎?

示例程序

  1. //main.c 
  2. #include<stdio.h> 
  3. void testFun() 
  4.     printf("公眾號:編程珠璣\n"); 
  5. int main(void) 
  6.     testFun(); 
  7.     return 0; 

編譯得到可執(zhí)行文件main:

  1. $ gcc -o main main.c 

ELF頭信息

只需要一條簡單的命令,就可以獲取很多信息

  1. $ readelf -h main 
  2. ELF Header: 
  3.   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  
  4.   Class:                             ELF64 
  5.   Data:                              2's complement, little endian 
  6.   Version:                           1 (current) 
  7.   OS/ABI:                            UNIX - System V 
  8.   ABI Version:                       0 
  9.   Type:                              EXEC (Executable file) 
  10.   Machine:                           Advanced Micro Devices X86-64 
  11.   Version:                           0x1 
  12.   Entry point address:               0x400430 
  13.   Start of program headers:          64 (bytes into file) 
  14.   Start of section headers:          6648 (bytes into file) 
  15.   Flags:                             0x0 
  16.   Size of this header:               64 (bytes) 
  17.   Size of program headers:           56 (bytes) 
  18.   Number of program headers:         9 
  19.   Size of section headers:           64 (bytes) 
  20.   Number of section headers:         31 
  21.   Section header string table index: 28 

程序位數(shù)

  1. Class:     ELF64 

Class展示了該程序的位數(shù),如這里顯示的是ELF64,如果你將它放到一個(gè)32位系統(tǒng)中運(yùn)行,運(yùn)行得起來就怪了。換句話說,64位系統(tǒng)上能運(yùn)行32位和64位的程序,但是32位系統(tǒng)上,無法運(yùn)行64位的程序。

大小端

  1. Data:   2's complement, little endian 

還記得那個(gè)到處可見的面試題嗎?如何判斷當(dāng)前CPU是大端還是小端?除了各種秀代碼的方式,你想到這個(gè)方式了嗎?

找一個(gè)該平臺上的正運(yùn)行的可執(zhí)行文件或系統(tǒng)庫,然后使用readelf -h看一下,是不是很快就看出來了?多么明顯的little endian。

運(yùn)行平臺

  1. Machine:   Advanced Micro Devices X86-64 

做嵌入式相關(guān)的可能經(jīng)常需要做交叉編譯,而編譯出來的程序到底對不對呢?比如你在86平臺編譯arm的程序,最終生成的可執(zhí)行文件到底能不能運(yùn)行在arm平臺呢?通過Machine字段就可以很容易確定,從這里可以看到,它是運(yùn)行在x86平臺的。

同樣的,當(dāng)你在交叉編譯的時(shí)候,發(fā)現(xiàn)總有一個(gè)庫鏈接不上,但是庫又存在,不妨看看這個(gè)庫和你要編譯的平臺是否匹配。

鏈接了哪些動(dòng)態(tài)庫?

編好的程序依賴了哪些動(dòng)態(tài)庫呢?可不要放到另外一個(gè)平臺就起不來啊。瞅瞅:

  1. $ ldd main 
  2.     linux-vdso.so.1 =>  (0x00007ffe750e7000) 
  3.     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f749920a000) 
  4.     /lib64/ld-linux-x86-64.so.2 (0x00007f74995d4000) 

原來鏈接了這些庫,所以當(dāng)你在網(wǎng)上下載一些程序,運(yùn)行的時(shí)候提示你某些so找不到,不妨看看它鏈接的動(dòng)態(tài)庫在什么位置,你的機(jī)器上到底有沒有吧。

新增的函數(shù)和全局變量包含了嗎?

新增了一個(gè)全局變量或者函數(shù),但是編譯完之后,不確定有沒有?

  1. $ nm main |grep testFun 
  2. 0000000000400526 T testFun 

nm看下就知道了。當(dāng)然了,如果你看到某個(gè)庫的函數(shù)前面的標(biāo)志不是T,而是U,說明該函數(shù)未在該庫中定義。

nm主要用于查看elf文件的符號表信息。

有符號表嗎

我們都知道,沒有符號表的程序,在core之后是沒有太多有效信息可看的,也是無法使用gdb正常調(diào)試的,那么怎么看有沒有符號表呢?

  1. $ file main 
  2. main: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=0d9a7eb860459b585d2b33ae28d7c67d5ba12669, not stripped 

咦?你看這里是不是也可以看到程序位數(shù),適用平臺等信息?

如果使用file命令看到最后是not stripped,那么則含有符號表,一般線上的程序可能會(huì)選擇去掉符號表信息,因?yàn)榭梢源蟠鬁p少可執(zhí)行文件的空間占用。

  1. $ strip main 

這個(gè)時(shí)候再看看:

  1. $ nm main 
  2. no main symbols 

程序占用空間太大?

為什么程序的占用空間這么大?不妨看看是不是使用了過多的靜態(tài)變量或全局變量:

  1. $ size main 
  2.    text       data     bss     dec     hex filename 
  3.    1261        552       8    1821     71d main 

看到data部分的大小了嗎?看起來并沒有多少,如果這里占用空間過大,那可能是你程序中用到了太多的全局變量和靜態(tài)變量或常量。當(dāng)然了,如果你的全局變量都是初始化為0的,那么data這里是不會(huì)有明顯的變化的(為什么?)。

在開頭分別加下面這一行,其影響可執(zhí)行文件的效果不一樣奧。

  1. char str[1000] = {0}; 
  2. char str[1000] = {1}; 

包含某個(gè)字符串嗎

這個(gè)程序里面包含什么特殊的字符串嗎?可以搜索一下:

  1. $ strings main |grep hello 
  2. hello, 

嗯?這樣一想,好像還可以把版本號信息寫進(jìn)去呢。

C還是C++?

如果將前面的程序按照C++編譯:

  1. $ g++ -o main main.c 
  2. $ nm main |grep test 
  3. 0000000000400526 T _Z7testFunv 

你會(huì)發(fā)現(xiàn)使用g++編譯出來的test函數(shù)符號前帶頭,后帶尾,這也是C++中有重載和C中沒有重載的原因之一。

函數(shù)的匯編代碼是?

反匯編所有代碼:

  1. $ objdump -d main 

那如果要反匯編特定函數(shù)(如main函數(shù))呢?先按照地址順序輸出符號表信息:

  1. $ nm -n main |grep main -A 1 
  2. 0000000000400537 T main 
  3. 0000000000400550 T __libc_csu_init 

我們得到main的開始地址為0x400537,結(jié)束地址為0x400550。

反匯編:

  1. $ objdump -d main --start-address=0x400537 --stop-address=0x400550 
  2. 0000000000400537 <main>
  3.   400537:    55                      push   %rbp 
  4.   400538:    48 89 e5                mov    %rsp,%rbp 
  5.   40053b:    b8 00 00 00 00          mov    $0x0,%eax 
  6.   400540:    e8 e1 ff ff ff          callq  400526 <testFun> 
  7.   400545:    b8 00 00 00 00          mov    $0x0,%eax 
  8.   40054a:    5d                      pop    %rbp 
  9.   40054b:    c3                      retq    
  10.   40054c:    0f 1f 40 00             nopl   0x0(%rax) 

 

 

看看只讀數(shù)據(jù)區(qū)有哪些內(nèi)容?

當(dāng)我們嘗試修改常量字符串的時(shí)候,編譯器會(huì)提示我們,它們是只讀的,真的如此嗎?

  1. $ readelf main -x .rodata 
  2. Hex dump of section '.rodata': 
  3.   0x004005d0 01000200 00000000 68656c6c 6f2ce585 ........hello,.. 
  4.   0x004005e0 ace4bc97 e58fb7ef bc9ae7bc 96e7a88b ................ 
  5.   0x004005f0 e78fa0e7 8e9100                     ....... 

看到了嗎?我們的hello,字符串放在了這里。

總結(jié)

本文僅列出了一些比較常見的可執(zhí)行文中能讀到的信息,歡迎補(bǔ)充。

思考

對于a和b,它們的內(nèi)存存儲區(qū)域是一樣的嗎?為什么?

  1. char *a = "hello,world"
  2. char a[] = "hello,world"; 

sizeof計(jì)算a和b的大小一樣嗎?又為什么?

 

 

 

責(zé)任編輯:趙寧寧 來源: 編程珠璣
相關(guān)推薦

2021-11-29 05:37:24

Windows Def操作系統(tǒng)微軟

2021-08-31 09:35:01

TCPIP漏洞

2021-08-12 06:52:02

谷歌面試ArrayList

2015-07-15 13:00:31

英特爾開源

2019-12-09 10:13:20

HashMap選擇容量

2021-03-18 09:06:17

函數(shù)MainJava

2021-01-27 18:13:35

日志nginx信息

2016-09-01 13:54:23

Google太空電梯懸滑板

2023-10-31 12:29:25

模型訓(xùn)練

2022-11-29 09:12:12

硬件技術(shù)拼圖

2023-12-26 15:10:00

處理二進(jìn)制文件

2020-08-14 08:19:25

Shell命令行數(shù)據(jù)

2015-02-02 11:03:12

2018-06-27 14:23:38

機(jī)器學(xué)習(xí)人工智能入門方法

2017-12-12 11:09:39

顯卡散熱CPU

2019-10-12 08:53:26

Redis多線程版本

2021-02-21 17:14:27

程序員技能開發(fā)者

2024-01-04 12:33:17

ChatGPTAI視頻

2012-01-05 10:37:40

Java

2018-05-02 09:38:02

程序員代碼互聯(lián)網(wǎng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产中文字幕在线观看 | 午夜精品在线 | 亚洲成人一区二区 | 亚洲视频在线观看 | 热99视频 | 国产真实精品久久二三区 | 欧美日韩国产在线 | www久久久| 亚洲综合99 | 国产人成精品一区二区三 | 久久久久国产精品免费免费搜索 | 91社区在线观看高清 | 99精品国产在热久久 | 久热爱| 91在线影院 | 中文二区 | 日韩中文不卡 | 国产乱码精品一区二区三区五月婷 | 精品国产精品国产偷麻豆 | 婷婷久久网 | 精品中文视频 | 91久久久久久久久久久久久 | 国产精品视频一 | 亚洲精品成人 | 亚洲精品一区二区二区 | 国产精品久久久久久久岛一牛影视 | 毛片综合 | 男女视频免费 | 久久久久久免费精品一区二区三区 | aaa国产大片| 国产精品视频久久久久久 | 成年人精品视频在线观看 | 久久激情视频 | 欧美aaaaaaaa| 日韩在线不卡视频 | 国产成人免费视频网站高清观看视频 | 色综合视频 | 视频一区二区中文字幕 | 爱爱爱av | 日韩福利在线 | 波多野吉衣在线播放 |