Windows では、NativeAPI 呼び出しNtOpenSectionおよびNtMapViewOfSectionを使用する必要があります。
マーク・ルシノビッチの例
static BOOLEAN MapPhysicalMemory( HANDLE PhysicalMemory,
PDWORD Address, PDWORD Length,
PDWORD VirtualAddress )
{
NTSTATUS ntStatus;
PHYSICAL_ADDRESS viewBase;
char error[256];
*VirtualAddress = 0;
viewBase.QuadPart = (ULONGLONG) (*Address);
ntStatus = NtMapViewOfSection (PhysicalMemory,
(HANDLE) -1,
(PVOID) VirtualAddress,
0L,
*Length,
&viewBase,
Length,
ViewShare,
0,
PAGE_READONLY );
if( !NT_SUCCESS( ntStatus )) {
sprintf_s( error, "Could not map view of %X length %X",
*Address, *Length );
PrintError( error, ntStatus );
return FALSE;
}
*Address = viewBase.LowPart;
return TRUE;
}
static HANDLE OpenPhysicalMemory()
{
NTSTATUS status;
HANDLE physmem;
UNICODE_STRING physmemString;
OBJECT_ATTRIBUTES attributes;
WCHAR physmemName[] = L"\\device\\physicalmemory";
RtlInitUnicodeString( &physmemString, physmemName );
InitializeObjectAttributes( &attributes, &physmemString,
OBJ_CASE_INSENSITIVE, NULL, NULL );
status = NtOpenSection( &physmem, SECTION_MAP_READ, &attributes );
if( !NT_SUCCESS( status )) {
PrintError( "Could not open \\device\\physicalmemory", status );
return NULL;
}
return physmem;
}
\device\physicalmemory
/dev/mem
物理メモリに直接アクセスする可能性もある Linuxの類似物です。ところで、Windows についてはわかりませんが、Linux では、BIOS テーブルなどのサービスの低レベル データが含まれている可能性があるため、1 Mb の物理アドレス空間しか利用できません。他の物理メモリへのアクセスは、OS によって管理されている仮想メモリを破損する可能性があるため、許可されていません。
更新: 提供されたコードは、Windows Vista 以降のユーザー モードでは機能しません。代わりに、GetSystemFirmwareTable() を呼び出して、検索せずに生メモリの最初の MB から有用な情報を取得できます。
ボーナス:クラスの一部であるBoost IOメモリマップファイルを使用して、Linux(Debian 9)で物理メモリを読み取る:
NativePhysicalMemory::NativePhysicalMemory(size_t base, size_t length)
: physical_memory_map_(std::make_unique<boost::iostreams::mapped_file_source>())
{
map_physical_memory(base, length);
}
// ...
void NativePhysicalMemory::map_physical_memory(size_t base, size_t length)
{
#ifdef _SC_PAGESIZE
size_t mempry_page_offset = base % sysconf(_SC_PAGESIZE);
#else
size_t mempry_page_offset = base % getpagesize();
#endif /* _SC_PAGESIZE */
boost_io::mapped_file_params params = {};
params.path = "/dev/mem";
params.flags = boost_io::mapped_file::mapmode::readonly;
params.length = length + mempry_page_offset;
params.offset = base - mempry_page_offset;
params.hint = nullptr;
physical_memory_map_->open(params);
}