學習一門新語言需要瞭解的基礎-04 符號

来源:http://www.cnblogs.com/lyj/archive/2017/10/18/foundation_04_symbol.html
-Advertisement-
Play Games

本節內容 - 使用nm查看符號 - 使用readelf -s輸出符號信息 - 刪除符號表對反彙編的影響 - 使用strip刪除符號和調試信息 - 使用UPX壓縮並保護可執行文件 ...


本節內容

  • 使用nm查看符號
  • 使用readelf -s輸出符號信息
  • 刪除符號表對反彙編的影響
  • 使用strip刪除符號和調試信息
  • 使用UPX壓縮並保護可執行文件

我們提到的所有的東西,編譯、鏈接、可執行文件。這裡面都會涉及到一個東西叫符號,什麼叫符號。符號(symbol)用來表示一個地址(函數、變數、段名、行號信息等)

使用nm查看符號

類型通常對應段:T .text;D .data;B .bss;R .rodata

$ cat hello.c

文件

#include <stdio.h>
#include <stdlib.h>

int x = 0x1234;
int y;
char *s = "x = %x, y = %x\n";

int main()
{
    printf(s, x, y);

    return 0;
}
$ gcc -o test hello.c
$ nm test

輸出符號信息

0000000000601048 B __bss_start
0000000000601048 b completed.7585
0000000000601028 D __data_start
0000000000601028 W data_start
0000000000400460 t deregister_tm_clones
00000000004004e0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000601030 D __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601048 D _edata
0000000000601050 B _end
00000000004005d4 T _fini
0000000000400500 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400718 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000004005f4 r __GNU_EH_FRAME_HDR
00000000004003c8 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
00000000004005e0 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
                 w _Jv_RegisterClasses
00000000004005d0 T __libc_csu_fini
0000000000400560 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main
                 U printf@@GLIBC_2.2.5
00000000004004a0 t register_tm_clones
0000000000601040 D s
0000000000400430 T _start
0000000000601048 D __TMC_END__
0000000000601038 D x
000000000060104c B y

可以看到s,x,y,main,printf@@GLIBC_2.2.5是符號,每個符號都有唯一地址。符號就是這個地址的別稱。因為反彙編時候,符號可以很快知道這個地址乾什麼用的。

反彙編

$ objdump -d -M intel test | grep -A15 "<main>:"
0000000000400526 <main>:
  400526:   55                      push   rbp
  400527:   48 89 e5                mov    rbp,rsp
  40052a:   8b 15 1c 0b 20 00       mov    edx,DWORD PTR [rip+0x200b1c]        # 60104c <y>
  400530:   8b 0d 02 0b 20 00       mov    ecx,DWORD PTR [rip+0x200b02]        # 601038 <x>
  400536:   48 8b 05 03 0b 20 00    mov    rax,QWORD PTR [rip+0x200b03]        # 601040 <s>
  40053d:   89 ce                   mov    esi,ecx
  40053f:   48 89 c7                mov    rdi,rax
  400542:   b8 00 00 00 00          mov    eax,0x0
  400547:   e8 b4 fe ff ff          call   400400 <printf@plt>
  40054c:   b8 00 00 00 00          mov    eax,0x0
  400551:   5d                      pop    rbp
  400552:   c3                      ret    
  400553:   66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
  40055a:   00 00 00 
  40055d:   0f 1f 00                nop    DWORD PTR [rax]

符號表對程式執行沒有用。反彙編,找到.main段,可以看到mov彙編指令最後面可以看到根據地址信息可以查到符號名,這樣我們反彙編時候很容易知道是在操作哪行數據。
符號也知道從哪一行開始執行哪個函數,例如0000000000400526 <main>:

使用readelf -s輸出符號信息

查看包括.dynsym在內的所有符號

$ readelf -S test

刪除符號表對反彙編的影響

$ ls -lh #文件大小8.5k
$ readelf -S test #有30個段
$ strip test #刪除符號表和調試信息,運行期不需要的信息都刪除了
$ ls -lh #文件大小6.2k
$ readelf -S test #有28個段
$ nm test #輸出符號信息,沒有符號
$ ./test #執行程式不會有影響
$ objdump -d -M intel test #反彙編,整個.text段沒有區分函數

使用strip刪除符號和調試信息

使用strip刪除符號和調試信息,不包括動態符號

刪除符號表對程式有一定的保護作用,刪除符號表不一定是安全的

$ cat panic.go
package main

func main() {
    panic("abc")
}

註意和go build -ldflags "-w -s"的差異

$ go build -o xxx panic.go
$ strip xxx
$ ./xxx #在mac環境下執行
$ go build -ldflags "-w -s" -o xxx2 panic.go #建議使用官方自帶的刪除功能
$ ./xxx2

使用UPX壓縮並保護可執行文件

UPX是一個可執行文件壓縮工具,一個可執行文件a和可執行文件b,a作為b一個段存儲在b中,當b執行時,把a釋放出來執行。既然a作為數據文件存儲在b中,我們使用壓縮後存儲到b中,再解壓縮執行。b就成了可執行文件的殼。

$ upx -9 test
$ readelf -S test #沒有段信息
$ objdump -d -M intel test #反彙編不能執行

UPX是常見的一種殼,把真實的目標壓縮以後存到殼的內部,由殼在執行時把內部的數據解壓縮釋放出來。殼起到了一定的保護作用,當然這個保護實際上對高手來說沒有多大效果的,因為既然釋放出來,真實的目標肯定在記憶體當中,我直接把記憶體那段數據拷到硬碟上就可以了。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 反射是程式猿的好幫手,有了反射你可以少寫一半的代碼。下麵是一些常用的反射擴展方法。 如有高見,歡迎交流與分享:) ...
  • 之前的文章中介紹了My Blog文章維護功能的開發,開發過程中使用Area的方法建立了用於維護文章的Controller、View和Model。但是無論代碼怎麼變對於瀏覽器來說都是通過一個url地址去訪問,現在My Blog可用的url有以下幾個: http://localhost:52356/ - ...
  • 本文以近乎v5.2產品為例截圖介紹,近乎產品是基於asp.net mvc 5.0框架。大家可以下一個近乎源碼版,來進一步熟悉和瞭解學習。 近乎下載地址:http://www.jinhusns.com/ MVC項目一啟動會首先進入到Global執行Application_Start()這個方法註冊 區 ...
  • 昨日去筆試了,遇到了一道編程題,因為經常坐在電腦前面,使用開發工具已經習慣了“alt+/”,導致了平時有些方法不是很註意看,於是在整理了思路之後,寫方法的時候,完蛋了,卡殼了....導致那道題做得不是盡如人意....現在筆者將之整理出來,希望加深自己的印象的同時也能夠對讀者有所幫助。 題目:從鍵盤中 ...
  • int #數值(整數) str #字元串(文字) float #浮點(小數點) list #列表 print() #列印\輸出 len() #長度 max() #最大值 min() #最小值 del() #刪除元素 list.append(obj) #此語法中list代表列表,obj代表需要添加到l ...
  • PS:再次說明一下,原本不想寫的太啰嗦的,可之前那個系列發佈後發現,好多朋友都想馬上拿到代碼立即能上手開發自己的項目,對代碼結構、基礎常識、分類目錄與文件功能結構、常用函數......等等什麼都不懂,然後就想使用,我真的很無語,還有一些朋友有十幾年開發經驗也會問一些很基礎的問題,我都不知道怎麼回答了 ...
  • 一、簡介 阿裡巴巴於10月14日在杭州雲棲大會上,正式發佈了《阿裡巴巴Java開發規約》掃描插件!該插件基於《阿裡巴巴Java開發規約》手冊內容,在掃描代碼後,將不符合規約的代碼按Blocker/Critical/Major三個等級顯示在下方,甚至在IDEA上,還基於Inspection機制提供了實 ...
  • 簡述 寫這個工具主要目的在於減少工作量,bear在寫gitbook的時候,發現對應目錄一個一個寫進去,非常繁瑣,而且最近在學習python,所以,手癢之下寫了一個目錄生成的小工具。 工具使用 本身工具並不複雜,主要實現功能接受一個github中的raw版本的url,然後列印自動生成對應文件的mark ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...