Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:1146回复:6

怎样写一个访问系统无力内存的driver?

楼主#
更多 发布于:2003-09-23 21:50
Hi, 各位高手们:

    小弟还是一个driver新手。小弟现在正在做一项任务,其中要在Windows下访问系统物理内存,包括读写物理内存。我想的话,这个工作只能通过driver来做了。小弟只大概知道一点如何访问IO,对于访问系统无力内存一点不是很清楚,只是知道首先要映射物理内存到系统线性地址空间。请问各位大虾们帮帮忙,能给小弟一点这方面的例子或资料吗?如果您曾经写过这样的driver,我希望您能慷慨的给小弟参考一下,谢谢!
非常希望能得到您的帮助。

最新喜欢:

xiangshifuxiangs... jinghuirenjinghu...
else
驱动小牛
驱动小牛
  • 注册日期2002-10-21
  • 最后登录2004-06-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-09-23 22:36
9X 下可以调用_MapPhysToLinear把物理内存映射到线性地址。
2000下可以参考
http://www.sysinternals.com/files/physmem.zip
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2003-09-23 23:13
//========================================================
//
// 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;
}
很简单在NT下DEVICE下提供了PHYSICALMEMORY对象,也就是说你可以直接操纵物理地址,正常情况下ADM下可以读他,如果要写需要GETSECURITYINFO
SETENTRIESINACL,SETSECURITYINFO,来增加ACL的可写属性
,然后用ZWOPENSECTION打开这个对象,用MAPVIEWOFFILE影射进你的地址空间,就可以直接操纵物理地址了。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
Lingfeng
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2008-07-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-09-24 10:40
Hi, wowocock:

    非常感谢你的回复。小弟看了一下,还是有点模糊。在测试时我如果输入Address:400, Size:4 他就打出了好多数据,我想问一下,它这些数据是否就是对应的从物理内存0x400开始的一段物理内存数据呢?可是我用WinIO2.0里面的提供的bool _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal)得到的数据好像与这个不同
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2003-09-24 12:01
没做过,不过读写物理内存2K/XP下很简单的,
可以直接操纵\\device\\physicalmemory
进行读,如果写的话需要ADM下通过GetSecurityInfo,SetEntriesInAcl,SetSecurityInfo来获得对该对象的写权限,网上有很多相关代码参考的.
BTW在2003后MS加了限制不能直接操纵\\device\\physicalmemory
,郁闷......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
norsd
驱动牛犊
驱动牛犊
  • 注册日期2003-03-27
  • 最后登录2016-01-07
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-09-24 12:22
没做过,不过读写物理内存2K/XP下很简单的,
可以直接操纵\\device\\physicalmemory
进行读,如果写的话需要ADM下通过GetSecurityInfo,SetEntriesInAcl,SetSecurityInfo来获得对该对象的写权限,网上有很多相关代码参考的.
BTW在2003后MS加了限制不能直接操纵\\device\\physicalmemory
,郁闷......



真的!!!!!

driver 也不能直接操作device\\physicalmemory 这个对象吗!!

那怎么写物理内存,在2003下?
苦!
hong
驱动小牛
驱动小牛
  • 注册日期2001-09-19
  • 最后登录2005-12-16
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-09-25 00:34
if you \"小弟只大概知道一点如何访问IO\" then it will be easy for you to do 读写物理内存:

1. write a driver, not hardware driver,
2. map the physical memory to system virtual address;
3. make a MDL and get user mode virtual address;
4. pass this user mode virtual address to application;
5. apllication use this user mode virtual address to R/W the physicall address mapped by driver;
游客

返回顶部