2009-06-29 3 views
12

Windows가 임의로 CPU를 커널 모드로 전환하는 사용자 모드 스레드로부터 보호하려면 어떻게해야합니까?Windows는 어떻게 커널 모드로의 전환을 보호합니까?

나는이 일에 해당하는 이해 : 시스템 호출이 NTDLL을 통해 만들어 질 때

  1. 사용자 모드 스레드가 실제로-커널 모드로 전환 마십시오.
  2. 커널 모드로의 전환은 프로세서 관련 지침을 통해 수행됩니다.

NTDLL을 통한 시스템 호출은 특별한 점이 무엇입니까? 왜 사용자 모드 쓰레드가 가짜가 아니고 커널 모드로 전환하기위한 프로세서 별 명령어를 실행할 수 없습니까? 여기에 Windows 아키텍처의 핵심 요소가 하나 빠져 있다는 것을 알고 있습니다. 그게 무엇입니까?

+0

사용자 모드 스레드는 위조 할 수 있지만 ntdll.dll을 사용하는 것과 어떻게 다른가요? 이 문제에 대한 추가 정보를 질문에 추가하십시오. –

+2

나는 OP가 링 0으로 전환 한 다음 링 0에있는 동안 임의의 비 -O/S 코드를 실행하는 것에 대해 걱정한다고 생각합니다. – ChrisW

+1

Windows는 노출 된 (usermode에 대한) 매개 변수에 대해 유효성 검사를 수행합니다. 잘못된 데이터는 알지 못해도 전달할 수 없습니다. 그렇습니다. 간과 된 경우가 있습니다. 로컬 권한 승격 취약점을 찾아보십시오. 거기에 그들 중 톤 – unixman83

답변

17

아마도 사용자 모드에서 실행중인 스레드가 링 0을 호출하고 있다고 생각할 것입니다.하지만 실제로 일어나지는 않습니다. 사용자 모드 스레드가 링 0 코드에 걸려있는 예외를 발생 시켰습니다. 사용자 모드 스레드는 정지되고 CPU는 kernel/ring 0 스레드로 전환하고, 스레드는 사용자 모드 스레드의 컨텍스트 (예 : 호출 스택 및 레지스터)를 검사하여 수행 할 작업을 파악할 수 있습니다. syscall 전에는 특별히 링 0 코드를 호출하는 특별한 예외가 아니라 실제로 예외였습니다.

다른 응답의 조언을 읽고 the Intel manuals을 읽으면 syscall/sysenter가 매개 변수를 취하지 않음을 알 수 있습니다. OS가 어떤 일이 발생할지 결정합니다. 임의의 코드를 호출 할 수 없습니다. WinNT는 사용자 모드 코드가 실행할 커널 모드 기능을 매핑하는 기능 번호를 사용합니다 (예 : NtOpenFile은 내 Windows   XP 시스템에서 fnc 75h입니다 (번호는 항상 바뀌며 NTDll의 작업 중 하나는 함수 호출을 사용하여 EAX에 넣고 EDX를 입력 매개 변수로 지정한 다음 sysenter를 호출하십시오.)

9

인텔 CPU는 '보호 링'을 사용하여 보안을 강화합니다.

0에서 3까지 번호가 매겨진 이들 중 4 개가 있습니다. 0 번 링에서 실행중인 코드는 가장 높은 권한을 갖습니다. 그것은 (실제로) 당신의 컴퓨터에 만족하는 무엇이든을 할 수 있습니다. 반면에 링 3의 코드는 항상 꽉 묶여 있습니다. 그것은 사물에 영향을 줄 수있는 힘이 제한되어 있습니다. 그리고 링 1과 2는 현재 어떤 목적으로도 사용되지 않습니다.

상위 권한이있는 링 (예 : 링 0)에서 실행중인 스레드는 원하는대로 낮은 권한 링 (예 : 링 1, 2 또는 3)으로 전환 할 수 있습니다. 그러나 다른 방향으로 전이하는 것은 엄격하게 규제됩니다. 이것은 높은 권한을 가진 자원 (예 : 메모리)의 보안이 유지되는 방법입니다.

당연히 사용자 모드 코드 (응용 프로그램 및 모두)는 링 3에서 실행되지만 OS 코드는 링 0에서 실행됩니다. 이렇게하면 사용자 모드 스레드가 OS의 데이터 구조 및 기타 중요한 리소스를 망칠 수 없습니다.

이 모든 것이 실제로 구현되는 방법에 대한 자세한 내용은 this 문서를 참조하십시오. 또한 Intel 설명서, 특히 Vol 1 및 Vol 3A를 통해 here을 다운로드 할 수도 있습니다.

이것은 인텔 프로세서의 이야기입니다. 나는 다른 아키텍쳐와 비슷한 점이있을 것이라고 확신한다.

+2

대부분의 다른 프로세서는 기본적으로 x86 링 0 및 3에 해당하는 두 가지 권한 수준 만 사용합니다. 링 1 및 2는 당시로서는 좋은 생각 인 것 같았지만 비용이 많이 드는 것에 대한 가치를 추가하지 않는 것으로 나타났습니다. – RBerteig

+1

IIRC Windows는 RISC 아키텍처가 지원하는 모든 링이기 때문에 2 개의 링만 사용합니다. 같은 기본 아키텍처로 RISC를 지원하기를 원했기 때문에 극단적 인 x86 링만 사용되었습니다. – noctonura

7

나는 (내가 잘못 될 수있다)가 전환을 위해 사용하는 메커니즘이 간단하다고 생각 :

  • 사용자 모드 코드는
  • 이 (인터럽트) 인터럽트 소프트웨어를 실행는 위치로 분기됩니다

사용자 모드 코드가 다음과 같이 침입하는 것을 방지하는 것은 다음과 같습니다. IDT에 쓰기 위해서는 권한이 필요합니다. 따라서 커널 만 인터럽트가 실행될 때 어떤 일이 발생하는지 지정할 수 있습니다.

+0

젊은 chris에 응답하는 큰 chris. –

+0

이것은 작동하는 데 사용되는 방법이지만 Tony Lee의 답변은 Windows가 현재하는 것과 훨씬 비슷합니다. –

+1

IDT에 관한 부분을 생략 했으므로 CPU가 실행을 시작하는 위치를 어떻게 알 수 있습니까? –

4

사용자 모드 (링 3)에서 실행중인 코드는 임의로 커널 모드 (링 0)로 변경할 수 없습니다. 점프 게이트, 인터럽트 및 sysenter 벡터와 같은 특수 경로를 사용하는 경우에만이 경로를 보호 할 수 있습니다.이 경로는 잘못된 데이터를 조작 할 수 없으므로 잘못된 데이터를 조작해서는 안됩니다.

커널에 의해 설정되는데 보통 커널 모드에서만 설정 될 수 있으므로 User-Mo 코드는 그것을 수정할 수 없습니다.

3

리눅스가하는 것과 비슷한 (상대적으로) 유사한 방식으로 말하는 것이 맞을 것입니다. 두 경우 모두 CPU에 따라 다르지만 x86에서는 INT 인터럽트를 사용하는 소프트웨어 인터럽트 또는 SYSENTER 명령어를 사용합니다.

Linux가하는 일의 이점은 Windows 소스 라이센스 없이도 그렇게 할 수 있다는 것입니다.

LXR에서 userspace source part is here herekernel space bit는 - 86에 리눅스에서 entry_32.S 및 entry_64.S

을보고 세 가지 다른 메커니즘, INT 0x80으로, 콜과 sysenter있다.

vdso라는 커널에 의해 런타임에 빌드되는 라이브러리는 CPU 라이브러리와 시스템 호출에 따라 다른 메커니즘을 사용하는 syscall 기능을 구현하기 위해 C 라이브러리에 의해 호출됩니다. 그런 다음 커널에는 해당 메커니즘에 대한 핸들러가 있습니다 (특정 CPU 변형에있는 경우).

관련 문제