怎样读取BIOS相关设置

atsiang 2004-01-06 06:05:55
怎样读取BIOS相关设置。

有些主板支持定时开机。想做一个这方面的小程序自用。
...全文
292 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zkxz 2004-07-16
  • 打赏
  • 举报
回复
参考这个帖子(Windows专区的):
http://community.csdn.net/Expert/topic/3176/3176384.xml?temp=.1248896
PiggyXP 2004-07-16
  • 打赏
  • 举报
回复
大家都知道,windows接管了对物理内存的直接存取,而bios信息存在物理内存
的f000:0000处,关键就是如何读取物理内存。
查阅了msdn的文章后,发现以下有几个函数和物理内存访问有关:
NTSTATUS ZwOpenSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS ZwMapViewOfSection(IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
IN OUT PSIZE_T ViewSize,
IN SECTION_INHERIT InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect
);
NTSTATUS ZwUnmapViewOfSection(IN HANDLE ProcessHandle,IN PVOID BaseAddress);

用到的结构定义如下

typedef struct _UNICODE_STRING {
USHORT Length;//长度
USHORT MaximumLength;//最大长度
PWSTR Buffer;//缓存指针,访问物理内存时,此处指向UNICODE字符串"\device\physicalmemory"
} UNICODE_STRING,*PUNICODE_STRING;


typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;//长度 18h
HANDLE RootDirectory;// 00000000
PUNICODE_STRING ObjectName;//指向对象名的指针
ULONG Attributes;//对象属性00000040h
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR,0
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE,0
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;



函数说明
第一个函数ZwOpenSection用来打开section,第一个参数是指向HANDLE变量的指针,第二个是访问参数,第三个是指向OBJECT_ATTRIBUTES的指针
第二个函数ZwMapViewOfSection用来建立物理内存和当前进程的一段物理内存的联系,参数很多,一会在例程里再详细解释
第三个函数ZwUnmapViewOfSection用来断开物理内存和当前进程中的映射断开联系,第一个参数是进程句柄,必须掉用第二个函数时一样,第二
个是当前进程中映射的基址,由ZwMapViewOfSection返回

这三个函数都在ntdll.dll中,msdn里的帮助说这几个函数用在驱动编制上。
例程如下

//结构定义
typedef struct _UNICODE_STRING {
USHORT Length;//长度
USHORT MaximumLength;//最大长度
PWSTR Buffer;//缓存指针
} UNICODE_STRING,*PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;//长度 18h
HANDLE RootDirectory;// 00000000
PUNICODE_STRING ObjectName;//指向对象名的指针
ULONG Attributes;//对象属性00000040h
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR,0
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE,0
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

//函数指针变量类型生命
typedef DWORD (__stdcall *ZWOS)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
typedef DWORD (__stdcall *ZWMV)(HANDLE,HANDLE,PVOID,ULONG,ULONG,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG);
typedef DWORD (__stdcall *ZWUMV)(HANDLE,PVOID);
//以上在程序开始定义全局变量处定义

//以下在程序的主函数里
//变量声明
UNICODE_STRING struniph;
OBJECT_ATTRIBUTES obj_ar;
ZWOS ZWopenS;
ZWMV ZWmapV;
ZWUMV ZWunmapV;
HANDLE hSection;
DWORD ba;
LARGE_INTEGER so;
SIZE_T ssize;
so.LowPart=0x000f0000;//物理内存的基址,就是f000:0000
so.HighPart=0x00000000;
ssize=0xffff;
wchar_t strPH[30]=L"\\device\\physicalmemory";
//变量初始化
ba=0;//联系后的基址将在这里返回
struniph.Buffer=strPH;
struniph.Length=0x2c;//注意大小是按字节算
struniph.MaximumLength =0x2e;//也是字节
obj_ar.Attributes =64;//属性
obj_ar.Length =24;//OBJECT_ATTRIBUTES类型的长度
obj_ar.ObjectName=&struniph;//指向对象的指针
obj_ar.RootDirectory=0;
obj_ar.SecurityDescriptor=0;
obj_ar.SecurityQualityOfService =0;
//读入ntdll.dll,得到函数地址
hinstLib = LoadLibrary("ntdll.dll");
ZWopenS=(ZWOS)GetProcAddress(hinstLib,"ZwOpenSection");
ZWmapV=(ZWMV)GetProcAddress(hinstLib,"ZwMapViewOfSection");
ZWunmapV=(ZWUMV)GetProcAddress(hinstLib,"ZwUnmapViewOfSection");
//调用函数,对物理内存进行映射
ZWopenS(&hSection,4,&obj_ar);
ZWmapV(
(HANDLE)hSection, //打开Section时得到的句柄
(HANDLE)0xffffffff, //将要映射进程的句柄,
&ba, //映射的基址
0, //没怎么看明白,设为0就好了
0xffff, //分配的大小
&so, //物理内存的地址
&ssize, //指向读取内存块大小的指针
1, //子进程的可继承性设定
0, //分配类型
2 //保护类型
);
//执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里
//映射的基址由ba返回,如果映射不在有用,应该用ZwUnmapViewOfSection断开映射
BTW:
思路主要是来之上次跟踪的联想的安装验证程序,真的要感谢联想的技术人员了:-)。

jenyhu 2004-01-29
  • 打赏
  • 举报
回复
同意AthlonxpX86(一滴水)
atsiang 2004-01-28
  • 打赏
  • 举报
回复
?
atsiang 2004-01-28
  • 打赏
  • 举报
回复
不同BIOS,怎么区分
AthlonxpX86 2004-01-21
  • 打赏
  • 举报
回复
到 NowCan的网页上去找NTMEM,和相关的读物理内存文章,上面我是以前修改NTMEM写的读取主板信息的源代码,其实就是读取bios不完,具体的物理内存基地址我记不太清楚了大概0x000f0000-0X000FFFFF

原理
bios一般被映射到物理内存,因此只需要找到BIOS的物理内存地址然后读出来就行了
AthlonxpX86 2004-01-21
  • 打赏
  • 举报
回复
int main( int argc, char *argv[] )
{
HANDLE physmem;
DWORD vaddress, paddress;
DWORD length=1;
// 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
//
int i=0;
paddress=0x000fec71;//Award
MapPhysicalMemory( physmem, &paddress, &length,&vaddress ) ;
paddress=0x000fec71-0x000fe000;

if(biosCheckAward(vaddress+paddress))
{
while(i<50)
{
if(*(PUCHAR)(vaddress+paddress+i) > 0x20 && *(PUCHAR)(vaddress+paddress+i) < 0x71)
{
ch = *(PCHAR)(vaddress+paddress+i);
printf("%c", ch);

}
else
{
printf("\r\n");
break;
}
i++;
}
}
paddress=0x000ff478;//AMI
MapPhysicalMemory( physmem, &paddress, &length,&vaddress ) ;
paddress=0x000ff478-0x000ff000;

if(biosCheckAMI(vaddress+paddress))
{
while(i<50)
{
if(*(PUCHAR)(vaddress+paddress+i) > 0x20 && *(PUCHAR)(vaddress+paddress+i) < 0x71)
{
ch = *(PCHAR)(vaddress+paddress+i);
printf("%c", ch);

}
else
{
printf("\r\n");
break;
}
i++;
}
}
paddress=0x000ff478;//AMI
MapPhysicalMemory( physmem, &paddress, &length,&vaddress ) ;
paddress=0x000ff478-0x000ff000;

if(biosCheckAMI(vaddress+paddress))
{
while(i<50)
{
if(*(PUCHAR)(vaddress+paddress+i) > 0x20 && *(PUCHAR)(vaddress+paddress+i) < 0x71)
{
ch = *(PCHAR)(vaddress+paddress+i);
printf("%c", ch);

}
else
{
printf("\r\n");
break;

}
i++;
}
}

paddress=0x000f6577;//Phoenix
MapPhysicalMemory( physmem, &paddress, &length,&vaddress ) ;
paddress=0x000f6577-0x000f6000;

if(biosCheckPhoenix(vaddress+paddress))
{
while(i<50)
{
if(*(PUCHAR)(vaddress+paddress+i) > 0x20 && *(PUCHAR)(vaddress+paddress+i) < 0x71)
{
ch = *(PCHAR)(vaddress+paddress+i);
printf("%c", ch);

}
else
{
printf("\r\n");
break;
}
i++;
}
}

paddress=0x000f7196;//Phoenix
MapPhysicalMemory( physmem, &paddress, &length,&vaddress ) ;
paddress=0x000f7196-0x000f7000;

if(biosCheckPhoenix(vaddress+paddress))
{
while(i<50)
{
if(*(PUCHAR)(vaddress+paddress+i) > 0x20 && *(PUCHAR)(vaddress+paddress+i) < 0x71)
{
ch = *(PCHAR)(vaddress+paddress+i);
printf("%c", ch);

}
else
{
printf("\r\n");
break;
}
i++;
}
}
paddress=0x000f7550;//Phoenix
MapPhysicalMemory( physmem, &paddress, &length,&vaddress ) ;
paddress=0x000f7550-0x000f7000;

if(biosCheckPhoenix(vaddress+paddress))
{
while(i<50)
{
if(*(PUCHAR)(vaddress+paddress+i) > 0x20 && *(PUCHAR)(vaddress+paddress+i) < 0x71)
{
ch = *(PCHAR)(vaddress+paddress+i);
printf("%c", ch);

}
else
{
printf("\r\n");
break;
}
i++;
}
}
return 0;
CloseHandle(physmem);
}
AthlonxpX86 2004-01-21
  • 打赏
  • 举报
回复
//相信也可以兼容今后版本
//Phymem.C
//========================================================
//
// Physmem
//
//
// 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 "ntmem.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
//

int biosCheckAward(DWORD Add)
{


//Example
//AWard:07/08/2002-i845G-ITE8712-JF69VD0CC-00
// 10/10/98-xxx……
//Phoenix-Award:03/12/2002-sis645-p4s333
if(*(PUCHAR)(Add+2)=='/' && *(PUCHAR)(Add+5)=='/'){
CHAR *p=(CHAR*)Add;
while(*p){
if(*p < 0x20 || *p > 0x71)
goto NOT_AWARD;
p++;
}
return 1;

}

NOT_AWARD:
return 0;

}

int biosCheckPhoenix(DWORD Add)
{
//Example
//Phoenix:NITELT0.86B.0044.P11.9910111055
if(*(PUCHAR)(Add+7)=='.' && *(PUCHAR)(Add+11)=='.'){
CHAR *p=(PCHAR)Add;
while(*p){
if(*p < 0x20 || *p > 0x71)
goto NOT_PHOENIX;
p++;
}
return 1;
}
NOT_PHOENIX:
return 0;

}

int biosCheckAMI(DWORD Add)
{
//Example
//AMI:51-2300-000000-00101111-030199-
if(*(PUCHAR)(Add+2)=='-' && *(PUCHAR)(Add+7)=='-'){
CHAR *p=(PCHAR)Add;
while(*p){
if(*p < 0x20 || *p > 0x71)
goto NOT_AMI;
p++;
}
return 1;

}
NOT_AMI:
return 0;

}


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 (__stdcall *)(PUNICODE_STRING,PCWSTR)) GetProcAddress( GetModuleHandle("ntdll.dll"),"RtlInitUnicodeString" )) )
{
return FALSE;
}
if( !(NtUnmapViewOfSection = (NTSTATUS (__stdcall *)(HANDLE,PVOID)) GetProcAddress( GetModuleHandle("ntdll.dll"),"NtUnmapViewOfSection" )) )
{
return FALSE;
}
if( !(NtOpenSection = (NTSTATUS (__stdcall *)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES)) GetProcAddress( GetModuleHandle("ntdll.dll"),"NtOpenSection" )) )
{
return FALSE;
}
if( !(NtMapViewOfSection = (NTSTATUS (__stdcall *)(IN HANDLE,
IN HANDLE,
IN OUT PVOID *,
IN ULONG ,
IN ULONG ,
IN OUT PLARGE_INTEGER ,
IN OUT PULONG,
IN SECTION_INHERIT ,
IN ULONG ,
IN ULONG )) GetProcAddress( GetModuleHandle("ntdll.dll"),"NtMapViewOfSection" )) )
{
return FALSE;
}
if( !(RtlNtStatusToDosError = (ULONG (__stdcall *)(NTSTATUS)) GetProcAddress( GetModuleHandle("ntdll.dll"),"RtlNtStatusToDosError" )) )
{
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------
//
// Main
//
// This program drives the command loop
//
//--------------------------------------------------------
stonesky 2004-01-19
  • 打赏
  • 举报
回复
好象在应用层是不可以的哦,记不太清楚了.
nkwesley 2004-01-19
  • 打赏
  • 举报
回复
学习,关注
NowCan 2004-01-19
  • 打赏
  • 举报
回复
读写端口用WinIO就可以了吧,但是该往哪个地址写呢?
TangJunLin2002 2004-01-18
  • 打赏
  • 举报
回复
UP顶上去看看有没有人知道答案
linfeng1216 2004-01-18
  • 打赏
  • 举报
回复
gz
BenWong1981126 2004-01-18
  • 打赏
  • 举报
回复
有意思
firmamenthy 2004-01-18
  • 打赏
  • 举报
回复
别沉~
theone 2004-01-07
  • 打赏
  • 举报
回复
试试WinIo吧,不过我没有用过
prettywolf 2004-01-06
  • 打赏
  • 举报
回复
对70H和71H这两 个端口进行读写。
CMOS设置一共是256个字节,
要读写时,先向70H端口写入索引值(0-255),
这样就可以在71H端口进行读写了。
checkyvc6 2004-01-06
  • 打赏
  • 举报
回复
不太清楚,帮你顶!!

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧