访问物理内存

本文介绍了一个用于访问特定物理内存区域(SMBIOS段)的驱动程序示例。该驱动能够读取从0xf0000到0xfffff地址范围内的64KB物理内存,并通过一个用户态应用程序演示了如何安装、启动驱动并获取这些内存段的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是一个驱动访问物理内存的小例子,但凡驱动都不可避免稳定性,

因此就尽量少在里面干其他事 :)

 

演示访问物理内存 0xf0000 ----0xfffff空间 64K的物理内存(其实是SMBIOS段)

 

MemQuery.h

#pragma once
#include 
"ntifs_ex.h"

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

//
// Define the various device type values.  Note that values used by Microsoft
// Corporation are in the range 0-0x7FFF(32767), and 0x8000(32768)-0xFFFF(65535)
// are reserved for use by customers.
//
#define FILE_DEVICE_MEMQUERY    0x8000

//
// Macro definition for defining IOCTL and FSCTL function control codes. Note
// that function codes 0-0x7FF(2047) are reserved for Microsoft Corporation,
// and 0x800(2048)-0xFFF(4095) are reserved for customers.
//
#define MEMQUERY_IOCTL_BASE    0x800

//
// The device driver IOCTLs
//

#define CTL_CODE_MEMQUERY(i) CTL_CODE(FILE_DEVICE_MEMQUERY, MEMQUERY_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_MEMQUERY_QUERYBIOS    CTL_CODE_MEMQUERY(0)

//
// Name that Win32 front end will use to open the MemQuery device
//

#define MEMQUERY_DEVICE_NAME_WIN32    "//./MemQuery"



#if DBG
#define dprintf DbgPrint
#else
#define dprintf
#endif

#define kprintf DbgPrint

#define NT_DEVICE_NAME    L"/Device/MemQuery"
#define DOS_DEVICE_NAME L"/DosDevices/MemQuery"

 

MemQuery.cpp

#include "MemQuery.h"

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

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

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

VOID MemQueryUnload(IN PDRIVER_OBJECT DriverObject);

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
    dprintf(
"MemQuery DriverEntry: %S ", RegistryPath->Buffer);

    UNICODE_STRING ntDeviceName;
    RtlInitUnicodeString(
&ntDeviceName, NT_DEVICE_NAME);
    PDEVICE_OBJECT DeviceObject 
= NULL;
    NTSTATUS ntStatus 
= IoCreateDevice(
        DriverObject,
        
sizeof(DEVICE_EXTENSION),
        
&ntDeviceName,
        FILE_DEVICE_MEMQUERY,
        
0,
        TRUE,
        
&DeviceObject
        );

    
if (!NT_SUCCESS(ntStatus))
    {
        dprintf(
"MemQuery IoCreateDevice=0x%x ", ntStatus);
        
return ntStatus;
    }

    PDEVICE_EXTENSION DeviceExtension 
= (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    UNICODE_STRING dosDeviceName;
    RtlInitUnicodeString(
&dosDeviceName, DOS_DEVICE_NAME);

    ntStatus 
= IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);

    
if (!NT_SUCCESS(ntStatus))
    {
        IoDeleteDevice(DeviceObject);
        
return ntStatus;
    }

    DriverObject
->MajorFunction[IRP_MJ_CREATE]         = MemQueryDispatchCreate;
    DriverObject
->MajorFunction[IRP_MJ_CLOSE]          = MemQueryDispatchClose;
    DriverObject
->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MemQueryDispatchDeviceControl;
    DriverObject
->DriverUnload                         = MemQueryUnload;

    
return ntStatus;
}

NTSTATUS MemQueryDispatchCreate(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    NTSTATUS ntStatus;
    Irp
->IoStatus.Status = STATUS_SUCCESS;
    Irp
->IoStatus.Information = 0;
    dprintf(
"MemQuery IRP_MJ_CREATE ");
    ntStatus 
= Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
return ntStatus;
}

NTSTATUS MemQueryDispatchClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    NTSTATUS ntStatus;
    Irp
->IoStatus.Status = STATUS_SUCCESS;
    Irp
->IoStatus.Information = 0;
    dprintf(
"MemQuery IRP_MJ_CLOSE ");
    ntStatus 
= Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
return ntStatus;
}

NTSTATUS MemQueryDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION IrpStack 
= IoGetCurrentIrpStackLocation(Irp);
    PDEVICE_EXTENSION DeviceExtension 
= (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
    PVOID lpInOutBuffer;
    ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;

    Irp
->IoStatus.Status = STATUS_SUCCESS;
    Irp
->IoStatus.Information = 0;

    lpInOutBuffer 
= Irp->AssociatedIrp.SystemBuffer;
    nInBufferSize 
= IrpStack->Parameters.DeviceIoControl.InputBufferLength;
    nOutBufferSize 
= IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    dprintf(
"MemQuery IRP_MJ_DEVICE_CONTROL ");

    dwIoControlCode 
= IrpStack->Parameters.DeviceIoControl.IoControlCode;

    
switch (dwIoControlCode)
    {
    
case IOCTL_MEMQUERY_QUERYBIOS:
        {
            
if(nOutBufferSize<64*1024)
            {
                Irp
->IoStatus.Status = STATUS_INVALID_PARAMETER;
                dprintf(
"nOutBufferSize<64*1024");
            }
            
else
            {
                PHYSICAL_ADDRESS paddr; 
                paddr.QuadPart 
= (__int64)0x000f0000
                PVOID maped 
= MmMapIoSpace(paddr, 64*1024, MmNonCached);
                dprintf(
"We start map io space,mapped addr is %p",maped);
                
if(maped!=NULL)
                {
                    READ_REGISTER_BUFFER_UCHAR((PUCHAR)maped, (PUCHAR)lpInOutBuffer, 
64*1024);
                    MmUnmapIoSpace(maped, 
64*1024);
                    Irp
->IoStatus.Information = 64*1024;
                }
                
else
                {
                    Irp
->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    dprintf(
"MmMapIoSpace return NULL");
                }
            }
            
break;
        }

    
default:
        Irp
->IoStatus.Status = STATUS_INVALID_PARAMETER;
        dprintf(
"MemQuery unknown IRP_MJ_DEVICE_CONTROL ");
        
break;
    }
    ntStatus 
= Irp->IoStatus.Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
return ntStatus;
}

VOID MemQueryUnload(IN PDRIVER_OBJECT DriverObject)
{
    UNICODE_STRING dosDeviceName;
    RtlInitUnicodeString(
&dosDeviceName, DOS_DEVICE_NAME);
    IoDeleteSymbolicLink(
&dosDeviceName);
    IoDeleteDevice(DriverObject
->DeviceObject);
    dprintf(
"MemQuery unloaded ");
}

 

下面的小程序演示如何调用这个驱动并获得目标段的数据:

 

#pragma once
#define WIN32_LEAN_AND_MEAN
#include 
<Windows.h>
#include 
<WinSvc.h>
#include 
<winioctl.h>
#include 
<stdlib.h>
#include 
<stdio.h>
#include 
<vector>
#define FILE_DEVICE_MEMQUERY    0x8000
using namespace std;
//
// Macro definition for defining IOCTL and FSCTL function control codes. Note
// that function codes 0-0x7FF(2047) are reserved for Microsoft Corporation,
// and 0x800(2048)-0xFFF(4095) are reserved for customers.
//
#define MEMQUERY_IOCTL_BASE    0x800

//
// The device driver IOCTLs
//

#define CTL_CODE_MEMQUERY(i) CTL_CODE(FILE_DEVICE_MEMQUERY, MEMQUERY_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_MEMQUERY_QUERYBIOS    CTL_CODE_MEMQUERY(0)


typedef 
struct _tagPhyMemStruct
{
    BYTE pBuf[
0x1001];

//    _tagPhyMemStruct()
//    {
//        memset( szBuf, 0 , 0x1001 );
//    };
}PHYMEM_STRUCT;

vector 
<PHYMEM_STRUCT*> vtPhymemItems;
class MemDriver
{
public:
    MemDriver(){_handle
=NULL;}
    
~MemDriver(){if(_handle!=NULL)CloseHandle(_handle);}
    
bool InstallAndStart();
    
bool UnInstall();
public:
    
bool OpenDriver();
    
void QueryBiosMemory();
private:
    HANDLE _handle;
};




#define DRIVERNAME "MemQuery"
#define DRIVERFILANAME "MemQuery.sys"

bool MemDriver::UnInstall()
{
    SC_HANDLE scmHandle
=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    
if(scmHandle!=0)
    {
        SC_HANDLE handle
=OpenService(scmHandle,DRIVERNAME,SERVICE_ALL_ACCESS);
        
if(handle!=0)
        {
            SERVICE_STATUS status;
            ControlService(handle,SERVICE_CONTROL_STOP,
&status);
            DeleteService(handle);
            CloseServiceHandle(handle);
        }
        CloseServiceHandle(scmHandle);
    }
    
return true;
}

bool MemDriver::InstallAndStart()
{
    
char systemDir[MAX_PATH];
    GetSystemDirectory(systemDir,MAX_PATH);
    strcat(systemDir,
"/drivers/");
    strcat(systemDir,DRIVERFILANAME);
    UnInstall();
    SetFileAttributes(systemDir,
0);
    DeleteFile(systemDir);
    
if(CopyFile("I:/BiosQuery/MemQuery/Debug/MemQuery.sys",systemDir,FALSE)==0)
        
return false;

    SC_HANDLE scmHandle
=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    
if(scmHandle==0)
        
return false;
    SC_HANDLE newDriver
=CreateService(scmHandle,DRIVERNAME,DRIVERNAME,SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_IGNORE,systemDir,NULL,NULL,NULL,NULL,NULL);
    
if(newDriver!=NULL)
    {
        
const char *args=NULL;
        StartService(newDriver,
0,&args);
        CloseServiceHandle(newDriver);
    }
    CloseServiceHandle(scmHandle);
    
return true;
}

bool MemDriver::OpenDriver()
{
    
char drvName[MAX_PATH];
    wsprintf(drvName,
"//./%s",DRIVERNAME);
    _handle
=CreateFile(drvName,GENERIC_ALL,0,NULL,OPEN_EXISTING,0,0);
    
if(_handle==INVALID_HANDLE_VALUE)
    {
        
return false;
    }
    
return true;
}

void MemDriver::QueryBiosMemory()
{
    
static char outbuf[64*1024];
    DWORD retLen
=sizeof(outbuf);
    memset(
&outbuf,0,sizeof(outbuf));

    
int inbuf=0;
    
if(!DeviceIoControl(_handle,IOCTL_MEMQUERY_QUERYBIOS,&inbuf,sizeof(inbuf),&outbuf,sizeof(outbuf),&retLen,NULL))
    {
        
//在这个数据里面
        return;
    } 
    
int j=1;

    PHYMEM_STRUCT 
*phyMem = new PHYMEM_STRUCT;


    BYTE  pTempBuf[
0x1000 + 1];
    
    memset( pTempBuf,
0,sizeof( pTempBuf ) );
    

    
for ( DWORD dwBase0 = 0xf0000; dwBase0 < 0xfffff; dwBase0 += 0x1000 )
    {
        DWORD dwLength 
= 0;

        memcpy(pTempBuf,
&outbuf[dwLength],0x1000);
        
        memset(phyMem
->pBuf,0,0x1001);

        memcpy(phyMem
->pBuf,pTempBuf,0x1000);

        vtPhymemItems.push_back(phyMem);

        dwLength 
+= 0x1000;
    }
    
    DWORD dwLength1 
= 0x1000;
    
for(int i = 0; i < ( dwLength1 - 4 ); ++i)
    {
        
if(strncmp((char*)&outbuf[i], "_SM_"4== 0 )
            MessageBox(NULL,
""" ",MB_OK);
    }
}

MemDriver gMemDriver;
int main(int argc,char *argv[])
{
    gMemDriver.UnInstall();
    gMemDriver.InstallAndStart();
    gMemDriver.OpenDriver();
    gMemDriver.QueryBiosMemory();
    gMemDriver.UnInstall();
    
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值