第一章  Windows 2000对调试技术的支持

翻译:Kendiv

更新: Friday, January 14, 2005

内核调试器的命令

尽管调试器的命令已经注意了易记性,但有时总是难以回忆起它们。因此,我把它们都整理到了附录A中。表A-1是其快速参考。这个表是调试器的help信息(使用?命令)的整理版。命令所需参数的类型汇总在表A-2。

前面提到过,内核调试器执行扩展命令时需要一个!号作为开始。只要命令前有个!号,调试器就会到已加载的扩展DLL的导出列表中进行查找。如果发现匹配的,就会跳转到相应的DLL中。1-7显示了内核调试器加载了kdextx86.dll、userkdx.dll和dbghelp.dll扩展DLL。最后一个和i386kd.exe位于同一目录;前两个共有四个版本:针对Windows NT 4.0的free和checked版本(对应子目录为:nt4fr和nt4chk),针对Windows 2000的free和checked版本。通常,调试器在搜寻扩展命令是会采用一个默认的搜索顺序。然而,你可以改变这个默认设置,只需要在命令前指定模块名称即可,采用.符号作为分隔符。例如,kedxtx86.dll和userkdx.dll都导出了help命令,键入!help,在默认情况下,你会得到kdextx86.dll的帮助信息。要执行userdkx.dll的help命令,你必须输入!userkdx.help(或者!userkdx.help –V如果你想得到更详细的帮助信息的话)。按照此方法,只要你知道规则,你也可以编写自己的扩展命令。在The NT Insider(Open Systems Resources 1999a)中你能找到很棒的how-to文章。不过其针对的是WinDbg.exe而不是i386kd.exe,但两者使用相同的扩展DLL,大多数信息对于i386kd.exe也是有效的。

附录A中的表A-3和A-4分别列出了kdextx86.dll和userkdx.dll的help命令的输出信息。为了便于阅读作了些修改和整编。你会发现这些表中列出的命令多于Microsoft  DDK文档中的,其中有些命令明显有DDK文档未提到的附加参数。

10大调试命令

表A-1到A-4列出了内核调试器及其标准扩展DLL提供的巨多的命令。因此,我将讨论其中一些常用命令的细节。

u:  反编译机器码

在检查crash dump是否正确时,你已经用过了此命令,u命令有三种格式:

1.u <from> 从地址<from>开始反编译8个机器码。

2.u <from>  <to> 反编译<from>到<to>之间的所有机器码。

3.u  不提供任何参数时,从上次u命令停止的位置开始反编译。

当然,反编译打段代码是十分厌烦的,但如果你只想知道在特定地址发生的事情,那这是最便捷的方法。或许u命令最令人感兴趣的特性是它可以解析代码引用到的符号----即使是目标模块没有导出的符号。不过,使用本书光盘中的Multi-Format Visual Disassembler反编译完整的Windows 2000可执行体将是十分有趣的。在随后章节中,会有关该产品的更多信息。

db,dw和ddDump Memory BYTEs、WORDs和DWORDs

如果你当前感兴趣的内存数据是二进制的,那么调试器的16进制转储命令将能完成此任务。根据你对源地址(source address)数据类型的判断,来选择dd(针对BYTES)、dw(针对WORDS)、dd(针对DWORDS)。

l         db 将指定内存范围里的数据显示为两个部分:左边是16进制表示(每2个8 bit一组),右边是对应的ASCI码。

l         dw 仅按照16进制显示(16 bit一组)

l         dw 仅按照16进制显示(32 bit一组)

此组命令可以使用与u命令相同的参数。注意,<to>所指示的地址内容,也会被显示出来。如果没有任何参数,将显示接下来的128个字节。

x检查符号

x命令非常重要。它可以根据已安装的符号文件创建一个列表。典型的使用方式如下:

1.x *!* 显示所有可用符号的模块。在启动后,默认只有ntoskrnl.exe的符号是可用的。其他模块的符号可以使用.reload命令来加载。

2.x <module>!<filter>  显示模块<module>的符号文件中的符号名称,<filter>可以包括通配符?和*。<module>必须属于x *!*列出的模块名。例如,x nt!*将列出在内核符号文件ntoskrnl.dbg中找到的所有符号,x win32k!*将列出win32k.dbg提供的符号。如果调试器报告说“Couldn’t resolve ‘X….’”,尝试用.reload再次加载所有的符号文件。

3.x <filter> 显示所有可用符号的一个子集,该子集不匹配<filter>表达式。本质上,这是x <module>!<filter>的一个变形,在这里<module>!被省略了。

随符号名一起显示的,还有与其相关的虚拟地址。对于函数名,与其对应的就是函数的入口地址。对于变量,就是改变量的基地址。该命令值得的注意的地方是,它可以输出很多内部符号(internal symbols),这些在可执行文件的导出表中都是找不到的。

ln列出最近的符号

ln是我最喜欢的一个命令。因为它可以快速且简单的访问已安装的符号文件。算是x命令的理想补充。不过后者适用于列出所有系统符号的地址。Ln命令则用于按照地址或名称查找符号。

l         ln <address> 显示<address>指示的地址以及和其前后相邻的地址的符号信息。

l         ln <symbol> 将符号名解析为与其对应的虚拟地址。其过程与ln <address>类似。

像x命令一样,调试器知道所有导出的以及一些内部的符号。因此,对于想弄清楚出现在反编译列表或16进制转储中的不明指针的确切含义的人有着非常大的帮助。注意,u、db、dw、dd也会使用符号文件。

!processfield列出EPROCESS的成员

该命令前的!号,意味着它来自于调试器的扩展模块—kdextx86.dll。该命令可显示内核用来代表一个进程的EPROCESS结构(该结构并没有正式的说明文档)的成员及其偏移量。

尽管该命令仅列出了成员的偏移量,但你也能很容易的猜出其正确的类型。例如,LockEvent位于0x70处,其下一个成员的偏移量为0x80。则该成员占用了16个字节,这与KEVENT结构非常类似。如果你不知道什么是KEVENT,不要担心,我在第7章将会讨论之。

!threadfields列出ETHREAD成员

这是kdextx86.dll提供的另一个强大的选项。和!processfields类似,它列出未文档化的ETHREAD结构的成员及其偏移量。内核使用它表示一个线程。参见示例1-2

!drivers列出已加载的Drivers

kdextx86.dll真是太棒了。!drivers列出了当前运行的内核和文件系统模块的详细信息。如果检查crash dump,该命令会列出系统崩溃那一刻的系统状态。示例1-3是我机器上输出的摘要。注意,在输出的最后一行,导致Windows 2000崩溃的Driver的地址为0xBECC2000,这显然是w2k_kill.sys引发蓝屏后显示的地址。

译注:

在新的i386kd.exe(ver: 6.3.0017.0)中,!driver命令已不被支持。取而代之的是lm命令。该命令的一般用法是:lm t n

!sel检查Selector的值

如果没有争议的话,!sel实现于kdextx86.dll。它用来显示16个连续的memory selector(按地址升序排列)。你可以反复的使用此命令直到出现“Selector is invalid”。在第4章将讨论Memory Selector,到时我会提供一个示列代码来演示如何在你的程序中crack selectors。

译注:

在新的调试器中,该命令已不被支持,取而代之的是:dg命令。其一般性用法为:dg.注意末尾的.符号。dg命令最多可列出256个Selector。调试器的Online Help中有详细说明

关闭调试器

你可以通过简单的关闭控制台窗口来关闭内核调试器。当然,更好的关闭办法是使用q命令,这儿“q”代表着quit。

更多的调试工具

在本书的光盘中,你可以找到两个由我的e-friends贡献的非常有价值的调试工具。我很高兴他们允许我将完整版本放入我的光盘中。 Wayne J. Radburn 的 PE and COFF文件浏览器(PEView)是本书读者的一个特殊免费工具。Jean-Louis Seigne的Multi-Format Visual Disassembler(MFVDasm)一个限时版本。本节将简单介绍这两个工具。

MFVDASM:可视化多格式反编译器

MFVDasm不仅仅是个汇编列表生成器。事实上,它比汇编代码浏览器增加了多个很不错的导航特性。如图1-8所示,那是我使用MFVDasm察看Windows 2000 I/O管理函数IoDetachDevice()的截图。图中并没有显示出屏幕上的颜色。例如,所有的函数表以及特定地址的jumps和calls都被显示为红色。针对其余地址(没有相关导出符号的地址)的jumps和calls显示为蓝色。引用了从其他模块动态导出的符号的显示为紫色。所有可到达的目标地址(reachable destinations)都加上了下划线,这意味着你可以通过单击他们来滚动代码窗口到达其地址。使用工具栏上的Back和Forward按钮,你能回顾看过的东东。这很像在IE中察看浏览过的网页。

在右边,你可以随意选择你想跳到的符号或目标地址。当然,通过单击列头你可以进行排序。在最底层,MFVDasm提供了Tab页来分别显示符号、16进制转储(HexDump)和重定位(Relocations)。对包含嵌入字符串的代码段进行反编译时16进制转储视图会显得很有用。在分析很大的文件如ntoskrnl.exe时,MFVDasm不会阻塞住,和其他流行的反编译工具一样,得到的汇编代码可以保存到文本文件中。

PEView --- PE和COFF文件察看器

尽管MFVDasm展示了PE(Portable Executable)文件的很多内部结构的细节,但其侧重于代码的查看。另一方面,PEView虽然不能展示比代码段的16进制码更进一步的细节,但它能非常详细的显示文件结构的细节。如图1-9所示。这是我用PEView察看ntoskrnl.exe的截图。可以看出PEView采用三种形式来显示ntoskrnl.exe的多个部分。如果你单击左边的一个叶结点,在右面就会显示与该项相关的所有信息。在图1-9种,我选择了IMAGE_OPTIONAL_HEADER结构,该结构是IMAGE_NT_HEADERS结构的成员之一。

译注:还有两段我没有译,和本书讨论的主题无关,感兴趣的话,去看原文吧。J

Windows 2000调试接口

对于喜欢研究系统内核的人来说,内核调试器是一个非常强大的工具。不过,它的界面有些简单。有时你可能希望有更强大的命令。很幸运,Windows 2000提供了两个完整的调试接口文档,使得你可以在你的程序中加入调试功能。这些接口远算不上豪华(但他们得到了微软官方文档的祝福 J)。在本节中,我将带你进行调试接口一日游,向你展示这些文档可以为你做什么以及你如何从这些文档中得到更多东东。

psapi.dll、imagehlp.dll和dbghelp.dll

长久以来,Windows NT由于缺乏对Windows 95的ToolHelp32接口的支持而备受指责。可能评论家们并不都知道Windows NT 4.0提供了其独有的调试接口---内建于系统组件psapi.dll(随Win32 SDK一起发布)中。随此DLL一起发布的还有imagehlp.dll和dbghelp.dll以及针对NT/2000的调试接口的官方文档。PSAPI是Process Status Application Programming Interface的首字母缩写,此接口提供了14个函数用于获取有关设备驱动程序、进程、进程的内存使用情况和其加载的模块、工作集、内存映射文件的系统信息。psapi.dll同时支持ANSI和Unicode字符串。

其余两个调试DLLs---imagehlp.dll和dgbhelp.dll涵盖了不同的工作范围。二者都导出了相似的函数集合,区别较大的是imagehlp.dll,它提供了更多函数,但dbghelp.dll提供了可重新发布的组件。这意味着微软允许你将dbghelp.dll放入你自己的调试程序的安装包中。如果选择使用imagehlp.dll,你必须获取在目标系统已安装的一个。这两个DLL都提供了丰富的函数来分析和维护PE文件。二者最显著的特性是能很好的使用符号文件(就是你为内核调试器准备的那些)。为了指导你该选择哪个DLL,我将这两个DLL的所有导出函数汇总到了表1-1,N/A表示不支持。

序号

函数名称

ImageHlp.DLL

DbgHelp.DLL

1

Bindlmage

N/A

2

BindlmageEx

N/A

3

CheckSumMappedFile

N/A

4

EnumerateLoadedModules

5

EnumerateLoadedModules64

6

ExtensionApiVersion

N/A

7

FindDebuglnfoFile

8

FindDebuglnfoFileEx

9

FindExecutablelmage

10

FindExecutablelmageEx

11

FindFilelnSearchPath

12

GetlmageConfiglnformation

N/A

13

GetlmageUnusedHeaderBytes

N/A

14

GetTimestampForLoadedLibrary

15

ImageAddCertificate

N/A

16

ImageDirectoryEntryToData

17

ImageDirectoryEntryToDataEx

18

ImageEnumerateCertificates

N/A

19

ImageGetCertificateData

N/A

20

ImageGetCertificateHeader

N/A

21

ImageGetDigestStream

N/A

22

ImagehlpApiVersion

23

ImagehlpApiVersionEx

24

ImageLoad

N/A

25

ImageNtHeader

26

ImageRemoveCertificate

N/A

27

ImageRvaToSection

28

ImageRvaToVa

29

ImageUnload

N/A

30

MakeSureDirectoryPathExists

31

MapAndLoad

N/A

32

MapDebuglnformation

33

MapFileAndCheckSumA

N/A

34

MapFileAndCheckSumW

N/A

35

ReBaselmage

N/A

36

ReBaseImage64

N/A

37

RemovePrivateCvSymbolic

N/A

38

RemovePrivateCvSymbolicEx

N/A

39

RemoveRelocations

N/A

40

SearchTreeForFile

41

SetlmageConfiglnformation

N/A

42

SplitSymbols

N/A

43

StackWalk

44

StackWalk64

45

Sym

N/A

46

SymCleanup

47

SymEnumerateModules

48

SymEnumerateModules64

49

SymEnumerateSymbols

50

SymEnumerateSymbols64

51

SymEnumerateSymbolsW

52

SymFunctionTableAccess

53

SymFunctionTa ble Access64

54

SymGetLineFromAddr

55

SymGetLineFromAddr64

56

SymGetLineFromName

57

SymGetLineFromName64

58

SymGetLineNext

59

SymGetLineNext64

60

SymGetLinePrev

61

SymGetLinePrev64

62

SymGetModuleBase

63

SymGetModuleBase64

64

SymGetModulelnfo

65

SymGetModuleInfo64

66

SymGetModulelnfo Ex

67

SymGetModulelnfo Ex64

68

SymGetModulelnfoW

69

SymGetModulelnfo W64

70

SymGetOptions

71

SymGetSearchPath

72

SymGetSymbolInfo

73

SymGetSymbolInfo64

74

SymGetSymFromAddr

75

SymGetSymFromAddr64

76

SymGetSymFromName

77

SymGetSymFromName64

78

SymGetSymNext

79

SymGetSymNext64

80

SymGetSymPrev

81

SymGetSymPrev64

82

Symlnitialize

83

SymLoadModule

84

SymLoadModule64

85

SymMatchFileName

86

SymEnumerateSymbolsW64

87

SymRegisterCallback

88

SymRegisterCallback64

89

SymRegisterFunctionEntryCallback

90

SymRegisterFunctionEntryCallback64

91

SymSetOptions

92

SymSetSearchPath

93

SymUnDName

94

SymUnDName64

95

SymUnloadModule

96

SymUnloadModule64

97

TouchFileTimes

N/A

98

UnDecorateSymbolName

99

UnMapAndLoad

N/A

100

UnmapDebuglnformation

101

UpdateDebuglnfoFile

N/A

102

UpdateDebuglnfoFileEx

N/A

103

WinDbgExtensionDllInit

N/A

在本节的示例代码中,我会演示如何使用psapi.dll和imagehlp.dll完成如下任务:

l         枚举所有内核组件和驱动程序

l         枚举系统当前管理的所有进程

l         枚举加载到进程地址空间的所有模块(modules)

l         枚举一个给定组件的所有符号(如果其符号文件可用的话)

psapi.dll的接口并不像其设计的那样好。它提供了最小的功能集,尽管它曾试图增加一些便利性。虽然,它能从内核获取一些信息但却扔掉了其中的大多数,只留下很少一部分。

由于psapi.dll和imagehlp.dll的函数并不是标准Win32 API的一部分,它们所需的头文件和导入库不会自动包括在Visual C/C++工程中。因此,列表1-2中列出的四个指示符(directives)应该在你的原文件中出现。第一部分是所需的头文件,剩余部分用于和这两个DLL中的导出函数建立动态链接。

#include <imagehlp.h>

#include <psapi.h>

#pragma comment (linker,”/defaultlib:imagehlp.dll”)

#pragma comment (linker,”/defaultlib:psapi.dll”)

列表1-2   增加psapi.dll和imagehlp.dll到Visual C/C++工程

译注:

其实,也可以采用静态链接,如下:

#pragma comment(lib,”psapi.lib”)

#pragma comment(lib,”imagehlp.lib”)

这样,就不需要目标平台必须有这两个DLL了。

光盘中的示列代码

在本书的附带光盘中,有两个工程是构建与psapi.dll和imagehlp.dll之上。其中一个示例工程是w2k_sym.exe----一个Windows 2000符号浏览器,它可以从任意符号文件中提取符号名称(假如你已经安装了的话)。它输出的符号表可以按照名称、地址和大小来排序,同时接受一个采用通配符的过滤器。作为附送功能,w2k_sym.exe还可列出当前活动的系统模块/驱动程序的名称,运行的进程和每个进程加载的模块。另一个示例工程是调试支持库w2k_dbg.dll,这个库包含几个便于使用的针对psapi.dll和imagehlp.dll的外包函数。w2k_sym.exe完全依赖这个DLL。这些工程的源代码分别位于光盘的/src/w2k_dbg和/src/w2k_sym目录。

表1-2列出了w2k_dbg.dll用到的函数名称。A./W列表示对ANSI和Unicode的支持情况。稍早提示过,psapi.dll同时支持ANSI和Unicode。不幸的是,imagehlp.dll和dbghelp.dll没有这么聪明,其中几个函数只能接受ANSI字符串。这有些烦人,因为Windows 2000的调试程序通常不能运行在Windows 9x上,所以不该限制使用Unicode。若将imagehlp.dll假如你的工程中,你就必须选择是使用ANSI还是来回转化Unicode字符串。因为我很讨厌在一个可处理16位字符串的系统中使用8位的字符串,所以我选择后一种方法。w2k_dbg.dll导出的所有函数中涉及的字符串默认都是Unicode。所以,如果你在自己的Windows 2000工程中使用这个DLL不需要再关心字符大小问题。

另一方面,imagehlp.dll和dbghelp.dll有一个psapi.dll没有的特性:他们同样适用于Win64----让每个开发人员恐惧的64位Windows,这是因为没人知道将Win32程序移植到Win64有多困难。这些DLL导出了Win64 API函数,好吧----或许有一天我们会用到他们。

名称

A/W

EnumDeviceDrivers

psapi.dll

EnumProcesses

psapi.dll

EnumProcessModules

psapi.dll

GetDeviceDriverFileName

A/W

psapi.dll

GetModuleFileNameEx

A/W

psapi.dll

GetModulelnformation

psapi.dll

ImageLoad

A

imagehlp.dll

ImageUnload

imagehlp.dll

SymCleanup

imagehlp.dll

SymEnumerateSymbols

A/W

imagehlp.dll

Symlnitialize

A

imagehlp.dll

SymLoadModule

A

imagehlp.dll

SymUnloadModule

imagehlp.dll

表1-2  w2k_dbg.dll使用的调试函数

我没有深入的探究psapi.dll和imagehlp.dll。本书的焦点在于未文档化的接口,而且在SDK中与这两个DLL的接口有关的文档还算不错。可是,我并不打算完全绕过它们,因为它们和Windows 2000 Native API(将在第2章讨论)紧密联系在一起。而且,psapi.dll是证明为什么未文档化的接口比文档化的那个更好的最佳实例。该DLL的接口不仅仅只是看上去的简单和笨拙---在某些地方它竟然会返回明显矛盾的数据。如果我不得不编写一个专业的调试工具来出售,我是不会指望这个DLL的。Windows 2000内核提供了强大、通用和更加合适的调试API函数。然而,这些几乎都没有文档化。幸运的是,微软提供的许多系统工具都广泛的使用了这些API,so it has undergone only slight changes across Windows NT versions。是的,如果你使用了这些API,每当发布了新版的NT,你就必须修订和小心的测试你的软件,但是它们带来的好处远大于这些障碍。

本章随后的大多数示例代码都来自w2k_dbg.dll,你可以在光盘的/src/w2k_dbg/w2k_dbg.c中发现它们。这个DLL封装了多个步骤,以返回更丰富的信息。数据会以合适的大小、链表(包括可选的索引值)返回,以便于对它们进行排序等操作。表1-3列出了w2k_dbg.dll导出的所有API函数。这些函数很多,详细讨论每个函数已经超出了本章的范围,因此我鼓励你去参考w2k_sym.exe的源代码(位于光盘/src/w2k_sym/x),来学习它们的典型用法。

表1-3

函数名称

描   

dbgBaseDriver

Return the base address and size of a driver, given its path

dbgBaseModule

Return the base address and size of a DLL module

dbgCrc32Block

Compute the CRC32 of a memory block

dbgCrc32Byte

Bytewise computation of a CRC32

dbgCrc32Start

CRC32 preconditioning

dbgCrc32Stop

CRC32 postconditioning

dbgDriverAdd

Add a driver entry to a list of drivers

dbgDriverAddresses

Return an array of driver addresses (EnumDeviceDrivers ( ) wrapper)

dbgDriverlndex

Create an indexed (and optionally sorted) driver list

dbgDriverList

Create a flat driver list

dbgFileClose

Close a disk file

dbgFileLoad

Load the contents of a disk file to a memory block

dbgFileNew

Create a new disk file

dbgFileOpen

Open an existing disk file

dbgFileRoot

Get the offset of the root token in a file path

dbgFileSave

Save a memory block to a disk file

dbgFileUnload

Free a memory block created by dbgFileLoad ( )

dbglndexCompare

Compare two entries referenced by an index (used by dbgindexsort ( ) )

dbglndexCreate

Create a pointer index on an object list

dbglndexCreateEx

Create a sorted pointer index on an object list

dbglndexDestroy

Free the memory used by an index and its associated list

dbglndexDestroyEx

Free the memory used by a two-dimensional index and its associated lists

dbglndexList

Create a flat copy of a list from its index

dbglndexListEx

Create a flat copy of a two-dimensional list from its index

dbglndexReverse

Reverse the order of the list entries referenced by an index

dbglndexSave

Save the memory image of an indexed list to a disk file

dbglndexSaveEx

Save the memory image of a two-dimensional indexed list to a disk file

dbglndexSort

Sort the list entries referenced by an index by address, size, ID, or name

dbgListCreate

Create an empty list

dbgListCreateEx

Create an empty list with reserved space

dbgListDestroy

Free the memory used by a list

dbgListFinish

Terminate a sequentially built list and trim any unused memory

dbgListlndex

Create a pointer index on an object list

dbgListLoad

Create a list from a disk file image

dbgListNext

Update the list header after adding an entry

dbgListResize

Reserve memory for additional list entries

dbgListSave

Save the memory image of a list to a disk file

dbgMemory

Align Round up a byte count to the next 64-bit boundary

dbgMemoryAlignEx

Round up a string character count to the next 64-bit boundary

dbgMemoryBase

Query the internal base address of a heap memory block

dbgMemoryBaseEx

Query the internal base address of an individually tagged heap memory block

dbgMemoryCreate

Allocate a memory block from the heap

dbgMemoryCreateEx

Allocate an individually tagged memory block from the heap

dbgMemoryDestroy

Return a memory block to the heap

dbgMemoryDestroyEx

Return an individually tagged memory block to the heap

dbgMemoryReset

Reset the memory usage statistics

dbgMemoryResize

Change the allocated size of a heap memory block

dbgMemoryResizeEx

Change the allocated size of an individually tagged heap memory block

dbgMemoryStatus

Query the memory usage statistics

dbgMemory

Track Update the memory usage statistics

dbgModulelndex

Create an indexed (and optionally sorted) process module sub-list

dbgModuleList

Create a flat process module sub-list

dbgPathDriver

Build a default driver path specification

dbgPathFile

Get the offset of the file name token in a file path

dbgPrivilegeDebug

Request the debug privilege for the calling process

dbgPrivilegeSet

Request the specified privilege for the calling process

dbgProcessAdd

Add a process entry to a list of processes

dbgProcessGuess

Guess the default display name of an anonymous system process

dbgProcessIds

Return an array of process IDs (EnumProcesses ( ) wrapper)

dbgProcessIndex

Create an indexed (and optionally sorted) process list

dbgProcessIndexEx

Create a two-dimensional indexed (and optionally sorted) process/module list

dbgProcessList

Create a flat process list

dbgProcessModules

Return a list of process module handles (EnumProcessModules ( )wrapper)

dbgSizeDivide

Divide a byte count by a power of two, optionally rounding up or down

dbgSizeKB

Convert bytes to KB, optionally rounding up or down

dbgSizeMB

Convert bytes to MB, optionally rounding up or down

dbgStringAnsi

Convert a Unicode string to ANSI

dbgStringDay

Get the name of a day given a day-of-week number

dbgStringMatch

Apply a wildcard filter to a string

dbgSymbolCallback

Add a symbol entry to a list of symbols (called by SymEnumerateSymbols ( ) )

dbgSymbolIndex

Create an indexed (and optionally sorted) symbol list

dbgSymbolList

Create a flat symbol list

dbgSymbolLoad

Load a module's symbol table

dbgSymbolLookup

Look up a symbol name and optional offset given a memory address

dbgSymbolUnload

Unload a module's symbol table

作者Blog: http://blog.csdn.net/Kendiv/

第一章 Windows 2000对调试技术的支持相关推荐

  1. Windows 2000缓冲区溢出技术原理

    前言: 在看Jason著backend翻译的<Windows 2000缓冲区溢出入门>时觉得过于简单,没有讲到真正的 原理,我简直不敢相信那会是老外写的文章. 相反在看ipxodi和袁哥的 ...

  2. 乐行学院RabbitMQ学习教程 第一章 RabbitMQ介绍(可供技术选型时使用)

    乐行学院RabbitMQ学习教程 第一章 RabbitMQ介绍 RabbitMQ介绍 1.RabbitMQ技术简介 2.RabbitMQ其他扩展插件 2.1监控工具rabbitmq-managemen ...

  3. 计算机网络第一章章节总结,第计算机网络技术第一章.ppt

    电子商务的网络技术;请考虑以下问题: 你为什么上网(或上网干什么)? 你认为网络上有什么? 企业通过网络能够做什么? 企业通过网络能够达到什么目的? 你希望通过这门课学到什么?;电子贺卡;远程教育;网 ...

  4. 【第一章】浅谈NB-IoT技术及介绍NB-IoT模组BC95的特点

    NB-IoT 窄带物联网(Narrow Band Internet of Things, NB-IoT)成为万物互联网络的一个重要分支.NB-IoT构建于蜂窝网络,只消耗大约180KHz的带宽,可直接 ...

  5. [转]第一章 Windows Shell是什么 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987862】...

    一个操作系统外壳的不错的定义是它是一个系统提供的用户界面,它允许用户执行公共的任务,如访问文件系统,导出执行程序,改变系统设置等.MS-DOS有一个Command.COM扮演着这个角色.然而Windo ...

  6. 第10章 嵌入式linux的调试技术

    一.      防止函数printk降低linux性能: 利用C语言中的编译指令(#if.#else.#endif等). 现在修改printk_demo驱动代码,通过编译指令定义了一个pr_debug ...

  7. 第一章 Windows编程基础(1~4课)

    第一课:从main到WinMain 第二课:窗口和消息 第三课:MFC编程 第四课:MFC应用程序框架 概括: Win32的两种编程框架:SDK方式.MFC方式 1. SDK方式:使用WinMain入 ...

  8. 蓝牙第一章:概述、无线技术协议和基带协议

    1.蓝牙技术的诞生与发展 1994年,爱立信公司为了在移动电话及其附件之间探求一种新的低功耗.低成本的空中接口,要能够去除连接移动电话与耳机.笔记本电脑及其它设备之间繁杂的线缆,更主要的目的则是分析有 ...

  9. 第一章 windows应用程序开发入门

    1.1第一个实例程序 1.1.1 start.exe 话不多说,先上代码: //头文件 #include <windows.h>//连接时使用User32.lib #pragram com ...

最新文章

  1. 太卷了!人大附中「内卷」到了美国?华裔家长抗议中国学生持F1签证抢占美国IMO名额...
  2. A Color Picker based on manifold learning
  3. 【Ansible】3个让Ansible性能飞起的简单优化方案!
  4. JavaWeb:Tomcat下配置数据源连接数据库
  5. 力扣(leetcode)-1. 两数之和
  6. python字符串逆序输出代码_一行代码实现字符串逆序输出
  7. Unusual Competitions CodeForces - 1323C(思维)
  8. 启动php-fpm服务器_无服务器冷启动不是问题-这就是为什么(对于大多数应用程序)...
  9. 如何正确的通过 C++ Primer 学习 C++?(转自知乎)
  10. 确认过眼神是先用上5G的人!中国联通将在7个城市开通5G试验网
  11. Python标准库中的io
  12. VS2017控制台打印问题
  13. MySql学习10-----存储过程和函数
  14. Tomcat Https配置
  15. linux如何生成awr报告,手工生成AWR报告方法记录
  16. 徽州区数字城管平台智慧管理城市
  17. 项目报错信息如下:java.text.ParseException: Unparseable date: “Wed Aug 03 2022 00:00:00 GMT+0800 (中国标准时间)“
  18. 下一个20年: 从搜索经济到算法经济 (从B站跨年爆红 等想到的)
  19. 浅谈一万小时定律的表与里
  20. adf被打开_ADF格式文件 如何打开ADF文件 ADF是什么格式的文件 用什么打开 - The X Online Tools...

热门文章

  1. PHP获取星期六星期日
  2. MP3文件的切割和合并
  3. 亚马逊推荐python_Python之亚马逊智能产品评论分析
  4. 高级技巧之vertical-align属性应用
  5. 小巧好用的真无线耳机,音质还挺好,SOUNDPEATS泥炭Air3体验
  6. 【记录爬虫实战过程】入门学习·详细过程·爬取天气信息并通过pyecharts进行可视化展示1
  7. 五金机电行业S2B2B商城系统打破传统线下营销方式,实现企业高质量发展
  8. 机器人-关节空间轨迹规划
  9. 笔记本显示网络电缆被拔出怎么解决_电脑提示本地网络电缆被拔出怎么办?
  10. Java设计模式之工厂模式篇 (转)