簡體   English   中英

使用非規范地址檢索 memory 數據會導致 SIGSEGV 而不是 SIGBUS

[英]Retrieving memory data with non-canonical-address causes SIGSEGV rather than SIGBUS

我無法使用以下匯編代碼生成“總線錯誤”。 這里我使用的 memory 地址不是合法的“規范地址”。 那么,如何觸發該錯誤?

我在 Ubuntu 20.04 LTS 和 NASM 2.14.02 下運行這段代碼,但它導致負載出現 SIGSEGV 分段錯誤,而不是 SIGBUS。

global _start
section .text
_start:
    mov rax, [qword 0x11223344557788]
    mov rax, 60
    xor rdi, rdi
    syscall

編譯后對應的X86-64匯編代碼:

Disassembly of section .text:

0000000000401000 <_start>:
  401000:   48 a1 88 77 55 44 33    movabs 0x11223344557788,%rax
  401007:   22 11 00 
  40100a:   b8 3c 00 00 00          mov    $0x3c,%eax
  40100f:   48 31 ff                xor    %rdi,%rdi
  401012:   0f 05                   syscall

如果您查看MOV指令的指令集架構手冊,您會發現訪問非規范地址會產生#GP(0)一般保護錯誤:

在此處輸入圖像描述

Linux 將所有#GP異常映射到 SIGSEGV 信號(分段錯誤)。 但是,在 Linux 中,有一種方法可以讓非規范地址導致總線錯誤,即讓處理器引發#SS (堆棧段)異常。 Linux 將#SS異常映射到 SIGBUS 信號。 將堆棧指針設置為非規范地址,然后執行堆棧相關操作將產生這樣的異常。

此代碼應產生總線錯誤

global _start
section .text
_start:
    mov rsp, 0x8000000000000000 ; Set RSP to a non-canonical address
    push rax                    ; Pushing value on stack should produce BUS ERROR

在 Linux 上產生總線錯誤的另一種方法是引發#AC (對齊檢查)異常。 如果您在 RFLAGS 中編寫啟用 Alignment 檢查位(位 18)的環 3(用戶)代碼並執行未對齊的memory訪問,您還應該收到 SIGBUS 信號。 此代碼應產生總線錯誤

global _start
section .text
_start:
    pushf                      ; Put current RFLAGS on the stack
    or dword [rsp], 1<<18      ; Enable bit 18 (Alignment Check) of the
                               ;     RFLAGS value saved on stack
    popf                       ; Pop new RFLAGS flags value into the RFLAGS register
    mov eax, [rsp + 1]         ; Move a DWORD value from unaligned address
                               ;     Should produce a BUS ERROR

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM