Linux0.00코어는 왜 스스로 0x80호 함정문을 설치하여 writechar 프로세스?
dividing_line:
push %gs
pushl %ebx
pushl %ecx
movl $10,%ecx/* 10 ' '*/
movl $SCRN_SEL,%ebx
movw %bx,%gs
1: movl scr_loc,%ebx
shl $1,%ebx
movb $32,%gs:(%ebx)/*' ' ASCII */
shr $1,%ebx
incl %ebx
cmpl $2000,%ebx
jb 2f
movl $0,%ebx
2: movl %ebx,scr_loc
loop 1b
popl %ecx
popl %ebx
pop %gs
ret
화면에 10개의 공백을 출력하는 기능입니다.그야말로 writechar는 거의 같습니다. 출력할 문자를 지정했을 뿐입니다. ax를 통해 가져오는 것이 아닙니다.또 하나는 제가 콜을 통해dividing을 호출해야 돼요.라인, write가 아니라char처럼 함정문에 호출됩니다.
결국 프로그램이 끊어져서 실행할 수 없었다.
나중에 분석해 보니 원인은 매우 간단했다.저는task1에서 write를 직접 호출합니다차도 안돼.이 두 가지 이유는 같다. 바로 이 두 줄의 코드이다.
movl $SCRN_SEL,%ebx
movw %bx,%gs
소스 코드에서 SCRNSEL=0x18은 GDT에서 데이터 세그먼트를 표시하는 selector이다. 그가 어떤 데이터 세그먼트든 상관없다. 어쨌든 그는 데이터 세그먼트가 맞다. 이 데이터 세그먼트 묘사부호인 DPL=0은 높은 특권급에 속한다. 그러나 우리는 지금 특권급 3급 코드로 이 과정을 호출한다. 그러면 이 처리 과정은 이때 3급 프로그램의 일원이라고 해도 그의 특권급도 3급이고 CPL=3이다. 비록SCRNSEL=0x18의 RPL=0이지만 CPL이 충분하지 않습니다. 이런 로드SCRNSEL=0x18 요청은 프로세서에서 거부됩니다.프로세서가 selector 세그먼트 레지스터를 불러올 때 현재 실행 중인 프로그램의 CPL, selector의 RPL, 설명자를 가리키는 DPL을 종합적으로 비교합니다. CPL과 RPL이 수치상 DPL보다 작지 않으면 특권급이 높습니다.그렇지 않으면, 이 selector를 불러오는 행위는 프로세서에 의해 차단되고 보호 이상이 발생합니다.
내 프로그램으로 돌아가기 때문에 0x18 이 selector를 불러오는 행위가 존재하면 이 과정의 호출은 반드시 실패할 것입니다. 0x18 이 selector가 가리키는 데이터 세그먼트 설명자인 DPL이 매우 높기 때문입니다.그래서 3급 프로그램에서 write를 직접 호출합니다char도 좋고dividingline도 실패하고 이 데이터 세그먼트에 접근할 권리가 없고 의도적으로도 안 됩니다.
이것이 바로 함정문을 통해 write를 호출하는 이유입니다char, 프로세서가 함정문을 통해 높은 특권급 코드만 옮길 수 있고 낮은 특권급 코드로 옮길 수 없다고 규정한 것은 내가 3급 사용자 코드에서 내부 핵 0급 코드로 옮길 수 있다는 것은 하늘과 땅의 뜻이다.그러나 주의해야 할 것은 3급 코드는 확실히 함정문을 통해 0급 코드로 들어갈 수 있지만 전제는 함정문의 문 설명자 DPL=3이어야 한다.그렇지 않으면 사용자 프로그램은 함정문에 접근할 권한이 전혀 없다.자, 함정문 설명자 DPL=3을 가정하자. 함정문 설명자 안의 목표 코드selector는 내부 핵 0급 코드를 가리킨다.
이렇게 하면 3급 프로그램에서 함정문 설명자를 불러올 수 있다. 왜냐하면 CPL=3이기 때문에 우리는 RPL=3의selector로 함정문에 접근하고 함정문DPL=3을 사용하면 함정문에 완전히 접근할 수 있다.그리고 함정문 안의 목표selector 부분은 0급 코드를 가리킨다. 이것은 상관없다. 함정문을 통해 우리는 완전히 돌아갈 수 있다. 프로세서가 우리에게 이렇게 하라고 한다!이것이야말로 마땅한 과정이다.저급 프로그램은 저급 함정문에 접근한다. 저급 함정문에는 높은 특권급의 코드 세그먼트 selector가 있다. 이렇게 하면 함정문을 통해 높은 특권급의 내부 코드로 들어갈 수 있다.이것은 일부 시스템의 호출에 편의를 제공했다.
마지막으로 한 가지, 우리는 이 두 줄에 문제가 생긴 코드를 제거하고, 정상적으로 호출할 수 있습니까?답은 긍정적이다. 이 두 줄을 갔으니 이 처리 과정의 기능은 폐기되고 차라리 간단한 것을 쓰는 것이 낫다. 예를 들어 다음과 같다.
example:
pushl %eax
movl $0x250,%eax
pop %eax
ret
이것은 매우 간단합니다. 3급 사용자 코드에서call example를 호출할 수 있습니다. 출력 알림이 없기 때문에bochs 디버깅을 통해 확인할 수 있습니다. 결과는 호출이 성공했고 실행 과정이 이 example 코드에 성공적으로 들어갔습니다.이것은 일반적인 근접 호출이어서 별다른 것이 없다.함정문 특권급에 관해서는 여기까지 하겠습니다.
얘기 끝났어.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
printk 인쇄 주파수 제한 함수 printkratelimitLinux 커널 코드에서 printk 인쇄 주파수를 제한해야 할 때ratelimit 또는 printkratelimit ( ratelimit 봉인). /var/log/messages에서 가능한 출력은 다음과 같습니다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.