2009-09-17 2 views
1

리눅스 프로세스의 CPUID 명령어를 트랩하고 피딩하는 좋은 방법을 찾고 있습니다. 프로세스에 의해 생성 된 모든 실행 가능 mmap 영역에서 ptrace()를 사용하여 모든 cpuid opcode를 패치하고 int3로 대체합니다. CPUID opcode 바이트가 다른 더 긴 opcode의 일부로 자주 등장하기 때문에 잘 작동하지 않았습니다.CPUID 명령어를 트랩하는 방법을 찾고 있습니다.

그래서 기본적으로 특정 메모리 주소가 아닌 opcode를 호출 할 때마다 중단 점을 설정할 수있는 방법을 찾고 있습니다. 누구든지 그 방법을 알고 있습니까?

답변

1

알아두면 좋은 쉬운 방법이 아닙니다.

GDB의 python 스크립팅 API를 사용하면 프로그램을 자동으로 단계별로 실행하고 각 명령을 실행하기 전에 검사 할 수 있습니다.

또 다른 불쾌한 방법은 오픈 소스 x86 에뮬레이터 인 Bochs 같은 소스를 가져 와서 원하는 지침이 실행될 때 원하는대로 편집 할 수 있습니다. 임의의 x86 코드에서이 작업을 수행하고 모든 코너 케이스를 잡을 수 일반적으로 유일한 방법에서

2

입니다하려면 다음 중 하나를

  • 한 단계 및이 실행되기 전에 (아래 참조, PTRACE_SINGLESTEP)를 각 명령을 검사; 또는
  • x86 명령어 세트를 완전히 에뮬레이트하십시오.

첫 번째 방법이 더 좋습니다.

(자기 계발 코드 나 다른 명령의 중간으로 점프하지 않기 때문에 단일 스텝핑을 사용하여 JIT 이외의 다른 opcode를 디 컴파일하는 것은 효과가 없습니다.

이 될 다음 단어를 받고, PTRACE_PEEKTEXT에 전달할 단일 스테핑 방법, 추적 된 프로세스가 중지 할 때마다, 당신은 다음 주소로 아이의 %eip 레지스터 값을 사용하여, 아이의 레지스터를 얻을 수 PTRACE_GETREGS을 사용을 구현하려면 실행. 해당 단어를 검사하여 CPUID 명령어인지 확인합니다. 그렇다면 자식 세트의 레지스터 세트를 조정하여 명령어를 에뮬레이트합니다 (CPUID 명령어를 지나친 %eip 전진 포함). 그런 다음 PTRACE_SINGLESTEP으로 전화하여 프로세스를 계속 진행하십시오.

관련 문제