📄 vxd-c7.htm
字号:
include \masm\include\shell.inc
VxDName TEXTEQU <VXDEXEC>
ControlName TEXTEQU <VXDEXEC_Control>
VxDMajorVersion TEXTEQU <1>
VxDMinorVersion TEXTEQU <0>
VxD_STATIC_DATA_SEG
VxD_STATIC_DATA_ENDS
VXD_LOCKED_CODE_SEG
;----------------------------------------------------------------------------
; Remember: The name of the vxd MUST be uppercase else it won't work/unload
;----------------------------------------------------------------------------
DECLARE_VIRTUAL_DEVICE %VxDName,%VxDMajorVersion,%VxDMinorVersion, %ControlName,UNDEFINED_DEVICE_ID,UNDEFINED_INIT_ORDER
Begin_control_dispatch %VxDName
Control_Dispatch W32_DEVICEIOCONTROL, OnDeviceIoControl
End_control_dispatch %VxDName
BeginProc OnDeviceIoControl
assume esi:ptr DIOCParams
.if [esi].dwIoControlCode==1
VxDCall _SHELL_CallAtAppyTime,<<OFFSET32 OnAppyTime>,0,0,0>
.endif
xor eax,eax
ret
EndProc OnDeviceIoControl
VXD_LOCKED_CODE_ENDS
VXD_PAGEABLE_CODE_SEG
BeginProc OnAppyTime, CCALL
ArgVar RefData,DWORD
ArgVar TheFlag,DWORD
EnterProc
mov File.shex_dwTotalSize,sizeof SHEXPACKET
add File.shex_dwTotalSize,sizeof EXEName
mov File.shex_dwSize,sizeof SHEXPACKET
mov File.shex_ibOp,0
mov File.shex_ibFile,sizeof SHEXPACKET
mov File.shex_ibParams,0
mov File.shex_ibDir,0
mov File.shex_dwReserved,0
mov File.shex_nCmdShow,1
VxDCall _SHELL_ShellExecute, <OFFSET32 File>
LeaveProc
Return
EndProc OnAppyTime
VXD_PAGEABLE_CODE_ENDS
VXD_PAGEABLE_DATA_SEG
File SHEXPACKET <>
EXEName db "calc.exe",0
VXD_PAGEABLE_DATA_ENDS
end</font>
</pre>
<p><font color="#FF0000">讲解</font></p>
<p>VxD等待一个DeviceIoControl消息:第1号服务。当它收到上述消息,它将注册一个appy time事件。</p>
<p><font color="#006666">VxDCall _SHELL_CallAtAppyTime,<<OFFSET32 OnAppyTime>,0,0,0></font></p>
<p>它将传送OnAppyTime函数的平板地址到_SHELL_CallAtAppyTime,这样,当appy time事件发生时,Shell VxD将调用它。因我们不需要使用任何参考数据并且不需要处理过期情况,所以紧跟OnAppyTime函数的三个参数都是0。</p>
<p>当appy time事件发生时, Shell VxD调用OnAppyTime函数。</p>
<p>BeginProc OnAppyTime, CCALL</p>
<p>我们用BeginProc描述一个函数。因为Shell VxD用C调用顺序调用OnAppyTime,我们需要指定CCALL属性。</p>
<p><font color="#006666">ArgVar RefData,DWORD<br>
ArgVar TheFlag,DWORD<br>
EnterProc<br>
...<br>
LeaveProc <br>
Return </font></p>
<p>因为Shell VxD用两个参数调用OnAppyTime,我们必须设置堆栈结构。ArgVar宏用来调整每个要传递到函数的参数的堆栈结构。它的语法如下:</p>
<p><font color="#006666">ArgVar varname, size, used</font></p>
<p>varname是参数的名字。你可以使用你喜欢的任意名字。size是参数的大小。你可以使用BYTE、WORD、DWORD或1,2,4。used通常被忽略。</p>
<p>紧接着ArgVar宏,我们需要使用EnterProc和LeaveProc宏来标志在程序中存放变量和参数的结构的开始与结束,使其能被正确访问。使用Return宏返回到调用者。</p>
<pre><font face="宋体" color="#006666"> mov File.shex_dwTotalSize,sizeof SHEXPACKET
add File.shex_dwTotalSize,sizeof EXEName
mov File.shex_dwSize,sizeof SHEXPACKET
mov File.shex_ibOp,0
mov File.shex_ibFile,sizeof SHEXPACKET
mov File.shex_ibParams,0
mov File.shex_ibDir,0
mov File.shex_dwReserved,0
mov File.shex_nCmdShow,1
VxDCall _SHELL_ShellExecute,</font><font face="宋体"> <OFFSET32 File></font>
</pre>
<p>在这个程序中的指令是简单的:初始化SHEXPACKET结构并且调用_SHELL_ShellExecute服务。记住 shex_dwTotalSize包含SHEXPACKET结构自身的和跟着它的字符串的组合大小。这是一个简单的事情。假如字符串不紧跟在此结构之后的,你必须计算从结构第一个字节到到字符串最后一个字节之间的距离。shex_ibFile包含此结构自身的大小,因为程序名紧跟在此结构之后。shex_ibDir是0,意味着把Windows目录作为工作目录。这并不意味着程序必须在Windows目录中。程序可以在Windows能找到的任意地方。</p>
<p>shex_nCmdShow是1,即SW_SHOWNORMAL的值。</p>
<p> <font color="#006666">File SHEXPACKET <><br>
EXEName db "calc.exe",0 </font></p>
<p>我们定义一个SHEXPACKET结构,其后紧跟着想要运行的程序名。</p>
<HR SIZE=1>
<DIV align=center> <font face="宋体">
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
<BR>
</font></DIV>
<font face="宋体"><!-- 10:1 文本广告交换 --> </font>
<DIV align=center> <font face="宋体">
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
<!-- 10:1 文本广告交换 --></font></DIV>
<HR SIZE=1>
<DIV align=center><font face="宋体">翻译:吕骏,整理:LuoYunBin's Win32 ASM Page, <A
href="http://asm.yeah.net/">http://asm.yeah.net</A></font></DIV>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -