准备工作:搭建ACPI调试环境请移步至:《搭建Win7调试ACPI的环境》里面有Checked Build ACPI.sys

本文中OS为Win7 x86(镜像:en_windows_7_ultimate_x86_dvd_X15-65921.iso)

kd> vertarget
;记得OS一定要和ACPI.sys匹配,否则替换ACPI后OS可能无法启动。
;我的OS版本信息如下
Windows 7 Kernel Version 7600 MP (1 procs) Free x86 compatible
Built by: 7600.16385.x86fre.win7_rtm.090713-1255

这次调试对象为vmware中串口设备COM1,如下图,目标是在设备管理中执行Disable Com1时,跟踪COM1所执行的AML代码(即,Method(_DIS))。

这是要跟踪的COM1 ACPI Method:

kd> !amli dns /s \_sb.pci0.isa.sio.COMA._DIS
;!amli dns /s查找ACPI命名空间中的命名对象
ACPI Name Space: \_SB.PCI0.ISA.SIO.COMA._DIS (ffffffff85172318)
Method(_DIS:Flags=0x0,CodeBuff=85172375,Len=7)

我停用COM1前,设置设备管理器的列出设备的方式为"Devices by connection",这为了方便确认COM设备在设备树中的总线路径。根据上图显示,初步断定设备COM1在ACPI命名空间中的路径是:\_SB.PCI0.ISA.SIO.COMA。确认一下我的猜测是否正确:

kd> !amli find COMA
\_SB.PCI0.ISA.SIO.COMA

!amli find将输出匹配的ACPI命名对象在ACPI命名空间中的完整路径。在不同域下会有同名ACPI对象,因此find的输出可能不唯一。比如,很多设备(毕竟Device(){}会在ACPI命名空间中创建一个新的域)都有Method(_DIS)这个函数,因此,执行!amli find _DIS可能会得到这样的输出:

如果不确定上述输出中哪个是调试目标,可以在windbg开启ACPI日志输出,然后执行对应的ACPI Method(如停用/启用设备)。在启停过程中,windbg将输出ACPI Object及相应Method执行的信息:

kd> !amli set spewon verboseon traceon
;开启ACPI Log输出
kd> g ;执行该命令后,在设备管理中停用COM1,得到如下输出
AMLI: 85409D48: EvalNameSpaceObject(\_SB.PCI0.ISA.SIO.COMA._STA)AMLI: 85409D48: \_SB.PCI0.ISA.SIO.COMA._STA()ffffffff851723e5: {
ffffffff851723e5: | If(And(SIOC=0xf,0x2,)=0x2)
ffffffff851723ef: | {
ffffffff851723ef: | | If(FCMA=0x0)
ffffffff851723f8: | | If(S1BL=0xfe)
ffffffff851723fe: | | {
ffffffff851723fe: | | | Return(0xd)
ffffffff85172401: | | }
ffffffff85172401: | }

我们在设备管理器中看到的COM设备名是COM1,为什么在ACPI输出中看到的设备名是\_SB.PCI0.ISA.SIO.COMA (RW Utility中在\_SB.PCI0.ISA下也找不到COM1这样的设备)?来看下Device(COMA)的ASL Code:

kd> !amli dns /s \_SB.PCI0.ISA.SIO.COMAACPI Name Space: \_SB.PCI0.ISA.SIO.COMA (ffffffff85172020)
Device(COMA)
| Integer(_HID:Value=0x000000000105d041[17158209])
| Integer(_UID:Value=0x0000000000000001[1])
| String(_DDN:Str="COM1")
| Method(_CRS:Flags=0x8,CodeBuff=851721c1,Len=18)
| Method(_SRS:Flags=0x9,CodeBuff=8517223d,Len=89)
| Method(_PRS:Flags=0x0,CodeBuff=85172301,Len=10)
| Method(_DIS:Flags=0x0,CodeBuff=85172375,Len=7)
| Method(_STA:Flags=0x0,CodeBuff=851723e5,Len=46)

ACPI Method是ACPI对象,ACPI Device也是ACPI对象,因此都可以用!amli dns /s命令查看对象信息。当然也可以RW Utility查看Device(COMA)的实现:

查看ACPI Spec,_DDN对象用于设置设备DOS Device Name(是不是可以认为是设备的别名?),可能这是我们在设备管理器中看到COM1的原因。

找到了COMA的Method对象,试试单步跟踪ACPI Method。根据前面的Log输出可知在停用过程中会调用Method(_STA)&Method(_DIS)方法,就在他们身上下断点吧:

kd> !amli bp  \_SB.PCI0.ISA.SIO.COMA._STA
kd> !amli bp  \_SB.PCI0.ISA.SIO.COMA._DIS

停用设备后,windbg会中断到ACPI解释器,(此时Windbg的Command框前缀为"Input>",在Command框中直接输入!amli的command即可,如bp \_SB.PCI0.ISA.SIO.COMA_STA,不用带!amli),如图:

之前下了2个ASL Code断点,所以windbg中断时,我们并不清楚中断发生在哪个函数,可以用!amli lc命令查看后台正在执行的ACPI Method:

Input> AMLI(? for help)-> lc
lc
*Ctxt=ffffffff85f56000, ThID=ffffffff85157998, Flgs=A--CR----, pbOp=ffffffff851723e5, Obj=\_SB.PCI0.ISA.SIO.COMA._STA
;每一行输出代表正在执行的ACPI method;如果行首带"*"表示该函数在执行过程中触发了中断

执行完!amli lc后,可以顺带执行!amli r命令,查看该函数执行的上下文(参数/局部变量等信息):

Input> AMLI(? for help)-> r
r
Context=85f56000*, Queue=0, ResList=0
ThreadID=85f5600085157998, Flags=00000130, pbOp=ffffffff851723e5:[\_SB.PCI0.ISA.SIO.COMA._STA]
StackTop=ffffffff85f57ee8, UsedStackSize=280 bytes, FreeStackSize=7664 bytes
LocalHeap=85f560c4, CurrentHeap=ffffffff85f560c4, UsedHeapSize=52 bytes
Object=\_SB.PCI0.ISA.SIO.COMA._STA, Scope=\_SB.PCI0.ISA.SIO.COMA._STA, ObjectOwner=ffffffff85f560e8, SyncLevel=0
AsyncCallBack=ffffffff87c4ac82, CallBackData=ffffffff8555fee0, CallBackContext=ffffffff8555feb0;ASL Method的局部变量
MethodObject=\_SB.PCI0.ISA.SIO.COMA._STA
ffffffff85f57f38: Local0=Unknown()
ffffffff85f57f50: Local1=Unknown()
ffffffff85f57f68: Local2=Unknown()
ffffffff85f57f80: Local3=Unknown()
ffffffff85f57f98: Local4=Unknown()
ffffffff85f57fb0: Local5=Unknown()
ffffffff85f57fc8: Local6=Unknown()
ffffffff85f57fe0: Local7=Unknown()
85f56040: RetObj=Unknown()Next AML Pointer: ffffffff851723e5:[\_SB.PCI0.ISA.SIO.COMA._STA];ASL Method的实现
ffffffff851723e5 : If(And(SIOC, 0x2, ))
ffffffff851723ef : {
ffffffff851723ef : | If(FCMA)
ffffffff851723f5 : | {
ffffffff851723f5 : | | Return(0xf)
ffffffff851723f8 : | }
ffffffff851723f8 : | If(S1BL)

最后,中断到ASL Method中了,就可以用!amli t或者!amli p单步跟踪Method执行:

Hit Breakpoint 1.AMLI(? for help)-> t ;单步执行\_SB.PCI0.ISA.SIO.COMA._STA函数的ASL Code
t  ;单步1
If(And(SIOC=0xf,0x2,)=0x2
AMLI(? for help)-> t
t  ;单步2
)
ffffffff851723ef: | {
ffffffff851723ef: | | If(FCMA=0x0)
;!amli u反汇编即将执行的ASL Code
AMLI(? for help)-> u
u
ffffffff851723f8:[\_SB.PCI0.ISA.SIO.COMA._STA+0x13]
ffffffff851723f8 : If(S1BL)
ffffffff851723fe : {
ffffffff851723fe : | Return(0xd)
ffffffff85172401 : }
ffffffff85172401 : Store(Ones, S1BL)
ffffffff85172407 : If(S1BL)
ffffffff8517240d : {
ffffffff8517240d : | Return(0xd)
ffffffff85172410 : }
ffffffff85172410 : Return(AMLI_DBGERR: UnAsmDataObj: input buffer is too small
AMLI_DBGERR: Failed to unassemble scope at da317e2 (size=27)

最后的最后,一些ACPI事件发生时,可以从ACPI解释器退出到内核调试器(!amli q),查看触发该ACPI事件的DeviceObject及相应的IRP。以ACPI _PTS对象为例,根据ACPI Spec,当系统关机(进入S5)时会执行该对象。

kd> !amli bp \_PTS
kd> g ;执行后马上关机,windbg中断到ACPI解释器
AMLI(? for help)-> q

在AMLI解释器中,输入q后,ACPI解释器(Input>)退出到内核调试器(kd>)。执行kb,查看进入ACPI解释器的函数栈:

kd> kb# ChildEBP RetAddr  Args to Child
00 8078fac8 87cad6f4 00000000 00000000 00000000 ACPI!DebugQuit+0x24
01 8078faf8 87cad875 87cc5128 8078fc1c 873c29e0 ACPI!DbgExecuteCmd+0xaf
02 8078fe34 87c9c1fa 87cc5128 87cb8854 8078fe64 ACPI!Debugger+0x104
03 8078fe44 87c9a145 00000000 873c29e0 873c29d8 ACPI!AMLIDebugger+0x33
....
13 8a00fae0 82a5cd16 86390030 85181bf0 00000016 ACPI!ACPIDispatchIrp+0x1dc
14 8a00faf8 82a8d4ae 8746fb2c 86390030 8a00fb10 nt!IopPoHandleIrp+0x28
15 8a00fb08 82a5f049 8a00fb30 87c53b57 86390030 nt!IofCallDriver+0x55
16 8a00fb10 87c53b57 86390030 8746fa58 87c5c398 nt!IoCallDriver+0x10

windbg输出的frame# 15显示在关闭OS时,曾执行了IoCallDriver,并最终进入到ACPI解释器。IoCallDriver的参数有DeviceObject和IRP,通过这两个参数可以定位执行Method(_PTS)的设备:

kd> !object 86390030
Object: 86390030  Type: (8521ebc8) DeviceObjectHeader: 86390018 (new version)HandleCount: 0  PointerCount: 7Directory Object: 88e0f638  Name: 0000004a
kd> !devstack 86390030 !DevObj   !DrvObj            !DevExt   ObjectName86667e10  \Driver\intelppm   866665d0
> 86390030  \Driver\ACPI       85181bf0  0000004a
!DevNode 860dba18 :DeviceInst is "ACPI\GenuineIntel_-_x86_Family_6_Model_94_-_Intel(R)_Core(TM)_i5-6300HQ_CPU_@_2.30GHz\_0"ServiceName is "intelppm"

windbg调试ACPI ASL Code 实例一则相关推荐

  1. 通过Windbg来追踪ASL code的运行

    通过Windbg来追踪ASL code的运行: 目标机的配置: 第一步: 在BIOS Setup下面 disable secure boot(不然下面debug on 命令会失败):关闭防火墙. 第二 ...

  2. 如何使用windebug追踪ASL CODE

    最经遇到很多BSOD的问题,不免要学一下windebug的方法. 主要步骤如下: 在现代计算机中,硬件和固件(BIOS)都必须符合ACPI规范,以便操作系统可以控制所有模块的自动配置和电源管理. 使用 ...

  3. windbg调试实例(4)--句柄泄露

    同事介绍了一篇调试句柄泄露的blog文章,今天有空看了一下,这家伙用视频的方式录下整个调试的过程,学习一目了然,真是有心.鉴于学习的过程总结一下能加深记忆,所以我这里做个记录,感兴趣的朋友可以看这里: ...

  4. windbg调试驱动学习总结

    简单驱动编写与windbg调试 http://trustsec.blog.51cto.com/305338/64694/ 一.驱动编写 随着对windows系统的深入研究,越来越多的内核方面的知识被挖 ...

  5. WinDbg调试.NET程序入门

    俗话说:万事开头难! 自从来到新公司遇到性能问题后,需要想办法解决这个问题,但是一直没有合适的性能分析工具,然后找到StevenChennet 大神帮忙,他用WinDbg工具远程帮我分析了一个 dum ...

  6. Windbg调试命令详解

    Windbg调试命令详解 发表于2013 年 8 月 23 日 转载注明>> [作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Win ...

  7. WinDBG调试dNet程序总结

    WinDBG工具简介 http://www.cnblogs.com/mashuping/archive/2009/03/28/1424168.html 对于一般的程序不需要使用WinDBG工具去调试, ...

  8. windbg调试堆破坏

    堆破坏 所谓的堆破坏,是说没控制好自己的指针,把不属于你分配的那块内存给写覆盖了.这块内存可能是你程序的数据,也可能是堆的管理结构.那么这个会导致怎样的后果呢?可能的情况我们来yy下 把程序里的计算结 ...

  9. windbg调试HEAP

    HEAP的概念 堆栈堆栈,在操作系统内存中有两种存储空间,一个是堆,一个是栈.堆主要用于存储用户动态分配的变量,而栈呢,则是存储我们程序过程中的临时变量.当然栈的作用远不止用作存储变量,但这不是我们这 ...

最新文章

  1. 获取SQLServer数据库中所有表
  2. mysql safe 关闭_新手请教,mysqld经常自动关闭是什么原因?-问答-阿里云开发者社区-阿里云...
  3. nginx 常见参数以及重定向参数配置
  4. JavaScript中split() 使用方法
  5. html用dom显示xml,dom 编程(html和xml)
  6. 日志库 winston 的学习笔记 - 创建一个使用 winston 的 Node.js 应用
  7. python args_Python可变参数*args和**kwargs用法实例小结
  8. .NET Core请求控制器Action方法正确匹配,但为何404?
  9. Linux Linux 集群
  10. PAI通过流式机器学习算法解决实时热点新闻挖掘案例
  11. 一文带你读懂!华为云在ACMUG技术沙龙上都透露了些啥?
  12. 大一计算机应用基础答案李小艳,13级幼师班期末考试计算机试题A卷
  13. java怎样实现重载一个方法
  14. 第三节:python 交互和调用参数
  15. bigdecimal取小数部分_无限小数的本质
  16. VS2019正式版注册码秘钥
  17. 一文看懂什么是车规级芯片
  18. 案例1:文件系统ACLs
  19. python+opencv+图像特效(图像灰度处理、颜色翻转、图片融合,边缘检测,浮雕效果,颜色映射)
  20. PARWAN处理器架构特点

热门文章

  1. 当程序员遇上电信诈骗犯 黑掉对方电脑!成功反制
  2. datax数据同步问题(mysql2hive)汇总
  3. Linux中DNS服务器地址查询命令nslookup使用教程
  4. 白葡萄酒/红葡萄酒质量分析与预测(PCA+MLPClassifier)100%
  5. VBA处理工作表合并单元格 - 格式篇
  6. 巧用PaperPass自建库免费检测提高降重效率
  7. 数据结构与算法(python) 线性结构:无序列表 Unordered List以及链表
  8. 掘安杯 web snake 适合新手
  9. java 1st 2nd 3rd 4th_1st怎么输入excel “st”在1的右上角 EXCEL excel 1st 2nd 3rd 4th 怎么设置上标 如何改为上标...
  10. Python中XGBoost的特性重要性和特性选择