Inside Native Applications 原生应用程序探微

本文深入探讨了NT操作系统中原生应用程序的工作原理和技术细节,包括它们的构建方式、执行时机及如何与系统交互。

引用自Sysinternal

Introduction
If you have some familiarity with NT's architecture you are probably aware that the API that Win32 applications use isn't the "real" NT API. NT's operating environments, which include POSIX, OS/2 and Win32, talk to their client applications via their own APIs, but talk to NT using the NT "native" API. The native API is mostly undocumented, with only about 25 of its 250 functions described in the Windows NT Device Driver Kit.
简介
如果你对NT的构架有些熟悉的话你很可能会意识到Win32应用程序所使用的API并非是“真正”NT的API。NT的操作环境(其中包括POSIX,OS/2和Win32环境)是通过他们各自的API与他们的客户应用程序进行通信的,而与NT自身通信时使用的还是NT 的“原生”API。原生的API大部分是没有公开文档记载的,仅仅250个函数中的25个左右在Windows NT的设备驱动工具箱内有描述。

What most people don't know, however, is that "native" applications exist on NT that are not clients of any of the operating environments. These programs speak the native NT API and can't use operating environment APIs like Win32. Why would such programs be needed" Any program that must run before the Win32 subsystem is started (around the time the logon box appears) must be a native application. The most visible example of a native application is the "autochk" program that runs chkdsk during the initialization Blue Screen (its the program that prints the "."'s on the screen). Naturally, the Win32 operating environment server, CSRSS.EXE (Client-Server Runtime Subsystem), must also be a native application.
然而所不为人知的是存在于NT上的“原生”应用程序不是任何操作环境的客户端。这些程序调用的是原生的NT API并且不使用像Win32这样的操作环境的API。为什么会需要有这样的应用程序?任何必须在Win32子系统启动之前运行的应用程序必须是一个原生的应用程序。最显而易见的原生应用程序的一个例子就是“autochk”程序,这个程序在系统初始化的蓝色屏幕阶段运行chkdsk(这个程序在屏幕上打印一个个“.”)。自然而然Win32操作环境服务器,CSRSS.EXE(客户-服务器 运行子系统),也必须是一个原生应用程序。

In this article I'm going to describe how native applications are built and how they work. I also provide you the source code for an example native application, Native, that you can easily install and that will print out a string you specify on the boot-time Blue Screen.
在本文中我将描述原生应用程序是如何构建的并且他们是怎样工作的。我也将提供给你一个原生应用程序的例子Native,你可以很容易地把它安装在系统上,这个程序会在启动的蓝色屏幕上打印出你指定的字符串。

How Does Autochk Get Executed
Autochk runs in between the time that NT's boot and system start drivers are loaded, and when paging is turned on. At this point in the boot sequence Session Manager (smss.exe) is getting NT's user-mode environment off-the-ground and no other programs are active. The HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute value, a MULTI_SZ, contains the names and arguments of programs that are executed by Session Manager, and is where Autochk is specified. Here is what you'll typically find if you look at this value, where "Autochk" is passed "*" as an argument:

Autocheck Autochk *

Session Manager looks in the <winnt>\system32 directory for the executables listed in this value. When Autochk runs there are no files open so Autochk can open any volume in raw-mode, including the boot drive, and manipulate its on-disk data structures. This wouldn't be possible at any later point.
Autochk是如何执行的
Autochk在NT的引导/系统启动驱动程序加载和内存分页开启的之间的时间点运行。在启动过程中的这点上,会话管理器(smss.exe)在启动NT的用户模式并且没有其他程序是活跃的。注册表键值HKLM\System\CurrentControlSet\Control\Session Manager\BootExecute,一个MULTI_SZ类型的值,包含了会话管理器要执行的程序名字和相应的参数,在那里指定了Autochk。如果你查看这个键值你通常会发现以下的值,这里“*”是传递给autochk的参数。

Autocheck Autochk *

会话管理器在目录<winnt>\system32下查找列在这个值下的可执行程序。当Autochk运行时文件都还没有打开因此Autochk可以以原始模式打开任何卷,包括启动驱动器,并且操作磁盘上的数据结构。这在以后的任何时间点都是做不到的。

Building Native Applications
Microsoft doesn't document it, but the NT DDK Build utility knows how to make native applications (and its probably used to compile Autochk). You specify information in a SOURCES file that defines the application, the same as would be done for device drivers. However, instead of indicating to Build that you want a driver, you tell it you want a native applicationin the SOURCES file like this:

TARGETTYPE=PROGRAM

The Build utility uses a standard makefile to guide it, \ddk\inc\makefile.def, which looks for a run-time library named nt.lib when compiling native applications. Unfortunately, Microsoft doesn't ship this file with the DDK (its included in the Server 2003 DDK, but I suspect that if you link with that version your native application won't run on XP or Windows 2000). However, you can work around this problem by including a line in makefile.def that overrides the selection of nt.lib by specifying Visual C++'s runtime library, msvcrt.lib

If you run Build under the DDK's "Checked Build" environment it will produce a native application with full debug information under %BASEDIR%\lib\%CPU%\Checked (e.g. c:\ddk\lib\i386\checked\native.exe), and if you invoke it in the "Free Build" environment a release version of the program will end up in %BASEDIR%\lib\%CPU%\Free. These are the same places device driver images are placed by Build.

Native applications have ".exe" file extensions but you cannot run them like Win32 .exe's. If you try you'll get the message:

The <Application Name> application cannot be run in Windows NT mode.
编译原生应用程序
微软并没有记载这各方面,但是NT的DDK编译工具知道如何生成原生的应用程序(并且很有可能就是用来编译Autochk的)。你只要在定义应用程序的一个SOURCES文件内指定相应的信息,这就如同我们对驱动程序所要做的一样。然而,取而代之,不要说你要编译一个驱动程序,你要告诉它你需要一个原生应用程序,在SOURCES文件中如下:

TARGETTYPE=PROGRAM

这个编译的工具使用一个标准的makefile(\ddk\inc\makefile.def)去指导它,编译原生程序时会搜寻名字叫做nt.lib的运行库。不幸地是微软并没有在DDK中包含这个库文件(该文件包含在Server 2003的DDK中,但是我怀疑如果你使用这个版本的库文件,你的原生应用程序很可能不能在XP或者Windows 2000上运行)。然而有个临时的解决办法就是在makefile.def中包括一行来覆盖选择nt.lib的设置,而选择Visual C++'s运行库,msvcrt.lib。

如果你在DDK的“Checked Build”的环境下编译,会在%BASEDIR%\lib\%CPU%\Checked(例如,c:\ddk\lib\i386\checked\native.exe)目录下生成一个包含完整debug信息的原生应用程序,但是如果你在“Free Build”的环境下启动编译,一个可发布的程序会在%BASEDIR%\lib\%CPU%\Free下生成。设备驱动程序镜像文件也按照编译的类型放在同样的目录下面。

原生应用程序具有“.exe”的扩展名但是你不能像运行Win32的exe那样运行他们。如果你尝试着那样做,你会看到如下信息:

<Application Name> appliation cannot be run in Windows NT mode.

Inside a Native Application
Instead of winmain or main, the entry point for native applications is NtProcessStartup. Also unlike the other Win32 entry points, native applications must reach into a data structure passed as its sole parameter to locate command-line arguments.

The majority of a native application's runtime environment is provided by NTDLL.DLL, NT's native API export library. Native applications must create their own heap from which to allocate storage by using RtlCreateHeap, a NTDLL function. Memory is allocated from a heap with RtlAllocateHeap and freed with RtlFreeHeap. If a native application wishes to print something to the screen it must use the function NtDisplayString, which will output to the initialization Blue Screen.

Native applications don't simply return from their startup function like Win32 programs, since there is no runtime code to return to. Instead, they must terminate themselves by calling NtProcessTerminate.

The NTDLL runtime consists of hundreds of functions that allow native applications to perform file I/O, interact with device drivers, and perform interprocess communications. Unfortunately, as I stated earlier, the vast majority of these functions are undocumented.
一个原生应用程序的探微
原生应用程序的入口既不是winmain或者main而是NtProcessStartup。同样和其他的Win32的入口不同,原生应用程序必须要进入到作为它唯一参数的数据结构内去找到命令行的所有参数。

一个原生应用程序运行环境的极大部分是由NTDLL.DLL(NT的原生API的库)来提供的。原生应用程序必须用NTDLL的函数RtlCreateHeap创建它们自己的堆,从堆内进而来分配存储空间。内存是由RtlAllocateHeap从一个堆内分配的,并由RtlFreeHeap释放的。如果原生程序希望在屏幕上打印某些东西,它必须使用NtDisplayString函数,这样就会输出到初始化的蓝色屏幕上。

原生应用程序不是像Win32应用程序简单地返回他们地起始函数,因为没有运行时的代码可以返回。取而代之,他们必须通过调用NtProcessTerminate函数来终结自己。

NTDLL运行环境包含着成千上百的函数能够让原生应用程序进行文件的I/O,与设备驱动程序通信,以及进程间通信。不幸地是,正如我开始所说地,这些函数中的极大多数并没有被记载。

转载于:https://www.cnblogs.com/steven938/archive/2007/06/19/789637.html

UVM(Universal Verification Methodology)是一种用于验证系统级芯片的方法学。它提供了一组验证方法和标准,以便芯片设计人员能够更好地验证他们的设计。UVM工厂机制是一种创建和管理UVM组件的方法。 在UVM中,工厂机制用于创建和管理UVM组件的实例。工厂的主要任务是根据工厂注册表中的类型创建新的实例,并将其传递给请求实例的组件。工厂机制的核心是工厂类,它是UVM组件类的基类。每个UVM组件都有一个之关联的工厂类,该类负责创建该组件的实例。工厂类通过使用工厂注册表来创建和管理实例。 以下是UVM工厂机制的源代码示例: ```systemverilog class uvm_factory; static uvm_factory get(); void set_type_override(string original_type_name, string override_type_name, bit replace = 0, uvm_object_wrapper replace_with=NULL); uvm_object_wrapper create_object(string type_name, string name=""); uvm_component create_component(string type_name, string name="", uvm_component parent=null); void print(); endclass : uvm_factory ``` 上面的代码定义了一个名为uvm_factory的类,该类包含了一些用于创建和管理UVM组件实例的方法。其中,最常用的方法是create_component和create_object,它们用于创建组件和对象的实例。 此外,uvm_factory还提供了set_type_override方法,用于覆盖原始类型并将其替换为新类型。这对于在运行时更改实例类型非常有用。 总之,UVM工厂机制是一种非常强大的工具,可以帮助UVM用户创建和管理UVM组件的实例。通过使用工厂机制,用户可以更轻松地编写可重用的UVM代码,并将其应用于各种不同的验证场景中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值