📄 vxd-e7.html
字号:
<tr>
<td><b><font face="Tahoma">shex_ibFile</font></b></td>
<td><font face="Tahoma"><font size=-1>The relative distance from the start
of this structure to the ASCIIZ string that is the name of the file you
want to send to ShellExecute, just like shex_ibOp.</font></font></td>
</tr>
<tr>
<td><b><font face="Tahoma">shex_ibParams</font></b></td>
<td><font face="Tahoma"><font size=-1>The optional parameters you want
to pass to the file specified in shex_ibFile. If the file is a document
or you don't want to pass any parameter to it, use 0. If you want to pass
some parameters to the file, put the parameter string somewhere after this
structure and put the relative distance from the start of this structure
to the string in this field. In short, just like shex_ibOp and shex_ibFile.</font></font></td>
</tr>
<tr>
<td><b><font face="Tahoma">shex_ibDir</font></b></td>
<td><font face="Tahoma"><font size=-1>The working directory. Specify 0
if you want to use the Windows directory else you can specify your preferred
directory string somewhere after this structure and put the relative distance
between the start of this structure and the directory string in this field.</font></font></td>
</tr>
<tr>
<td><b><font face="Tahoma">shex_dwReserved</font></b></td>
<td><font face="Tahoma"><font size=-1>As the name implied, it's reserved.
Don't mess with it.</font></font></td>
</tr>
<tr>
<td><b><font face="Tahoma">shex_nCmdShow</font></b></td>
<td><font face="Tahoma"><font size=-1>How the application window should
be shown. It's one of the value you normally pass to ShowWindow, ie. the
SW_XXXX value. Look up those values in windows.inc.</font></font></td>
</tr>
</table></center>
<p><font face="Tahoma"><font size=-1><font color="#FFFFFF">All members
are DWORDs in size. Now where is that </font><b><font color="#FFFF99">rgchBaggage</font></b><font color="#FFFFFF">
member I promised I would describe? It's a little difficult to explain.
</font><b><font color="#FFFF99">rgchBaggage</font></b><font color="#FFFFFF">
is a member of SHEXPACKET structure but it cannot be included into the
structure definition because its size is arbitrary. Check shell.inc, you'd
see that </font><b><font color="#FFFF99">rgchBaggage</font></b><font color="#FFFFFF">
is not defined in SHEXPACKET yet the Windows 9x DDK documentation asserts
that it's a member of SHEXPACKET.</font></font></font>
<br><font face="Tahoma"><font size=-1><font color="#FFFFFF">What's</font><b><font color="#FFFF99">
rgchBaggage</font></b><font color="#FFFFFF">? It's simply an array of ASCIIZ
strings that follows SHEXPACKET structure. Within this array, you can put
the name of the operation you want to perform on the file, the name of
the file, the parameters you want to pass to the file and the working directory.
SHELL VxD obtains the offset of the string in </font><b><font color="#FFFF99">rgchBaggage</font></b><font color="#FFFFFF">
by adding the relative distance between the SHEXPACKET structure to the
first byte of the string to the flat offset of the SHEXPACKET. For example,
if the SHEXPACKET structure begins at 60000h, and the string immediately
follows the structure, the distance between the structure and the string
is the size of the structure itself, 32 bytes (20h). So Shell VxD knows
that the string is located at address 60020h.</font></font></font>
<h3>
<b><font face="Tahoma"><font color="#FF99FF">The Example</font></font></b></h3>
<font face="Tahoma"><font size=-1>This will be a very simple example just
to show you how to register for an appy time event and use _SHELL_ShellExecute.
The VxD will be a dynamic one which is loaded by a simple win32 application.
When the user presses the "run Calculator" button, the win32 app calls
DeviceIoControl to ask the VxD to register for an appy time event and run
calc.exe which is located in the Windows directory.</font></font>
<br><font face="Tahoma"><font size=-1></font></font>
<blockquote><b><tt>;---------------------------------------------------------------------------------</tt></b>
<br><b><tt>;
VxD Source Code</tt></b>
<br><b><tt>;---------------------------------------------------------------------------------</tt></b>
<br><b><tt>.386p</tt></b>
<br><b><tt>include \masm\include\vmm.inc</tt></b>
<br><b><tt>include \masm\include\vwin32.inc</tt></b>
<br><b><tt>include \masm\include\shell.inc</tt></b><b><tt></tt></b>
<p><b><tt>VxDName TEXTEQU <VXDEXEC></tt></b>
<br><b><tt>ControlName TEXTEQU <VXDEXEC_Control></tt></b>
<br><b><tt>VxDMajorVersion TEXTEQU <1></tt></b>
<br><b><tt>VxDMinorVersion TEXTEQU <0></tt></b><b><tt></tt></b>
<p><b><tt>VxD_STATIC_DATA_SEG</tt></b>
<br><b><tt>VxD_STATIC_DATA_ENDS</tt></b><b><tt></tt></b>
<p><b><tt>VXD_LOCKED_CODE_SEG</tt></b>
<br><b><tt>;----------------------------------------------------------------------------</tt></b>
<br><b><tt>; Remember: The name of the vxd MUST be uppercase else it won't
work/unload</tt></b>
<br><b><tt>;----------------------------------------------------------------------------</tt></b>
<br><b><tt>DECLARE_VIRTUAL_DEVICE %VxDName,%VxDMajorVersion,%VxDMinorVersion,
%ControlName,UNDEFINED_DEVICE_ID,UNDEFINED_INIT_ORDER</tt></b><b><tt></tt></b>
<p><b><tt>Begin_control_dispatch %VxDName</tt></b>
<br><b><tt> Control_Dispatch
W32_DEVICEIOCONTROL, OnDeviceIoControl</tt></b>
<br><b><tt>End_control_dispatch %VxDName</tt></b>
<br><b><tt></tt></b> <b><tt></tt></b>
<p><b><tt>BeginProc OnDeviceIoControl</tt></b>
<br><b><tt> assume esi:ptr DIOCParams</tt></b>
<br><b><tt> .if [esi].dwIoControlCode==1</tt></b>
<br><b><tt><font color="#FFFF99"> VxDCall
_SHELL_CallAtAppyTime,<<OFFSET32 OnAppyTime>,0,0,0></font></tt></b>
<br><b><tt> .endif</tt></b>
<br><b><tt> xor eax,eax</tt></b>
<br><b><tt> ret</tt></b>
<br><b><tt>EndProc OnDeviceIoControl</tt></b>
<br><b><tt>VXD_LOCKED_CODE_ENDS</tt></b><b><tt></tt></b>
<p><b><tt>VXD_PAGEABLE_CODE_SEG</tt></b>
<br><b><tt><font color="#FFFF99">BeginProc OnAppyTime, CCALL</font></tt></b>
<br><b><tt><font color="#FFFF99"> ArgVar RefData,DWORD</font></tt></b>
<br><b><tt><font color="#FFFF99"> ArgVar TheFlag,DWORD</font></tt></b>
<br><b><tt><font color="#FFFF99"> EnterProc</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_dwTotalSize,sizeof
SHEXPACKET</font></tt></b>
<br><b><tt><font color="#FFFF99"> add File.shex_dwTotalSize,sizeof
EXEName</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_dwSize,sizeof SHEXPACKET</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibOp,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibFile,sizeof SHEXPACKET</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibParams,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibDir,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_dwReserved,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_nCmdShow,1</font></tt></b>
<br><b><tt><font color="#FFFF99"> VxDCall _SHELL_ShellExecute, <OFFSET32
File></font></tt></b>
<br><b><tt><font color="#FFFF99"> LeaveProc</font></tt></b>
<br><b><tt><font color="#FFFF99"> Return</font></tt></b>
<br><b><tt><font color="#FFFF99">EndProc OnAppyTime</font></tt></b>
<br><b><tt>VXD_PAGEABLE_CODE_ENDS</tt></b><b><tt></tt></b>
<p><b><tt>VXD_PAGEABLE_DATA_SEG</tt></b>
<br><b><tt><font color="#66FF99"> File SHEXPACKET <></font></tt></b>
<br><b><tt><font color="#66FF99"> EXEName db "calc.exe",0</font></tt></b>
<br><b><tt>VXD_PAGEABLE_DATA_ENDS</tt></b><b><tt></tt></b>
<p><b><tt>end</tt></b></blockquote>
<h3>
<font face="Tahoma"><font color="#FF99FF">Analysis</font></font></h3>
<font face="Tahoma"><font size=-1>The VxD waits for DeviceIoControl messages,
service no.1. When it receives such message, it registers for an application
time event.</font></font>
<blockquote><b><tt><font color="#FFFF99">VxDCall _SHELL_CallAtAppyTime,<<OFFSET32
OnAppyTime>,0,0,0></font></tt></b></blockquote>
<font face="Tahoma"><font size=-1>It passes the flat address of OnAppyTime
function to _SHELL_CallAtAppyTime so that Shell VxD will call it when an
appy time event occurs. We don't use any reference data and have no need
for timeout so all three parameters following the flat address of OnAppyTime
are zeroes.</font></font>
<br><font face="Tahoma"><font size=-1>When an appy time event occurs, the
Shell VxD calls OnAppyTime function.</font></font>
<blockquote><b><tt><font color="#FFFF99">BeginProc OnAppyTime, CCALL</font></tt></b></blockquote>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>We declare a function
with BeginProc. Since the Shell VxD will call OnAppyTime with C calling
sequence, we need to specify <b>CCALL</b> attribute.</font></font></font>
<blockquote><b><tt><font color="#FFFF99">ArgVar RefData,DWORD</font></tt></b>
<br><b><tt><font color="#FFFF99">ArgVar TheFlag,DWORD</font></tt></b>
<br><b><tt><font color="#FFFF99">EnterProc</font></tt></b>
<br><b><tt><font color="#FFFF99">...</font></tt></b>
<br><b><tt><font color="#FFFF99">LeaveProc</font></tt></b>
<br><b><tt><font color="#FFFF99">Return</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">Since the Shell
VxD will call OnAppyTime with two parameters, we must setup the stack frame
accordingly. </font><b><font color="#FFFF99">ArgVar</font><font color="#FFFFFF">
</font></b><font color="#FFFFFF">macro is for adjusting the stack frame
for each of the argument passed to the function. Its syntax is as follows:</font></font></font>
<blockquote><b><font face="Tahoma"><font color="#66FF99"><font size=-1>ArgVar
varname, size, used</font></font></font></b></blockquote>
<font face="Tahoma"><font size=-1><b><font color="#FFFF99">varname</font></b><font color="#FFFFFF">
is the name of the parameter. You can use any name you like. </font><b><font color="#FFFF99">size</font></b><font color="#FFFFFF">
is, of course, the size of the parameter in bytes. You can use BYTE, WORD,
DWORD or 1,2,4. </font><b><font color="#FFFF99">used</font></b><font color="#FFFFFF">
is usually omitted.</font></font></font>
<br><font face="Tahoma"><font size=-1><font color="#FFFFFF">Immediately
following the </font><b><font color="#FFFF99">ArgVar </font></b><font color="#FFFFFF">macros,
we need to use </font><b><font color="#FFFF99">EnterProc</font></b><font color="#FFFFFF">
and </font><b><font color="#FFFF99">LeaveProc </font></b><font color="#FFFFFF">macros
to mark the beginning and the end of the instructions in the procedure
so that the local variables and parameters can be accessed correctly. Use
</font><b><font color="#FFFF99">Return </font></b><font color="#FFFFFF">macro
to return to the caller.</font></font></font>
<blockquote><b><tt><font color="#FFFF99"> mov File.shex_dwTotalSize,sizeof
SHEXPACKET</font></tt></b>
<br><b><tt><font color="#FFFF99"> add File.shex_dwTotalSize,sizeof
EXEName</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_dwSize,sizeof SHEXPACKET</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibOp,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibFile,sizeof SHEXPACKET</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibParams,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_ibDir,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_dwReserved,0</font></tt></b>
<br><b><tt><font color="#FFFF99"> mov File.shex_nCmdShow,1</font></tt></b>
<br><b><tt><font color="#FFFF99"> VxDCall _SHELL_ShellExecute, <OFFSET32
File></font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">The instructions
inside the procedure is simple: initialize the SHEXPACKET structure and
call </font><b><font color="#FFFF99">_SHELL_ShellExecute</font></b><font color="#FFFFFF">
service. Note that </font><b><font color="#FFFF99">shex_dwTotalSize</font></b><font color="#FFFFFF">
contains the combined size of the SHEXPACKET structure itself and the size
of the string that follows it. This is the simple case. If the string doesn't
immediately follow the structure, you must calculate the distance between
the first byte of the structure and the last byte of the string yourself.
</font><b><font color="#FFFF99">shex_ibFile</font></b><font color="#FFFFFF">
contains the size of the structure itself because the name of the program
immediately follows the structure. </font><b><font color="#FFFF99">shex_ibDir</font></b><font color="#FFFFFF">
is zero meaning that we want to use the Windows directory as the working
directory. Note that this doesn't mean the program must be in the windows
directory. The program can be anywhere so long as Windows can find it.
</font><b><font color="#FFFF99">shex_nCmdShow</font></b><font color="#FFFFFF">
is 1 which is the value SW_SHOWNORMAL.</font></font></font>
<blockquote><b><tt><font color="#66FF99">File SHEXPACKET <></font></tt></b>
<br><b><tt><font color="#66FF99">EXEName db "calc.exe",0</font></tt></b></blockquote>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>We define a SHEXPACKET
structure followed immediately by the name of the program that we want
to execute.</font></font></font>
<br>
<hr WIDTH="100%">
<center><b>[<a href="http://win32asm.cjb.net">Iczelion's Win32 Assembly
Homepage</a>]</b></center>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -