⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vxd-e8.html

📁 汇编语言编写的虚拟驱动程序
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<br><b><tt><font color="#FFFFFF">CB_VM_Status DD ?</font></tt></b>
<br><b><tt><font color="#FFFFFF">CB_High_Linear DD ?</font></tt></b>
<br><b><tt><font color="#FFFFFF">CB_Client_Pointer DD ?</font></tt></b>
<br><b><tt><font color="#FFFFFF">CB_VMID DD ?</font></tt></b>
<br><b><tt><font color="#FFFFFF">CB_Signature DD ?</font></tt></b>
<br><b><tt><font color="#FFFFFF">cb_s ENDS</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><b><font color="#FFFF99">CB_Client_Pointer</font></b><font color="#FFFFFF">
contains the pointer to the </font><b><font color="#FFFF99">client register
structure </font></b><font color="#FFFFFF">of that VM. For example, you
can obtain the pointer to the client register structure of the current
VM by the following code:</font></font></font>
<blockquote><b><tt><font color="#FFFFFF">VMMCall Get_Cur_VM_Handle&nbsp;&nbsp;
; return the current VM handle in ebx</font></tt></b>
<br><b><tt><font color="#FFFFFF">assume ebx:ptr cb_s</font></tt></b>
<br><b><tt><font color="#FFFFFF">mov ebp,[ebx+CB_Client_Pointer] ; pointer
to client reg struct</font></tt></b></blockquote>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>Now that we understand
the client register structure, we can proceed to using it. We will use
the client register structure to pass values in registers to an MS-DOS
interrupt, namely, int 21h, service 2h, Display Character service. This
MS-DOS service takes the character to be displayed in <b>dl.</b> If we
pass the bell character (07h) to this service, it will play the bell through
the PC speaker.</font></font></font>
<br><font face="Tahoma"><font size=-1><font color="#FFFFFF">Remember that
int 21h is an MS-DOS service thus it's available under V86 mode, how can
we call a V86 interrupt from a VxD? One way is to use </font><b><font color="#FFFF99">Exec_Int</font></b><font color="#FFFFFF">
service. This VMM service takes the interrupt number to be called in </font><b><font color="#FFFF99">eax</font></b><font color="#FFFFFF">.
It simulates the specified interrupt and resumes the execution of the VM.
However, it must be called within a nested execution block. A nested execution
block is bracketed by </font><b><font color="#FFFF99">Begin_Nest_V86_Exec</font></b><font color="#FFFFFF">
(or </font><b><font color="#FFFF99">Begin_Nest_Exec</font></b><font color="#FFFFFF">)
and </font><b><font color="#FFFF99">End_Nest_Exec</font></b><font color="#FFFFFF">.&nbsp;
So if we want to call int 21h, service 2, we need to alter the Client_ah
and Client_Dl of the </font><b><font color="#FFFF99">Client_Byte_Reg_Struc</font></b><font color="#FFFFFF">
structure within the nested execution block and then store the value 21h
into eax. When everything is ready, call </font><b><font color="#FFFF99">Exec_Int</font></b><font color="#FFFFFF">.</font></font></font>
<h3>
<font face="Tahoma"><font color="#FF99FF">The Example</font></font></h3>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>The example is
a dynamic VxD that issues int 21h service 2 to play the PC speaker.</font></font></font>
<br><font face="Tahoma"><font color="#FFFFFF"><font size=-1></font></font></font>&nbsp;
<blockquote><b><tt><font color="#FFFFFF">.386p</font></tt></b>
<br><b><tt><font color="#FFFFFF">include \masm\include\vmm.inc</font></tt></b>
<br><b><tt><font color="#FFFFFF">include \masm\include\vwin32.inc</font></tt></b>
<br><b><tt><font color="#FFFFFF">include \masm\include\v86mmgr.inc</font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">VxDName TEXTEQU &lt;VXDINT></font></tt></b>
<br><b><tt><font color="#FFFFFF">ControlName TEXTEQU &lt;VXDINT_Control></font></tt></b>
<br><b><tt><font color="#FFFFFF">VxDMajorVersion TEXTEQU &lt;1></font></tt></b>
<br><b><tt><font color="#FFFFFF">VxDMinorVersion TEXTEQU &lt;0></font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">VxD_STATIC_DATA_SEG</font></tt></b>
<br><b><tt><font color="#FFFFFF">VxD_STATIC_DATA_ENDS</font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">VXD_LOCKED_CODE_SEG</font></tt></b>
<br><b><tt><font color="#FFFFFF">;----------------------------------------------------------------------------</font></tt></b>
<br><b><tt><font color="#FFFFFF">; Remember: The name of the vxd MUST be
uppercase else it won't work/unload</font></tt></b>
<br><b><tt><font color="#FFFFFF">;----------------------------------------------------------------------------</font></tt></b>
<br><b><tt><font color="#FFFFFF">DECLARE_VIRTUAL_DEVICE %VxDName,%VxDMajorVersion,%VxDMinorVersion,
%ControlName,UNDEFINED_DEVICE_ID,UNDEFINED_INIT_ORDER</font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">Begin_control_dispatch %VxDName</font></tt></b>
<br><b><tt><font color="#FFFFFF">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Control_Dispatch W32_DEVICEIOCONTROL, OnDeviceIoControl</font></tt></b>
<br><b><tt><font color="#FFFFFF">End_control_dispatch %VxDName</font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">VXD_LOCKED_CODE_ENDS</font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">VXD_PAGEABLE_CODE_SEG</font></tt></b>
<br><b><tt><font color="#FFFFFF">BeginProc OnDeviceIoControl</font></tt></b>
<br><b><tt><font color="#FFFFFF">&nbsp;assume esi:ptr DIOCParams</font></tt></b>
<br><b><tt><font color="#FFFFFF">&nbsp;.if [esi].dwIoControlCode==1</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; Push_Client_State</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; VMMCall Begin_Nest_V86_Exec</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; assume ebp:ptr Client_Byte_Reg_Struc</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; mov [ebp].Client_dl,7</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; mov [ebp].Client_ah,2</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; mov eax,21h</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; VMMCall Exec_Int</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; VMMCall End_Nest_Exec</font></tt></b>
<br><b><tt><font color="#FFFF99">&nbsp; Pop_Client_State</font></tt></b>
<br><b><tt><font color="#FFFFFF">EndI:</font></tt></b>
<br><b><tt><font color="#FFFFFF">&nbsp;.endif</font></tt></b>
<br><b><tt><font color="#FFFFFF">&nbsp;xor eax,eax</font></tt></b>
<br><b><tt><font color="#FFFFFF">&nbsp;ret</font></tt></b>
<br><b><tt><font color="#FFFFFF">EndProc OnDeviceIoControl</font></tt></b>
<br><b><tt><font color="#FFFFFF">VXD_PAGEABLE_CODE_ENDS</font></tt></b><b><tt><font color="#FFFFFF"></font></tt></b>
<p><b><tt><font color="#FFFFFF">end</font></tt></b></blockquote>

<h3>
<font face="Tahoma"><font color="#FF99FF">Analysis</font></font></h3>

<blockquote><b><tt><font color="#FFFF99">Push_Client_State</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">There is not much
to analyze. When the VxD receives DeviceIoControl message, ebp already
points to the current VM's client register structure. We call </font><b><font color="#FFFF99">Push_Client_State</font></b><font color="#FFFFFF">
macro to save the current state of the client registers on the stack. We
later restore the client registers with </font><b><font color="#FFFF99">Pop_Client_State</font></b><font color="#FFFFFF">.</font></font></font>
<blockquote><b><tt><font color="#FFFF99">VMMCall Begin_Nest_V86_Exec</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">Begin the nested
execution block by calling </font><b><font color="#FFFF99">Begin_Nest_V86_Exec</font></b><font color="#FFFFFF">.</font></font></font>
<blockquote><b><tt><font color="#FFFF99">assume ebp:ptr Client_Byte_Reg_Struc</font></tt></b>
<br><b><tt><font color="#FFFF99">mov [ebp].Client_dl,7</font></tt></b>
<br><b><tt><font color="#FFFF99">mov [ebp].Client_ah,2</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">Alter the images
of </font><b><font color="#FFFF99">dl </font></b><font color="#FFFFFF">and</font><b><font color="#FFFF99">
ah</font></b><font color="#FFFFFF"> registers in the client register structure.
This altered values will be used by the interrupt.</font></font></font>
<blockquote><b><tt><font color="#FFFF99">mov eax,21h</font></tt></b>
<br><b><tt><font color="#FFFF99">VMMCall Exec_Int</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><b><font color="#FFFF99">Exec_Int</font></b><font color="#FFFFFF">
expects the interrupt number in eax. We want to issue int 21h. Then we
call </font><b><font color="#FFFF99">Exec_Int </font></b><font color="#FFFFFF">to
simulate the interrupt.</font></font></font>
<blockquote><b><tt><font color="#FFFF99">VMMCall End_Nest_Exec</font></tt></b>
<br><b><tt><font color="#FFFF99">Pop_Client_State</font></tt></b></blockquote>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">When </font><b><font color="#FFFF99">Exec_Int</font></b><font color="#FFFFFF">
returns, we end the nested execution block and restore the saved values
of the client registers from the stack.</font></font></font>
<br><font face="Tahoma"><font color="#FFFFFF"><font size=-1>You'll hear
your PC speaker plays the bell character.</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 + -