可以是可以,但是还是不太好,因为这方面的资料太少了,你会做不下去的。如果你以前没有用过C开发VXD的话,我建议你还是用C吧!!转贴一篇文章。用 Delphi 编写 VxD 设备驱动程序(转)(sundyl 转贴)
出处:http://www.chinaasp.com/columns/delphi/article1472.asp正文:用 Delphi 编写 VxD 设备驱动程序(转)关键词:Delphi控件杂项作者:Emil Biserov([email protected])(Russion)
英语翻译:Vitaly Zayko([email protected])
中文翻译改编:Riceball([email protected]) 前言
用 Delphi 3.0 编写 VxD 设备驱动程序,在Delphi 3 下编译通过,Delphi 2 下没有测试,Delphi 4 建立的 Object 文件 M$ Linker 5.12.8181 不能识别,这里使用的汇编器是M$的Macro Assembler ver. 6.11d ,联结器是M$ Incremental Linker ver. 5.12.8181 ,它们来自 Windows 98DDK(http://www.microsoft.com/ddk/ddk98.htm)。 介绍
Windows 存在有两种类型的 VxD 设备驱动程序:
1、静态(Static) VxD ,装入操作系统并永久的存在于内存中;
2、动态(Dynamic) VxD,当需要时才调入内存,用完后关闭VxD即可释放内存。
Inprise Delphi 有能力建立任何一种类型的 VxD 设备驱动程序,下面我们将介绍如何建立动态 VxD。
当 Win32 应用程序打开一个 VxD “虚拟”设备时,VWIN32 使用 LoadDevice 将 VxD 装入内存,并建立消息W32_DEVICEIOCONTROL ,发向 VxD。
也就是说,VxD 至少应该响应以下两个系统信息和编写以下的一个函数:
SYS_DYNAMIC_DEVICE_INIT
SYS_DYNAMIC_DEVICE_EXIT
W32_DEVICEIOCONTROL 函数.
消息 SYS_DYNAMIC_DEVICE_INIT 在尝试装入 VxD 时发送到 VxD ,消息 SYS_DYNAMIC_DEVICE_EXIT 在尝试动态交换时发送到 VxD ,消息的处理者在成功处理后,应该在寄存器 AX 中返回 VXD_SUCCESS 标志。 W32_DEVICEIOCONTROL 的 dwService 参数有以下的值:
DIOC_OPEN 当 VxD 通过 CreateFile() 函数尝试打开操作时发送(在 SYS_DYNAMIC_DEVICE_INIT 消息后),如果成功返回 NO_ERROR (0);
DIOC_CLOSEHANDLE 当 VxD 通过 CloseHandle() 函数尝试关闭操作时发送(在 SYS_DYNAMIC_DEVICE_EXIT 前)
所有其它的值 > 0 意味着不同的函数调用(由 dwIoControlCode 给出),当 VxD 被 DeviceIoControl 函数调用时。 启动模块(vxdmain.asm)
...
extrn SysDynamicDeviceInit :PROC
extrn SysDynamicDeviceExit :PROC
extrn W32DeviceIoControl :PROC
...
PUBLIC DELPHIIO_DDB
Public @@HandleFinally
Public @initialization
...
Control_0 proc
cmp eax, SYS_DYNAMIC_DEVICE_INIT
jnz short chkSysDynExit
call SysDynamicDeviceInit
cmp eax, 1
retn
;------------- chkSysDynExit:
cmp eax, SYS_DYNAMIC_DEVICE_EXIT
jnz short chkDevIOCtl
call SysDynamicDeviceExit
cmp eax, 1
retn
;-------------
chkDevIOCtl:
cmp eax, W32_DEVICEIOCONTROL
jnz short loc_ret
push esi
push edx
push ebx
push ecx
call W32DeviceIoControl
cmp eax, 1
retn
;-------------
loc_ret:
clc
retn Control_0 endp @@HandleFinally:
@initialization:
ret _LTEXT ends
END Delphi 会为单元的 initialization/finalization 建立代码调用外部过程 HandleFinaly 和 initialization ,即使 initialization/finalization 在单元中不存在。因此我们在汇编的启动文件中建立空的外部过程入口。 主 Delphi 程序单元(vxdProcs.pas)
...
procedure ShellMessage(Handle, Flags : integer; const Message, Caption : PChar;
Callback, ReferenceData : pointer); stdcall; assembler;
asm
mov ebx, Handle // virtual machine handle
mov eax, Flags // message box flags
mov ecx, Message // address of message text
mov edi, Caption // address of caption text
mov esi, Callback // address of callback
mov edx, ReferenceData // reference data for callback int 20H // VxDCall
dd 170004h // Shell_Message
end; function SysDynamicDeviceInit : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'SysDynInit: Hello from Delphi VxD !!!', nil, nil);
Result := VXD_SUCCESS;
end; function SysDynamicDeviceExit : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'SysDynDevExit: Bye from Delphi VxD !!!', nil, nil);
Result := VXD_SUCCESS;
end; function W32DeviceIoControl(dwService : INTEGER;
dwDDB : INTEGER;
hDevice : INTEGER;
lpDIOCParms : pointer) : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'W32DevIOCtl', nil, nil); if (dwService = DIOC_OPEN) then
begin
Result := NO_ERROR;
end
else if (dwService = DIOC_CLOSEHANDLE) then
begin
Result := VXD_SUCCESS;
end
else if (dwService > MAX_PASVXD_W32_API) then
begin
Result := ERROR_NOT_SUPPORTED;
end
else
begin
Result := VXD_SUCCESS;
end;
end;
...
[译者:好了,简单的 VxD 设备驱动程序编写完毕了。你可以将它当作一个写 VxD 设备驱动程序的模板。] 附一:Make.bat
D:\VISUAL~1\98DDK\BIN\Win98\ml -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 vxdmain.asm
call dcc3.bat -J vxdprocs.pas
D:\VISUAL~1\98DDK\BIN\link /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /OUT:delphiio.vxd 附二:
现在让我们来编写对该 VxD 的测试程序,两个按钮:一个打开 VxD;一个关闭 VxD。 const
VxDName = '\\.\DELPHIIO.VXD'; ... function TVxDTestForm.OpenVxDDriver: boolean;
begin
HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0);
Result := HVxDHandle <> INVALID_HANDLE_VALUE;
end; procedure TVxDTestForm.CloseVxDDriver;
begin
if HVxDHandle <> INVALID_HANDLE_VALUE then begin
CloseHandle(HVxDHandle);
HVxDHandle := INVALID_HANDLE_VALUE;
end;
end
出处:http://www.chinaasp.com/columns/delphi/article1472.asp正文:用 Delphi 编写 VxD 设备驱动程序(转)关键词:Delphi控件杂项作者:Emil Biserov([email protected])(Russion)
英语翻译:Vitaly Zayko([email protected])
中文翻译改编:Riceball([email protected]) 前言
用 Delphi 3.0 编写 VxD 设备驱动程序,在Delphi 3 下编译通过,Delphi 2 下没有测试,Delphi 4 建立的 Object 文件 M$ Linker 5.12.8181 不能识别,这里使用的汇编器是M$的Macro Assembler ver. 6.11d ,联结器是M$ Incremental Linker ver. 5.12.8181 ,它们来自 Windows 98DDK(http://www.microsoft.com/ddk/ddk98.htm)。 介绍
Windows 存在有两种类型的 VxD 设备驱动程序:
1、静态(Static) VxD ,装入操作系统并永久的存在于内存中;
2、动态(Dynamic) VxD,当需要时才调入内存,用完后关闭VxD即可释放内存。
Inprise Delphi 有能力建立任何一种类型的 VxD 设备驱动程序,下面我们将介绍如何建立动态 VxD。
当 Win32 应用程序打开一个 VxD “虚拟”设备时,VWIN32 使用 LoadDevice 将 VxD 装入内存,并建立消息W32_DEVICEIOCONTROL ,发向 VxD。
也就是说,VxD 至少应该响应以下两个系统信息和编写以下的一个函数:
SYS_DYNAMIC_DEVICE_INIT
SYS_DYNAMIC_DEVICE_EXIT
W32_DEVICEIOCONTROL 函数.
消息 SYS_DYNAMIC_DEVICE_INIT 在尝试装入 VxD 时发送到 VxD ,消息 SYS_DYNAMIC_DEVICE_EXIT 在尝试动态交换时发送到 VxD ,消息的处理者在成功处理后,应该在寄存器 AX 中返回 VXD_SUCCESS 标志。 W32_DEVICEIOCONTROL 的 dwService 参数有以下的值:
DIOC_OPEN 当 VxD 通过 CreateFile() 函数尝试打开操作时发送(在 SYS_DYNAMIC_DEVICE_INIT 消息后),如果成功返回 NO_ERROR (0);
DIOC_CLOSEHANDLE 当 VxD 通过 CloseHandle() 函数尝试关闭操作时发送(在 SYS_DYNAMIC_DEVICE_EXIT 前)
所有其它的值 > 0 意味着不同的函数调用(由 dwIoControlCode 给出),当 VxD 被 DeviceIoControl 函数调用时。 启动模块(vxdmain.asm)
...
extrn SysDynamicDeviceInit :PROC
extrn SysDynamicDeviceExit :PROC
extrn W32DeviceIoControl :PROC
...
PUBLIC DELPHIIO_DDB
Public @@HandleFinally
Public @initialization
...
Control_0 proc
cmp eax, SYS_DYNAMIC_DEVICE_INIT
jnz short chkSysDynExit
call SysDynamicDeviceInit
cmp eax, 1
retn
;------------- chkSysDynExit:
cmp eax, SYS_DYNAMIC_DEVICE_EXIT
jnz short chkDevIOCtl
call SysDynamicDeviceExit
cmp eax, 1
retn
;-------------
chkDevIOCtl:
cmp eax, W32_DEVICEIOCONTROL
jnz short loc_ret
push esi
push edx
push ebx
push ecx
call W32DeviceIoControl
cmp eax, 1
retn
;-------------
loc_ret:
clc
retn Control_0 endp @@HandleFinally:
@initialization:
ret _LTEXT ends
END Delphi 会为单元的 initialization/finalization 建立代码调用外部过程 HandleFinaly 和 initialization ,即使 initialization/finalization 在单元中不存在。因此我们在汇编的启动文件中建立空的外部过程入口。 主 Delphi 程序单元(vxdProcs.pas)
...
procedure ShellMessage(Handle, Flags : integer; const Message, Caption : PChar;
Callback, ReferenceData : pointer); stdcall; assembler;
asm
mov ebx, Handle // virtual machine handle
mov eax, Flags // message box flags
mov ecx, Message // address of message text
mov edi, Caption // address of caption text
mov esi, Callback // address of callback
mov edx, ReferenceData // reference data for callback int 20H // VxDCall
dd 170004h // Shell_Message
end; function SysDynamicDeviceInit : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'SysDynInit: Hello from Delphi VxD !!!', nil, nil);
Result := VXD_SUCCESS;
end; function SysDynamicDeviceExit : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'SysDynDevExit: Bye from Delphi VxD !!!', nil, nil);
Result := VXD_SUCCESS;
end; function W32DeviceIoControl(dwService : INTEGER;
dwDDB : INTEGER;
hDevice : INTEGER;
lpDIOCParms : pointer) : INTEGER;
begin
ShellMessage(0, $10, Copyright, 'W32DevIOCtl', nil, nil); if (dwService = DIOC_OPEN) then
begin
Result := NO_ERROR;
end
else if (dwService = DIOC_CLOSEHANDLE) then
begin
Result := VXD_SUCCESS;
end
else if (dwService > MAX_PASVXD_W32_API) then
begin
Result := ERROR_NOT_SUPPORTED;
end
else
begin
Result := VXD_SUCCESS;
end;
end;
...
[译者:好了,简单的 VxD 设备驱动程序编写完毕了。你可以将它当作一个写 VxD 设备驱动程序的模板。] 附一:Make.bat
D:\VISUAL~1\98DDK\BIN\Win98\ml -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 vxdmain.asm
call dcc3.bat -J vxdprocs.pas
D:\VISUAL~1\98DDK\BIN\link /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /OUT:delphiio.vxd 附二:
现在让我们来编写对该 VxD 的测试程序,两个按钮:一个打开 VxD;一个关闭 VxD。 const
VxDName = '\\.\DELPHIIO.VXD'; ... function TVxDTestForm.OpenVxDDriver: boolean;
begin
HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0);
Result := HVxDHandle <> INVALID_HANDLE_VALUE;
end; procedure TVxDTestForm.CloseVxDDriver;
begin
if HVxDHandle <> INVALID_HANDLE_VALUE then begin
CloseHandle(HVxDHandle);
HVxDHandle := INVALID_HANDLE_VALUE;
end;
end
理论上,Windows上的程序Delphi都能写。当然了Delphi的效率确实比VC稍差。
我对底层程序没有兴趣,所以,你别问我该怎么写,我不会。另:提问题最好在工作日,工作时间提。那时人气比较旺。
extrn SysDynamicDeviceInit :PROC
extrn SysDynamicDeviceExit :PROC
extrn W32DeviceIoControl :PROC
...
PUBLIC DELPHIIO_DDB
Public @@HandleFinally
Public @initialization
...
Control_0 proc
cmp eax, SYS_DYNAMIC_DEVICE_INIT
jnz short chkSysDynExit
call SysDynamicDeviceInit
cmp eax, 1
retn
;------------- chkSysDynExit:
cmp eax, SYS_DYNAMIC_DEVICE_EXIT
jnz short chkDevIOCtl
call SysDynamicDeviceExit
cmp eax, 1
retn
;-------------
chkDevIOCtl:
cmp eax, W32_DEVICEIOCONTROL
jnz short loc_ret
push esi
push edx
push ebx
push ecx
call W32DeviceIoControl
cmp eax, 1
retn
;-------------
loc_ret:
clc
retn Control_0 endp @@HandleFinally:
@initialization:
ret _LTEXT ends
END
//***************************
前面的这一段是什么意思?省略号省略的是:"asm.......end;" 吗??
Vtoolsd生成了以下
appytime.c
appytime.h
appytime.mak
三个文件,那么你就最好生成名字为appytime的工程。然后制定它的mak文件为appytime.mak。指定它编译生成的文件为appytime.vxd,这样你再把上面的三个文件考到工程文件的目录下,把这三个文件用Addfile(右击生成的工程项)加入到工程中,这样你就可以看到该工程的结构了,然后就可以加入自己的代码并且编译了。
用程序来封锁键盘,你可以连ctrl+alt+del都封锁啊!!所有的键都不能用,除了用鼠标结束你的程序之外,用什么来结束呢?如果你连鼠标也锁住不就行了!!Vxd也是要加载的呀!!别人如果查到你那个Vxd,一样可以从注册表里把它去掉,再重启就就没有了,动态加载的VXD也是需要一个程序来调用的。 你是怎么协载的?
var
tempint:Integer;
begin
SystemParametersInfo(SPI_SCREENSAVERRUNNING,1,@tempint,0);
end;恢复
var
tempint:Integer;
begin
SystemParametersInfo(SPI_SCREENSAVERRUNNING,0,@tempint,0);
end;
(使用工具)可以不予考虑第二:你的方法完全不起作用;原因:在进入windows时,一般的程序是要先加载后,才执行过程的。也就是说在你的程序还不完
全加载时,按下ctrl+alt+del,你的程序是完全暴露的,你的所有的隐藏程序过程和锁键盘过程还
没有执行到,就根本不起作用。如果使用vxd,它可以在注册表里注册,由系统来加载,不使用进程的形式,ctrl+alt+del也就不起作用了。在vxd中放入我们的过程,vxd在加载时执行就行了。(后面一段,只是我个人认为)
不知可行否?)。请多指教。。
(使用工具)可以不予考虑第二:你的方法完全不起作用;原因:在进入windows时,一般的程序是要先加载后,才执行过程的。也就是说在你的程序还不完
全加载时,按下ctrl+alt+del,你的程序是完全暴露的,你的所有的隐藏程序过程和锁键盘过程还
没有执行到,就根本不起作用。如果使用vxd,它可以在注册表里注册,由系统来加载,不使用进程的形式,ctrl+alt+del也就不起作用了。在vxd中放入我们的过程,vxd在加载时执行就行了。(后面一段,只是我个人认为)
不知可行否?)。请多指教。。
你要关程序了。只要她是进程,就一定能被关掉(用这种方法)
[email protected]
这也是没办法中的办法,只能从根本上去解决问题,只有vxd不属于进程。难作,也是必须要作的,不可回避。我是知道,这个是不可回避的。我问这么多只有两个目的,那就是
第一:除了vxd外,有没有第二种方法。
第二:如不得已而用vxd的话,有没有作vxd得捷径,因为我对vc++不熟,既学vc++,又学vxd,达到目的的周期太长。如果,delphi能作,就勉强用一用。起码不用重新去学一门语言。当然,如果能得到你的建议(或帮助)最好。在此,我谢谢你的建议。。
1,可否考虑用钩子来处理,写一个Explorer要调用的钩子,然后再这个Dll中调用你要启动的程序,然后进行封锁键盘。
2,如果要学VXD的话,只开发键盘方面的,基本可以不需要C++,会C就可以了。VC++你只需要学习如何用它来编译你的 C版本的VXD就可以了。不知道你看了Vtoolsd的例子没有,它里面有两部分的例子分别是C和C++的(当然不是一样的)。我以前用它来做的硬盘隐藏就是用C编的。关于什么时候该用C什么时候该用C++,我可以说在开发VXD的时候大部分情况都是你想用什么就用什么!
你的东东太多,我也一下糊涂了。
用Dephi做Vxd的也看过一些,差不多很烦。调用也麻烦。
"Explorer要调用的钩子",这句话的意思不就是用Explorer来调用自己的dll吗?怎么用Explorer来调用自己的dll?Explorer能调用吗?我真有点不可思议。怎么做?你能给我讲一讲。