📄 ring0.txt
字号:
; *我们则自己置TF=1引发之,注意在中断处理中关闭TF,否则会造成死循环,不断单步,还有故,
; *障门产生故障之后注意cs:eip已经压入堆栈,如果不改指令的话,就得自己修改eip指向安全
; *地址故障门的好处在于不必自己置sel为28h,也不必担心DPL=0,操作系统为我们准备好了一
; *切我们只要替换int处理地址就行了,以下是简单例子
; *__________________________________________
invoke MessageBoxA,0,addr CTEXTTrap,addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit001 ;继续演示?
;---------------------------------
; int1 单步陷阱或者int4 除法溢出陷阱
; 这里演示int 1,int 4类似
; 这个和上面的有不同吗,有!就是int 1
; 是由CPU而不是我们显式用int 1指令引发
;---------------------------------
push dword ptr [esi+(8*1)+0] ; 保存原int 1
push dword ptr [esi+(8*1)+4]
push offset myring0_prc_Trapgt
pop word ptr [esi+(8*1)+0]
pop word ptr [esi+(8*1)+6]
pushfd
pop eax
or ah,1
push eax
popfd ; set TF=1
nop ; ring0!
pop dword ptr [esi+(8*1)+4]; restore IDT entry
pop dword ptr [esi+(8*1)+0]
;--------------------------------------------
; 这里演示故障门,除法错误
;--------------------------------------------
@xit001:invoke MessageBoxA,0,addr CTEXTFault,addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000 ;继续演示?
push dword ptr [esi+(8*0)+0] ;
push dword ptr [esi+(8*0)+4]
push offset Ring0Code_div
pop word ptr [esi+(8*0)+0]
pop word ptr [esi+(8*0)+6]
xor eax,eax
div eax ; 除法错误,进入故障门ring0!
;-----------------------------------------
invoke MessageBoxA,0,addr CTEXTTask,addr sztit,MB_YESNO
cmp eax,IDNO
jz @xit000
;-------------------------------------
; 这里演示在GDT中寻找空白表项来制造TSS
;-------------------------------------
mov esi,dword ptr [gdtR+2]
movzx eax,word ptr [gdtR]
call Search_XDT
and ax,0fff8h
mov Tss1Sel,ax ;save Tss1 selector ,esi==gdt Base
mov esi,dword ptr [gdtR+2]
mov ebx,offset TSS1
mov word ptr [esi+eax+0],Tss1Limit
mov dword ptr [esi+eax+2],ebx ;offset
mov word ptr [esi+eax+5],89h
shr ebx,24
mov byte ptr [esi+eax+7],bl ;set mytss
;--------------------------------------------
; 这里演示在Ldt中制造任务门
;--------------------------------------------
mov esi,dword ptr [ldtDes+4]
mov eax,dword ptr [ldtDes]
call Search_XDT ;eax返回找到的空白选择子
push eax
or ax,7h
mov Tss1Gate,ax
pop eax
mov esi,dword ptr [ldtDes+4]
mov word ptr [esi+eax+0],0
mov word ptr [esi+eax+6],0 ;offset
push word ptr Tss1Sel
pop word ptr [esi+eax+2]
mov word ptr [esi+eax+4],0E500h ;Tss Gate
mov esi,dword ptr [TrDes+4]
assume esi:ptr TSS
push word ptr ldtR
pop word ptr[esi].TRLDTR ;设置LDT SELECTOR(WINDOWS98的TSS中LDT 为0???)
lea edi,TSS1
assume edi:ptr TSS
push word ptr trR
pop word ptr [edi].TRLink ;返回TSS选择子,设置联接字
push dword ptr[esi].TRESP0 ;设置SP0
pop dword ptr[edi].TRESP0
push word ptr[esi].TRSS0 ;设置SS0
pop word ptr[edi].TRSS0
push dword ptr[esi].TRCR3
;设置CR3寄存器,即设置好转换以后所有的段及页转换相关寄存器
pop dword ptr[edi].TRCR3
push offset Ring0
pop dword ptr[edi].TREIP
mov word ptr[edi].TRCS,28h ;CS=28
mov word ptr[edi].TRSS,30h ;ss=30
push word ptr ldtR ;设置LDTR
pop word ptr[edi].TRLDTR
push ds
pop dword ptr[edi].TRDS
mov word ptr[edi+54h+2],0
call fword ptr Call32
mov ebx,dword ptr [TestCR3]
@xit000:
invoke wsprintf,addr temp2,addr temp1,TestCR3
invoke MessageBoxA,0,addr temp2,addr sztit,0
mov eax,dword ptr [ldtDes+4];恢复GDT,LDT中的空选择子。
movzx esi,Tss1Gate
and esi,0fffffff8h
add eax,esi
mov dword ptr [eax],0
mov dword ptr [eax+4],0
mov eax,dword ptr [gdtR+2]
movzx esi,Tss1Sel
add eax,esi
mov dword ptr [eax],0
mov dword ptr [eax+4],0
invoke ExitProcess,0
;-----------------------------------------
Ring0Code_div proc far
pushad
mov ecx,10 ;EIP
ambalance002: ;cs
push ecx ;EFLAGS
call Beeps
pop ecx
loop ambalance002
popad
add dword ptr [esp],2 ; 修改Eip,略过除错指令(div eax)2个字节长,继续执行
iretd
Ring0Code_div endp
myring0_prc_Trapgt proc far
pushad ;注意压栈结构为
mov ecx,10 ;esp->EIP
ambalance002: ; cs
push ecx ; EFLAGS
call Beeps
pop ecx
loop ambalance002
popad
and byte ptr [esp+9],0FEh ;一定要置TF=0,终止
iretd ;注意iretd,不是iret(w)
myring0_prc_Trapgt endp
myring0_prc_Intgt proc far
pushad
mov ecx,10
ambalance001:
push ecx
call Beeps
pop ecx
loop ambalance001
popad
iretd
myring0_prc_Intgt endp
myring0_prc_callgt proc far
pushad
pushfd
pop eax
or eax,3000h
push eax
popfd
mov ecx,10
ambalance:
push ecx
call Beeps
pop ecx
loop ambalance
popad
retf
myring0_prc_callgt endp
;-----------------------------------------
Search_XDT proc near ;entry esi==Base of Ldt or GDT
;eax==Limit
pushad
mov ebx,eax ;ebx=limit
mov eax,8 ; skipping null selector
@@1:
cmp dword ptr [esi+eax+0],0
jnz @@2
cmp dword ptr [esi+eax+4],0
jz @@3
@@2:
add eax,8
cmp eax,ebx
jb @@1 ;if we haven't found any free GDT entry,
;lets use the last two entries
mov eax,ebx
sub eax,7
@@3:
mov [esp+4*7],eax ; return off in eax
popad ; eax=free GDT entry selector
ret
Search_XDT endp
;-----------------------------------------
Beeps proc near ;经典的发声子程序,学dos的时候应该
pushad ;没少用吧...
mov al,0B6h
out 43h,al
mov al,Freq ;接口要求,不要多问
out 42h,al
out 42h,al
xor byte ptr Freq,0Ch ; 换频率
; 以便下次发出不同的音高
in al,61h
or al,3
out 61h,al
mov ecx,1000000h ;延时
loop $
and al,0FCh ;关声音
out 61h,al
popad
ret
Beeps endp
Ring0:
mov ebx,cr3
mov TestCR3,ebx
iretd
END __Start
;______________________________Over...___________
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -