欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]驱动伪造卷序列号

[原创]驱动伪造卷序列号

驱动伪造卷序列号
卷序列号指:
S:\>dir
驱动器 S 中的卷是 RAMDISK
卷的序列号是 FA32-4148
S:\ 的目录
2016-08-21  15:33    <DIR>          TEMP
               0 个文件              0 字节
               1 个目录    396,854,272 可用字节
获取卷序列号:
https://msdn.microsoft.com/zh-cn/library/windows/desktop/aa364993(v=vs.85).aspx
BOOL WINAPI GetVolumeInformation(
  _In_opt_  LPCTSTR lpRootPathName,
  _Out_opt_ LPTSTR  lpVolumeNameBuffer,
  _In_      DWORD   nVolumeNameSize,
  _Out_opt_ LPDWORD lpVolumeSerialNumber,
  _Out_opt_ LPDWORD lpMaximumComponentLength,
  _Out_opt_ LPDWORD lpFileSystemFlags,
  _Out_opt_ LPTSTR  lpFileSystemNameBuffer,
  _In_      DWORD   nFileSystemNameSize
);
IDA -> Kernel32.dll!GetVolumeInformationW()
         NtQueryVolumeInformationFile(FileHandle, &IoStatusBlock, Buf, BufSize, FileFsVolumeInformation)
    -> Ntdll.dll!NtQueryVolumeInformationFile()
.text:7C92D970 _NtQueryVolumeInformationFile@20 proc near
.text:7C92D970                 mov     eax, 0B3h
.text:7C92D975                 mov     edx, 7FFE0300h
.text:7C92D97A                 call    dword ptr [edx]
.text:7C92D97C                 retn    14h
.text:7C92D97C _NtQueryVolumeInformationFile@20 endp
IDA -> Ntoskrnl.exe!NtQueryVolumeInformationFile()
    PIRP pIrp = IoAllocateIrp(v15->StackSize, 1u);
    PIO_STACK_LOCATION IrpSp =
        (PIO_STACK_LOCATION)(pIrp->Tail.Overlay.PacketType - 36);
    IrpSp->MajorFunction = 0xA;    // IRP_MJ_QUERY_VOLUME_INFORMATION
    // IrpSp->Parameters.Create.Options 实际就是(参考 _IO_STACK_LOCATION 定义)
    // IrpSp->Parameters.QueryVolume.FsInformationClass
    IrpSp->Parameters.Create.Options = VolumeInformationClass;
   
然后手写GetVolumeInformation(),内核调试跟一下;
懒人靠运气,笔者发现硬盘某分区躺着个cntfs,来自于NT4源码;
看IRP_MJ_QUERY_VOLUME_INFORMATION的处理函数,最后发现:
Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
也就是卷序列号最终是由文件系统驱动赋值的;
WDK里有FAT32的驱动源码FASTFAT,也是它赋值的;
再测一下win7x64系统,数据结构也兼容;
done! 码如下:
ps1 : 伪造序列号的话,把那个值改掉就行,可以用RtlRandomEx()生成;
ps2 : C语言习惯了,说每句话后面也是分号。。;
#include <ntddk.h>
extern POBJECT_TYPE *IoDriverObjectType;
NTKERNELAPI
NTSTATUS
ObReferenceObjectByName(
                        IN PUNICODE_STRING ObjectName,
                        IN ULONG Attributes,
                        IN PACCESS_STATE PassedAccessState OPTIONAL,
                        IN ACCESS_MASK DesiredAccess OPTIONAL,
                        IN POBJECT_TYPE ObjectType,
                        IN KPROCESSOR_MODE AccessMode,
                        IN OUT PVOID ParseContext OPTIONAL,
                        OUT PVOID *Object
                        );
PDRIVER_DISPATCH g_NTFSQueryVolume;
PDRIVER_DISPATCH g_FATQueryVolume;
NTSTATUS NTFSQueryVolume(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
    NTSTATUS status;
   
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(pIrp);
    if (IrpSp->Parameters.QueryVolume.FsInformationClass == FileFsVolumeInformation)
    {
        PFILE_FS_VOLUME_INFORMATION p =
            (PFILE_FS_VOLUME_INFORMATION)pIrp->AssociatedIrp.SystemBuffer;
        status = g_NTFSQueryVolume(pDeviceObject, pIrp);
        if (NT_SUCCESS(status))
        {
            KdPrint(("NTFS volume : %X\n", p->VolumeSerialNumber));
        }
    }
    else
        status = g_NTFSQueryVolume(pDeviceObject, pIrp);
    return status;
}
NTSTATUS hook_NTFSQueryVolume(PUNICODE_STRING pDrvName, BOOLEAN bHook)
{
    NTSTATUS status;
    PDRIVER_OBJECT realDriverObject;
    status = ObReferenceObjectByName(pDrvName, OBJ_CASE_INSENSITIVE, NULL, 0,
        *IoDriverObjectType, KernelMode, NULL, &realDriverObject);
    if (NT_SUCCESS(status))
    {
        if (bHook)
        {
            g_NTFSQueryVolume = realDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION];
            realDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = NTFSQueryVolume;
        }
        else
        {
            if (g_NTFSQueryVolume)
                realDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = g_NTFSQueryVolume;
        }
        ObDereferenceObject(realDriverObject);
    }
    return status;
}
NTSTATUS FATQueryVolume(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
    NTSTATUS status;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(pIrp);
    if (IrpSp->Parameters.QueryVolume.FsInformationClass == FileFsVolumeInformation)
    {
        PFILE_FS_VOLUME_INFORMATION p =
            (PFILE_FS_VOLUME_INFORMATION)pIrp->AssociatedIrp.SystemBuffer;
        status = g_FATQueryVolume(pDeviceObject, pIrp);
        if (NT_SUCCESS(status))
        {
            KdPrint(("FAT volume : %X\n", p->VolumeSerialNumber));
        }
    }
    else
        status = g_FATQueryVolume(pDeviceObject, pIrp);
    return status;
}
NTSTATUS hook_FATQueryVolume(PUNICODE_STRING pDrvName, BOOLEAN bHook)
{
    NTSTATUS status;
    PDRIVER_OBJECT realDriverObject;
    status = ObReferenceObjectByName(pDrvName, OBJ_CASE_INSENSITIVE, NULL, 0,
        *IoDriverObjectType, KernelMode, NULL, &realDriverObject);
    if (NT_SUCCESS(status))
    {
        if (bHook)
        {
            g_FATQueryVolume = realDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION];
            realDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = FATQueryVolume;
        }
        else
        {
            if (g_FATQueryVolume)
                realDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = g_FATQueryVolume;
        }
        ObDereferenceObject(realDriverObject);
    }
    return status;
}
NTSTATUS init_volume_driver_hook()
{
    NTSTATUS status;
    UNICODE_STRING drv_name;
    RtlInitUnicodeString(&drv_name, L"\\FileSystem\\Ntfs");
    status = hook_NTFSQueryVolume(&drv_name, TRUE);
    RtlInitUnicodeString(&drv_name, L"\\FileSystem\\Fastfat");
    status = hook_FATQueryVolume(&drv_name, TRUE);
    return status;
}
VOID uninit_volume_driver_hook()
{
    UNICODE_STRING drv_name;
    RtlInitUnicodeString(&drv_name, L"\\FileSystem\\Ntfs");
    hook_NTFSQueryVolume(&drv_name, FALSE);
    RtlInitUnicodeString(&drv_name, L"\\FileSystem\\Fastfat");
    hook_FATQueryVolume(&drv_name, FALSE);
}
VOID Unload(PDRIVER_OBJECT DriverObject)
{
    uninit_volume_driver_hook();
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath)
{
    init_volume_driver_hook();
    DriverObject->DriverUnload = Unload;
    return STATUS_SUCCESS;
}

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功