문제

깔끔하게 컴파일되는 일부 코드를 추가했는데 방금 다음 Windows 오류가 발생했습니다.

---------------------------
(MonTel Administrator) 2.12.7: MtAdmin.exe - Application Error
---------------------------
The exception Privileged instruction.

 (0xc0000096) occurred in the application at location 0x00486752.

나는 버그 사냥을 하려고 하는데, 내가 한 일이 우연히 이 메시지를 생성한 어리석은 일이 될 것이라고 예상합니다.코드는 오류나 경고 없이 깔끔하게 컴파일됩니다.EXE 파일의 크기는 1,454,132바이트로 늘어났으며 다음 링크를 포함합니다. ODCS.lib, 그러나 DEBUG가 설정된 Win32 API에 대한 순수 C입니다(Windows 2000의 P4에서 실행).

도움이 되었습니까?

해결책

질문에 답하기 위해 특권 명령어는 "수퍼바이저"(또는 링-0) 모드에서만 실행될 수 있는 프로세서 연산 코드(어셈블러 명령어)입니다.이러한 유형의 명령어는 Windows 커널에서 I/O 장치 및 보호된 데이터 구조에 액세스하는 데 사용되는 경향이 있습니다.

일반 프로그램은 I/O 장치 등에 대한 직접 액세스를 허용하지 않는 "사용자 모드"(Ring-3)에서 실행됩니다.

다른 사람들이 언급했듯이 원인은 아마도 손상된 스택이거나 엉망인 함수 포인터 호출일 것입니다.

다른 팁

이런 종류의 일은 일반적으로 유효하지 않은 데이터를 가리키는 함수 포인터를 사용할 때 발생합니다.반환 스택을 폐기하는 코드가 있는 경우에도 발생할 수 있습니다.이러한 종류의 버그는 일반적으로 재현하기 어렵기 때문에 추적하는 것이 때로는 매우 까다로울 수 있습니다.

특권 명령어는 링-0에서만 실행이 허용되는 IA-32 명령어입니다(예:커널 모드).사용자 공간에서 이 문제가 발생한다면 정말 오래된 EXE이거나 손상된 바이너리를 갖고 있는 것입니다.

내가 생각할 수 있는 첫 번째 확률은 로컬 배열을 사용하고 있을 수 있으며 함수 선언의 상단 근처에 있다는 것입니다.범위 검사가 미쳐서 반환 주소를 덮어쓰고 커널만 실행할 수 있는 일부 명령을 가리킵니다.

내가 의심했던 것처럼 내가 한 일은 어리석은 일이었습니다.위 메시지의 댓글에 있는 몇 가지 단서 덕분에 이 문제를 두 배나 빨리 해결했다고 생각합니다.특히 앱 초기에 스택 덮어쓰기를 지적한 분들께 감사드립니다.실제로 여기에서 몇 가지 답변이 더 유용하다는 것을 알았습니다. 질문에 대한 답변으로 표시한 게시물이 어디를 봐야 할지에 대한 단서와 대기열을 제공했지만 답변이 가장 잘 요약되어 있다고 생각합니다.

결과적으로 나는 일부 도구 모음 버튼 정보(스택에 있음)를 포함하는 배열의 최대 크기를 초과하는 버튼을 추가했습니다.나는 그것을 잊고 있었다

#define MAX_NUM_TOOBAR_BUTTONS  (24)

심지어 존재했다!

오류 위치 0x00486752는 실행 가능한 코드가 일반적으로 존재하기 전에는 정말 작은 것 같습니다.나는 Daniel의 의견에 동의합니다. 그것은 나에게 거친 포인터처럼 보입니다.

나는 이것을 2000년 Visual C++ 6.0에서 보았습니다.

디버그 C++ 라이브러리에는 예외 처리기에서 물리적 I/O 명령에 대한 호출이 있었습니다.내 기억이 정확하다면 DMA 기본 레지스터용이었던 I/O 포트에 상태를 덤프하고 있었는데, Microsoft 직원이 디버거 카드용으로 사용했던 것으로 추정됩니다.

잠재적으로 진단 코드 실행을 유발할 수 있는 일부 오류 조건을 찾으십시오.

나는 디버깅하고, 역추적하고, 디스어셈블리를 읽었습니다.처리하는 동안 예외가 발생했습니다. std::string, 어쩌면 끝 부분에서 색인을 생성할 수도 있습니다.

지난 15년 동안 제조된 대부분의 프로세서의 CPU에는 매우 강력한 몇 가지 특수 명령이 있습니다.이러한 권한 있는 명령어는 운영 체제 커널 응용 프로그램용으로 유지되며 사용자가 작성한 프로그램에서는 사용할 수 없습니다.

이는 사용자가 작성한 프로그램이 시스템에 가할 수 있는 손상을 제한하고 시스템이 실제로 충돌하는 횟수를 줄입니다.

커널 모드에서 실행될 때 운영 체제는 커널과 사용자 프로그램의 메모리 모두에 무제한으로 액세스할 수 있습니다.

기본 및 한계 레지스터에 대한 로드 명령어는 특권 명령어입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top