Home

Awesome

Build status

hwid-checker-mg

Before I proceed, I would like to give a huge thanks to nealhow_ (github, twitter) for being a huge help, by contributing so much with his knowlegde and skills. Without him and his guidence, this project would've took longer to make. Fun fact, at the time of making this project I wasn't able to find a single C++ hwid checker

INTRODUCTION

hwid-checker-mg is simple, proof-of-concept, hardware id checker made in C++ that utilizes the SMBIOS/DMI standards to output information that's been described by the BIOS. The information ranges from system manufacturer, model name, serial number (Which is our main focus for this hwid checker)

C++ has been chosen as the language of this project for two reasons:

This was a great learning experience and was much a challenge. Here are some of the concepts I've encountered

Evidently, it'll be need to read System Management BIOS (SMBIOS) Reference Specification Version 3.3.0 to further your understanding on this topic.

Also, allocating a RawSMBIOSData data struct in the heap at runtime gave undefine behavior. So I wouldn't recommended it.

DOCUMENTATION

Doc 1: Table 3 – Structure header format description


// windows struct

typedef struct _dmi_header
{
	BYTE		type;
	BYTE		length;
	WORD		handle;
} dmi_header;

// and for linux

struct dmi_header {
	u8 type;
	u8 length;
	u16 handle;
} __packed;
  enum dmi_entry_type
    : BYTE /* 6.1.2 Structure header format */
  {
    DMI_ENTRY_BIOS = 0,
    DMI_ENTRY_SYSTEM,
    DMI_ENTRY_BASEBOARD,
    DMI_ENTRY_CHASSIS,
    DMI_ENTRY_PROCESSOR,
    DMI_ENTRY_MEM_CONTROLLER,
    DMI_ENTRY_MEM_MODULE,
    DMI_ENTRY_CACHE,
    DMI_ENTRY_PORT_CONNECTOR,
    DMI_ENTRY_SYSTEM_SLOT,
    DMI_ENTRY_ONBOARD_DEVICE,
    DMI_ENTRY_OEMSTRINGS,
    DMI_ENTRY_SYSCONF,
    DMI_ENTRY_BIOS_LANG,
    DMI_ENTRY_GROUP_ASSOC,
    DMI_ENTRY_SYSTEM_EVENT_LOG,
    DMI_ENTRY_PHYS_MEM_ARRAY,
    DMI_ENTRY_MEM_DEVICE,
    DMI_ENTRY_32_MEM_ERROR,
    DMI_ENTRY_MEM_ARRAY_MAPPED_ADDR,
    DMI_ENTRY_MEM_DEV_MAPPED_ADDR,
    DMI_ENTRY_BUILTIN_POINTING_DEV,
    DMI_ENTRY_PORTABLE_BATTERY,
    DMI_ENTRY_SYSTEM_RESET,
    DMI_ENTRY_HW_SECURITY,
    DMI_ENTRY_SYSTEM_POWER_CONTROLS,
    DMI_ENTRY_VOLTAGE_PROBE,
    DMI_ENTRY_COOLING_DEV,
    DMI_ENTRY_TEMP_PROBE,
    DMI_ENTRY_ELECTRICAL_CURRENT_PROBE,
    DMI_ENTRY_OOB_REMOTE_ACCESS,
    DMI_ENTRY_BIS_ENTRY,
    DMI_ENTRY_SYSTEM_BOOT,
    DMI_ENTRY_MGMT_DEV,
    DMI_ENTRY_MGMT_DEV_COMPONENT,
    DMI_ENTRY_MGMT_DEV_THRES,
    DMI_ENTRY_MEM_CHANNEL,
    DMI_ENTRY_IPMI_DEV,
    DMI_ENTRY_SYS_POWER_SUPPLY,
    DMI_ENTRY_ADDITIONAL,
    DMI_ENTRY_ONBOARD_DEV_EXT,
    DMI_ENTRY_MGMT_CONTROLLER_HOST,
    DMI_ENTRY_INACTIVE = 126,
    DMI_ENTRY_END_OF_TABLE = 127,
  };

Doc 2: Raw SMBIOS firmware table provider

#include <windows.h>

typedef struct RawSMBIOSData
{
	BYTE    Used20CallingMethod;
	BYTE    SMBIOSMajorVersion;
	BYTE    SMBIOSMinorVersion;
	BYTE    DmiRevision;
	DWORD   Length;
	BYTE    SMBIOSTableData[];
} RawSMBIOSData;

DWORD smbios_data_size	       {};
BYTE  *b_		       {nullptr};
dmi_header* header             {nullptr};
RawSMBIOSData* smbios_data     {nullptr};
BYTE smbios_data_buffer[0x10000] = { 0 };

GetSystemFirmwareTable('RSMB', 0, smbios_data_buffer, smbios_buffersize);

The GetSystemFirmwareTable function retrieves specified firmware tables from a firmware tables provider. in our case the Raw SMBIOS Firmware provider tables.

Also, allocating a RawSMBIOSData data_structure in the heap at runtime, gave undefined behaviors. So I wouldn't recommended it.

Resource that undeceive my research

Most all of them are bit vague:	
https://www.youtube.com/watch?v=yX6caxDOPu0
https://stackoverflow.com/questions/43473262/getting-the-motherboards-serial-number
https://www.experts-exchange.com/videos/7444/What-is-WMI-and-how-it-can-be-used-to-get-hardware-and-software-information-from-remote-computers.html
https://www.codeproject.com/Questions/437379/Cplusplus-source-code-to-get-CPU-number-motherboar
https://docs.microsoft.com/en-us/windows/win32/sysinfo/system-information-functions?redirectedfrom=MSDN
https://stackoverflow.com/questions/56935213/how-to-get-adapter-driver-version-in-directx12/56960922
https://stackoverflow.com/questions/1090261/get-the-graphics-card-model
https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dadapter-identifier9
https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid
https://stackoverflow.com/questions/1672677/print-a-guid-variable
https://www.windows-commandline.com/get-serial-number-for-ram-motherboard-hard-disk/
https://stackoverflow.com/questions/43473262/getting-the-motherboards-serial-number
https://www.dmtf.org/standards/smbios
https://gist.github.com/daiakushi/98a004e7cd750803dfe1
https://www.codeproject.com/Tips/5263343/How-to-Get-the-BIOS-UUID


by reading source code of dmicode:
- https://github.com/mirror/dmidecode/blob/master/dmidecode.c
- https://elixir.bootlin.com/linux/latest/source/include/linux/dmi.h

uuid vs guid: 
- https://stackoverflow.com/questions/246930/is-there-any-difference-between-a-guid-and-a-uuid?rq=1

dmicode:
- https://linux.die.net/man/8/dmidecode  

Thanks for the read