簡體   English   中英

在 aarch64 上獲取/設置 arm32 可執行文件的寄存器

[英]Getting/setting registers for arm32 executable on aarch64

我的目標是使用ptrace設置在 64 位處理器上運行 32 位 ARM 可執行文件的進程的程序計數器(和其他寄存器)。

如果這是一個 64 位的可執行文件,那么我可以使用struct user_pt_regspc字段(在 asm/ptrace.h 中定義)。

對於 32 位可執行文件,我將使用哪種結構? 我看到struct user_regs (在 sys/user.h 中)定義為

struct user_regs {
    unsigned long uregs[18];
};

我閱讀了這個問題的答案(盡管作者承認這是一個有根據的猜測),這表明使用struct user_regs中的uregs[15] 但是,由於我實際上有一個 64 位系統,這仍然適用於我的情況嗎?

即使在 64 位處理器上運行時, ptrace也會返回有效的 32 位寄存器。 為了確認這一點,請考慮以下兩個可執行文件(為簡潔起見,我省略了頭文件):

測試.c

int main()
{
    printf("PID = %li\n", (long)getpid());
    pause();
    return 0;
}

附件.c

int main(int argc, char **argv)
{
    int ret = 1;
    unsigned int expected_size;
    pid_t pid;
    struct {
        uint32_t r[18];
    } regs;
    struct iovec iov;

    if ( argc < 2 ) {
        return 1;
    }
    pid = atoi(argv[1]); // Yes, I know I should use strtol.  However, this suffices for this example.
    if ( ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 ) {
        perror("ptrace (ATTACH)");
        return 1;
    }

    iov.iov_base = &regs;
    iov.iov_len = expected_size = sizeof(regs);
    if ( ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov) != 0 ) {
        perror("perror (GETREGSET)");
        goto done;
    }
    if ( iov.iov_len != expected_size ) {
        fprintf(stderr, "Unexpected size (%zu instead of %u)\n", iov.iov_len, expected_size);
        goto done;
    }
    printf("PC is 0x%x\n", regs.r[15]);

    ret = 0;

done:
    if ( ptrace(PTRACE_DETACH, pid, NULL, NULL) != 0 ) {
        perror("ptrace (DETACH)");
        ret = 1;
    }
    ret = 1;
}

我將第一個編譯成 32 位可執行文件,第二個編譯成 64 位可執行文件。

從附加程序獲取輸出,我在/proc/<pid>/maps中查找地址,發現它位於 libc 的可執行部分(對應於pause )。

暫無
暫無

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

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