[英]Getting/setting registers for arm32 executable on aarch64
我的目標是使用ptrace
設置在 64 位處理器上運行 32 位 ARM 可執行文件的進程的程序計數器(和其他寄存器)。
如果這是一個 64 位的可執行文件,那么我可以使用struct user_pt_regs
的pc
字段(在 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 = ®s;
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.