驱动开发入门相关资料url

 

WDK:
 http://www.cnblogs.com/fiestay/archive/2008/07/14/1242513.html
window2003 DDK download url:
 http://www.microsoft.com/whdc/devtools/ddk/default.mspx

one key build VC+DDK Project:
 http://hi.baidu.com/lengie/blog/item/0a1bd4393be0a1f33b87cecd.html
shom:
 http://blog.csdn.net/rageliu/archive/2006/06/21/817680.aspx
how to install .sys file:
 http://topic.csdn.net/u/20080312/08/be49627d-a264-4d68-9a51-2a60ba88b226.html
sample:FileMoon:
 http://www.sysinternals.com/

others:
 http://community.csdn.net/Expert/topic/4854/4854559.xml?temp=.9858209
 http://topic.csdn.net/t/20060701/22/4855007.html
hide file:
 #include <ntddk.h>

#define FILE_DEVICE_NTHIDEFILES    0x8000
#define NTHIDEFILES_IOCTL_BASE    0x800

#define CTL_CODE_NTHIDEFILES(i) CTL_CODE(FILE_DEVICE_NTHIDEFILES, NTHIDEFILES_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_NTHIDEFILES_HELLO    CTL_CODE_NTHIDEFILES(0)

#define NTHIDEFILES_DEVICE_NAME     L"\\Device\\NtHideFiles"
#define NTHIDEFILES_DOS_DEVICE_NAME L"\\DosDevices\\NtHideFiles"

#define dprintf if (DBG) DbgPrint
#define nprintf DbgPrint

typedef struct _DEVICE_EXTENSION
{
    ULONG StateVariable;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct _FILE_BOTH_DIR_INFORMATION
{
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

#pragma pack(1)
typedef struct _SERVICE_DESCRIPTOR_ENTRY
{
    unsigned int * ServiceTableBase;
    unsigned int * ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char * ParamTableBase;
} SERVICE_DESCRIPTOR_ENTRY, *PSERVICE_DESCRIPTOR_ENTRY;
#pragma pack()

// ZwQueryDirectoryFile 的原型
typedef NTSTATUS (NTAPI *PFN_ZwQueryDirectoryFile)(
    IN HANDLE hFile,
    IN HANDLE hEvent OPTIONAL,
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
    IN PVOID IoApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK pIoStatusBlock,
    OUT PVOID FileInformationBuffer,
    IN ULONG FileInformationBufferLength,
    IN FILE_INFORMATION_CLASS FileInfoClass,
    IN BOOLEAN bReturnOnlyOneEntry,
    IN PUNICODE_STRING PathMask OPTIONAL,
    IN BOOLEAN bRestartQuery);

NTSYSAPI
NTSTATUS
NTAPI
ZwQueryDirectoryFile(
    IN HANDLE hFile,
    IN HANDLE hEvent OPTIONAL,
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
    IN PVOID IoApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK pIoStatusBlock,
    OUT PVOID FileInformationBuffer,
    IN ULONG FileInformationBufferLength,
    IN FILE_INFORMATION_CLASS FileInfoClass,
    IN BOOLEAN bReturnOnlyOneEntry,
    IN PUNICODE_STRING PathMask OPTIONAL,
    IN BOOLEAN bRestartQuery);

NTSTATUS HookZwQueryDirectoryFile(
    IN HANDLE hFile,
    IN HANDLE hEvent OPTIONAL,
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
    IN PVOID IoApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK pIoStatusBlock,
    OUT PVOID FileInformationBuffer,
    IN ULONG FileInformationBufferLength,
    IN FILE_INFORMATION_CLASS FileInfoClass,
    IN BOOLEAN bReturnOnlyOneEntry,
    IN PUNICODE_STRING PathMask OPTIONAL,
    IN BOOLEAN bRestartQuery);

__declspec(dllimport) SERVICE_DESCRIPTOR_ENTRY KeServiceDescriptorTable;

// 保存原 ZwQueryDirectoryFile 函數指標
PFN_ZwQueryDirectoryFile OriginalZwQueryDirectoryFile = NULL;

PMDL g_pmdlSystemCall = NULL;
PVOID *MappedSystemCallTable = NULL;
BOOLEAN g_bHooked = FALSE;

#define SYSCALL_INDEX(_Function)              *(PULONG)((PUCHAR)_Function + 1)
#define SYSTEMSERVICE(_Function)              KeServiceDescriptorTable.ServiceTableBase[SYSCALL_INDEX(_Function)]
#define HOOK_SYSCALL(_Function, _Hook, _Orig) _Orig = (PVOID)InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Hook)
#define UNHOOK_SYSCALL(_Function, _Orig)      InterlockedExchange((PLONG)&MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG)_Orig)

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);
PCWSTR GetProcessFullName();

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, DispatchCreate)
#pragma alloc_text(PAGE, DispatchClose)
#pragma alloc_text(PAGE, DispatchDeviceControl)
#pragma alloc_text(PAGE, DriverUnload)
#endif // ALLOC_PRAGMA

#define BASE_PROCESS_PEB_OFFSET                   0x1B0
#define BASE_PEB_PROCESS_PARAMETER_OFFSET         0x010
#define BASE_PROCESS_PARAMETER_FULL_IMAGE_NAME    0x03C
#define W2003_BASE_PROCESS_PEB_OFFSET             0x190
#define W2003_BASE_PROCESS_PEB_OFFSET_SP1         0x1A0
#define W2003_BASE_PROCESS_PEB_OFFSET_SP2         W2003_BASE_PROCESS_PEB_OFFSET_SP1
#define VISTA_BASE_PROCESS_PEB_OFFSET             0x188

PCWSTR GetProcessFullName()
{
    NTSTATUS status    = -1;
    ULONG    dwAddress = 0;
    PCWSTR   lpszTemp  = NULL;
    RTL_OSVERSIONINFOEXW osVerInfo;

    dwAddress = (ULONG)PsGetCurrentProcess();
    if (dwAddress == 0 || dwAddress == (ULONG)-1)
        return NULL;

    RtlZeroMemory(&osVerInfo, sizeof(RTL_OSVERSIONINFOEXW));
    osVerInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);

    status = RtlGetVersion((PRTL_OSVERSIONINFOW)&osVerInfo);
    if (!NT_SUCCESS(status))
        return NULL;

    // 目前只支持 Windows 2000/XP/2003/Vista
    if (osVerInfo.dwMajorVersion < 5 || osVerInfo.dwMinorVersion > 2)
        return NULL;

    // 取得PEB,不同平臺的位置是不同的
    if (osVerInfo.dwMajorVersion == 5)
    {
        if (osVerInfo.dwMinorVersion < 2)    // 2000   0X0500       XP 0X0501
        {
            dwAddress += BASE_PROCESS_PEB_OFFSET;
        }
        else if (osVerInfo.dwMinorVersion == 2)    // 2003   0X0502
        {
            if (osVerInfo.wServicePackMajor == 0)    // No Service Pack
                dwAddress += W2003_BASE_PROCESS_PEB_OFFSET;
            else if (osVerInfo.wServicePackMajor < 3)    // Service Pack 1 & 2
                dwAddress += W2003_BASE_PROCESS_PEB_OFFSET_SP1;
        }
    }
    else    // Vista   0X0600
    {
        dwAddress += VISTA_BASE_PROCESS_PEB_OFFSET;
    }

    if ((dwAddress = *(PULONG)dwAddress) == 0)
        return NULL;

    // 通過PEB取得RTL_USER_PROCESS_PARAMETERS
    dwAddress += BASE_PEB_PROCESS_PARAMETER_OFFSET;
    if ((dwAddress = *(PULONG)dwAddress) == 0)
        return NULL;

    // 在RTL_USER_PROCESS_PARAMETERS->ImagePathName保存了路徑,偏移為0x038
    dwAddress += BASE_PROCESS_PARAMETER_FULL_IMAGE_NAME;
    if ((dwAddress = *(PULONG)dwAddress) == 0)
        return NULL;

    // [10/14/2006]
    lpszTemp = (PCWSTR)dwAddress;
    if (wcslen(lpszTemp) > 4)
    {
        if (lpszTemp[0] == L'\\' &&
            (lpszTemp[1] == L'?' || lpszTemp[1] == L'\\') &&
            lpszTemp[2] == L'?' &&
            lpszTemp[3] == L'\\')
        {
            dwAddress += 4 * sizeof(WCHAR);
        }
    }

    return (PCWSTR)dwAddress;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
    NTSTATUS       status = STATUS_SUCCESS;
    UNICODE_STRING ntDeviceName;
    UNICODE_STRING dosDeviceName;
    PDEVICE_OBJECT deviceObject = NULL;
    BOOLEAN        fSymbolicLink = FALSE;

    dprintf("[NtHideFiles] DriverEntry: %wZ\n", RegistryPath);

    RtlInitUnicodeString(&ntDeviceName, NTHIDEFILES_DEVICE_NAME);

    status = IoCreateDevice(
        DriverObject,
        sizeof(DEVICE_EXTENSION),    // DeviceExtensionSize
        &ntDeviceName,                // DeviceName
        FILE_DEVICE_NTHIDEFILES,    // DeviceType
        0,                            // DeviceCharacteristics
        TRUE,                        // Exclusive
        &deviceObject                // [OUT]
        );

    if (!NT_SUCCESS(status))
        goto __failed;

    RtlInitUnicodeString(&dosDeviceName, NTHIDEFILES_DOS_DEVICE_NAME);

    status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);

    if (!NT_SUCCESS(status))
        goto __failed;

    fSymbolicLink = TRUE;

    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DispatchClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
    DriverObject->DriverUnload                         = DriverUnload;

    // Map the memory into our domain to change the permissions on the MDL
    g_pmdlSystemCall = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase,
        KeServiceDescriptorTable.NumberOfServices * 4,
        FALSE, FALSE, NULL);

    if (g_pmdlSystemCall == NULL)
    {
        status = STATUS_UNSUCCESSFUL;
        goto __failed;
    }

    MmBuildMdlForNonPagedPool(g_pmdlSystemCall);
    // Change the flags of the MDL
    g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
    MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode);

    // HOOK ZwQueryDirectoryFile 並保存原 ZwQueryDirectoryFile 函數位址
    HOOK_SYSCALL(ZwQueryDirectoryFile, HookZwQueryDirectoryFile, OriginalZwQueryDirectoryFile);
    g_bHooked = TRUE;

    if (NT_SUCCESS(status))
        return status;

__failed:

    if (fSymbolicLink)
        IoDeleteSymbolicLink(&dosDeviceName);

    if (deviceObject)
        IoDeleteDevice(deviceObject);

    return status;
}

NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS status = STATUS_SUCCESS;

    Irp->IoStatus.Information = 0;

    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}

NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS status = STATUS_SUCCESS;

    Irp->IoStatus.Information = 0;

    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return status;
}

NTSTATUS DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS           status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpStack;
    PVOID              ioBuf;
    ULONG              inBufLength, outBufLength;
    ULONG              ioControlCode;

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    Irp->IoStatus.Information = 0;

    //
    // Get the pointer to the input/output buffer and it's length
    //

    ioBuf = Irp->AssociatedIrp.SystemBuffer;
    inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

    switch (ioControlCode)
    {
    case IOCTL_NTHIDEFILES_HELLO:
        break;
    default:
        status = STATUS_INVALID_PARAMETER;
        break;
    }

    //
    // DON'T get cute and try to use the status field of
    // the irp in the return status.  That IRP IS GONE as
    // soon as you call IoCompleteRequest.
    //

    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    //
    // We never have pending operation so always return the status code.
    //

    return status;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING dosDeviceName;

    // UnHook ZwQueryDirectoryFile
    if (g_bHooked && OriginalZwQueryDirectoryFile != NULL)
        UNHOOK_SYSCALL(ZwQueryDirectoryFile, OriginalZwQueryDirectoryFile);

    if (g_pmdlSystemCall != NULL)
    {
        MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
        IoFreeMdl(g_pmdlSystemCall);
    }

    //
    // Delete the symbolic link
    //

    RtlInitUnicodeString(&dosDeviceName, NTHIDEFILES_DOS_DEVICE_NAME);

    IoDeleteSymbolicLink(&dosDeviceName);

    //
    // Delete the device object
    //

    IoDeleteDevice(DriverObject->DeviceObject);

    dprintf("[NtHideFiles] unloaded\n");
}

NTSTATUS HookZwQueryDirectoryFile(
    IN HANDLE hFile,
    IN HANDLE hEvent OPTIONAL,
    IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
    IN PVOID IoApcContext OPTIONAL,
    OUT PIO_STATUS_BLOCK pIoStatusBlock,
    OUT PVOID FileInformationBuffer,
    IN ULONG FileInformationBufferLength,
    IN FILE_INFORMATION_CLASS FileInfoClass,
    IN BOOLEAN bReturnOnlyOneEntry,
    IN PUNICODE_STRING PathMask OPTIONAL,
    IN BOOLEAN bRestartQuery)
{
    NTSTATUS rc = STATUS_SUCCESS;
    ANSI_STRING ansiFileName, ansiDirName, HideDirFile;
    UNICODE_STRING uniFileName;
    PCWSTR pProcPath = NULL;

    // 初始化要過慮的檔案名,大寫形式
    RtlInitAnsiString(&HideDirFile, "WAR3.EXE");

    pProcPath = GetProcessFullName();
    DbgPrint("[NtHideFiles] GetProcessFullName: %ws\n", pProcPath == NULL ? L"<null>" : pProcPath);

    // 執行真正的 ZwQueryDirectoryFile 函數
    rc = OriginalZwQueryDirectoryFile(
        hFile,
        hEvent,
        IoApcRoutine,
        IoApcContext,
        pIoStatusBlock,
        FileInformationBuffer,
        FileInformationBufferLength,
        FileInfoClass,
        bReturnOnlyOneEntry,
        PathMask,
        bRestartQuery);

    // 如果執行成功,而且 FILE_INFORMATION_CLASS 的值為 FileBothDirectoryInformation,我們就進行處理,過濾
    if (NT_SUCCESS(rc) && FileInfoClass == FileBothDirectoryInformation)
    {
        // 把執行結果賦給 pFileInfo
        PFILE_BOTH_DIR_INFORMATION pFileInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer;
        PFILE_BOTH_DIR_INFORMATION pLastFileInfo = NULL;
        BOOLEAN bLastOne = FALSE;
       
        // 迴圈檢查
        do
        {
            bLastOne = !pFileInfo->NextEntryOffset;
            RtlInitUnicodeString(&uniFileName, pFileInfo->FileName);
            RtlUnicodeStringToAnsiString(&ansiFileName, &uniFileName, TRUE);
            RtlUnicodeStringToAnsiString(&ansiDirName, &uniFileName, TRUE);
            RtlUpperString(&ansiFileName, &ansiDirName);
           
            // 列印結果,用 debugview 可以查看列印結果
            //dprintf("ansiFileName :%s\n", ansiFileName.Buffer);
            //dprintf("HideDirFile :%s\n", HideDirFile.Buffer);
           
            // 開始進行比較,如果找到了就隱藏這個檔或者目錄
            if (RtlCompareMemory(ansiFileName.Buffer, HideDirFile.Buffer, HideDirFile.Length) == HideDirFile.Length)
            {
                dprintf("This is HideDirFile!\n");

                if (bLastOne)
                {
                    if (pFileInfo == (PFILE_BOTH_DIR_INFORMATION)FileInformationBuffer)
                        rc = STATUS_NO_MORE_FILES;    // 隱藏檔或者目錄;
                    else
                        pLastFileInfo->NextEntryOffset = 0;

                    break;
                }
                else    // 指標往後移動
                {
                    int iPos = (ULONG)pFileInfo - (ULONG)FileInformationBuffer;
                    int iLeft = (ULONG)FileInformationBufferLength - iPos - pFileInfo->NextEntryOffset;
                    RtlCopyMemory((PVOID)pFileInfo, (PVOID)((PCHAR)pFileInfo + pFileInfo->NextEntryOffset), (ULONG)iLeft);
                    continue;
                }
            }
           
            pLastFileInfo = pFileInfo;
            pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((PCHAR)pFileInfo + pFileInfo->NextEntryOffset);
        } while (!bLastOne);
       
        RtlFreeAnsiString(&ansiDirName);
        RtlFreeAnsiString(&ansiFileName);
    }

    return rc;
}

 

posted @ 2009-06-05 11:16  死循环  阅读(626)  评论(0编辑  收藏  举报