为了尊重wowocock前辈 我把wowocock的代码贴在我代码后面。
毕竟是发表我自己的吧. 在看完wowocock大哥的代码后。因为有一些地方
说得不是很明白 所以自己动手测试了一次 并自己写了一个类试的代码。
加上了比较详细的注释 希望大家看起来不费力
废话不多说了。代码开始 大家可以保存为.bat文件.调试是设置了编译器环境变量。
代码分为驱动代码 装载驱动的程序代码 和测试代码
下面为驱动部分。
;@echo off
;goto make .386
.model flat, stdcall
option casemap:none
;>>>>>>>>>>>>>>>STRUCT>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CALLGATE STRUCT
OFFSETL DW 0
SELECTOR DW 0
DCOUNT DB 0
GTYPE DB 0
OFFSETH DW 0
CALLGATE ENDS
DESCRIPTOR STRUCT
LIMITL DW 0
BASEL DW 0
BASEM DB 0
ATTRIBUTES DW 0
BASEH DB 0
DESCRIPTOR ENDS
;>>>>>>>>>>>>>>>>>equ>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
CODES_SEL = 3E8H
CODE_TYPE = 0CF9AH
GATE_TYPE = 0ECH
.code
DriverEntry:
pushfd
pushad
push edx
sgdt [esp-2]
pop edx ;全局描述符表基地址
mov eax,edx ;存放全局描述符开始地址
mov BYTE ptr [edx],0C3H
;在全句描述符表开始地址
;存放retn指令机器码,全
;句描述符表第一个描述符
;为空表述符,被保留,没被用
;书上说这个描述符应该全为0
;这里看出 可以写东西进去。
mov ecx,3E0h ;定位自己的门描述符
add edx,ecx ;让描述位置在全局描述
assume edx:ptr CALLGATE;符的3E0这个位置
cmp [edx].SELECTOR,CODES_SEL
jz ToEnd
mov [edx].OFFSETL,ax ;创建门描述符
mov [edx].SELECTOR,CODES_SEL
mov [edx].DCOUNT,0
mov [edx].GTYPE,GATE_TYPE
shr eax,16
mov [edx].OFFSETH,ax
;描述符的偏移地址其实就是上面说到的
;那个retn指令地址,当call 这个门的时候
;只从堆栈弹出EIP地址,所以CS寄存器没被
;覆盖,所以还是ting0权限
add edx,8
assume edx:ptr DESCRIPTOR
mov [edx].LIMITL,0FFFFH ;创建自己的代码段描述符
mov [edx].BASEL,0
mov [edx].BASEM,0
mov [edx].ATTRIBUTES,CODE_TYPE
mov [edx].BASEH,0
ToEnd:
popad
popfd
mov eax,0C0000182h
ret 8
end DriverEntry
;如果设置了环境变量 就把代码直接保存为mykmd.bat 然后双击 就OK
;没有设置环境变量的可以按下面方法编译,具体编译方法不用我介绍了吧
:make
set drv=mykmd
ml /nologo /c /coff %drv%.bat
link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj
del %drv%.obj
echo.
pause ;这里开始为测试代码部分
;@echo off
;goto make
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
szOK db '成功访问rc0寄存器',0
szFormat db 'cr0=%X',0
szBuffer db 50 dup (?)
CallGate_Sel dd 0
dw 03E3H ;调用门的选择子
.code
start:
call FWORD ptr CallGate_Sel
;进入ring0
;有兴趣自己也可以创建一个0级堆栈 呵呵。。
;我这里就用ring3的堆栈吧
mov eax,esp ;保存ring0堆栈
mov esp,[esp+4] ;装入ring3堆栈地址
;解释下这里为什么是+4 因为call 调用门会把
;ss esp cs eip分别放入堆栈 在驱动程序里面
;已经有一句retn指令把eip弹出来了。所以这里
;就是加4 得到ring3堆栈地址
push eax
mov eax,cr0 ;ring0下才可以访问的寄存器
pop esp
;;;开发返回ring3
push offset ring3
;正如刚刚所说 已经弹出了eip地址。
;用retf返回肯定出错。所以还是手
;动帮忙来恢复堆栈 压入ring3下的
;代码地址吧
retf
ring3:
invoke wsprintf,addr szBuffer,addr szFormat,eax
invoke MessageBox,0,addr szBuffer,addr szOK,0
invoke ExitProcess,0
end start
:make
set drv=s
ml /nologo /c /coff %drv%.bat
link /nologo /subsystem:windows %drv%.obj
del %drv%.obj
echo.
pause
最后 前辈这里没有提到的。.装载驱动的程序。
;@echo off
;goto make
.386
.model flat, stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include advapi32.inc
includelib kernel32.lib
includelib user32.lib
includelib advapi32.lib
.data
szError db '装载驱动失败',0
szOK1 db '驱动安装成功',0
szOK db 'OH YEAH.~~!',0
szMyWdm db 'mykmd.sys',0
szMyWdnName db 'mykmd',0
szBuffer db MAX_PATH dup (0)
hSCManager dd ?
hService dd ?
.code
start:
invoke OpenSCManager,NULL,NULL,SC_MANAGER_CREATE_SERVICE
.if !eax
invoke MessageBox,0,addr szError,0,MB_ICONERROR or MB_OK
jmp Err
.endif
mov hSCManager,eax
push ecx
invoke GetFullPathName,addr szMyWdm,sizeof szBuffer,addr szBuffer,esp
pop ecx
invoke CreateService,hSCManager,addr szMyWdnName,addr szMyWdm,SERVICE_START or DELETE,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,addr szBuffer,0,0,0,0,0
.if !eax
invoke MessageBox,0,addr szError,0,MB_ICONERROR
jmp Err
.endif
mov hService,eax
invoke StartService, hService, 0, NULL
invoke DeleteService, hService
invoke CloseServiceHandle, hService
invoke CloseServiceHandle, hSCManager
invoke MessageBox,0,addr szOK1,addr szOK,0
Err:
invoke ExitProcess,0
end start
;如果设置了环境变量 就把代码直接保存为LoadDriver.bat 然后双击 就OK
;没有设置环境变量的可以按下面方法编译,具体编译方法不用我介绍了吧
:make
set drv=LoadDriver
ml /nologo /c /coff %drv%.bat
link /nologo /subsystem:windows %drv%.obj
del %drv%.obj
echo.
pause
;说明下 如果用bat文件自动编译 把驱动代码改成mykmd.bat 测试代码改为s.bat 装载驱动程序代码改为LoadDriver.bat 分别双击就OK
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!