簡體   English   中英

C 中的非法匯編指令

[英]Illegal assembly instruction in C

我正在嘗試使用 C 程序生成匯編指令跟蹤。 我正在使用 asm 函數插入在 x86_64 中非法的匯編指令並檢測它們。

我有以下 C 程序 -

int main()
{
    asm(".byte 0x16"); // Illegal in x86_64
    asm(".byte 0x17"); // Illegal in x86_64
    return 0;
}

這是主函數的指令跟蹤,這是預期的 -

.text:004004d6 55                               push   %rbp
.text:004004d7 48 89 e5                         mov    %rsp,%rbp
.text:004004da 16                               (bad)  
.text:004004db 17                               (bad)  
.text:004004dc b8 00 00 00 00                   mov    $0x0,%eax
.text:004004e1 5d                               pop    %rbp
.text:004004e2 c3                               retq   
.text:004004e3 66 2e 0f 1f 84 00 00 00 00 00    nopw  %cs:0x0(%rax,%rax,1)
.text:004004ed 0f 1f 00                         nopl   (%rax)

我正在使用英特爾 PIN 來運行程序跟蹤,並根據我得到的指令進行某種分析。 因此,對於(壞的)指令,它們是非法的,從而導致程序崩潰。 我檢查跟蹤中每條指令的指令地址以及下一條指令的地址。

Pin所示的mov %rsp, %rbp指令的下一條指令地址(地址0x004004d7,0x16指令之前的那個)是0x0。 當下一條指令是條件/無條件分支指令時,0x0 由 Pin 顯示。 由於它也顯示為錯誤指令,我懷疑錯誤指令正在調用終止程序並給出以下消息的異常處理程序 -

Illegal instruction (core dumped)

我正在使用 Pin 來檢測指令,當我收到非法指令時,我會進行某種模擬,然后刪除該指令,以便跟蹤可以進一步進行。

是否有任何類型的設置/標志來禁用此非法指令異常生成?

我正在使用 gcc 生成我的可執行文件,它可以簡單地編譯而不會產生錯誤。 當我執行指令時問題就來了。 當遇到非法指令時,是否有任何設置只是簡單地遍歷指令?

根據要求,這是我用來將ud2未定義指令修補到ud2核機器上的nop nop和多核機器上的nop lock 我刪除了與您的用例完全無關的代碼:

void __gmon_start__(void)
{
   if(ill) return;
   ill=true;
   struct sigaction act;
   memset((void *) &act, 0, sizeof(act));
   act.sa_sigaction=sigill;
   act.sa_flags=SA_SIGINFO;
   sigaction(SIGILL, &act, NULL);
   // more code to set IsUP goes here
}

和:

static void sigill(int, struct siginfo *info, void *extra)
{
    // Dynamically patch a 'ud2' to a 'nop lock' or a 'nop nop'

    // Begin with a full CPU sync (purge unmodified code)
    __asm__ __volatile__("cpuid" : : : "ax", "bx", "cx", "dx");

 // There was code here to acquire a mutex to prevent
 // multiple attempts to change the same code

  ucontext_t *uc=(ucontext_t *) extra;
  if (uc==NULL) { char *j=NULL; *j++; } // fatal

  unsigned char *instr=(unsigned char *) uc->uc_mcontext.gregs[14]; // EIP
  if(instr==NULL) { char *j=NULL; *j++; } // fatal


    if(instr[0] != 0x90)
    { // instruction wasn't already patched

     if ( (instr[0] != 0x0f) || // must be a ud2
            ((instr[1] != 0x0b) && (instr[1] != 0xb9)) )
      { char *j=NULL; *j++; } // fatal

      mprotect( (void *) ( ((int) instr) & ~(PAGESIZE-1)),
           PAGESIZE, PROT_WRITE | PROT_EXEC | PROT_READ);
      instr[0] = 0x90; // first byte is always a nop
      instr[1] = (IsUP) ? 0x90 : 0xf0;
      mprotect( (void *) ( ((int) instr) & ~(PAGESIZE-1)),
          PAGESIZE, PROT_EXEC | PROT_READ);
   }

  // mutex was released here

  // Reflush the CPU
  __asm__ __volatile__("cpuid" : : : "ax", "bx", "cx", "dx");
 }

抱歉,代碼一團糟。

暫無
暫無

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

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