|
楼主 |
发表于 2022-10-10 16:18:45
|
显示全部楼层
类似这种 做一下改良
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#define StartAddress 0xF0000
#define EndAddress 0xFFFFF
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
typedef unsigned long DWORD;
typedef unsigned int DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef struct
{
BYTE Type;
BYTE Length;
WORD Handle;
}Header;
typedef struct
{
BYTE Major_Version;
BYTE Minor_Version;
WORD Length;
DWORD Address;
WORD Struct_Count;
}EPS;
const char *characteristics[]={
"Reserved", "Reserved", "Unknown", "BIOS Characteristics are not supported",
"ISA is supported", "MICA is supported","EISA is supported","PCI is supported",
"PC card(PCMCIA) is supported", "Plug and Play is supported",
"APM is supported", "BIOS is upgradeable(Flash)", "BIOS shadowing is allowed",
"VL-VESA is supported", "ESCD support is available",
"Boot from CD is supported", "Selected boot is supported",
"BIOS ROM is socketed", "Boot from PC card(PCMCIA)is supported",
"EDD specification is supported",
"Int 13h--Japanese floppy for NEC 9800 1.2 MB(3.5\",1K bytes/sector, 360 RPM)is supported",
"Int 13h--Japanese floppy for Toshiba 1.2 MB(3.5\", 360 RPM)is supported",
"Int 13h--5.25\"/360 KB floppy services are supported",
"Int 13h--5.25\"/1.2 MB floppy services are supported",
"Int 13h--3.5\"/720 KB floppy services are supported",
"Int 13h--5.25\"/2.88 MB floppy services are supported",
"Int 5h, print screen Service is supported",
"Int 9h, 8042 keyboard services are supported",
"Int 14h, serial services are supported",
"Int 17h, printer services are supported",
"Int 10h, CGA/Mono Video Services are supported",
"NEC PC-98", "Reserved for BIOS vendor", "Reserved for system vendor"
};
const char *characteristics_ex[]={
"ACPI is supported", "USB Legacy is supported", "AGP is supported",
"I2O boot is supported", "LS-120 SuperDisk boot is supported",
"ATAPI ZIP drive boot is supported", "1394 boot is supported",
"Smart battery is supported", "BIOS Boot Specification is supported",
"Function key-initiated network service boot is supported",
"Enabled targeted content distribution",
"UEFI Specification is supported",
"SMBIOS table describes a virtual machine",
"Reserved for future assignment"
};
DWORD Find_EPS_Addr(EPS *eps, BYTE *addr);
WORD Find_Structure(BYTE *TableAddress, WORD StructureCount, BYTE Type);
int main()
{
char ch ;
while(1)
{
printf("\n");
printf("***************************************************\n");
printf("* 1.show entries of type 0 *\n");
printf("* 2.exit *\n");
printf("***************************************************\n");
printf("PLEASE ENTER YOUR CHOICE : ");
scanf("%d",&ch);
while(getchar()!='\n')
continue;
switch(ch)
{
case 1:dmidecode();
break;
case 2:exit(0);
break;
default:printf("INVALID COMMAND!--NOT EXISTS \n");
break;
}
}
return 0;
}
DWORD Find_EPS_Addr(EPS *eps, BYTE *addr)
{
DWORD i;
BYTE * SM;
SM = addr;
for(i = 0; i <= 0xFFFF; i++)
{
if(SM == MAP_FAILED)
{
handle_error("mmap");
}
if(SM[i] != '_' || SM[i+1] != 'S' || SM[i+2] != 'M' || SM[i+3] != '_')
continue;
if(SM[i+16] != '_' || SM[i+17] != 'D' || SM[i+18] != 'M' || SM[i+19] != 'I'|| SM[i+20] != '_')
continue;
eps->Length = *(short *)(SM + i + 0x16);
eps->Address = *(DWORD *)(SM + i + 0x18);
eps->Struct_Count = *(short *)(SM + i + 0x1C);
eps->Major_Version = *(short *)(SM + i + 0x06);
eps->Minor_Version = *(short *)(SM + i + 0x07);
}
return 0;
}
int dmidecode()
{
DWORD Table_Address,segment,offset;
EPS p = {0, 0, 0, 0, 0};
EPS *eps = &p;
int fd = open("/dev/mem",O_RDONLY|O_SYNC);
if(fd == -1)
{
handle_error("open /dev/mem");
return -1;
}
//void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
BYTE *addr= mmap(0, EndAddress-StartAddress, PROT_READ, MAP_SHARED, fd, 0xF0000);
Find_EPS_Addr(eps, addr);
printf("SMBIOS %d.%d present.\n", eps->Major_Version, eps->Minor_Version);
if(eps->Major_Version >= 3)
{
printf("# SMBIOS implementations newer than version 3.0 are not\n");
printf("# fully supported by this version of dmidecode.\n");
}
printf("%d structures occupying %d bytes.\nTable at 0x%08X.\n", eps->Struct_Count, eps->Length, eps->Address);
Table_Address = eps->Address;
segment = Table_Address & 0xFFFF;
offset = Table_Address & 0xF0000;
BYTE * TableAddress = (BYTE *)mmap(0, segment + eps->Length , PROT_READ, MAP_SHARED, fd, offset);
Find_Structure((TableAddress + segment), eps->Struct_Count, 0);
//usage of munmap
//int munmap(void *addr, size_t length);
munmap(addr, 0xFFFF);
munmap(TableAddress, 0xFFFF);
return 0;
}
//Find specified type0 's structure
//TableAddress value is located at offset 18h in EPS table
//StructureCount value is located at offset 1Ch in EPS
WORD Find_Structure(BYTE *TableAddress, WORD StructureCount, BYTE Type)
{
int i;
char *str[10];
BYTE currtype;
BYTE *Addr;
BYTE *firstAddr = TableAddress;
while(TableAddress-firstAddr < StructureCount)
{
currtype = ((Header *)TableAddress)->Type;
if(currtype != 0)
{
TableAddress += ((Header *)TableAddress)->Length;
while(*(WORD *)TableAddress != 0)
{
TableAddress ++;
}
TableAddress += 2;
}
else
{
Addr = TableAddress;
TableAddress += ((Header *)Addr)->Length;
while(*(WORD *)TableAddress != 0 && *(WORD *)(TableAddress -1) !=0)
{
str[i+1] = (char *)TableAddress;
while(*(BYTE *)TableAddress != 0)
{
TableAddress ++;
}
i ++;
TableAddress ++;
}
}
}
BYTE type = Addr[0x00];
BYTE length = Addr[0x01];
WORD handle = Addr[0x02];
printf("\nHandle 0x%04x, DMI type %d, %d bytes\n",handle,type,length);
printf("BIOS Information\n");
//vendor
printf("%15s %s\n","Vendor:", Addr[0x04]==0x0000 ? "": str[Addr[0x04]]);
//version
printf("%16s %s\n","Version:", Addr[0x05]==0x0000 ? "": str[Addr[0x05]]);
//address
WORD Address = *(WORD *)(Addr+6);
printf("%16s 0x%X\n","Address:", StartAddress);
//release date
printf("%21s %s\n","Release Date:", Addr[0x08]==0x0000 ? "": str[Addr[0x08]]);
//Runtime Size
printf("%21s %d %s\n","Runtime Size:", (0x10000-Address) * 16 /1024, "KB");
//ROM Size
printf("%17s %d %s\n","ROM Size:", (Addr[0x09]+1) * 64, "KB");
//BIOS Characteristics
printf("%24s\n","Characteristics:");
QWORD CHAR = *(QWORD *)(Addr + 0x0A);
WORD CHAR_ex = *(WORD *)(Addr + 0x12);
//printf("%x\n",CHAR);
//0011_0111_1000_1011_1001_1000_1000_0000b
for(i = 0; i < 32; i++)
{
if((CHAR >> i) & 1)//check if each bit equals to 1
{
printf("%16s%s\n","",characteristics[i]);
}
}
for(i = 0; i < 13; i++)
{
if((CHAR_ex >> i) & 1)
{
printf("%16s%s\n","",characteristics_ex[i]);
}
}
//BIOS Revision
//if the system does not support the use of this field ,the value is 0FFh
if(Addr[0x14] != 0xFF || Addr[0x15] != 0xFF)
{
printf("%22s %d.%d\n","BIOS Revision:",Addr[0x14],Addr[0x15]);
}
//Firmware Revision
//if the system does not have field upgradeable embedded controller firmware ,the value is 0FFh
if(Addr[0x16] != 0xFF || Addr[0x17] != 0xFF)
{
printf("%26s %d.%d\n","Firmware Revision:",Addr[0x16],Addr[0x17]);
}
return 0;
}
|
|