1.Kernel DLL 生成
使用DDK生成kernel dll是非常简单的,只要注意少数几个地方既可以
- source
关键点在于声明EXPORT_DRIVER和指定DEF
TARGETNAME=sampledll
TARGETTYPE=EXPORT_DRIVER
TARGETPATH = obj$(BUILD_ALT_DIR)
DRIVERTYPE = WDM
DLLDEF=sampledll.def
MSC_WARNING_LEVEL=/W3
INCLUDES=$(DDK_INC_PATH)
SOURCES=sampledll.cpp
TARGETTYPE=EXPORT_DRIVER
TARGETPATH = obj$(BUILD_ALT_DIR)
DRIVERTYPE = WDM
DLLDEF=sampledll.def
MSC_WARNING_LEVEL=/W3
INCLUDES=$(DDK_INC_PATH)
SOURCES=sampledll.cpp
- def
NAME SAMPLEDLL.SYS
EXPORTS
DllInitialize PRIVATE
DllUnload PRIVATE
SampleOutput
EXPORTS
DllInitialize PRIVATE
DllUnload PRIVATE
SampleOutput
- c/cpp
#include <wdm.h>
EXTERN_C NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
EXTERN_C DECLSPEC_IMPORT NTSTATUS SampleOutput(char *output);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
return STATUS_SUCCESS;
}
NTSTATUS DllInitialize(IN PUNICODE_STRING RegistryPath)
{
DbgPrint("SAMPLE: DllInitialize(%wZ)\n", RegistryPath);
return STATUS_SUCCESS;
}
NTSTATUS DllUnload()
{
DbgPrint("SAMPLE: DllUnload\n");
return STATUS_SUCCESS;
}
NTSTATUS SampleOutput(char *output)
{
DbgPrint("SampleOutput: %s\n", output);
return STATUS_SUCCESS;
}
2.Kernel DLL 调用EXTERN_C NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
EXTERN_C DECLSPEC_IMPORT NTSTATUS SampleOutput(char *output);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
return STATUS_SUCCESS;
}
NTSTATUS DllInitialize(IN PUNICODE_STRING RegistryPath)
{
DbgPrint("SAMPLE: DllInitialize(%wZ)\n", RegistryPath);
return STATUS_SUCCESS;
}
NTSTATUS DllUnload()
{
DbgPrint("SAMPLE: DllUnload\n");
return STATUS_SUCCESS;
}
NTSTATUS SampleOutput(char *output)
{
DbgPrint("SampleOutput: %s\n", output);
return STATUS_SUCCESS;
}
如前文所述,MS同时支持使用导出Lib静态link或者动态调用,但实际上,考虑到使用DLL的初衷,动态调用几乎没有意义。因为MS并没有提供kernel可用的类似于LoadLibrary的API,而需要使用IOCTL来定义导出函数,也就是说DLL同样需要像驱动一样安装,才能在其他驱动中通过IOCTL来调用,这样一来似乎没什么必要的理由来使用DLL了,kernel提供很多类似方式,loaddriver,callback等等,DLL没有优势。所以通常的我们选择将编译生成的导出Lib直接link进驱动中,即可在驱动中使用DLL中提供的函数,需要注意的是DLL要和driver一样复制到SYSTEM32\driver下面。通过DbgPrint可以看到,driver 被load时,DLLInitialize就被调用了。理论上只要不更改DEF的定义,替换DLL可以不重新编译driver。
没有评论:
发表评论