iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0

組合語言

組合語言(Assembly Language)是介於機器語言與高階語言之間的程式設計語言。主要針對處理器的架構設計,因此不同的處理器可能會有不同的指令集,這使得組合語言具有高度的硬體相關性。

組合語言的特點

  • 低階語言:組合語言使用助憶符號來表示機器指令,這些符號與處理器的指令集直接對應,讓程式設計者能夠控制每一個指令的執行。

  • 高效能:由於組合語言直接操作硬體資源(如寄存器、記憶體),其效能比高階語言更高,特別是在嵌入式系統、驅動程式或對效能有極高要求的場景中,組合語言的應用十分廣泛。

  • 精確控制:程式設計者能夠完全掌控程式的執行流程、記憶體配置和處理器資源的使用,這使得組合語言在進行低階系統開發時具有極大的靈活性。

  • 難度高:由於組合語言相較於高階語言更接近機器指令,程式設計者需要更高的專業知識。debug 困難且容易出現與硬體相關的問題。

暫存器

暫存器(Register)是處理器內部的一種高速存儲單元,用於暫時儲存數據或指令,存取速度極快,遠高於主記憶體(RAM)。在組合語言的程式設計中,暫存器是至關重要的資源,因為它們是 CPU 進行各種運算的核心部分。處理器在執行指令時,會將數據載入暫存器中進行運算,這比直接操作記憶體更有效率。

常見的暫存器種類

  1. 通用暫存器(General-Purpose Registers, GPRs):這類暫存器可用於存放任何類型的數據,處理器在進行算術、邏輯或數據搬移操作時,都會使用到這些暫存器。例如,x86架構中的 AX、BX、CX 和 DX 是常見的通用暫存器。

  2. 特殊用途暫存器:

    • 累加器(Accumulator):通常用於算術和邏輯運算,存放操作的結果。累加器的典型名稱如 AX(x86架構)。
    • 基底暫存器(Base Register):儲存基址,通常在記憶體尋址中用來計算有效地址。
    • 計數暫存器(Counter Register):通常用於迴圈計數或字符串操作中的計數操作。
  3. 指令指標暫存器(Instruction Pointer, IP 或 PC):儲存當前正在執行的指令地址,處理器根據指令指標的值來決定下一條指令的位置。它在每次執行完一條指令後自動更新,用以指向下一條即將執行的指令。

  4. 堆疊指標暫存器(Stack Pointer, SP):用於指向堆疊的頂部。堆疊是一種特殊的數據結構,暫存器 SP 用於管理函數調用和返回地址。在進行函數調用或中斷處理時,堆疊指標用來儲存上下文資訊,確保正確性。

  5. 狀態暫存器/標誌暫存器(Status/Flag Register):此暫存器保存操作的結果標誌(flags),例如運算是否發生進位、是否為零等。這些標誌用於控制後續的程式流程。Zero Flag、Carry Flag、Overflow Flag 等。

舉例來說

將資料從記憶體載入到暫存器,或者從一個暫存器移到另一個暫存器。在 x86 組合語言中:

MOV AX, [1000h] ; 將記憶體地址 1000h 的數據搬移到 AX 暫存器
MOV BX, AX      ; 將 AX 中的數據搬移到 BX

暫存器中的數據進行算術運算。例如:

ADD AX, BX ; 將 AX 和 BX 中的數值相加,結果保存在 AX 中

今天的練習都是有關組合語言的題目

Lab_1 - Bit-O-Asm-1

https://ithelp.ithome.com.tw/upload/images/20241001/20169462FNp7553lnl.png

先來看看題目給的組合語言裡面都寫了些什麼。題幹寫說 flag 會儲存在 eax 裡面,那 <+15> 正好在做把 0x30 放進 eax 暫存器的動作。

<+0>:     endbr64 
<+4>:     push   rbp
<+5>:     mov    rbp,rsp
<+8>:     mov    DWORD PTR [rbp-0x4],edi
<+11>:    mov    QWORD PTR [rbp-0x10],rsi
<+15>:    mov    eax,0x30
<+20>:    pop    rbp
<+21>:    ret

0x30 拿去線上的進制轉換工具,將 16 進位 轉換成 10 進位,30 -> 48,用 picoCTF{} 包起來就是我們的 flag 惹。

Lab_2 - Bit-O-Asm-2

https://ithelp.ithome.com.tw/upload/images/20241001/20169462aGQfK7BdEe.png

題目寫說 flag 會儲存在 eax 裡面,那這題多了一次轉換,先把 0x9fe1a 存入 rbp-0x4 的位置,再將 rbp-0x4 的值加載到 eax 暫存器中。因此 eax 的值也就是 0x9fe1a

<+0>:     endbr64 
<+4>:     push   rbp
<+5>:     mov    rbp,rsp
<+8>:     mov    DWORD PTR [rbp-0x14],edi
<+11>:    mov    QWORD PTR [rbp-0x20],rsi
<+15>:    mov    DWORD PTR [rbp-0x4],0x9fe1a
<+22>:    mov    eax,DWORD PTR [rbp-0x4]
<+25>:    pop    rbp
<+26>:    ret

一樣把 0x9fe1a 拿去線上的進制轉換工具,將 16 進位 轉換成 10 進位,9fe1a -> 654874,用 picoCTF{} 包起來就是我們的 flag 惹。

今天的練習就到這邊,以下是參考資料,請搭配服用:

組合語言 1
組合語言 2

內文如有錯誤,還請不吝指教~


上一篇
Day16 - [Reverse] 程式碼分析
下一篇
Day18 - [Reverse] GDB
系列文
新手村預備,CTF 小菜雞跌跌撞撞的旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言