Linux_C++_編譯過程以及二進位制分析

辰令發表於2024-12-02

目標

1.編寫程式碼-解剖程式碼
   瞭解二進位制格式、記憶體佈局和給定處理器的指令集	
   使用反彙編器和逆向工具的組合來理解、解剖或修改程式的行為
   分析記憶體轉儲、重建程序映像,並探索一些更神秘的二進位制分析領域,包括 Linux 病毒感染和二進位制取證
   
   Linux 二進位制分析學習手冊 二進位制分析實戰

工具

 Binutils 是一組開發工具,包括聯結器,彙編器和其他用於目標檔案和檔案的工具	  
 進階--ida	
 
ptrace, 這個系統呼叫是Linux程式除錯工具gdb以及系統呼叫追蹤器strace的基礎
    硬體_CPU特權級別分層機制  -->使用者態和核心態	--> 系統呼叫  --> CPU上下文切換 
命令列
	ptrace 即 (process trace    )程序跟蹤  控制程序被稱為tracer  被控制的程序被稱為tracee
	strace 即 (system call trace)系統呼叫跟蹤 利用
	  迴圈中的
	     PTRACE_SYSCALL請求來顯示執行程式中系統呼叫(也稱為syscalls)活動的資訊,以及執行過程中捕獲的訊號
	ltrace 即 (library trace )   庫跟蹤 提供更細粒度的資訊,因為它解析可執行檔案的動態段,並列印來自共享和靜態庫的實際符號/函式	 
  readelf 命令是解剖ELF二進位制檔案的最有用的工具之一	 
內容
  裝置和檔案:
  環境變數
  命令列	

發展

 本地工具鏈(native toolchain)與交叉編譯工具鏈(cross-compilation toolchain) 
   預處理-編譯器-彙編器--連結器 

GNU編譯工具鏈
  Frontend:前端詞法分析、語法分析、語義分析、生成中間程式碼
  Optimizer:最佳化器   中間程式碼最佳化
  Backend:後端  生成機器碼
    編譯器-gcc
       語法語義--彙編程式
       編譯器(如gcc或clang)來自動處理從原始碼到可執行檔案的整個編譯過程。
      這些編譯器內部整合了彙編器和其他工具,使得我們可以更方便地進行程式設計和除錯。
	  在生成目的碼之前,編譯器通常會對中間表示進行最佳化,以提高程式的效能和效率
    
    彙編器 GNU Assembler
        as是GNU Binutils工具集的一部分,
          用於將組合語言源程式(通常以.s或.S為副檔名)轉換為機器語言的目標檔案(通常以.o為副檔名)
        二進位制機器碼
    連結器
        將編譯器生成的目標檔案(.o檔案)連結成可執行檔案或共享庫
        ld  
          輸入檔案內的section放入輸出檔案內, 並控制輸出檔案內各部分在程式地址空間內的佈局.
            輸入檔案內的section稱為輸入section(input section),
        	    每個section至少包含兩個資訊: 名字和大小。 
        		     大部分section還包含與它相關聯的一塊資料, 稱為section contents(section內容).
        		     “loadable(可載入的)”或“allocatable(可分配的)
        	輸出section
        	   兩個地址: VMA(virtual memory address )虛擬記憶體地址或 程式地址空間地址)和
        	             LMA(load memory address    )載入記憶體地址或 程序地址空間地址)
        		 VMA是執行輸出檔案時section所在的地址,而LMA是載入輸出檔案時section所在的地址
        ld.gold 是GNU二進位制工具鏈中的一個連結器,它作為GNU ld(GNU Linker)的一個快速替代品
          ELF連結器

llvm 編譯工具鏈支援
    LLVM中間表示(Intermediate Representation, IR)

ELF 二進位制格式

        包括程式載入、動態連結、符號表查詢以及許多其他緊密協調的元件
        readelf
 ELF 二進位制檔案保護程式
 ELF檔案有兩種檢視形式:連結檢視和執行檢視
 
Linux下gcc 編譯 C 原始檔時,生成的是Shared object file而不是Executable file	 
   檔案型別是DYN (Shared object file),而不是EXEC (Executable file)
      gcc預設加了--enable-default-pie選項
   Position-Independent-Executable是Binutils,glibc和gcc的一個功能,能用來建立介於共享庫和通常可執行程式碼之間的程式碼–	  
      上-no-pie 禁用掉該預設選項:
   
readelf, objdump, ldd, xxd,hexdump, dd, strace,   
    1. 使用 file 解決型別問題
	    Linux作業系統自帶了base64的小工具(通常作為 GNU coreutils 的一部分),這個工具可以對Base64進行編碼和解碼
		file的另一個功能:檢視壓縮檔案。將-z選項傳遞給file,檢視壓縮檔案的內容而無須進行提取檔案的操作
	2 使用ldd探索依賴性
	3 使用xxd檢視檔案內容
	4 使用readelf解析並提取ELF庫檔案
	5 使用nm解析符號 C++編譯器提出了符號修飾(mangled name)。符號修飾實質上是原始函式名稱與函式引數編碼的組合。這樣,函式的每個版本都會獲得唯一的名
	6 使用strings檢視Hints
	7 使用strace和ltrace跟蹤系統呼叫和庫檔案呼叫
	8 使用objdump檢查指令集行為
	9 使用GDB轉儲動態字串緩衝區
		
    GNU binutils    (配合gcc工作)
    GNU coreutils	  coreutils【對應的嵌入式場合,主要是 busybox 】

交叉編譯

 交叉編譯工具鏈主要由binutils、gcc和glibc 3個部分組成
    確定目標平臺
	構建交叉工具鏈:

	crosstool-ng的

設計和實現了機器學習框架

 (如TensorFlow、PyTorch、MindSpore等)
 編譯器前端
   編譯器前端: 機器學習框架往往具有AI編譯器來構建計算圖,並將計算圖轉換為硬體可以執行的程式
 編譯器後端和執行時: 
    完成計算圖的分析和最佳化後,機器學習框架進一步利用編譯器後端和執行時實現針對不同底層硬體的最佳化

通用編譯器中的概念,
  如AOT(Ahead of Time提前編譯)、
   JIT(Just in time 即時)、IR(Intermediate Representation中間表示)、
   PASS最佳化、AST(Abstract Trees)、副作用、閉包等概念
機器學習編譯器-AI編譯器
    AI編譯器的設計受到了主流編譯器(如LLVM)的影響
	      AI編譯器一般採用多層級IR設計
        MLIR(Multi-Level Intermediate Representation)是一種用於構建可重用和可擴充套件編譯的新方法
		   使用MLIR為Fortran、機器學習圖構建抽象
		   
		   
機器學習框架如 MindSpore 採用統一的IR設計(MindIR)		
    MindSpore IR (MindIR) is a function-style IR based on graph representation	

使用機器學習框架

參考

 www.gnu.org/software/binutils/	
 Linux交叉編譯工具鏈 https://www.cnblogs.com/hellokitty2/p/9745959.html	
   https://www.cnblogs.com/apachecn/p/18196561
   成為一名二進位制分析師需要用到的Linux二進位制分析工具有哪些?
MindSpore IR(MindIR)   
 https://www.mindspore.cn/docs/zh-CN/r0.7/design/mindspore/ir.html   
 https://openmlsys.github.io/chapter_introduction/design.html

相關文章