再和 DriverStudio 过不去之加强版:)
再和DriverStudio"过不去"之加强版
(<<抢先DriverStudio夺取机器控制权>>系列2)
?(测试平台 windows 2000 sp4 + masm32v9.0)
?上篇仅仅说到如何抢先DriverStudio,并在结尾留给大家一
?个遐想。现在我进一步拓展这个遐想,从而给大家更多的遐
?想。: )
?那么现在我要给这个驱动增加新的功能,不但抢
?DriverStudio 启动,而且给用户显示几行提示,并等待用
?户的输入,如果用户敲 B 键则发生蓝屏,如果用户按任
?意其他键则继续往下执行,So DriverStudio 可以正常执
?行下去。
?要完成这个功能必须解决两个问题:
?0 如何在系统引导时显示字符串;
?1 如何捕获用户输入并延时等待。
?那么从哪入手呢?我首先想到直接写Video Buffer和直接捕获
?键盘寄存器,但是这个方法可行吗?我们不妨先看一下
?DriverStudio的 bootcfg.sys 是如何做的。
?照例用IDA载入bootcfg.sys,按照DriverStudio初始化
?显示的字符串来到驱动的DriverEntry,如图0
?图0
?通过查找字符串的引用很快就找到对应的指令调用点,全文
?只有一个引用,如图1所示:
?图1
?为了确认这一点,我将地址0x107dd - 0x107e6中的指令全
?部nop掉,
?图2
?这时原先应该显示"Press ESC ..."这段话的地方果然没有显示,
?而是直接跳到 Config 对话框那里去了。既然找对了地方下一
?步就好办了,通过进一步反汇编bootcfg.sys的代码片断,
?更加印证了我先前的想法!
?下面进一步谈谈DriverStudio是如何做的:
?a. 使用 MmMapIoSpace 完成物理地址到虚拟地址的映射,
?因为内核已经进入保护模式,并且开了分页。要想读写物
?理地址必须做这样的映射(我的
?《Windows 核心编程研究系列之二:读取指定物理内存地址
?中的内容 》
?一篇中有更为详细的说明)。
?该函数原形如下:
?PVOID
MmMapIoSpace(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberOfBytes,
IN MEMORY_CACHING_TYPE CacheType
?MmMapIoSpace(
IN PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG NumberOfBytes,
IN MEMORY_CACHING_TYPE CacheType
参数含义都比较明显,其中CacheType我们选择NoCache类型。
?b. 使用类似于bios字符中断显示的规则,一个字符占一
?个word(16bit),低位为字符的ascii码,高位为显示属性。
?我这里要显示闪烁的红色字体,所以属性为 84h。与bios
?中断不同的是,我们直接写视频缓冲,而不是调用 int 10h。
?视频缓冲的物理地址为 0b8000h 。我写了一个显示函数,
?包含两个参数:
?第一个是字符串地址,第二个是显示的位置。
?为了美观,我将2行字符串显示在屏幕的倒数最后两行上:
?Screen_W equ 50h
?Screen_H equ 19h ;1ch
?Show_Pos_Line0 equ (Screen_W * (Screen_H - 2) + 5) * 2
?Show_Pos_Line1 equ (Screen_W * (Screen_H - 1) + 5) * 2
?函数内容如下:
;******************************************************
?;******************************************************
_DisplayString proc _lpstr,_pos
?local pa:qword
local lpvmem:dword
?local lpvmem:dword
mov dword ptr [pa],Video_Addr
?mov dword ptr [pa+4],0
?push 0 ;MmNonCached
?push 8000h ;NumberOfBytes
?push dword ptr [pa+4]
?push dword ptr [pa]
?call MmMapIoSpace
?mov lpvmem,eax
?mov esi,_lpstr
?mov edi,lpvmem
?add edi,_pos
?mov bh,84h ;char show_attribute
?.while TRUE
?.if byte ptr [esi] != 0
?mov bl,byte ptr [esi]
?mov word ptr [edi],bx
?inc esi
?inc edi
?inc edi
?.else
?.break
?.endif
?.endw
?invoke MmUnmapIoSpace,lpvmem,8000h
?ret
?_DisplayString endp
?最后不要忘了用MmUnmapIoSpace取消映射。
?c. 为了达到延时的效果需要调用ntoskrnl.exe中的api
KeDelayExecutionThread,其原形如下:
NTSTATUS
KeDelayExecutionThread(
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Interval
);
?KeDelayExecutionThread(
IN KPROCESSOR_MODE WaitMode,
IN BOOLEAN Alertable,
IN PLARGE_INTEGER Interval
);
其中 WaitMode选择KernelMode,将可报警置为FALSE.尤为值得
?注意的是第3个参数Interval。这个参数说明如下:
?Interval
Specifies the absolute or relative time, in units of 100 nanoseconds, for which the wait is to occur. A negative value indicates relative time. Absolute expiration times track any changes in system time; relative expiration times are not affected by system time changes.
我们最好使用相对时间的延时方式,这就需要写成负数的形式,而将
参数前缀位(byte)全部置1。为了达到捕获键盘输入,需要直接访问
IO端口64h和60h,这在ring0种都不成问题 。我同样写了一个子函数方
便调用,代码如下:
;************************************************************
?_WaitForInput proc
?local al_tmp:byte
local interval:LARGE_INTEGER
local turnsNow:dword
?local interval:LARGE_INTEGER
local turnsNow:dword
mov dword ptr [interval],0ffffe000h
?mov dword ptr [interval+4],0ffffffffh
?mov turnsNow,0
?.while TRUE
?.if turnsNow == Turns
?.break
?.else
?inc turnsNow
?in al,64h
?test al,1 ;is anykey is pressed ?
?jz Delay
?in al,60h
?mov al_tmp,al
?movzx eax,al_tmp
?cmp eax,1
?jz ExitWhile
?cmp eax,1eh
?jz ExitWhile
?cmp eax,0b0h
?jz ExitWhile
?cmp eax,1ch
?jnz Delay
?ExitWhile:
?.break
?Delay:
?invoke KeDelayExecutionThread,0,0,addr interval
?.endif
?.endw
?xor eax,eax
?mov al,al_tmp
?ret
?_WaitForInput endp
?;**********************************************************
?d. 剩下来做的事就是在Main中判断用户输入的键码:
?invoke _DisplayString,addr szhopysay,Show_Pos_Line0
?invoke _DisplayString,addr szchoose,Show_Pos_Line1
?invoke _WaitForInput
?.if al == 01h
?;do nothing
?.elseif al == 0b0h
?invoke _TryBS
?.else
?;do nothing
?.endif
?运行的效果如图3所示:
?图3
?蓝屏的代码就不给出了,因为相信每个人都能写出N种来。
?写续篇的原因是因为正好看到驱网(www.driverdevelop.com)的
?一篇逆向的文章,想现学现卖一番,呵呵。
?暂时到这里吧(以前预告的第3篇文章因为要将原先结合VB的
?界面变为C#而且又有了新的想法,所以还要等一段时间,呼呼),准
?备去看女足啦,哇咔咔.......(无语了,这不是我...不是我....
?不是我 ... ...)
?(因为写得仓促,难免有不妥的地方,希望大家多多指出,谢谢)
?(点击小图看大图)
?侯佩|hopy
?写于2007.09.18
