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

📄 physmem.c

📁 可查看计算机物理内存包括BIOS数据的源码!
💻 C
字号:
//========================================================
//
// Physmem
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//
// This program demonstrates how you can open and
// map physical memory. This is essentially the NT 
// equivalent of the \dev\kmem device in UNIX.
//
//========================================================
#include <windows.h>
#include <stdio.h>
#include "native.h"

//
// Number of bytes to print per line
//
#define BYTESPERLINE	16

//
// Lines to print before pause
//
#define LINESPERSCREEN	25


//
// Functions in NTDLL that we dynamically locate
//

NTSTATUS (__stdcall *NtUnmapViewOfSection)(
		IN HANDLE  ProcessHandle,
		IN PVOID  BaseAddress
		);

NTSTATUS (__stdcall *NtOpenSection)(
		OUT PHANDLE  SectionHandle,
		IN ACCESS_MASK  DesiredAccess,
		IN POBJECT_ATTRIBUTES  ObjectAttributes
		);

NTSTATUS (__stdcall *NtMapViewOfSection)(
		IN HANDLE  SectionHandle,
		IN HANDLE  ProcessHandle,
		IN OUT PVOID  *BaseAddress,
		IN ULONG  ZeroBits,
		IN ULONG  CommitSize,
		IN OUT PLARGE_INTEGER  SectionOffset,	/* optional */
		IN OUT PULONG  ViewSize,
		IN SECTION_INHERIT  InheritDisposition,
		IN ULONG  AllocationType,
		IN ULONG  Protect
		);

VOID (__stdcall *RtlInitUnicodeString)(
		IN OUT PUNICODE_STRING  DestinationString,
		IN PCWSTR  SourceString
		);

ULONG (__stdcall *RtlNtStatusToDosError) (
		IN NTSTATUS Status
		);

NTSTATUS (__stdcall *ZwOpenSection)(
	PHANDLE SectionHandle,
    DWORD DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes
);
/*
typedef NTSTATUS (WINAPI *ZwOpenSectionProc)
(
    PHANDLE SectionHandle,
    DWORD DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes
);
*/
typedef NTSTATUS (WINAPI *ZwMapViewOfSectionProc)
(
    HANDLE SectionHandle,
    HANDLE ProcessHandle,
    PVOID *BaseAddress,
    ULONG ZeroBits,
    ULONG CommitSize,
    PLARGE_INTEGER SectionOffset,
    PULONG ViewSize,
    SECTION_INHERIT InheritDisposition,
    ULONG AllocationType,
    ULONG Protect
);
typedef NTSTATUS (WINAPI *ZwUnmapViewOfSectionProc)
(
    HANDLE ProcessHandle,
    PVOID BaseAddress
);
typedef VOID (WINAPI *RtlInitUnicodeStringProc)
(
    IN OUT PUNICODE_STRING DestinationString,
    IN PCWSTR SourceString
);

//----------------------------------------------------------------------
//
// PrintError
//
// Formats an error message for the last error
//
//----------------------------------------------------------------------
void PrintError( char *message, NTSTATUS status )
{
	char *errMsg;

	FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
			NULL, RtlNtStatusToDosError( status ), 
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
			(LPTSTR) &errMsg, 0, NULL );
	printf("%s: %s\n", message, errMsg );
	LocalFree( errMsg );
}


//--------------------------------------------------------
//
// UnmapPhysicalMemory
//
// Maps a view of a section.
//
//--------------------------------------------------------
VOID UnmapPhysicalMemory( DWORD Address )
{
	NTSTATUS		status;

	status = NtUnmapViewOfSection( (HANDLE) -1, (PVOID) Address );
	if( !NT_SUCCESS(status)) {

		PrintError("Unable to unmap view", status );
	}
}


//--------------------------------------------------------
//
// MapPhysicalMemory
//
// Maps a view of a section.
//
//--------------------------------------------------------
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 );
							   //PAGE_READWRITE);

	if( !NT_SUCCESS( ntStatus )) {

		sprintf( error, "Could not map view of %X length %X",
				*Address, *Length );
		PrintError( error, ntStatus );
		return FALSE;					
	}

	*Address = viewBase.LowPart;
	return TRUE;
}


//--------------------------------------------------------
//
// OpensPhysicalMemory
//
// This function opens the physical memory device. It
// uses the native API since 
//
//--------------------------------------------------------
HANDLE OpenPhysicalMemory()
{
	NTSTATUS		status,zwstatus;
	HANDLE			physmem;
	UNICODE_STRING	physmemString;
	OBJECT_ATTRIBUTES attributes;
	WCHAR			physmemName[] = L"\\device\\physicalmemory";

	RtlInitUnicodeString( &physmemString, physmemName );	

	InitializeObjectAttributes( &attributes, &physmemString,
								OBJ_CASE_INSENSITIVE/*OBJ_VALID_ATTRIBUTES*/, NULL, NULL );			
	status = NtOpenSection( &physmem, SECTION_MAP_READ/*|SECTION_MAP_WRITE*/, &attributes );
	
	//zwstatus = ZwOpenSection( &physmem, /*SECTION_MAP_READ|*/SECTION_MAP_WRITE, &attributes );
	if( !NT_SUCCESS( status )) {

		PrintError( "Could not open \\device\\physicalmemory", status );
		return NULL;
	}

	return physmem;
}



//--------------------------------------------------------
//
// LocateNtdllEntryPoints
//
// Finds the entry points for all the functions we 
// need within NTDLL.DLL.
//
//--------------------------------------------------------
BOOLEAN LocateNtdllEntryPoints()
{
		char *pTemp;
	if( !(RtlInitUnicodeString = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
			"RtlInitUnicodeString" )) ) {

		return FALSE;
	}
	if( !(NtUnmapViewOfSection = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
			"NtUnmapViewOfSection" )) ) {

		return FALSE;
	}
	if( !(NtOpenSection = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
			"NtOpenSection" )) ) {

		return FALSE;
	}
	if( !(NtMapViewOfSection = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
			"NtMapViewOfSection" )) ) {

		return FALSE;
	}
	if( !(RtlNtStatusToDosError = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
			"RtlNtStatusToDosError" )) ) {

		return FALSE;
	}

	if( !(ZwOpenSection = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
			"ZwOpenSection" )) ) {

		return FALSE;
	}
	return TRUE;
}

//--------------------------------------------------------
//
// Main
// 
// This program drives the command loop
//
//--------------------------------------------------------
int main( int argc, char *argv[] )
{
	HANDLE		physmem;
	DWORD		vaddress, paddress, length;
	char		input[256];
	DWORD		lines;
	char		ch;
	DWORD		i, j;

	printf("\nPhysmem v1.0: physical memory viewer\n"
		   "By Mark Russinovich\n"
		   "Systems Internals - http://www.sysinternals.com\n\n");
	//
	// Load NTDLL entry points
	//
	if( !LocateNtdllEntryPoints() ) {

		printf("Unable to locate NTDLL entry points.\n\n");
		return -1;
	}

	//
	// Open physical memory
	//
	if( !(physmem = OpenPhysicalMemory())) {

		return -1;
	}

	//
	// Enter the command loop
	//
	printf("Enter values in hexadecimal. Enter 'q' to quit.\n");
	while( 1 ) {

		printf("\nAddress: " ); fflush( stdout );
		gets( input );
		if( input[0] == 'q' || input[0] == 'Q' ) break;
		sscanf( input, "%x", &paddress );

		printf("Bytes: "); fflush( stdout );
		gets( input );
		if( input[0] == 'q' || input[0] == 'Q' ) break;
		sscanf( input, "%x", &length );

		//
		// Map it
		//
		if( !MapPhysicalMemory( physmem, &paddress, &length,
								&vaddress )) 
			continue;
		//
		// Dump it
		//
		lines = 0;
		for( i = 0; i < length; i += BYTESPERLINE ) {

			printf("%08X: ", paddress + i );

			for( j = 0; j < BYTESPERLINE; j++ ) {

				if( i+j == length ) break;
				if( j == BYTESPERLINE/2 ) printf("-" );
				printf("%02X ", *(PUCHAR) (vaddress + i +j ));
			}

			for( j = 0; j < BYTESPERLINE; j++ ) {

				if( i+j == length ) break;
				ch = *(PUCHAR) (vaddress + i +j );

				if( __iscsym( ch ) || 
					isalnum( ch ) ||
					ch == ' ') {

					printf("%c", ch);

				} else {

					printf("." );
				}
			}

			printf("\n");

			if( lines++ == LINESPERSCREEN ) {

				printf("-- more -- ('q' to abort)" ); fflush(stdout);
				ch = getchar();
				if( ch == 'q' || ch == 'Q' ) {
					fflush( stdin );
					break;
				}
				lines = 0;
			}
		}

		//
		// Unmap the view
		//
		UnmapPhysicalMemory( vaddress );
	}

	//
	// Close physical memory section
	//
	CloseHandle( physmem );

	return 0;
}

/*
typedef LONG    NTSTATUS;
 
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
    PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
 
typedef enum _SECTION_INHERIT
{
    ViewShare = 1,
    ViewUnmap = 2
} SECTION_INHERIT, *PSECTION_INHERIT;
 
typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;
    PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
 
#define InitializeObjectAttributes( p, n, a, r, s ) { \ 
    (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ 
    (p)->RootDirectory = r; \ 
    (p)->Attributes = a; \ 
    (p)->ObjectName = n; \ 
    (p)->SecurityDescriptor = s; \ 
    (p)->SecurityQualityOfService = NULL; \ 
}
 
// Interesting functions in NTDLL
typedef NTSTATUS (WINAPI *ZwOpenSectionProc)
(
    PHANDLE SectionHandle,
    DWORD DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes
);
typedef NTSTATUS (WINAPI *ZwMapViewOfSectionProc)
(
    HANDLE SectionHandle,
    HANDLE ProcessHandle,
    PVOID *BaseAddress,
    ULONG ZeroBits,
    ULONG CommitSize,
    PLARGE_INTEGER SectionOffset,
    PULONG ViewSize,
    SECTION_INHERIT InheritDisposition,
    ULONG AllocationType,
    ULONG Protect
);
typedef NTSTATUS (WINAPI *ZwUnmapViewOfSectionProc)
(
    HANDLE ProcessHandle,
    PVOID BaseAddress
);
typedef VOID (WINAPI *RtlInitUnicodeStringProc)
(
    IN OUT PUNICODE_STRING DestinationString,
    IN PCWSTR SourceString
);
 
// Global variables
static HMODULE hModule = NULL;
static HANDLE hPhysicalMemory = NULL;
static ZwOpenSectionProc ZwOpenSection;
static ZwMapViewOfSectionProc ZwMapViewOfSection;
static ZwUnmapViewOfSectionProc ZwUnmapViewOfSection;
static RtlInitUnicodeStringProc RtlInitUnicodeString;
 
// initialize
BOOL InitPhysicalMemory()
{
    if (!(hModule = LoadLibrary("ntdll.dll")))
    {
        return FALSE;
    }
 
    // 以下从NTDLL获取我们需要的几个函数指针
    if (!(ZwOpenSection = (ZwOpenSectionProc)GetProcAddress(hModule, "ZwOpenSection")))
    {
        return FALSE;
    }
 
    if (!(ZwMapViewOfSection = (ZwMapViewOfSectionProc)GetProcAddress(hModule, "ZwMapViewOfSection")))
    {
        return FALSE;
    }
 
    if (!(ZwUnmapViewOfSection = (ZwUnmapViewOfSectionProc)GetProcAddress(hModule, "ZwUnmapViewOfSection")))
    {
        return FALSE;
    }
  
    if (!(RtlInitUnicodeString = (RtlInitUnicodeStringProc)GetProcAddress(hModule, "RtlInitUnicodeString")))
    {
        return FALSE;
    }
 
    // 以下打开内核对象
    WCHAR PhysicalMemoryName[] = L"\\Device\\PhysicalMemory";
    UNICODE_STRING PhysicalMemoryString;
    OBJECT_ATTRIBUTES attributes;
    RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName);
    InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL);
    NTSTATUS status = ZwOpenSection(&hPhysicalMemory, SECTION_MAP_READ, &attributes );
 
    return (status >= 0);
}
 
// terminate -- free handles
void ExitPhysicalMemory()
{
    if (hPhysicalMemory != NULL)
    {
        CloseHandle(hPhysicalMemory);
    }
 
    if (hModule != NULL)
    {
        FreeLibrary(hModule);
    }
}
 
BOOL ReadPhysicalMemory(PVOID buffer, DWORD address, DWORD length)
{
    DWORD outlen;            // 输出长度,根据内存分页大小可能大于要求的长度
    PVOID vaddress;          // 映射的虚地址
    NTSTATUS status;         // NTDLL函数返回的状态
    LARGE_INTEGER base;      // 物理内存地址
 
    vaddress = 0;
    outlen = length;
    base.QuadPart = (ULONGLONG)(address);
 
    // 映射物理内存地址到当前进程的虚地址空间
    status = ZwMapViewOfSection(hPhysicalMemory,
        (HANDLE) -1,
        (PVOID *)&vaddress,
        0,
        length,
        &base,
        &outlen,
        ViewShare,
        0,
        PAGE_READONLY);
 
    if (status < 0)
    {
        return FALSE;
    }
 
    // 当前进程的虚地址空间中,复制数据到输出缓冲区
    memmove(buffer, vaddress, length);
 
    // 完成访问,取消地址映射
    status = ZwUnmapViewOfSection((HANDLE)-1, (PVOID)vaddress);
 
    return (status >= 0);
}
 
// 一个测试函数,从物理地址0xfe000开始,读取4096个字节
// 对于Award BIOS,可以从这段数据找到序列号等信息
BOOL test()
{
    UCHAR buf[4096];
 
    if (!InitPhysicalMemory())
    {
        return FALSE;
    }
 
    if (!ReadPhysicalMemory(buf, 0xfe000, 4096))
    {
        // ... 成功读取了指定数据
        ExitPhysicalMemory();
        return FALSE;
    }
 
    ExitPhysicalMemory();
  
    return TRUE;
}
*/

⌨️ 快捷键说明

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