ptrace 라이브러리를 사용하여 모든 시스템 호출과 그 인수를 추적하는 방법을 배우려고합니다. 인수를 시스템 호출에 전달하는 데 막혔습니다. 많은 온라인 리소스와 SO 질문을 통해 64 비트 머신에서 인수가 같은 순서로 레지스터 rax(sys call number), rdi, rsi, rdx, r10, r8, r9
에 저장된다는 것을 알아 냈습니다. this website을 확인하십시오. 당신이 볼 수 있듯이GCC 어셈블리 코드는 64 비트 시스템에서 32 비트 레지스터를 보여줍니다.
.file "t.c"
.section .rodata
.LC0:
.string "some print data"
.LC1:
.string "/tmp/sprintf.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $.LC0, %edi
movl $0, %eax
call printf
movl $2, %esi
movl $.LC1, %edi
movl $0, %eax
call open
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits
다음과 같이 생성이 사용 gcc -S t.c
하지만 어셈블리 코드
#include<stdio.h>
#include<fcntl.h>
int main() {
printf("some print data");
open("/tmp/sprintf.c", O_RDWR);
}
생성 된 어셈블리 코드를 다음과 같이
그냥이 확인 나는 간단한 C 프로그램을 작성입니다 코드는 esi
및 edi
에 매개 변수를 대신 저장합니다. 왜 그런가요?
또한 C 코드에서 이러한 레지스터/메모리 위치에서 전달 된 인수에 액세스하는 가장 좋은 방법은 무엇입니까? register의 내용이 인수 자체인지 또는 실제 인수가 저장되는 메모리 위치인지 어떻게 알 수 있습니까?
감사합니다. esi
에
x86 64 비트 프로세서에서 32 비트 레지스터의 내용을 변경하면 ** 제로 확장 ** 결과가 전체 64 비트 레지스터에 배치됩니다. 32 비트 레지스터를 사용하면 명령어의 인코딩을 단축 할 수 있습니다. _EDI_는 레지스터 _RDI_의 하위 32 비트이고 _ESI_는 _RSI_ –
의 하위 32 비트입니다. @MichaelPetch : ptrace 호출에서이 레지스터에 액세스하려고합니다. 그래서 rdi에 액세스하려고해도 내게 정확한 데이터를 제공해야한다고 귀하의 의견에서, 나는 맞습니까? – harrythomas
32 비트 레지스터에 vale을 두는 경우 64 비트 레지스터와 동일한 값이어야하지만 64 비트 폭이어야합니다. 따라서 64 비트 레지스터를 보는 것은 정확합니다. 따라서 _EDI_에 기록되었지만 내용은 64 비트 레지스터 _RDI_를 통해 볼 수 있습니다. –