⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osinfo.c

📁 驱动编程学习代码
💻 C
📖 第 1 页 / 共 3 页
字号:



#include <ntddk.h>          // various NT definitions
#include <ntimage.h>
#include <string.h>
#include <stdio.h>

#include "OSInfo.h"





//#pragma comment(lib,"ntdll.lib")

//__declspec(dllimport)
__declspec(dllimport) SERVICE_DESCRIPTOR_TABLE  KeServiceDescriptorTable;
//__declspec(dllimport) ZWQUERYSYSTEMINFORMATION  ZwQuerySystemInformation;
//
// Device driver routine declarations.
//

NTSTATUS ZwQuerySystemInformation(
                                    ULONG SystemInformationCLass,
                                    PVOID SystemInformation,
                                    ULONG SystemInformationLength,
                                    PULONG ReturnLength
                                  );

NTSTATUS ZwOpenDirectoryObject (
                                    OUT PHANDLE DirectoryHandle,
                                    IN ACCESS_MASK DesiredAccess,
                                    IN POBJECT_ATTRIBUTES ObjectAttributes
                               );


NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT   DriverObject,
                     IN PUNICODE_STRING      RegistryPath);

NTSTATUS OSInfoCreateClose(IN PDEVICE_OBJECT       DeviceObject,
                           IN PIRP                 Irp);

NTSTATUS OSInfoDeviceControl(IN PDEVICE_OBJECT       DeviceObject,
                             IN PIRP                 Irp);

VOID     OSInfoUnloadDriver(IN PDRIVER_OBJECT       DriverObject);

PMODULE_LIST GetListOfModules(PNTSTATUS pns);

NTSTATUS GetNtOsKrlInfo();

ULONG    GetServiceAddr(ULONG ulServiceID);

void     GetSSDTTable(PULONG outBuf);

void     IdentifySSDTHooks(PCHAR outBuf);

NTSTATUS GetServiceNames(PCHAR outBuf, ULONG ulBufLen);

NTSTATUS GetServiceNamesFromKernal(PCHAR outBuf, ULONG ulBufLen);

NTSTATUS IoCompletionRoutine(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp,IN PVOID pContext);
VOID     WorkItem_GetNT (IN PDEVICE_OBJECT  pDeviceObject,IN PVOID  pContext );
VOID     DelayThread(IN PVOID pStartContext);

#ifdef ALLOC_PRAGMA
#pragma alloc_text( INIT, DriverEntry )
#pragma alloc_text( PAGE, OSInfoCreateClose)
#pragma alloc_text( PAGE, OSInfoDeviceControl)
#pragma alloc_text( PAGE, OSInfoUnloadDriver)
#pragma alloc_text( PAGE, GetListOfModules)
#pragma alloc_text( PAGE, GetNtOsKrlInfo)
#pragma alloc_text( PAGE, GetServiceAddr)
#pragma alloc_text( PAGE, GetSSDTTable)
#pragma alloc_text( PAGE, IdentifySSDTHooks)
#pragma alloc_text( PAGE, GetServiceNames)
#pragma alloc_text( PAGE, GetServiceNamesFromKernal)

#endif // ALLOC_PRAGMA


PMODULE_LIST    g_pModuleList;
NTOSKRNL        g_ntoskrnl;
PIO_WORKITEM    g_pWorkItem = NULL;
//IRP             g_Irp;


NTSTATUS DriverEntry(IN OUT PDRIVER_OBJECT   DriverObject,
                     IN PUNICODE_STRING      RegistryPath)
{
    NTSTATUS        ntStatus;
    UNICODE_STRING  ntUnicodeString;    
    UNICODE_STRING  ntWin32NameString;    
    PDEVICE_OBJECT  deviceObject = NULL;    // ptr to device object
    
    RtlInitUnicodeString( &ntUnicodeString, NT_DEVICE_NAME );
    
    ntStatus = IoCreateDevice( DriverObject,                   // Our Driver Object
                               0,                              // We don't use a device extension
                               &ntUnicodeString,               // Device name 
                               FILE_DEVICE_UNKNOWN,            // Device type
                               FILE_DEVICE_SECURE_OPEN,        // Device characteristics
                               FALSE,                          // Not an exclusive device
                               &deviceObject );                // Returned ptr to Device Object

    if ( !NT_SUCCESS( ntStatus ) )
    {
        OSINFO_KDPRINT(("Couldn't create the device object\n"));
        return ntStatus;
    }
    
    //
    // Initialize the driver object with this driver's entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]          = OSInfoCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = OSInfoCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = OSInfoDeviceControl;
    DriverObject->DriverUnload                          = OSInfoUnloadDriver;
   
    //
    // Initialize a Unicode String containing the Win32 name
    // for our device.
    //

    RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );

    //
    // Create a symbolic link between our device name  and the Win32 name 
    //

    ntStatus = IoCreateSymbolicLink(&ntWin32NameString, &ntUnicodeString );

    if ( !NT_SUCCESS( ntStatus ) )
    {
        //
        // Delete everything that this routine has allocated.
        //
        OSINFO_KDPRINT(("Couldn't create symbolic link\n"));
        IoDeleteDevice( deviceObject );
    }

    
	
    

    GetNtOsKrlInfo();

    return ntStatus;
}


NTSTATUS OSInfoCreateClose(IN PDEVICE_OBJECT DeviceObject,
                           IN PIRP Irp)
{
    Irp->IoStatus.Status        = STATUS_SUCCESS;
    Irp->IoStatus.Information   = 0;
    
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    
    return STATUS_SUCCESS;
}

VOID OSInfoUnloadDriver(IN PDRIVER_OBJECT DriverObject )
{
    PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
    UNICODE_STRING uniWin32NameString;

    //
    // Create counted string version of our Win32 device name.
    // Delete the link from our device name to a name in the Win32 namespace.

    RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );

    IoDeleteSymbolicLink( &uniWin32NameString );

    if(g_pWorkItem)
        IoFreeWorkItem(g_pWorkItem);   
    
    if ( deviceObject != NULL )
    {
        IoDeleteDevice( deviceObject );
    }
}








////////////////////////////////////////////////////////////////////

// PMODULE_LIST GetListOfModules

// Parameters:

//     IN PNTSTATUS pointer to NTSTATUS variable. This is useful for debugging.

// Returns:

//     OUT PMODULE_LIST     pointer to MODULE_LIST



PMODULE_LIST GetListOfModules(PNTSTATUS pns)

{
    ULONG           ul_NeededSize;
    ULONG       *   pul_ModuleListAddress = NULL;
    NTSTATUS        ns;
    PMODULE_LIST    pml                   = NULL;

    // Call it the first time to determine the size required
    // to store the information.

    ZwQuerySystemInformation(SystemModuleInformation,
                             &ul_NeededSize,
                             0,
                             &ul_NeededSize);

    pul_ModuleListAddress = (ULONG *) ExAllocatePool(PagedPool, ul_NeededSize);

    if (!pul_ModuleListAddress) // ExAllocatePool failed.
    {
        if (pns != NULL)
            *pns = STATUS_INSUFFICIENT_RESOURCES;

        return NULL;
    }



    ns = ZwQuerySystemInformation(SystemModuleInformation,
                                  pul_ModuleListAddress,
                                  ul_NeededSize,
                                  0);

    if (ns != STATUS_SUCCESS)// ZwQuerySystemInformation failed.
    {
        // Free allocated paged kernel memory.
        ExFreePool((PVOID) pul_ModuleListAddress);
        if (pns != NULL)
           *pns = ns;

        return NULL;
    }

    pml = (PMODULE_LIST) pul_ModuleListAddress;

    if (pns != NULL)
       *pns = ns;

    return pml;
}


NTSTATUS GetNtOsKrlInfo()
{
    NTSTATUS    ns ;
    BYTE    *   abName = NULL;

    g_pModuleList = NULL;

    g_ntoskrnl.ulBaseAddr = 0;
    g_ntoskrnl.ulEndAddr  = 0;

    g_pModuleList = GetListOfModules(&ns);

    if (!g_pModuleList)
    {
        return STATUS_UNSUCCESSFUL;
    }

    g_ntoskrnl.ulSrvNum = KeServiceDescriptorTable.NumberOfService;
        

    // Find the entry for ntoskrnl.exe.
    abName = g_pModuleList->a_Modules[0].a_bPath + g_pModuleList->a_Modules[0].w_NameOffset;

    g_ntoskrnl.ulBaseAddr = (DWORD)g_pModuleList->a_Modules[0].p_Base;
    g_ntoskrnl.ulEndAddr  = (DWORD)g_pModuleList->a_Modules[0].p_Base + g_pModuleList->a_Modules[0].d_Size;
    strcpy(g_ntoskrnl.a_bName , abName);
    
    ExFreePool(g_pModuleList);

    
    if (g_ntoskrnl.ulBaseAddr != 0)
        return STATUS_SUCCESS;
    else
        return STATUS_UNSUCCESSFUL;
}


NTSTATUS GetServiceNames(PCHAR outBuf, ULONG ulBufLen)
{
    NTSTATUS                ns ;
    BYTE    *               abName      = NULL;
    ULONG                   i           = 0;
    ULONG                   j           = 0;
    DWORD                   dwOffset    = 0;
    PIMAGE_EXPORT_DIRECTORY pExpDir     = NULL;
    ULONG                   nNameCnt    = 0;
    DWORD   *               pNameArray  = NULL;
    ULONG                   hNtdll      = 0;
    DWORD   *               pFuncArray  = NULL;
    VOID    *               pFunc       = NULL;
    PCSTR                   pszName     = NULL;
    WORD    *               pOrdNameArray = NULL;
    SSDTENTRY *             pSSDTEntry  = NULL;

    if(ulBufLen < g_ntoskrnl.ulSrvNum * sizeof(SERVICENAME))
    {
        return STATUS_UNSUCCESSFUL;
    }

    g_pModuleList = NULL;

    g_pModuleList = GetListOfModules(&ns);

    if (!g_pModuleList)
    {
        return STATUS_UNSUCCESSFUL;
    }

    for(i = 0; i < g_pModuleList->d_Modules; i++)
    {
        abName = g_pModuleList->a_Modules[i].a_bPath + g_pModuleList->a_Modules[i].w_NameOffset;
        if(_stricmp("ntdll.dll", abName) == 0)
        {
            hNtdll = (ULONG)g_pModuleList->a_Modules[i].p_Base;
            break;
        }
    }

    dwOffset  = hNtdll;
    // PE header
    dwOffset += ((PIMAGE_DOS_HEADER)hNtdll)->e_lfanew + sizeof( DWORD );
    // DATA_DIRECTORY
    dwOffset += sizeof( IMAGE_FILE_HEADER ) + sizeof( IMAGE_OPTIONAL_HEADER ) - IMAGE_NUMBEROF_DIRECTORY_ENTRIES * sizeof( IMAGE_DATA_DIRECTORY );
    // EXPORT_DIRECTORY
    dwOffset = hNtdll + ((PIMAGE_DATA_DIRECTORY)dwOffset)->VirtualAddress;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -