阅读:2055回复:18
物理内存 到 虚拟内存 映射的问题??
在驱动里如何将 物理内存(cpu 的空闲 dram,这里是外存) 映射到 用户进程的虚拟内存??
|
|
最新喜欢:![]() |
沙发#
发布于:2003-09-16 11:02
修改PDE,PTE将相应的页写到其中,并设置有效位.
|
|
|
板凳#
发布于:2003-09-16 11:36
老问题了, 搜一下以前的帖子吧.
|
|
|
地板#
发布于:2003-09-16 14:57
wowocock 你好!
能不能举个例子呢? |
|
地下室#
发布于:2003-09-16 15:07
seaquester 你好!
能不能提供个地址呢? |
|
5楼#
发布于:2003-09-16 16:33
这里的物理地址首先是空闲的,其次是连续的,至少1M的空间,分配后要保护的
|
|
6楼#
发布于:2003-09-17 10:39
//========================================================
// // 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 ); //---------------------------------------------------------------------- // // 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 ); 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; 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; } //-------------------------------------------------------- // // LocateNtdllEntryPoints // // Finds the entry points for all the functions we // need within NTDLL.DLL. // //-------------------------------------------------------- BOOLEAN LocateNtdllEntryPoints() { 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; } 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; } |
|
|
7楼#
发布于:2003-09-18 09:20
非常感谢 wowocock
能不能解释一下程序的思路?? 这个程序需不需要驱动支持?? |
|
8楼#
发布于:2003-09-18 11:21
很简单在NT下DEVICE下提供了PHYSICALMEMORY对象,也就是说你可以直接操纵物理地址,正常情况下ADM下可以读他,如果要写需要GETSECURITYINFO
SETENTRIESINACL,SETSECURITYINFO,来增加ACL的可写属性 ,然后用ZWOPENSECTION打开这个对象,用MAPVIEWOFFILE影射进你的地址空间,就可以直接操纵物理地址了。 |
|
|
9楼#
发布于:2003-09-20 12:39
还愣着干啥,,给分阿!!!!!
|
|
|
10楼#
发布于:2003-09-22 09:03
wowocock,thank you very much! if you come to here,i will ask you to eat!
|
|
11楼#
发布于:2003-09-23 16:43
我很想知道一下,内存映射中,ISA与PCI板卡的内存有什么区别?
我查过很多地方,但只看到一套源代码,大致都是上面的这些,而对于ISA与PCI好像并没提到。 但是我找到的一个针对ISA板卡内存映射的源代码,却无法成功的将PCI板卡的内存映射到虚拟内存。 各位有这方面的了解么? 请给我点提示。 非常感谢! |
|
12楼#
发布于:2004-02-03 09:55
各位大侠,wowocock 的程序在vc里并不能用,
编译器不认识NTSTATUS( DDK 里可以 ), __stdcall 也出错,怎么办?? |
|
13楼#
发布于:2004-02-03 11:08
typedef long NTSTATUS
|
|
|
14楼#
发布于:2004-02-08 19:49
wowocock,你好__stdcall
也出错,怎么办?? |
|
15楼#
发布于:2004-02-09 09:16
你用的是VC吗??/吐血。。。。。。
|
|
|
16楼#
发布于:2004-02-09 09:53
是VC
程序里有main,vc里应该可以用吧 |
|
17楼#
发布于:2004-02-09 15:01
wowocock,你好,vc里不能用用么??
|
|
18楼#
发布于:2004-02-09 17:02
我就是VC里用的,你连SDTCALL这都不能识别,我还能说什么??
要么你就用汇编的方法,找到地址后 PUSH XXX PUSH XXX 。。。 CALL XXX 算了,至少在X86下,汇编总还认识的吧???? |
|
|