找回密码
 加入计匠网
搜索
热搜: BIOS ACPI CPU Windows
查看: 22339|回复: 8

[原创]WMIACPI.SYS

[复制链接]
发表于 2009-5-22 17:14:23 | 显示全部楼层 |阅读模式
WMIACPI.SYS

; v" V, Q) }5 N) X# |8 D3 F+ r5 v1. WMI Concept# w# N. S/ w$ T

1 `; f. @3 t# m3 c% U- UWMI全称Windows Management Instrumentation是一种管理计算机系统的方式。它是微软基于WBEM的实现,WMI希望为系统管理以及分布式数据描述提供一种模型,并且允许使用基于COM的user mode API对系统部件进行访问、管理、控制。- Q( y2 P9 q' ]1 m5 B5 K) o
! e; k, _* }; [6 Q) V
4 E7 D4 n! A% G+ H+ Z
2. WMIACPI.SYS
* A/ P( v) u* }; N
- \0 c: P: U$ p& n* ~Wmiacpi.sys 是微软提供的一只generic mapping driver它的Plug and Play ID为 PNP0c14.,ACPI包含丰富的系统信息,OEM厂商可以利用这支mapping driver定制平台相关的功能而且允许使用WMI获取,如此便可以在单机或者在网络环境中获得平台的特定信息。关于如何在BIOS、OS中定制wmiacpi,bini已经给出了非常详细的讲解,有兴趣可以参考
bini的文章。在这里我会讲解一下原理部分。ACPI-to-WMI mapping function是通过下述两只driver达成的:7 Y: O' ^! d% S9 K2 G7 P- T
A.Acpi.sys6 N' e  n, ]' Q% b
B.Wmiacpi.sys; G" g. N& |& H& O* `8 Z* I) W4 y
A).Acpi.sys的一个主要功能是解释和执行aml,而aml就是asl code的机器码,所以ACPI asl code真正的执行是由acpi.sys触发的,而不是BIOS主动执行的。它的另一个功能就是查找ACPI spec定义的device Plug and Play ID,并据此创建相应的software device后续OS会为这些device加载对应driver。如power button driver,battery driver,lid driver,fan driver等等。Device 对应的Plug and Play ID可以查阅ACPI spec获得。
& t# r+ j% _% x% I) n0 iB).Wmiacpi.sys它的Plug and Play ID为PNP0c14,一旦BIOS 在asl code给出定义,acpi.sys就会创建这个pseudo device,OS就会load wmiacpi.sys作为该device的driver。当然仅仅加载这支driver还是不够的,为了能够使用WMI访问该software device包含的具体信息我们还需要一个供BIOS使用的asl文件以及与asl code对应的MOF文件而微软并没有提供Wmiacpi.sys相关的MOF文件。那么MOF文件到底有什么作用呢?要搞明白这一点我们来研究一下WMI的工作原理了,下图1展示了WMI Architecture:
  W& p1 O3 [% ~$ Q% l  ^
3 J+ G& }8 ^7 r+ y) i6 R! ^
2 B0 C1 N9 a4 ^. `/ u( {+ g wmiacpi1.JPG ( V* h0 d( j! H: r
当user使用API访问WMI信息时,WMI CORE会查看repository中已知的scheme定义,然后将希望获得的信息通过IRP的形式送给Providers这些Providers通常都是WMI Driver,它们处理IRP并将所需信息送给上层。那么也就是说必须要将MOF scheme加到WMI repository之中,consumer 才可能透过WMI COM API访问到。完整的过程是这样的OS在加载WMI驱动程序的时候会查看驱动程序的MOF scheme,如果驱动程序MOF scheme 部分正确无误,那么OS会将MOF scheme提取出来并自动加入到repository之中。所以OS仅仅加载wmiacpi.sys并不行,我们还需要给出与ACPI asl code对应的MOF scheme,并且通过在WMIACPI service key 下面建立一个key MofImagePath它的value指向MOF档的路径。如此在OS加载wmiacpi.sys时就会将对应的MOF scheme加入到repository之中,后续consumer访问时WMI CORE就会检索到scheme信息,然后下IRP给wmiacpi.sys。讲到这里原理应该差不多了但还要注意的是wmiacpi.sys并不会去执行asl code,最终执行动作还是会由acpi.sys发动。driver是层次结构的,acpi.sys是wmiacpi.sys的lower driver,wmiacpi.sys会将上层对asl的访问转化为low level IRP 送给acpi.sys,acpi.sys再返回具体信息然后逐级回送。  M! z) M4 E4 p/ l" N0 v

! I. \/ F% b( g# f3. Under the hood, k& B" @( e3 m" H8 u) a, y
$ c6 P% o$ t  I; ]
前面都是原理的介绍,讲的我都快吐血了J,实践是检验理论的唯一标准。说不如做,随我揭开内幕一探究竟。WDK ver6000 src带了一个wmiacpi的samplecode,build之后会生成一只acpimof.dll,在BIOS里面将device.asl
包进去然后再注册表中加入acpimof.dll的信息然后重启。讲到这里还要提到一个验证wmi的好工具叫做WMICodeCreator.exe微软的网站上有下载,下面我们就使用该tool验证前面的说法,下图2演示了我们定制wmiacpi之后的状况:
1 V1 X: L0 T5 q% M- T
4 O0 p6 M; R* ~2 s8 P. }& m- g6 S  n9 d* t
wmiacpi2.JPG
3 Y9 f8 D0 `. t7 K4 D& |
图 2

! U0 [* j, c( F+ B9 q. {图2红色方框标注的AcpiTest_**就是我们定制的WMI class。也就是OS Load wmiacpi.sys之后将其MOF档案解析出来并加入到WMI repository于是我们就看到了上图的信息。下面我们来跟踪一下访问具体的class的情况吧,祭出WinDbg,let’s go!首先查看一下wmiacpi.sys这支driver有没有被加载下图3表明该driver被正常加载了。
. W' R1 x) O/ G4 O  w8 O5 m" s2 `) J: V7 y0 r; w0 i  U& w6 v
wmiacpi3.JPG

) ^3 t5 K, [4 E0 g* G; e
图3
/ n- j, ?7 u; h1 q& I9 F: c* S, X6 n
由图3显示与wmi相关的有两个driver:wmilib.sys和wmiacpi.sys,wmilib.sys是干嘛的呢?别急后续讲述wmi driver的文章会详细介绍它。既然被加载了那我们就要dump wmiacpi.sys的symbol看看有哪些有用的信息,这样我们才比较容易下手J。下图4显示了wmiacpi.sys的所有symbol。1 J$ `6 i; m6 v5 X" p2 C

& O9 O2 U$ s: @/ k' t; ~, }
wmiacpi4.JPG
% B1 \- d5 X) E
图4

# |% o+ B* S) C! \' M6 T+ f" j前面我们还讲到wmiacpi.sys最终会调用到acpi.sys访问asl code那我们再看一看acpi.sys有哪些symbol,下图5显示了acpi.sys的所有symbol:# B, e5 |6 _" x2 q

( E9 F; v: C5 r2 u# G
wmiacpi5.JPG

) e$ `- T" t& t( k- l
图5
9 |4 }$ G9 m+ p5 x* I+ `
经过分析上述symbol我觉得下述函数很有作案嫌疑,所以将它们秘密监控J都给设上断点,被怀疑的对象如下图6所示:
' d6 o9 Q0 k$ n2 u  q; s9 L
( ?+ \2 L* s* o5 _# p
wmiacpi6.JPG

8 O) d' C4 R' H% C$ E
图6
) U; y8 `  b1 ?8 U. e+ n
如图所示:5 A1 h0 c# z2 a

5 w4 t9 N3 ?3 ]7 j2 Kwmiacpi!WmiAcpiSetWmiDataItem
0 e+ O$ ~4 t  c, }. s! N

( ^# H9 u# R# G5 d! \9 Z! Jwmiacpi!WmiAcpiSetWmiDataBlock
- p( e# [$ B3 V  O( I8 t

9 f; i/ _6 D& S9 ~wmiacpi!WmiFireEvent
8 E" g  e1 {3 m1 m- y

. L- |1 K' c) M/ _; i! u* f0 ?) \wmiacpi!WmiAcpiQueryWmiDataBlock
, J1 O; E+ ^: V. k' ?

( W, O  D+ z; z& y6 Ewmiacpi!WmiAcpiSendAsyncDownStreamIrp

( z' }6 `6 r/ e; a* |1 k* c* v- r- p! f
wmiacpi!WmiSystemControl

* s+ q& k( A! s2 j: f& D
3 Z! v; P, `/ E3 I9 O4 p! R& _wmiacpi!WmiAcpiSystemControlDispatch

9 i. y' I: ^8 T/ Y3 e8 W; d# y$ g/ P+ I2 u$ C0 ?& r0 Z* c
acpi!ACPIIoctlEvalControlMethod

3 Y- J7 _& z. Y: [
3 k/ f& h9 z# ~* W- R" }3 c* }$ |acpi!ACPIIoctlAsyncEvalControlMethod
% d# @; x" ~9 V
$ ?" o, U) j  ~# W- i
acpi!ACPIIoctlAsyncEvalControlMethodEx
- ?8 p# D5 F- S( I4 B$ M) q$ u
$ U. Q, r3 f3 w
acpi!ACPIIoctlEvalControlMethodEx
; p: k7 w" x, d
/ p- l9 d, j% I7 ?6 c
acpi!ACPIButtonDeviceControl

2 _$ a3 x/ K  D0 J+ f7 S& s# L' p* K. i) b
acpi!ACPIEcInternalControl

! T; m  @: w4 Q& ~+ P6 ]/ G% |: X- [) E% f) [' v
acpi!AcpiEmbeddedControllerIrpDispatch

& B  g* G7 p3 r/ u/ e. e4 ^" X& y4 h- h
acpi!ACPIIrpDispatchDeviceControl

, M" E8 U8 ~  L: z1 X
3 a) ]( m4 w1 ~$ Pacpi!WmiSystemControl

7 P, y. l# o* H, _9 _- |3 ^; t5 D
这些函数都被设置的断点,下面就我们读写一个class试试看了,图7证实了我之前的所说绝非空口无凭,我们读AcpiTest_MPackage class时发现先会call wmiacpi!WmiAcpiQueryWmiDataBlock,然后acpi!ACPIIrpDispatch DeviceControl会接手,当然后续还会有别的一些动作,但是上述行为就足以支撑我的论点了J。
+ h0 d- C' n& V: N3 ?% i- l$ @& O3 \% d' ]9 O- [' J* B4 T
0 R; v; j; F& S+ M1 P9 u
; _6 {/ X, f7 ^( ?3 G
wmiacpi7.JPG

2 ?. J; {5 H4 m- _7 Z
图7
" Z/ Q$ \' j7 m
图8演示了我们发一个event的状况,图中显示acpi.sys会接到该event然后透过wmiacpi!WmiFireEvent送给上层AP,上层AP再透过IRP下来qurey其它相关的具体信息。; V- |" _0 W/ N1 E
4 r8 h+ ?  \9 U% n3 E- G- ?! P" H

; t* G8 t; k7 M: P! I  H" m" e
wmiacpi8.JPG

9 u& J# R8 U: r, V5 H7 X
图8

* A; c% Y6 q3 b/ ^7 w以上就是我费尽九牛二虎之力挖掘的wmiacpi.sys的秘密了,再附上一幅我的debug环境J。  [; K: h% k" z, Q

+ w, B2 l( e$ T4 B( @# W
: `% T( V+ L) c8 N' \
wmiacpiA.JPG

4 w0 r: U/ d5 g( V! @/ M
图9
/ i7 O) ~9 ?3 ^7 e7 I9 `" }
That’s all!
  S9 s1 V# B) \Peter
7 L$ S, U/ W* H: ]& D- k+ n/ M3 d9 d. b
[ 本帖最后由 peterhu 于 2009-5-25 09:31 编辑 ]
发表于 2009-5-22 20:27:37 | 显示全部楼层
兄弟说的很详细。
2 [! k8 J5 |3 @5 J# e+ z4 F但最终的实现是不是采用MS的那个AP" l  L* F9 F5 d
动态生成VBS脚本,然后执行& T* V, O+ @' `- }' g3 a. F# O+ N
上面Debug中那些内核函数,兄弟你不会是自己做申明吧?
, Q: O) O" m6 m7 Z4 e2 h# \刚才骑车时仔细想了一下,觉得用那动态生成脚本是最方便的。
6 u' E5 a  ?2 O6 q/ m" S, [如果用COM来访问,我试了去调用,结果总是不能执行。
回复

使用道具 举报

 楼主| 发表于 2009-5-23 11:13:23 | 显示全部楼层
那些内核函数是微软的symbol,怎么可能是我声明的呢?
- g0 w' y) r" k! q% c* Z: R) F使用COM API访问绝对可以,请看这里http://blog.csdn.net/hgf1011/archive/2009/04/14/4073457.aspx
9 s" [3 s8 d: `/ E这是我写的一个tool,使用COM访问.
回复

使用道具 举报

发表于 2009-5-24 10:39:03 | 显示全部楼层
可以了,附件为C++写的一个执行WMI的程序,可以执行ASL代码了。0 _( O6 x; W4 C+ N2 r
以前不能执行是我把namespace给弄错了。( w# L4 R# F+ H  K& G- X6 d
谢谢各位。

Using WMI.rar

1.08 KB, 下载次数: 1437

回复

使用道具 举报

发表于 2009-7-30 16:05:21 | 显示全部楼层
刚开始学习acpi,收藏了,谢谢!
回复

使用道具 举报

发表于 2009-8-11 11:25:53 | 显示全部楼层
看了楼主的文章,有两点实在不是很清楚,望楼主指教:
3 Q4 G$ e' I1 V; W( ?1  该怎么把asl文件刷到BIOS中,是否需要BIOS的源代码,还需要其他的工具么?如果没有BIOS的源代码,我是否可以用ACPISCOPE刷到BIOS里面?但是这又引出一个问题,我不知道该把这段ASL放在DSDT表格的什么地方?4 A5 g. M# Q3 O( c( n. I
2  我在其他的地方找到一般都是把acpimof.dll注册在HKLM\System\CurrentControlSet\Services\WmiAcpi里面,
9 [, Y* W6 ]3 ]5 {1 w8 d  _2 }# j我在xp上试验的,我的机器里面没有WmiAcpi这一项,是否我需要自己新创建这一项,然后把它加入?/ _& ~2 T: X$ w; ?1 I+ M# X
不好意思,我刚接触这个,很多都不是很清楚,自己在网上找了好长时间都没有搞清楚,所以只有麻烦楼主了。" L$ ?( x* U$ @  l: C2 O3 b# W
先谢了!
回复

使用道具 举报

发表于 2009-8-11 14:10:43 | 显示全部楼层
关于第一个问题,我用iasl  device.asl编译没有通过,出现了一个错误:
9 Z# z! w8 M9 j# a9 Q+ s6 ^3 OError    4095 -                    ^ parse error, expecting `error' or `PARSEOP_DEFINITIONBLOCK'3 k6 t3 ~" @. z/ z$ e. E8 O' c
但是这个device.asl就是DDK自带的。
8 B" s- A6 ~9 {( m3 m7 q2 L9 e第二个问题我直接在cmd里面执行的时候也出现了一个错误:“已加载 acpimof.dll,但没有找到DllRegisterServer输入点,无法注册这个文件。”
: V) T: t+ s. a; O" [5 P  E我在网上下载了一个wmiacpi.sys,请问我可以自己修改注册表,然后将这个驱动加载到系统中么?* _  @4 i0 C! Z- V; a  k+ B4 u2 M
好迷糊。。。$ w& D1 P; H5 m: H

/ R" K  q( ~0 j' ~[ 本帖最后由 go_ahead 于 2009-8-11 16:48 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2009-8-11 22:03:52 | 显示全部楼层
to go_ahead:; ]1 L% Q: Z4 I+ x) l* U% @0 n
使用DDK build wmiacpi code.
" V4 }7 j" B. [* O# y- |' Oasl code要包在BIOS code中,所以需要BIOS的源代碼。
. l8 M, Q: \% G% M5 D沒有Wmiacpi選項就自己創建一個。
回复

使用道具 举报

发表于 2009-8-12 09:31:51 | 显示全部楼层
原帖由 peterhu 于 2009-8-11 22:03 发表
  T; _/ v1 v, g) b3 \( ]to go_ahead:
: I0 }% i6 O  t. ~" B% Y使用DDK build wmiacpi code.
% o$ _+ [' U" ~( K" v, ^! x* Tasl code要包在BIOS code中,所以需要BIOS的源代碼。6 y/ H5 d2 z( L2 S7 g+ `
沒有Wmiacpi選項就自己創建一個。

, p. C4 m  Q& W7 q2 w1 j/ o4 `8 F6 V1 e. d: @; y3 L
谢谢peterhu,今天看到了注册表出现了wmiacpi项了,而且查看acpiscope看到了添加进去的内容了。
; d- \5 z2 Y4 |" [但是还是不知道该怎么把dll加入注册表, 今天我再试试也许就出来了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入计匠网

本版积分规则

Archiver|手机版|小黑屋|计匠网

GMT+8, 2026-11-1 21:32 , Processed in 0.555986 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表