求教大虾们::ring3进ring0中的一个指针问题
.586p.model flat,stdcall
option casemap:none
.code
start:
nop
nop
nop
nop
pushfd
pushad
push edx
sgdt [esp-2]
pop edx
mov eax,edx
mov ecx,3e0h
.if dword ptr [edx+ecx+2]!=0ec0003e8h
mov byte ptr [edx],0c3h
mov word ptr [edx+ecx],ax
shr eax,16
mov word ptr [edx+ecx+6],ax
mov dword ptr [edx+ecx+2],0ec0003e8h;1110 1100 0000 0000 ,03e8h
mov dword ptr [edx+ecx+8],0000ffffh
mov dword ptr [edx+ecx+12],00cf9a00h
.endif
popad
popfd
xor eax,eax
ret 8
end start
把以上的汇编代码保存到文件mywdm.asm,然后用MASM 6.14按照下面的方法编译:
ml /c /coff /Cp mywdm.asm
link /subsystem:windows /driver:wdm /release /out:mywdm.sys mywdm.obj
mywdm.sys的功能是在GDT中创建一个3级调用门和一个0级32位代码段描述符,3级调用
门的选择子是3E3,0级32位代码段的选择子是3E8。
好了,现在执行mywdm.sys,但驱动程序是不能直接执行的,所以要构造它的执行环境。
先在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services中建立一个mywdm
子键,然后建立3个DWORD型的键值:
ErrorControl=0
Start=3 (如果Start=1,mywdm.sys会随电脑启动而自动装入)
Type=1
好了,既然GDT中已经有了我们的调用门,那么意味着我们写的应用程序可以自由地在
RING3和RING0之间切换,但如何使用这个调用门还是有讲究的,它的使用方法是:
...
call 3e3:00000000 ;机器码 9A 00 00 00 00 E3 03
;此时已经进入RING0,CS=3E8,跟着要切换堆栈
mov eax,esp
mov esp,[esp+4]
push eax
;这里加入你要在RING0里执行的代码
;准备返回RING3
pop esp
push offset ring3
retf
ring3:
;此时回到RING3
本人的问题:call 3e3:00000000 返回之后的cs:eip能否定位下条指令mov eax,esp
(cs=3e8了,不再是原cs了)