4.6 이전의 커널은 어셈블리 스텁을 사용하여 중요한 시스템 호출(예: 포크, 복제, 실행 등)의 후크를 강제합니다. 특히 execve의 경우 다음 코드 조각은커널 4.5execve에 대한 항목 스텁 표시:
ENTRY(stub_execve)
call sys_execve
return_from_execve:
...
END(stub_execve)
체계통화 테이블이 스텁의 주소를 포함하며 이 스텁은 원래 execve를 추가로 호출합니다. 따라서 이 환경에서 execve를 후크하려면 call sys_execve
후크 루틴으로 스텁을 패치하고 필요한 작업을 완료한 후 원래 execve를 호출해야 합니다. 그것은 모두 행동으로 볼 수 있습니다프로그램 실행, Linux용 프로세스 실행 모니터링 유틸리티입니다. 커널 4.4를 사용하여 Ubuntu 16.04에서 execmon이 성공적으로 실행되는 것을 테스트했습니다.
커널 4.6부터 중요한 통화 보호의 상위 수준 체계가 변경되었습니다. 이제 스텁은 다음과 같습니다.
ENTRY(ptregs_\func)
leaq \func(%rip), %rax
jmp stub_ptregs_64
END(ptregs_\func)
execve 호출 \func
로 확장되는 위치입니다 . sys_execve
시스템에 대해 이야기해보자통화 테이블이 스텁은 포함되어 있으며 이 스텁은 원래 execve를 호출하지만 이제 를 실행하는 대신 더 안전한 방법으로 call sys_execve
이 최신 스텁은 호출된 함수의 주소를 RAX
레지스터에 저장하고 아래와 같이 다른 스텁으로 점프합니다(설명 제거됨).
ENTRY(stub_ptregs_64)
cmpq $.Lentry_SYSCALL_64_after_fastpath_call, (%rsp)
jne 1f
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
popq %rax
jmp entry_SYSCALL64_slow_path
1:
jmp *%rax /* called from C */
END(stub_ptregs_64)
이것을 봐주세요이것이 스텁의 댓글과 기타 참조 태그를 확인하세요.
나는 이 보호를 극복하고 원래 호출을 후크 기능으로 패치하기 위해 몇 가지 논리를 생각해내려고 열심히 노력했지만 아직 성공하지 못했습니다. 저와 함께 도와주실 분 계신가요?