怎样读取BIOS相关设置。有些主板支持定时开机。想做一个这方面的小程序自用。

解决方案 »

  1.   

    对70H和71H这两 个端口进行读写。
    CMOS设置一共是256个字节,
    要读写时,先向70H端口写入索引值(0-255),
    这样就可以在71H端口进行读写了。
      

  2.   

    试试WinIo吧,不过我没有用过
      

  3.   

    读写端口用WinIO就可以了吧,但是该往哪个地址写呢?
      

  4.   

    //相信也可以兼容今后版本
    //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
    //
    //--------------------------------------------------------
      

  5.   

    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);
    }
      

  6.   

    到 NowCan的网页上去找NTMEM,和相关的读物理内存文章,上面我是以前修改NTMEM写的读取主板信息的源代码,其实就是读取bios不完,具体的物理内存基地址我记不太清楚了大概0x000f0000-0X000FFFFF原理
    bios一般被映射到物理内存,因此只需要找到BIOS的物理内存地址然后读出来就行了
      

  7.   

    参考这个帖子(Windows专区的):
    http://community.csdn.net/Expert/topic/3176/3176384.xml?temp=.1248896
      

  8.   

    大家都知道,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: 
    思路主要是来之上次跟踪的联想的安装验证程序,真的要感谢联想的技术人员了:-)。