设置编译内核lib驱动及应用层dll的source文件,一

2019-11-14 17:21栏目:网络技术
TAG:

驱动层的一些策略性代码,算法性代码,和

以上就是用户模式下的控制程序了,下面来看看我们的驱动程序。

1.首先下载ddk开发包

驱动内API不相关的代码,可以用在应用层进行测试,

代码:unit VirtToPhys;

Windows DDK 3790.1830 下载

以提高编写的速度,

interface

安装DDK后,去 下载ddkwizard_setup_v1.2.0a、ddkbuild_bat.zip、ddkbuild_cmd.zip。

这是明显的,应用层在这方面的有其优点.

uses
    nt_status, ntoskrnl, ntutils;

2.拷贝 DDKBUILD.bat 和 DDKBUILD.cmd 到DDK安装根目录,如我的是D:WinDDK.

那么如何来实现这个功能.

function _DriverEntry(pDriverObject:PDRIVER_OBJECT; pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;

3.. 将上述文件(DDKBUILD.bat 和 DDKBUILD.cmd )的路径添加到系统的path变量(右击我的电脑,系统属性/高级/环境变量/系统变量/path变量双击修改值)。

主要是在写两个文件

implementation

  1. 根据你所安装的DDK的不同版本添加不同的变量到系统变量中。

一个是sources文件,  一个是Sample.def文件.

const
    NUM_DATA_ENTRY = 4;
    DATA_SIZE = sizeof(DWORD) * NUM_DATA_ENTRY;

  右击我的电脑,系统属性/高级/环境变量/系统变量/新建:

一.    sources文件

var
    g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;

  2000 DDK则变量名为: W2KBASE

KERNEL_BUILD=1                    #若想编译成DLL的话 那么在之前加#号

function DispatchCreateClose(p_DeviceObject:PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
begin
    p_Irp^.IoStatus.Status := STATUS_SUCCESS;
    p_Irp^.IoStatus.Information := 0;

  XP DDK则变量名为: WXPBASE

TARGETNAME=Sample
DLLDEF=Sample.def                 #输出函数的.def文件
TARGETPATH=../../bin                 #文件输出目录 (.sys文件或.dll文件)
TARGETPATHLIB=../../lib            #.lib输出目录

    IofCompleteRequest(p_Irp, IO_NO_INCREMENT);
    result := STATUS_SUCCESS;
end;

  2003 sp1 DDK则变量名为: WNETBASE

!ifdef KERNEL_BUILD               #若定义了KERNEL_BUILD 则生成一个.sys文件 相当于内核库 
TARGETTYPE=EXPORT_DRIVER
!else                                              #若没有定义,则生成一个.dll 
TARGETTYPE=DYNLINK          #生成一个dll
USE_MSVCRT=1
DLLENTRY=_DllMainCRTStartup        #dll的入口函数
INCLUDES= $(INCLUDES); $(DDK_INC_PATH);      #H文件的目录
INCLUDES= $(INCLUDES); $(SDK_INC_PATH);
TARGETLIBS=$(TARGETLIBS) $(SDK_LIB_PATH)kernel32.lib     #LIB目录  kernel32.lib  gdi32.lib advapi32.lib
TARGETLIBS=$(TARGETLIBS) $(SDK_LIB_PATH)gdi32.lib
TARGETLIBS=$(TARGETLIBS) $(SDK_LIB_PATH)advapi32.lib
TARGETLIBS=$(TARGETLIBS) $(SDK_LIB_PATH)ntdll.lib
!endif

function DispatchControl(p_DeviceObject: PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
var
    status:NTSTATUS;
    dwBytesReturned:DWORD;
    psl:PIO_STACK_LOCATION;
    IOCTL_GET_PHYS_ADDRESS: DWORD;
    pSystemBuffer: PULONG;
    iCnt: DWORD;
    liPhysicalAddress: PHYSICAL_ADDRESS;
begin
    dwBytesReturned := 0;

  这里我的是WNETBASE(值为D:WinDDK3790.1830)

INCLUDES=$(INCLUDES); ../../inc;                       #自己的.H文件目录
INCLUDES=$(INCLUDES); ../../inc/SampleOne; #自己的.H文件目录二
INCLUDES=$(INCLUDES); ../../inc/SampleTwo;#自己的.H文件目录三

    IOCTL_GET_PHYS_ADDRESS := CTL_CODE(FILE_DEVICE_UNKNOWN,
      $800, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS);

5.启动vs2008 打开菜单中的工具——选项,弹出选项对话框。选择左边的项目和解决方案——VC++目录,在右边的显示以下内容的目录下拉列表中选择可执行文件,在下面列表框中添加上面DDKBuild.bat文件所在的路径(这里是D:WinDDK),同样设置包含文件和库文件 如下图:

SOURCES=
A.cpp
B.cpp
C.cpp
D.cpp  

    psl := IoGetCurrentIrpStackLocation(p_Irp);

设置可执行文件

 

    if psl^.Parameters.DeviceIoControl.IoControlCode = IOCTL_GET_PHYS_ADDRESS then
    begin
      if (psl^.Parameters.DeviceIoControl.OutputBufferLength >= DATA_SIZE)
         and (psl^.Parameters.DeviceIoControl.InputBufferLength >= DATA_SIZE) then
      begin
        pSystemBuffer := p_Irp^.AssociatedIrp.SystemBuffer;
        iCnt := 0;
        for iCnt := 1 to NUM_DATA_ENTRY do
        begin
          liPhysicalAddress := MmGetPhysicalAddress(PVOID(pSystemBuffer^));
          pSystemBuffer^ := liPhysicalAddress.LowPart;
          inc(pSystemBuffer);
        end;
        dwBytesReturned := DATA_SIZE;
        status := STATUS_SUCCESS;
      end else
      begin
        status := STATUS_BUFFER_TOO_SMALL;
      end;
    end else
    begin
      status := STATUS_INVALID_DEVICE_REQUEST;
    end;
    
    p_Irp^.IoStatus.Status := status;
    p_Irp^.IoStatus.Information := dwBytesReturned;

设置包含文件(D:WINDDK3790.1830incwnet D:WINDDK3790.1830incddkwnet )

 

    IofCompleteRequest(p_Irp, IO_NO_INCREMENT);
    result := status;
end;

设置库文件(D:WINDDK3790.1830libwneti386)

二. Sample.def文件

procedure DriverUnload(p_DriverObject:PDRIVER_OBJECT); stdcall;
begin
    IoDeleteSymbolicLink(@g_usSymbolicLinkName);
    IoDeleteDevice(p_DriverObject^.DeviceObject);
end;

  1. 开始安装DDKWizard,在安装的最后一步你可以选择编辑ddkwizard的配置文件。

  2. 现在重新打开VC2008就会发现在新建项目里面有DDK Project的选项了,里面就可以建立驱动工程来编写驱动程序了。

  3. 验证你做的工作,你可以直接新建一个Driver工程按F7编译,编译看看。

NAME "Sample.sys"        #若为内核库则为Sample.sys   若为应用层dll则修改为Sample.dll
EXPORTS
 DllInitialize PRIVATE
 DllUnload PRIVATE

function _DriverEntry(pDriverObject:PDRIVER_OBJECT; pusRegistryPath:PUNICODE_STRING): NTSTATUS;
var
    status:NTSTATUS;
    pDeviceObject:TDeviceObject;
begin
    status := STATUS_DEVICE_CONFIGURATION_ERROR;
    RtlInitUnicodeString(g_usDeviceName, DevicedevVirtToPhys);
    RtlInitUnicodeString(g_usSymbolicLinkName, ??slVirtToPhys);

建立EmptyDriver时,

AFunc

    if (IoCreateDevice(pDriverObject, 0, @g_usDeviceName,
                       FILE_DEVICE_UNKNOWN, 0, FALSE,
                       pDeviceObject) = STATUS_SUCCESS) then
    begin
      if (IoCreateSymbolicLink(@g_usSymbolicLinkName,
                               @g_usDeviceName) = STATUS_SUCCESS) then
      begin
        pDriverObject^.MajorFunction[IRP_MJ_Create] := @DispatchCreateClose;
        pDriverObject^.MajorFunction[IRP_MJ_CLOSE] := @DispatchCreateClose;
        pDriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL] := @DispatchControl;
        pDriverObject^.DriverUnload := @DriverUnload;

要在sources文件的第4行TARGETTYPE=后面加DRIVER

BBFunc

        status := STATUS_SUCCESS;
      end else
      begin
        IoDeleteDevice(@pDeviceObject);
      end;
    end;
    result := status;
end;

加入[源文件]后还要在sources文件里的SOURCES=后面加上[源文件名]。比如:

 

end.
   程序很简单,所以一行注释也没加^_^。既然驱动程序的主要作用是用于控制一些设备,包括物理设备、虚拟设备或者逻辑设备,那么我们首先必须将这些设备创建起来(本例中是虚拟设备),这可以通过调用IoCreateDevice函数来完成,函数将创建并初始化一个由驱动程序使用的设备对象(DEVICE_OBJECT结构),其原型如下:
   代码:function IoCreateDevice(DriverObject: PDRIVER_OBJECT;
                          DeviceExtensionSize: ULONG;
                          DeviceName: PUNICODE_STRING;
                          DeviceType: DEVICE_TYPE;
                          DeviceCharacteristics: ULONG;
                          Exclusive: 

SOURCES=DriverDemo.cpp

 

代码:unitVirtToPhys; interface uses nt_status,ntoskrnl,ntutils; function_DriverEntry(pDrive...

  DriverDemo.h

三.函数库入口函数

VS2008集成DDKWizard遇到的问题>>>>>>>>>>>>>>>>>>>>>

#include "ntddk.h"

————————————————————————————

extern "C"{
 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pusRegPath);
 void DriverUnload(PDRIVER_OBJECT pDriverObject);
 NTSTATUS DllInitialize(PUNICODE_STRING RegistryPath);
 NTSTATUS DllUnload();
};

▲建立EmptyDriver时,

void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
 DllUnload();
}

要在sources文件的第4行TARGETTYPE=后面加DRIVER

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pusRegPath)
{
 DllInitialize(pusRegPath);
 pDriverObject->DriverUnload = DriverUnload;
 return STATUS_SUCCESS;
}

加入[源文件]后还要在sources文件里的SOURCES=后面加上[源文件名]。比如:

NTSTATUS DllInitialize(PUNICODE_STRING RegistryPath)
{
 DbgPrint("Sample: DllInitialize(%wZ)n", RegistryPath);
 return STATUS_SUCCESS;
}

SOURCES=DriverDemo.cpp

NTSTATUS DllUnload()
{
 DbgPrint("Sample: DllUnloadn");
 return STATUS_SUCCESS;
}

  DriverDemo.h

 

▲Cannot open include file: 'NTDDK.h': No such file or directory

//这里要注意的是 

解决方案:VS2005/工具/选项/VC++目录/,

//DDK 中编译器默认为  _stdcall

[显示以下内容的目录]为[包含文件],把DDK包含文件加进目录——

//而VC中编译默认为 _cdecel 

[D:WINDDK3790.1830incddkwnet]和[D:WINDDK3790.1830incwnet]。

//因此在这里显式加入 _stdcall 防止编译器link错误

[显示以下内容的目录]为[库文件],把DDK库文件加进目录——

 

[D:WINDDK3790.1830LIBWNETI386]

 

以上DDK的路径要放到最先。

ULONG _stdcall TestFun(void)             

参考自:

{

结果:

    return 100;

▲编译提示错误:

}

BufferOverflowK.lib(gs_support.obj) : error LNK2019: unresolved external symbol _DriverEntry@8 referenced in function _GsDriverEntry@8

 

objchk_w2K_x86i386Helloworld.sys : fatal error LNK1120: 1 unresolved externals

示例代码下载地址:

解决方案:

把[入口函数DriverEntry]前加上extern "C":

驱动内API不相关的代码,可以用在应用层进行测试, 以提高编写的速度, 这是明显的,应用层在这方面...

extern "C"{

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)

{ /*DriverEntry函数内容*/ }

}//extern "C"

结果:OK。编译通过,才。我靠!终于啊!

另:据说改成.c文件也可。理论上是这样,但测试失败。

测试代码如下

// sources文件

# $Id$

TARGETNAME=HelloWorld

TARGETPATH=obj

TARGETTYPE=DRIVER

# Create browse info

#BROWSER_INFO=1

#BROWSERFILE=<some path>

# Additional defines for the C/C++ preprocessor

C_DEFINES=$(C_DEFINES)

SOURCES=HelloWorld.c

//makefile文件

#

# DO NOT EDIT THIS FILE!!! Edit .sources. if you want to add a new source

# file to this component. This file merely indirects to the real make file

# that is shared by all the components of the Windows NT DDK

#

!INCLUDE $(NTMAKEENV)makefile.def

//HelloWorld.h文件

#ifndef __HELLOWORLD_H__

#define __HELLOWORLD_H__

#include <ntddk.h>

#define DEVICE_HELLO_INDEX 0x860

#define START_HELLOWORLD CTL_CODE( FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define STOP_HELLOWORLD CTL_CODE(FILE_DEVICE_UNKNOWN,DEVICE_HELLO_INDEX+1,METHOD_BUFFERED,FILE_ANY_ACCESS)

#define NT_DEVICE_NAME L"\Device\HelloWorld"

#define DOS_DEVICE_NAME L"\DosDevices\HelloWorld"

NTSTATUS HelloWorldDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp);

VOID HelloWorldUnload(IN PDRIVER_OBJECT DriverObject);

#endif

// HelloWorld.c文件

#ifndef __HELLOWORLD_C__

#define __HELLOWORLD_C__

#define DEBUGMSG

#include "HelloWorld.h"

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)

{

  NTSTATUS ntStatus=STATUS_SUCCESS;

  PDEVICE_OBJECT IpDeviceObject=NULL;

  UNICODE_STRING DeviceNameString;

  UNICODE_STRING DeviceLinkString;

  #ifdef DEBUGMSG

  DbgPrint("hi, Starting DriverEntry()n");

  #endif

  RtlInitUnicodeString(&DeviceNameString,NT_DEVICE_NAME);

  ntStatus=IoCreateDevice(DriverObject,0,&DeviceNameString,FILE_DEVICE_UNKNOWN,0,FALSE,&IpDeviceObject);

  if(!NT_SUCCESS(ntStatus))

  {

  #ifdef DEBUGMSG

  DbgPrint("hi, Error IoCreateDevice()n");

  #endif

  goto Error;

  }

  RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);

  ntStatus=IoCreateSymbolicLink(&DeviceLinkString,&DeviceNameString);

  if(!NT_SUCCESS(ntStatus))

  {

  #ifdef DEBUGMSG

  DbgPrint("hi, Error IoCreateSymbolicLink()n");

  #endif

  goto Error;

  }

  DriverObject->MajorFunction[IRP_MJ_CREATE]=HelloWorldDispatch;

  DriverObject->MajorFunction[IRP_MJ_CLOSE]=HelloWorldDispatch;

  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=HelloWorldDispatch;

  DriverObject->DriverUnload=HelloWorldUnload;

  return ntStatus;

Error:

  #ifdef DEBUGMSG

  DbgPrint("hi, Error DriverEntry()n");

  #endif

  return ntStatus;

}

NTSTATUS HelloWorldDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp)

{

  NTSTATUS ntStatus=STATUS_SUCCESS;

  ULONG IoControlCodes=0;

  PIO_STACK_LOCATION IrpStack=NULL;

  pIrp->IoStatus.Status=STATUS_SUCCESS;

  pIrp->IoStatus.Information=0;

  #ifdef DEBUGMSG

  DbgPrint("hi, Starting HelloWorldDispatch()n");

  #endif

  IrpStack=IoGetCurrentIrpStackLocation(pIrp);

  switch(IrpStack->MajorFunction)

  {

  case IRP_MJ_CREATE:

  #ifdef DEBUGMSG

  DbgPrint("hi, IRP_MJ_CREATEn");

  #endif

  break;

  case IRP_MJ_CLOSE:

  #ifdef DEBUGMSG

  DbgPrint("hi, IRP_MJ_CLOSEn");

  #endif

  break;

  case IRP_MJ_DEVICE_CONTROL:

  #ifdef DEBUGMSG

  DbgPrint("hi, IRP_MJ_DEVICE_CONTROLn");

  #endif

  IoControlCodes=IrpStack->Parameters.DeviceIoControl.IoControlCode;

  switch(IoControlCodes)

  {

  case START_HELLOWORLD:

  DbgPrint("hi, Starting "Hello World "n");

  break;

  case STOP_HELLOWORLD:

  DbgPrint("hi, Stoping "Hello World "n");

  break;

  default:

  pIrp->IoStatus.Status=STATUS_INVALID_PARAMETER;

  break;

  }

  break;

  default:

  break;

  }

  ntStatus=pIrp->IoStatus.Status;

  IoCompleteRequest(pIrp,IO_NO_INCREMENT);

  return ntStatus;

}

VOID HelloWorldUnload(IN PDRIVER_OBJECT DriverObject)

{

  UNICODE_STRING DeviceLinkString;

  PDEVICE_OBJECT DeviceObjectTemp1=NULL;

  PDEVICE_OBJECT DeviceObjectTemp2=NULL;

  #ifdef DEBUGMSG

  DbgPrint("hi,Starting HelloWorldUnload()n");

  #endif

  RtlInitUnicodeString(&DeviceLinkString,DOS_DEVICE_NAME);

  IoDeleteSymbolicLink(&DeviceLinkString);

  if(DriverObject)

  {

  DeviceObjectTemp1=DriverObject->DeviceObject;

  while(DeviceObjectTemp1)

  {

  DeviceObjectTemp2=DeviceObjectTemp1;

  DeviceObjectTemp1=DeviceObjectTemp1->NextDevice;

  IoDeleteDevice(DeviceObjectTemp2);

  }

  }

}

#endif

手动编译命令如下:

打开:开始/程序/……/Windows Server 2003 Checked x86 Build Environment

输入如下:

D:WINDDK3790~1.183>cd ..//uu

D:WINDDKuu>build

版权声明:本文由澳门新葡亰平台游戏发布于网络技术,转载请注明出处:设置编译内核lib驱动及应用层dll的source文件,一