当前位置:编程学习 > Delphi >>

Delphi研究之驱动开发篇(六)--利用Section与用户模式程序通讯(下)

整个驱动程序非常简单,但它却是个完整意义上的驱动程序,包含了一个驱动程序所必须的各个部分。程序很简单,大家一看就明白,所以也没加什么注释,只捡几个重要的地方说明一下。
   使用共享资源通常情况下需要考虑同步问题,即读写线程不能同时访问共享资源。在本例中总是只有一个线程,所以不需要同步。
代码:InitializeObjectAttributes(oa, @g_usSectionName,
                       OBJ_CASE_INSENSITIVE, 0, nil);
取得控制代码IOCTL_SHARE_MY_SECTION,驱动程序尝试打开section对象,其名字定义为变量g_usSectionName。

代码:status := ZwOpenSection(@hSection,
                       SECTION_MAP_WRITE or SECTION_MAP_READ,
                       @oa);
if status = STATUS_SUCCESS then
begin
    DbgPrint(SharedSection: Section object opened#13#10);
    pSectionBaseAddress := nil;
    liViewSize.HighPart := 0;
    liViewSize.LowPart := 0;
    status := ZwMapViewOfSection(hSection, HANDLE(NtCurrentProcess),
                              pSectionBaseAddress, 0,
                              SECTION_SIZE, nil,
                              @liViewSize, ViewShare, 0,
                              PAGE_READWRITE);
如果取得了section的句柄,我们就来映射它的视图。这里与应用程序中的映射视图部分几乎完全相同。但是在调用了ZwMapViewOfSection之后,变量pSectionBaseAddress保存的值位于用户地址区域中,而不是核心区域中的地址,这点我们可以预料到。这可是个原则上的问题,即对这个地址的使用将只能在这个进程的上下文中,在映射section的地址空间中。由于SharedSection驱动程序是单层的(您还记得IRP_MJ_DEVICE_CONTROL类型的IRP处理要经过驱动程序进入发出该操作的线程上下文中),所以我们位于我们的应用程序的上下文中。
这里视图的虚拟地址与应用程序中视图的地址将有所不同,但共享section所在的物理页是同一个。我们这里有一个内存页,其中还保存着倒着写的一行文字。

代码:asm
    push offset DefaultExceptionHandler
    push fs:[0]
    mov fs:[0], esp

    mov sseh.SafeEip, offset SafePlace
    mov sseh.PrevEbp, ebp
    mov sseh.PrevEsp, esp
end;
_strrev(pSectionBaseAddress);
p_Irp^.IoStatus.Status := STATUS_SUCCESS;
DbgPrint(SharedSection: String reversed#13#10);
SafePlace:
asm
    pop fs:[0]
    add esp, 4
end;
 
以上建立SEH-frame,并调用_strrev函数将内存里的字符串反转过来。
下面来看看在用户模式下如何加载和调用这个驱动程序。
代码:program SharedSection;

{$APPTYPE CONSOLE}

uses
    SysUtils,
    Windows,
    Dialogs,
    WinSvc,
    nt_status,
    native,
    macros,
    ntdll;

const
    SECTION_SIZE = $1000;
    str = .revird ecived a dna sessecorp resu neewteb yromem erahs ot euqinhcet emas eht esu nac uoy ,revewoH .sessecorp resu gnoma yromem gnirahs rof desu euqinhcet nommoc a si elif gnigap eht yb dekcab elif deppam-yromem A;
    _Delete = $10000;

var
    hSection:HANDLE;
    liSectionSize: LARGE_INTEGER;
    oa:OBJECT_ATTRIBUTES;
    pSectionBaseAddress:PVOID;
    liViewSize: LARGE_INTEGER;
    g_usSectionName: UNICODE_STRING;
    status:NTSTATUS;
    sTemp: array[0..255] of char;

function CallDriver: boolean;
var
    fOk: boolean;
    hSCManager:HANDLE;
    hService:HANDLE;
    acModulePath: string;
    _ss:SERVICE_STATUS;
    hDevice:HANDLE;

    dwBytesReturned: DWORD;
    IOCTL_SHARE_MY_SECTION: DWORD;
    lpTemp: PChar;
begin
    fOk := false;
    IOCTL_SHARE_MY_SECTION := CTL_CODE(FILE_DEVICE_UNKNOWN, $800, 0, 0);
    hSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
    if hSCManager <> 0 then
    begin
      acModulePath := GetCurrentDir + + ExtractFileName(SharedSection.sys);
      hService := CreateService(hSCManager, SharedSection,
                                One way to share section,
                                SERVICE_START or SERVICE_STOP or _Delete,
                                SERVICE_KERNEL_DRIVER,
                                SERVICE_DEMAND_START,
                                SERVICE_ERROR_IGNORE,
                                PChar(acModulePath),
                                nil, nil, nil, nil, nil);

      if hService <> 0 then
      begin
        if StartService(hService, 0, lpTemp) then
        begin;
          hDevice := CreateFile(PChar(\.SharedSection), 0, 0,
                                nil, OPEN_EXISTING, 0, 0);
          if hDevice <> INVALID_HANDLE_VALUE then
          begin
            if DeviceIoControl(hDevice, IOCTL_SHARE_MY_SECTION,
                               nil, 0, nil, 0, dwBytesR

补充:软件开发 , Delphi ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,