如何用VC++读取BIOS的版本号等信息。奖励100分
发布网友
发布时间:2022-04-22 06:23
我来回答
共1个回答
热心网友
时间:2023-12-18 08:18
可能需要ddk,否则有些结构可能没有,可以回帖我补上
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <RegStr.h>
#include <winioctl.h>
#include <ntddndis.h>
//结构定义
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;
PVOID SecurityQualityOfService;
} 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);
/*====================================================================
函数 : FindAwardBios
功能 : 获取Award 系列的Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
UINT FindAwardBios( BYTE** ppBiosAddr )
{
BYTE* pBiosAddr = * ppBiosAddr + 0xEC71;
BYTE szBiosData[128];
::CopyMemory( szBiosData, pBiosAddr, 127 );
szBiosData[127] = 0;
int iLen = lstrlen( ( char* )szBiosData );
if( iLen > 0 && iLen < 128 )
{
//AWard: 07/08/2002-i845G-ITE8712-JF69VD0CC-00
//Phoenix-Award: 03/12/2002-sis645-p4s333
if( szBiosData[2] == '/' && szBiosData[5] == '/' )
{
BYTE* p = szBiosData;
while( * p )
{
if( * p < ' ' || * p >= 127 )
{
break;
}
++ p;
}
if( * p == 0 )
{
* ppBiosAddr = pBiosAddr;
return ( UINT )iLen;
}
}
}
return 0;
}
/*====================================================================
函数 : FindAmiBios
功能 : 获取Ami 系列的Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
UINT FindAmiBios( BYTE** ppBiosAddr )
{
BYTE* pBiosAddr = * ppBiosAddr + 0xF478;
BYTE szBiosData[128];
::CopyMemory( szBiosData, pBiosAddr, 127 );
szBiosData[127] = 0;
int iLen = lstrlen( ( char* )szBiosData );
if( iLen > 0 && iLen < 128 )
{
// Example: "AMI: 51-2300-000000-00101111-030199-"
if( szBiosData[2] == '-' && szBiosData[7] == '-' )
{
BYTE* p = szBiosData;
while( * p )
{
if( * p < ' ' || * p >= 127 )
{
break;
}
++ p;
}
if( * p == 0 )
{
* ppBiosAddr = pBiosAddr;
return ( UINT )iLen;
}
}
}
return 0;
}
/*====================================================================
函数 : FindPhoenixBios
功能 : 获取Phoenix 系列的Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
UINT FindPhoenixBios( BYTE** ppBiosAddr )
{
UINT uOffset[3] = { 0x6577, 0x7196, 0x7550 };
for( UINT i = 0; i < 3; ++ i )
{
BYTE* pBiosAddr = * ppBiosAddr + uOffset[i];
BYTE szBiosData[128];
::CopyMemory( szBiosData, pBiosAddr, 127 );
szBiosData[127] = 0;
int iLen = lstrlen( ( char* )szBiosData );
if( iLen > 0 && iLen < 128 )
{
// Example: Phoenix "NITELT0.86B.0044.P11.9910111055"
if ( szBiosData[7] == '.' && szBiosData[11] == '.' )
{
BYTE* p = szBiosData;
while( * p )
{
if( * p < ' ' || * p >= 127 )
{
break;
}
++ p;
}
if( * p == 0 )
{
* ppBiosAddr = pBiosAddr;
return ( UINT )iLen;
}
}
}
}
return 0;
}
/*====================================================================
函数 : GetBiosSerialNum
功能 : 获取Bios序列号
输入 : TSystemInfo& tSystemInfo [OUT]
输出 : TSystemInfo
返回 : FALSE 表示获取失败
======================================================================*/
BOOL GetBiosSerialNum(TSystemInfo& tSystemInfo)
{
SIZE_T ssize;
LARGE_INTEGER so;
so.LowPart=0x000f0000;
so.HighPart=0x00000000;
ssize=0xffff;
wchar_t strPH[30]= L"\\device\\physicalmemory";
DWORD ba=0;
UNICODE_STRING struniph;
struniph.Buffer=strPH;
struniph.Length=0x2c;
struniph.MaximumLength =0x2e;
OBJECT_ATTRIBUTES obj_ar;
obj_ar.Attributes =64;
obj_ar.Length =24;
obj_ar.ObjectName=&struniph;
obj_ar.RootDirectory=0;
obj_ar.SecurityDescriptor=0;
obj_ar.SecurityQualityOfService =0;
HMODULE hinstLib = LoadLibrary("ntdll.dll");
ZWOS ZWopenS=(ZWOS)GetProcAddress(hinstLib,"ZwOpenSection");
ZWMV ZWmapV=(ZWMV)GetProcAddress(hinstLib,"ZwMapViewOfSection");
ZWUMV ZWunmapV=(ZWUMV)GetProcAddress(hinstLib,"ZwUnmapViewOfSection");
//调用函数,对物理内存进行映射
HANDLE hSection;
if( 0 == ZWopenS(&hSection,4,&obj_ar) &&
0 == ZWmapV(
( HANDLE )hSection, //打开Section时得到的句柄
( HANDLE )0xFFFFFFFF, //将要映射进程的句柄,
&ba, //映射的基址
0,
0xFFFF, //分配的大小
&so, //物理内存的地址
&ssize, //指向读取内存块大小的指针
1, //子进程的可继承性设定
0, //分配类型
2 //保护类型
)
)
//执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里
//映射的基址由ba返回,如果映射不再有用,应该用ZwUnmapViewOfSection断开映射
{
BYTE* pBiosSerial = ( BYTE* )ba;
UINT uBiosSerialLen = FindAwardBios( &pBiosSerial );
if( uBiosSerialLen == 0U )
{
uBiosSerialLen = FindAmiBios( &pBiosSerial );
if( uBiosSerialLen == 0U )
{
uBiosSerialLen = FindPhoenixBios( &pBiosSerial );
}
}
if( uBiosSerialLen != 0U )
{
tSystemInfo.Append((u8*)"BIOS=", 5);
::CopyMemory( tSystemInfo.szInfo+5, pBiosSerial, uBiosSerialLen );
tSystemInfo.dwRealSize = uBiosSerialLen+5;
}
else
{
printf("BIOS: not support!\n");
return FALSE;
}
ZWunmapV( ( HANDLE )0xFFFFFFFF, ( void* )ba );
printf("BIOS: %s\n", (s8*)tSystemInfo.szInfo);
return TRUE;
}
printf("BIOS: not supported!\n");
return FALSE;
}