2017-04-14 83 views
0

我一直在研究迷你strace程序的重新編碼,而不使用PTRACE_SYSCALL來熟悉寄存器。我使用ptrace(PTRACE_GETREGS,...)來設置user_reg_struct字段,我使用ptrace(PTRACE_PEEKDATA,...)從中讀取。如何解釋PTRACE_PEEKTEXT返回值

不是真的知道如何處理函數中使用它的數據的retur(系統調用等)做的,我開始尋找一些代碼,我遇到的事情來,如:

int is_a_syscall() { 

struct user_reg_struct regs; 
unsigned short int ret; 

ret = ptrace(PTRACE_PEEKDATA, pid, regs.rip, 0); 
if (ret == 0xFFFF) { 
    perror("failed") 
    exit(1); } 
if (ret == 0x80CD || ret == 0x50F) 
    return (true); 
return (false); 
} 

現在可以有人向我解釋什麼是數字在if()語句,又名:

  • 0xFFFF的,我認爲它與處理器的架構做,但我無法驗證它
  • 0x80CD0x50F

我想知道它們是什麼,在哪裏可以找到他們,我能理解他們,我如何使用它們讓我的系統調用和他們的論點。

回答

0

你的意思是這些與十進制(例如0x80CD = 32973)有什麼關係,或者它們與ptrace()相關的語義是什麼(例如0xFFFF可能意味着函數遇到錯誤)?

如果是前者,這些數字用表示的十六進制數表示。也就是說,數字範圍由0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F組成的數字系統。

如果後者請查看man page for ptrace中的返回值部分

1

您包含的代碼有點不符合常規,所以我會解釋它的作用,然後展示一種不同的方式來實現它。

unsigned short int ret; 
ret = ptrace(PTRACE_PEEKDATA, pid, regs.rip, 0); 

Linux上的ptrace返回一個長而不是無符號的短。代碼的作者只是查看ptrace返回的4或8個字節的低位2字節。由於x86是little-endian,這可以完成這項工作,但我將在稍後介紹另一種方法。

if (ret == 0xFFFF) { 
    perror("failed") 
    exit(1); } 

ptrace在失敗時返回-1。由於代碼僅存儲返回值的低位2個字節,並將該值視爲無符號,因此-1的測試使用0xFFFF代替。

由於ptrace(PTRACE_PEEKDATA, ...)即使成功也可以返回-1,所以最好還是看看errno(稍後我會進行介紹)。

if (ret == 0x80CD || ret == 0x50F) 
    return (true); 
return (false); 

您可以在像http://ref.x86asm.net/coder64.html這樣的站點上找到操作碼列表。 CDintCD80int 800F05syscall。這些是x86 Linux中用於執行系統調用的兩個操作碼。更多信息,請致電What is better 「int 0x80」 or 「syscall」?

這裏是另一種方式來檢查系統調用指令(未經測試):

int is_a_syscall(regs) 
struct user_reg_struct regs; 
{ 
    long ret; 
    unsigned char primary, secondary; 
    extern int errno; 

    errno = 0; 
    ret = ptrace(PTRACE_PEEKTEXT, pid, regs.rip, 0); 
    if (ret == -1 && errno != 0) { 
     perror("failed") 
     exit(1); 
    } 
    primary = (unsigned)0xFF & ret; 
    secondary = ((unsigned)xFF00 & ret) >> 8; 
    if (primary == 0xCD && secondary == 0x80 || primary == 0x0F && secondary == 0x05) 
     return true; 
    return false; 
} 

我使用ptrace的返回值的整個寬度。如果它是-1並且已經設置了errno,則表明有錯誤。我也使用PTRACE_PEEKTEXT而不是PTRACE_PEEKDATA,雖然在x86上並不重要。位掩碼用於獲取主操作碼和輔助操作碼字節。

我該如何使用它們來獲取我的系統調用及其參數。

對此,請參閱此詳細答案:What are the calling conventions for UNIX & Linux system calls on x86-64

相關問題