首页 > 编程语言 >Wdf框架:FxDriverEntry----驱动程序的入口函数

Wdf框架:FxDriverEntry----驱动程序的入口函数

时间:2022-11-07 21:36:48浏览次数:42  
标签:WdfVersionBind 驱动程序 Wdf 00000000 ffff8881 ---- fffff802 nt ffffd381


    在前面的文章<Wdf框架中WdfDriverGlobals对象的创建>中简单的提到过WdfVersionBind函数的作用,但是没有来得及分析这个函数的调用处。今天得空,借这篇文章写下WdfVersionBind函数的调用者:FxDriverEntry。

    在写这篇文章前,我被WdfLdr.sys的名字误导,以为这个sys文件是内核的加载器,用于加载整个内核启动(Ldr是Loader的缩写)。所以,当时我很粗浅的认为这个驱动只在系统引导阶段才被调用,之后就靠边站了。然而事实却是,当系统启动后,只要加载基于WDF框架的驱动,就会中断在WdfVersionBind函数上。以登录到系统后,加载WinDDK中WdfSimple.sys驱动(toast驱动的WDF版本)为例:

kd> bp WDFLDR!WdfVersionBind
kd> g
Breakpoint 1 hit
WDFLDR!WdfVersionBind:
fffff802`9598d2d0 488bc4 mov rax,rsp
kd> kb
RetAddr : Args to Child : Call Site
fffff802`98a414a3 : ffff8881`fc86f000 ffff8881`fbf2c750 00000000`00000000 ffff327f`24cdc304 : WDFLDR!WdfVersionBind
fffff802`5ab053e9 : 00000000`00000000 ffffd381`a819d460 ffff8881`fbf2c750 ffffffff`00000000 : wdfsimple!FxDriverEntryWorker+0x7f
fffff802`5abab13e : 00000000`00000000 00000000`00000000 00000000`00000004 ffffc285`00000004 : nt!IopLoadDriver+0x521
fffff802`5ab04495 : ffffd381`a819da01 ffffd381`a819d6c8 00000000`c0000000 ffffd381`a819d6a4 : nt!PipCallDriverAddDeviceQueryRoutine+0x1b6
fffff802`5ab03e93 : 00000000`00000000 00000000`00000014 00000000`c0000034 ffff8881`fbd6cd30 : nt!PnpCallDriverQueryServiceHelper+0xbd
fffff802`5ab0323d : ffff8881`fbd6cd30 ffffd381`a819d8e0 ffff8881`fbd6cd30 00000000`00000000 : nt!PipCallDriverAddDevice+0x317
fffff802`5acd5eda : ffff8881`fbd6cd30 00000000`00000001 ffffd381`a819db19 fffff802`5ab0397b : nt!PipProcessDevNodeTree+0x1cd
fffff802`5a824d9e : 00000001`00000003 00000000`00000000 ffffd381`a819daf0 00000000`00000000 : nt!PiRestartDevice+0xba
fffff802`5a6e0d79 : ffff8881`f97af040 fffff802`5a9a5320 fffff802`5aa46280 fffff802`5aa46280 : nt! ?? ::FNODOBFM::`string'+0x42bde
fffff802`5a7254bd : fffff802`5a9cb180 00000000`00000080 ffff8881`f88af6c0 ffff8881`f97af040 : nt!ExpWorkerThread+0xe9
fffff802`5a7d8456 : fffff802`5a9cb180 ffff8881`f97af040 fffff802`5a72547c 43ffff41`04080003 : nt!PspSystemThreadStartup+0x41
00000000`00000000 : ffffd381`a819e000 ffffd381`a8198000 00000000`00000000 00000000`00000000 : nt!KxStartSystemThread+0x16

图1:


Wdf框架:FxDriverEntry----驱动程序的入口函数_d3


图1结合调试输出显示,在登录系统后,加载驱动也会中断到WdfVersionBind。由此可见,OS会为每个Wdf驱动设置WDF框架的版本号等信息。这些内容属于上一篇文章的延伸,我要借助它引出这篇文章的主题:FxDriverEntry。

    上面的函数调用栈中只有frame 1与我们的驱动模块有关,但名字却是FxDriverEntryWorker。整份Sample源码中没有调用这个函数,可见,它是由编译器插入的。这就又引出2个疑问:

1.驱动入口DriverEntry在FxDriverEntryWorker函数执行完后调用;

2.反之,驱动入口DriverEntry在FxDriverEntryWorker函数之前执行。

如果属于情况2,可能我要重启或者重新加载驱动。怕麻烦的我最终选择用IDA加载wdfsimple.sys分析了函数流程。下图是在IDA中对DriverEntry函数执行"XRefs graph to"后生成的调用图,调用次序依次为FxDriverEntry->FxDriverEntryWorker->DriverEntry:

Wdf框架:FxDriverEntry----驱动程序的入口函数_d3_02

    FxDriverEntry只是一个包装函数,真正的工作全交由FxDriverEntryWorker完成。下面的代码是IDA对FxDriverEntryWorker函数反汇编后生成的伪代码。FxDriverEntryWorker首先为WdfSimple驱动对象DriverObject调用WdfVersionBind,设置Wdf框架信息并关联WdfDriverGlobals这个重要的全局变量。如果WdfVersionBind调用成功,则会调用DriverEntry进入我们程序的入口。这才是原来WDM模型中驱动程序的入口。

int __fastcall FxDriverEntryWorker(_DRIVER_OBJECT *DriverObject, _UNICODE_STRING *RegistryPath)
{
_UNICODE_STRING *v2; // rsi@1
_DRIVER_OBJECT *v3; // rdi@1
int result; // eax@2
int v5; // ebx@4
void (__cdecl *v6)(_DRIVER_OBJECT *); // rax@7

v2 = RegistryPath;
v3 = DriverObject;
if ( DriverObject )
{
result = WdfVersionBind_0(v3, &WdfDriverStubRegistryPath, &WdfBindInfo, &WdfDriverGlobals);
if ( result >= 0 )
{
v5 = FxStubBindClasses(&WdfBindInfo);
if ( v5 < 0 || (FxStubInitTypes(), v5 = DriverEntry(v3, v2), v5 < 0) ) //WdfVersionBind执行成功后,调用DrvierEntry
{
}

    本篇完


标签:WdfVersionBind,驱动程序,Wdf,00000000,ffff8881,----,fffff802,nt,ffffd381
From: https://blog.51cto.com/u_13927568/5831389

相关文章

  • P2280 [HNOI2003]激光炸弹
    前缀和对于二维前缀和,令\(b[n][m]\)是\(\sum_{i=1}^n\sum_{j=1}^ma_{ij}\)的值,那么因为容斥原理,有\[b[i][j]=b[i-1][j]+b[i][j-1]-b[i-1][j-1]+a[i][j].\]要是......
  • Wdf框架中WdfDriverGlobals对象的创建
      前面写过一篇<WDF基本对象和句柄定义>,反响一般,不过这不会成为阻挡我继续写下去的绊脚石~本篇我们继续来分析Wdf框架。   WdfDriverGlobals对象的身影活跃在wdf框......
  • Go进阶53:从零Go实现Websocket-H5-RDP/VNC远程桌面客户端
    Go进阶53:从零Go实现Websocket-H5-RDP/VNC远程桌面客户端Go&Rust......
  • 对<源码级调试WDF框架>一文进行补充
    MS曾在他的Github站点上提出过​​《源码级调试WDF框架》​​的方法,文中提到通过.srcfix命令使windbg源码服务器路径指向MS的源码服务器。这样当调试到wdf框架代码时,windbg......
  • freeCodecamp_认证项目_调查表单
    点击查看代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="view......
  • 搜索驱动程序分配的内存和查看KEVENT状态
    问题的提出:(类似windbg~*kb命令)的调用栈不就行了。没错,对于应用程序而言,这样做十有八九已经定位了。但是,对于驱动程序而言,它运行的上下文可能并不固定在某一进程,回溯内核......
  • CodeStar第五周周赛
    T1:复合逻辑表达式本题难度中等,线性\(dp\)问题。根据最后一个运算递推:如果是AND,需要两边都是true;如果是OR,只需任意一个是true当S[i]='AND'y[i-1]=T且x[i]=T:......
  • 数组~Count digits from a text stream
    题目描述Countdigits,whitespaces(‘’,’\n’,’\t’)andothercharactersfromatextstreamendingwithEOF.输入AtextstreamendingwithEOF输出Pr......
  • TestNg注解
    packagetest;importorg.testng.annotations.Optional;importorg.testng.annotations.Parameters;importorg.testng.annotations.Test;publicclasstest01{......
  • 2种内核级反用户态调试方法
    0.前言  很久前写过一些应用层的反调试的文章,这类反调试方法的好处是易于实现,但缺点是很容易被绕过----保护因此失效。我们的危机公关手段是:将反调试功能放到内核中用驱......