/*
如何在驱动中获取SYS或者DLL,EXE等的签名信息?
自己编写代码也可以,就是难定位到文件的签名文件,如:用CAT的。
高版本的WDK下有个Early Launch Anti-Malware Driver或者叫elam工程。
这个工程IoRegisterBootDriverCallback的使用有限制,测试了没有成功:平常返回失败,BOOT启动也失败。
不过,在这里看到一个数据结构:PBDCB_IMAGE_INFORMATION。
偶尔你会看到这两个函数:
SeRegisterImageVerificationCallback,SeUnregisterImageVerificationCallback
在网上一搜,果然看到:
http://www.codemachine.com/article_kernel_callback_functions.html
http://eretik.omegahg.com/art/1E.html
其实这两个函数定义在WDK8.1及以上的版本的WDM.H中,且也导出了,所以可直接使用。
本文就是关于这的测试代码。
made by correy
made at 2017.09.07
http://correy.webs.com
*/
#include <fltKernel.h>
PVOID g_CallbackHandle;
VOID PrintHex(_In_reads_bytes_(DataSize) PVOID Data, _In_ ULONG DataSize)
/*++
Routine Description:
This routine prints out the supplied data in hexadecimal form.
Arguments:
Data - Supplies a pointer to the data to be printed.
DataSize - Supplies the length in bytes of the data to be printed.
--*/
{
PCUCHAR Bytes;
ULONG Index;
for (Bytes = (PCUCHAR)Data, Index = 0; Index < DataSize; Index++)
{
if ((Index & 15) == 0)
{
KdPrint(("\r\n: "));
}
KdPrint(("%02x ", Bytes[Index]));
}
KdPrint(("\r\n"));
}
VOID MY_SE_IMAGE_VERIFICATION_CALLBACK_FUNCTION(_In_opt_ PVOID CallbackContext, _In_ SE_IMAGE_TYPE ImageType, _Inout_ PBDCB_IMAGE_INFORMATION ImageInformation)
/*
加载没有签名的驱动这里拦截不到。
估计这里的ImageType的值和传递给SeRegisterImageVerificationCallback的第一个参数的值一样。
*/
{
UNREFERENCED_PARAMETER(CallbackContext);
KdPrint((" ImageType = 0x%08x.\r\n", ImageType));
// Display the image name and any associated registry path.
KdPrint((" Image name \"%wZ\"\r\n", &ImageInformation->ImageName));
if (ImageInformation->RegistryPath.Buffer != NULL)
{
KdPrint((" Registry path \"%wZ\"\r\n", &ImageInformation->RegistryPath));
}
// Did this image fail Code Integrity checks?
if ((ImageInformation->ImageFlags & BDCB_IMAGEFLAGS_FAILED_CODE_INTEGRITY) != 0)
{
KdPrint((" FAILED Code Integrity checks but boot policy allowed it to be loaded.\r\n"));
}
// Display the image's hash.
if (ImageInformation->ImageHash != NULL && ImageInformation->ImageHashLength != 0)
{
KdPrint((" Image hash algorithm = 0x%08x.\r\n", ImageInformation->ImageHashAlgorithm));
KdPrint((" Image hash:"));
PrintHex(ImageInformation->ImageHash, ImageInformation->ImageHashLength);
}
// Display who signed the image (if at all).
if (ImageInformation->CertificatePublisher.Buffer != NULL)
{
KdPrint((" Image is signed by \"%wZ\".\r\n", &ImageInformation->CertificatePublisher));//重点是获取这个。
if (ImageInformation->CertificateIssuer.Buffer != NULL)
{
KdPrint((" Certificate issued by \"%wZ\".\r\n", &ImageInformation->CertificateIssuer));
}
if (ImageInformation->CertificateThumbprint != NULL && ImageInformation->CertificateThumbprintLength != 0)
{
KdPrint((" Certificate thumb print algorithm = 0x%08x.\r\n", ImageInformation->ThumbprintHashAlgorithm));
KdPrint((" Certificate thumb print:"));
PrintHex(ImageInformation->CertificateThumbprint, ImageInformation->CertificateThumbprintLength);
}
}
else
{
KdPrint((" Not signed.\r\n"));
}
KdPrint(("\r\n"));
}
extern "C" void DriverUnload(PDRIVER_OBJECT driver_object)
{
UNREFERENCED_PARAMETER(driver_object);
SeUnregisterImageVerificationCallback(g_CallbackHandle);
}
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver_object, PUNICODE_STRING registry_path)
{
UNREFERENCED_PARAMETER(registry_path);
PAGED_CODE();
__debugbreak();
driver_object->DriverUnload = DriverUnload;
NTSTATUS status = STATUS_SUCCESS;
#if (NTDDI_VERSION < NTDDI_WINBLUE)
return STATUS_UNSUCCESSFUL;
#endif
status = SeRegisterImageVerificationCallback(SeImageTypeDriver, SeImageVerificationCallbackInformational, MY_SE_IMAGE_VERIFICATION_CALLBACK_FUNCTION, NULL, NULL, &g_CallbackHandle);
return status;
}
没有评论:
发表评论