iczelion Vxd tut8

vxd 专栏收录该内容
17 篇文章 0 订阅


Client Register Structure

We will examine another important structure in this tutorial, namely the client register structure. Download the example.

Some theory

VxDs are very different from normal win32/win16/DOS applications. VxDs are, most of the time, dormant while other normal apps do their businesses. They act like supervisors which look over other ring-3 apps and correct them when they did something wrong. The typical situation is as follows:
  1. An interrupt occurs
  2. The VMM gains control
  3. The VMM saves the values of the registers
  4. The VMM services the interrupt or calls other VxDs to do the job
  5. The VMM returns control to the interrupted program.
The interesting thing about the above process is that, the only way VMM can affect the interrupted app is by modifying the saved register image. For example, if the VMM deems the interrupted program should resume at a different address, it can alter the value of CS:IP in the saved register image and then when the program is redispatched, it will resume execution at the new CS:IP.
The VMM saves the values of the registers at the interrupted point in the client register structure.
Client_Reg_Struc STRUC
Client_EDI DD ?
Client_ESI DD ?
Client_EBP DD ?
Client_res0 DD ?
Client_EBX DD ?
Client_EDX DD ?
Client_ECX DD ?
Client_EAX DD ?
Client_Error DD ?
Client_EIP DD ?
Client_CS DW ?
Client_res1 DW ?
Client_EFlags DD ?
Client_ESP DD ?
Client_SS DW ?
Client_res2 DW ?
Client_ES DW ?
Client_res3 DW ?
Client_DS DW ?
Client_res4 DW ?
Client_FS DW ?
Client_res5 DW ?
Client_GS DW ?
Client_res6 DW ?
Client_Alt_EIP DD ?
Client_Alt_CS DW ?
Client_res7 DW ?
Client_Alt_EFlags DD ?
Client_Alt_ESP DD ?
Client_Alt_SS DW ?
Client_res8 DW ?
Client_Alt_ES DW ?
Client_res9 DW ?
Client_Alt_DS DW ?
Client_res10 DW ?
Client_Alt_FS DW ?
Client_res11 DW ?
Client_Alt_GS DW ?
Client_res12 DW ?
Client_Reg_Struc ENDS
You can see that there are two sets of members in this structure: Client_xxx and Client_Alt_xxx. This requires a little explanation. In a given VM, there can be two threads of execution: V86 and protected-mode. If an interrupt occurs when a V86 program is active, the Client_xxx will contain the images of the registers of the V86 program, the Client_Alt_xxx will contain those of the PM program. Alternately, if an interrupt occurs when the PM program is active, the Client_xxx will contain the values of the PM program's registers while the Client_Alt_xxx will contain the values of the V86 program's registers. The Client_resX are reserved and not used.
You may have a question after examining the structure: what if I want to alter only a byte  in a register, say al ? The above structure only describes word-and dword-sized registers. Have no fear. Take a look inside vmm.inc. There are additional two structures for just this purpose: Client_Word_Reg_Struc and Client_Byte_Reg_Struc. If you want to access word-or byte-sized registers, typecast the Client_Reg_Struc into Client_Word_Reg_Struc or Client_Byte_Reg_Struc according to your need. You can also

The next question: How can we obtain the pointer to the client register structure?

It's actually easy: most of the time, the VMM puts the address of the client register structure in ebp when it calls our VxD. The client register structure in this case is the current VM's. Alternatively, you can obtain this pointer from the VM handle. Remember that a VM handle is actually the linear address of the VM control block.
cb_s STRUC
CB_VM_Status DD ?
CB_High_Linear DD ?
CB_Client_Pointer DD ?
CB_Signature DD ?
cb_s ENDS
CB_Client_Pointer contains the pointer to the client register structure of that VM. For example, you can obtain the pointer to the client register structure of the current VM by the following code:
VMMCall Get_Cur_VM_Handle   ; return the current VM handle in ebx
assume ebx:ptr cb_s
mov ebp,[ebx+CB_Client_Pointer] ; pointer to client reg struct
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 dl. If we pass the bell character (07h) to this service, it will play the bell through the PC speaker.
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 Exec_Int service. This VMM service takes the interrupt number to be called in eax. 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 Begin_Nest_V86_Exec (or Begin_Nest_Exec) and End_Nest_Exec.  So if we want to call int 21h, service 2, we need to alter the Client_ah and Client_Dl of the Client_Byte_Reg_Struc structure within the nested execution block and then store the value 21h into eax. When everything is ready, call Exec_Int.

The Example

The example is a dynamic VxD that issues int 21h service 2 to play the PC speaker.
include /masm/include/vmm.inc
include /masm/include/vwin32.inc
include /masm/include/v86mmgr.inc

ControlName TEXTEQU <VXDINT_Control>
VxDMajorVersion TEXTEQU <1>
VxDMinorVersion TEXTEQU <0>


; Remember: The name of the vxd MUST be uppercase else it won't work/unload

Begin_control_dispatch %VxDName
        Control_Dispatch W32_DEVICEIOCONTROL, OnDeviceIoControl
End_control_dispatch %VxDName


BeginProc OnDeviceIoControl
 assume esi:ptr DIOCParams
 .if [esi].dwIoControlCode==1
  VMMCall Begin_Nest_V86_Exec
  assume ebp:ptr Client_Byte_Reg_Struc
  mov [ebp].Client_dl,7
  mov [ebp].Client_ah,2
  mov eax,21h
  VMMCall Exec_Int
  VMMCall End_Nest_Exec
 xor eax,eax
EndProc OnDeviceIoControl



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 Push_Client_State macro to save the current state of the client registers on the stack. We later restore the client registers with Pop_Client_State.
VMMCall Begin_Nest_V86_Exec
Begin the nested execution block by calling Begin_Nest_V86_Exec.
assume ebp:ptr Client_Byte_Reg_Struc
mov [ebp].Client_dl,7
mov [ebp].Client_ah,2
Alter the images of dl and ah registers in the client register structure. This altered values will be used by the interrupt.
mov eax,21h
VMMCall Exec_Int
Exec_Int expects the interrupt number in eax. We want to issue int 21h. Then we call Exec_Int to simulate the interrupt.
VMMCall End_Nest_Exec
When Exec_Int returns, we end the nested execution block and restore the saved values of the client registers from the stack.
You'll hear your PC speaker plays the bell character.

[Iczelion's Win32 Assembly Homepage]
  • 0
  • 0
  • 0
  • 一键三连
  • 扫一扫,分享海报

<p> <span style="font-size:14px;color:#337FE5;">【为什么学爬虫?】</span> </p> <p> <span style="font-size:14px;">       1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!</span> </p> <p> <span style="font-size:14px;">       2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站</span> </p> <p> <br /> </p> <span style="font-size:14px;color:#337FE5;">【课程设计】</span> <p class="ql-long-10663260"> <span> </span> </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 网络请求:模拟浏览器的行为从网上抓取数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 </li> <li class="" style="font-size:11pt;color:#494949;"> Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。 </p> <p style="font-size:11pt;color:#494949;">   </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> <br /> </p> <p> <br /> </p> <p> <span style="font-size:14px;background-color:#FFFFFF;color:#337FE5;">【课程服务】</span> </p> <p> <span style="font-size:14px;">专属付费社群+定期答疑</span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"><br /> </span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"></span> </p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
钱包余额 0