[求助] 解释拆分注册表中的 SMBiosData 数据
2023-8-25 652

机器的SMBios数据保存在注册表中,据说从XP开始微软就已经这么干,附件是从注册表导出的数据供参考。

现在需要从SMBios中拆分出机器的BIOS信息、机器硬件信息等等,只是这是二进制数据,不知道如何处理,求大神援助!

另:红毛搞过用API直接读取SMBios数据的示例,我为什么不用上呢?因为该API不兼容XP,最重要的是我没研究明白。

这里有些资料介绍貌似比较详细:BIOS入知识枝桠——SMBIOS_smbios是什么意思

image.webp

最后于 2023-8-25 被anson4编辑 ,原因:
上传的附件:
收藏
点赞
道具卡
分享
单机计算
最新回复 (17)
  • avatar image
    爱心会员VIP会员
    527104427 2023-8-26

    去把红毛撺掇过来吧,他搞这个在行。

    https://www.123pan.com/s/NflRVv-Cm5Sh
  • avatar image
    anson4 2023-8-26
    楼主   3

    红毛提不起兴趣

    单机计算
  • avatar image
    anson4 2023-9-12
    楼主   4

    顶一下,希望得到解答。

    单机计算
  • avatar image
    123 2023-9-12

    示例文件夹·有红毛写的例子

    123
  • avatar image
    123 2023-9-12
    此楼层已删除
    123
  • avatar image
    123 2023-9-12
    ENVI^ ENVIMODE=1
    
    ENVI$ &NL=0d 0a
    
    //转换RSMB为DWORD----开始
    
    CODE *,RSMB,*-ANSI,&FirmwareTableProviderSignatureHex
    
    SED -ex &FirmwareTableProviderSignature=0, 0x,,&FirmwareTableProviderSignatureHex
    
    //转换RSMB为DWORD----结束
    
    //第四个参数传入0,则返回获取RSMB结构长度
    
    CALL $--qd --ret:&GetSystemFirmwareTableRet Kernel32.dll,GetSystemFirmwareTable,#%&FirmwareTableProviderSignature%,#0,#0,#0
    
    //判断API是否成功
    
    IFEX #%&GetSystemFirmwareTableRet%=0,EXIT
    
    //设置RSMB长度
    
    ENVI &BufferSize=%&GetSystemFirmwareTableRet%
    
    //申请%&BufferSize%长度的&pFirmwareTableBuffer变量内存空间
    
    SET$# pFirmwareTableBuffer=*%&BufferSize% 0
    
    //获取&pFirmwareTableBuffer数据
    
    CALL $--qd --ret:&GetSystemFirmwareTableRet Kernel32.DLL,GetSystemFirmwareTable,#%&FirmwareTableProviderSignature%,#0,*&pFirmwareTableBuffer,#%&BufferSize%
    
    //MESS. %&GetSystemFirmwareTableRet%
    
    //SET?数据类型 源PE变量名或地址=变量名:偏移字节数 //取PE对象中指定类型2进制数据。
    
    SET?char pFirmwareTableBuffer=&&Used20CallingMethod:0
    
    CALC &Used20CallingMethod=%&Used20CallingMethod% //16进制转10进制
    
    SET?char pFirmwareTableBuffer=&&SMBIOSMajorVersion:1
    
    CALC &SMBIOSMajorVersion=%&SMBIOSMajorVersion%
    
    SET?char pFirmwareTableBuffer=&&SMBIOSMinorVersion:2
    
    CALC &SMBIOSMinorVersion=%&SMBIOSMinorVersion%
    
    SET?char pFirmwareTableBuffer=&&DmiRevision:3
    
    CALC &DmiRevision=%&DmiRevision%
    
    SET?int pFirmwareTableBuffer=&&SMBIOSTableDataLength:4
    
    ENVI &&SMBIOS_Version=%&SMBIOSMajorVersion%.%&SMBIOSMinorVersion%
    
    //SET-make PE变量名=[地址|&PE变量名[@[$]偏移]][;[*][[$]字节数]] //创建PE变量。*为char串
    
    SET-make &SMBIOSTableData=&pFirmwareTableBuffer@(1 + 1 + 1 + 1 + 4);*%&SMBIOSTableDataLength% //获取实际的SMBIOSTableData数据
    
    //把数据写入到一个文件中,方便用Winhex查看对比。
    
    //IFEX %&CurDir%\SMBIOSTableData.Bin,FILE %&CurDir%\SMBIOSTableData.Bin
    
    //GETF -bin &pFirmwareTableBuffer,(1 + 1 + 1 + 1 + 4)#%&SMBIOSTableDataLength%,&SMBIOSTableDataTemp
    
    //PUTF %&CurDir%\SMBIOSTableData.Bin,0#,%&SMBIOSTableDataTemp%
    
    SET$# &type=*1 0 //申请1个字节的内存空间,定义一个变量,作为类型变量
    
    SET$# &data_offset=*1 0 //申请1个字节的内存空间,定义一个变量,作为类型(格式区)长度
    
    ENVI &&Type_Start=0 //定义一个变量,作为当前类型的起始位置值的标记
    
    CODE *ANSI,0x00 0x00,**ANSI,&&TypeKeyWords
    
    CODE *ANSI,0x00,**ANSI,&&CharKeyWords
    
    LOOP #%&Type_Start%>=0,
    
    {*
    
    //SET-zero PE变量名=[[$]数值][@[$]偏移]][;[$]数量] //清除变量的内存,默认0 $:加宽,可多次
    
    SET-zero type=
    
    SET-zero data_offset=
    
    SET?char SMBIOSTableData=&type:%&&Type_Start%
    
    ENVI &&Type_Start_Last=%&Type_Start% //上一个类型的结束位置
    
    SET?char SMBIOSTableData=&data_offset:(%&Type_Start% + 1)
    
    CALC &data_offset=%&data_offset%
    
    //MESS &data_offset=%&data_offset%
    
    CALC &pdata_offset=%&data_offset%-1 //格式区结束地址,0x00为首地址
    
    GETF -find &SMBIOSTableData,(%&data_offset% + %&Type_Start%)###0#1#0,&&Type_End,*&&TypeKeyWords
    
    //MESS %&Type_End%
    
    IFEX $%&Type_End%=-1,EXIT LOOP
    
    CALC &&Type_Start=%&Type_End% + 2 //尾部加上两个字节的0x00 0x00
    
    //MESS aaa
    
    IFEX [ #%&type%=17 & $%&SMBIOS_Version%>=2.0 ],
    
    {*
    
    CALC &BIOS_INFO_Len=%&Type_Start% - %&data_offset% - %&Type_Start_Last% //字符串区的长度
    
    GETF -find &SMBIOSTableData,(%&Type_Start_Last% + %&data_offset% )#%&BIOS_INFO_Len%##0#1#0,*&&BIOS_INFO_CharKeyWords,*&&CharKeyWords
    
    CALL Memory_Manufacturer &&Memory_vendor
    
    CALL Memory_Size &&Size
    
    CALL Memory_SerialNumber &&SerialNumber
    
    CALL Memory_PartNumber &&PartNumber
    
    CALL Memory_MemoryType &&MemoryType
    
    CALL Memory_Speed &&Speed
    
    MESS.
    
    \%&NL%品牌:%&Memory_vendor%
    
    \%&NL%大小:%&&Size%
    
    \%&NL%序列号:%&&SerialNumber%
    
    \%&NL%零件号:%&&PartNumber%
    
    \%&NL%内存类型:%&&MemoryType%
    
    \%&NL%速度:%&&Speed%
    
    }
    
    }
    
    _SUB Memory_Speed *
    
    //MESS %&Type_Start_Last%
    
    SET?wchar &SMBIOSTableData=&Speed:( %&Type_Start_Last% + 0x15 )
    
    CALC &Speed=%&Speed%
    
    ENVI-ret %1=%&Speed%
    
    _END
    
    _SUB Memory_MemoryType *
    
    SET?char &SMBIOSTableData=&MemoryType:( %&Type_Start_Last% + 0x12 )
    
    IFEX $%&MemoryType%=0x1A,ENVI &MemoryType=DDR4
    
    IFEX $%&MemoryType%=0x18,ENVI &MemoryType=DDR3
    
    IFEX $%&MemoryType%=0x13,ENVI &MemoryType=DDR2
    
    IFEX $%&MemoryType%=0x12,ENVI &MemoryType=DDR
    
    IFEX $%&MemoryType%=0x1B,ENVI &MemoryType=LPDDR
    
    IFEX $%&MemoryType%=0x1C,ENVI &MemoryType=LPDDR2
    
    IFEX $%&MemoryType%=0x1D,ENVI &MemoryType=LPDDR3
    
    IFEX $%&MemoryType%=0x1E,ENVI &MemoryType=LPDDR4
    
    IFEX $%&MemoryType%=0x23,ENVI &MemoryType=LPDDR5
    
    ENVI-ret %1=%&MemoryType%
    
    _END
    
    _SUB Memory_PartNumber *
    
    GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x1A )#1,&&PartNumber_CharNum
    
    CALL Get_Split_Dmi_Info "%&PartNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&PartNumber
    
    ENVI-ret %1=%&&PartNumber%
    
    _END
    
    _SUB Memory_SerialNumber *
    
    GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x18 )#1,&&SerialNumber_CharNum
    
    CALL Get_Split_Dmi_Info "%&SerialNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&SerialNumber
    
    ENVI-ret %1=%&&SerialNumber%
    
    _END
    
    _SUB Memory_Size *
    
    //MESS %&Type_Start_Last%
    
    SET?wchar &SMBIOSTableData=&Size:( %&Type_Start_Last% + 0x0C )
    
    CALC &Size=%&Size%
    
    ENVI-ret %1=%&Size%
    
    _END
    
    _SUB Memory_Manufacturer *
    
    GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x17 )#1,&&BIOS_vendor_CharNum
    
    CALL Get_Split_Dmi_Info "%&BIOS_vendor_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&Memory_vendor
    
    ENVI-ret %1=%&&Memory_vendor%
    
    _END
    
    _SUB Get_Split_Dmi_Info
    
    ^ENVI &&CharNum=%~1 //字符串区域的第几个字符串>=1
    
    //MESS aaa
    
    IFEX $%&&CharNum%=0,
    
    {*
    
    EXIT
    
    }
    
    ^ENVI &&This_CharKeyWords=%&pdata_offset% %~2
    
    //MESS %&&This_CharKeyWords%
    
    CALC &&NextCharNum=%&&CharNum% + 1
    
    MSTR &&Start,&&End=<%&&CharNum%><%&&NextCharNum%>%&&This_CharKeyWords%
    
    GETF &SMBIOSTableData,( %&&Start% + 1 )#( %&&End% - %&&Start%),&&This_Info
    
    CODE ***ANSI,&&This_Info,**UNI,&&This_Info
    
    MSTR * -trim &This_Info=&This_Info
    
    //MESS %&&This_Info%
    
    ENVI-ret %3=%&This_Info%
    
    _END
    
    EXIT FILE
    
    结构体
    
    struct RawSMBIOSData
    
    {
    
    BYTE Used20CallingMethod; //1b
    
    BYTE SMBIOSMajorVersion; //1b
    
    BYTE SMBIOSMinorVersion; //1b
    
    BYTE DmiRevision; //1b
    
    DWORD Length; //4b
    
    BYTE SMBIOSTableData[]; //Length b
    
    };
    最后于 2023-9-12 被123编辑 ,原因:
    123
  • avatar image
    123 2023-9-12

    这是内存信息,根据我自己的习惯把红毛代码稍微改了改,其他信息查阅文档计算偏移量就行

    123
  • avatar image
    123 2023-9-12

    从注册表读取(信息可能会有一些缺失):

    ENVI^ ENVIMODE=1
    ENVI$ &NL=0d 0a
    REGI .HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mssmbios\Data\\SMBiosData,&&smbios
    SET$# &SMBIOSTableData=%&&smbios%
    SET$# &type=*1 0    //申请1个字节的内存空间,定义一个变量,作为类型变量
    SET$# &data_offset=*1 0    //申请1个字节的内存空间,定义一个变量,作为类型(格式区)长度
    ENVI &&Type_Start=0      //定义一个变量,作为当前类型的起始位置值的标记
    CODE *ANSI,0x00 0x00,**ANSI,&&TypeKeyWords
    CODE *ANSI,0x00,**ANSI,&&CharKeyWords
    LOOP #%&Type_Start%>=0,
    {*
        
        //SET-zero  PE变量名=[[$]数值][@[$]偏移]][;[$]数量]  //清除变量的内存,默认0  $:加宽,可多次
        SET-zero type=
        SET-zero data_offset=
        SET?char SMBIOSTableData=&type:%&&Type_Start%
        ENVI &&Type_Start_Last=%&Type_Start%        //上一个类型的结束位置
        SET?char SMBIOSTableData=&data_offset:(%&Type_Start% + 1)
        CALC &data_offset=%&data_offset%
        //MESS &data_offset=%&data_offset%
        CALC &pdata_offset=%&data_offset%-1      //格式区结束地址,0x00为首地址
        GETF -find &SMBIOSTableData,(%&data_offset% + %&Type_Start%)###0#1#0,&&Type_End,*&&TypeKeyWords
        //MESS %&Type_End%
        IFEX $%&Type_End%=-1,EXIT LOOP
        CALC &&Type_Start=%&Type_End% + 2   //尾部加上两个字节的0x00 0x00
        //MESS aaa
        IFEX #%&type%=17,
        {*
            CALC &BIOS_INFO_Len=%&Type_Start% - %&data_offset% - %&Type_Start_Last%     //字符串区的长度
            GETF -find &SMBIOSTableData,(%&Type_Start_Last% + %&data_offset% )#%&BIOS_INFO_Len%##0#1#0,*&&BIOS_INFO_CharKeyWords,*&&CharKeyWords
            CALL Memory_Manufacturer &&Memory_vendor
            CALL Memory_Size &&Size
            CALL Memory_SerialNumber &&SerialNumber
            CALL Memory_PartNumber &&PartNumber
            CALL Memory_MemoryType &&MemoryType
            CALL Memory_Speed &&Speed
            MESS.
            \%&NL%品牌:%&Memory_vendor%
            \%&NL%大小:%&&Size%
            \%&NL%序列号:%&&SerialNumber%
            \%&NL%零件号:%&&PartNumber%
            \%&NL%内存类型:%&&MemoryType%
            \%&NL%速度:%&&Speed%
        }
    }
    _SUB Memory_Speed *
        //MESS %&Type_Start_Last%
        SET?wchar &SMBIOSTableData=&Speed:( %&Type_Start_Last% + 0x15 )
        CALC &Speed=%&Speed%
        ENVI-ret %1=%&Speed%
    _END
    _SUB Memory_MemoryType *
        SET?char &SMBIOSTableData=&MemoryType:( %&Type_Start_Last% + 0x12 )
        IFEX $%&MemoryType%=0x1A,ENVI &MemoryType=DDR4
        IFEX $%&MemoryType%=0x18,ENVI &MemoryType=DDR3
        IFEX $%&MemoryType%=0x13,ENVI &MemoryType=DDR2
        IFEX $%&MemoryType%=0x12,ENVI &MemoryType=DDR
        IFEX $%&MemoryType%=0x1B,ENVI &MemoryType=LPDDR
        IFEX $%&MemoryType%=0x1C,ENVI &MemoryType=LPDDR2
        IFEX $%&MemoryType%=0x1D,ENVI &MemoryType=LPDDR3
        IFEX $%&MemoryType%=0x1E,ENVI &MemoryType=LPDDR4
        IFEX $%&MemoryType%=0x23,ENVI &MemoryType=LPDDR5
        ENVI-ret %1=%&MemoryType%
    _END
    _SUB Memory_PartNumber *
        GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x1A )#1,&&PartNumber_CharNum
        CALL Get_Split_Dmi_Info "%&PartNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&PartNumber
        ENVI-ret %1=%&&PartNumber%
    _END    
    _SUB Memory_SerialNumber *
        GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x18 )#1,&&SerialNumber_CharNum
        CALL Get_Split_Dmi_Info "%&SerialNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&SerialNumber
        ENVI-ret %1=%&&SerialNumber%
    _END
    _SUB Memory_Size *
        //MESS %&Type_Start_Last%
        SET?wchar &SMBIOSTableData=&Size:( %&Type_Start_Last% + 0x0C )
        CALC &Size=%&Size%
        ENVI-ret %1=%&Size%
    _END
    _SUB Memory_Manufacturer *
        GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x17 )#1,&&BIOS_vendor_CharNum
        CALL Get_Split_Dmi_Info "%&BIOS_vendor_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&Memory_vendor
        ENVI-ret %1=%&&Memory_vendor%
    _END
    _SUB Get_Split_Dmi_Info
        ^ENVI &&CharNum=%~1     //字符串区域的第几个字符串>=1
        //MESS aaa
        IFEX $%&&CharNum%=0,
        {*
           EXIT
        }
        ^ENVI &&This_CharKeyWords=%&pdata_offset% %~2
        //MESS %&&This_CharKeyWords%
        CALC &&NextCharNum=%&&CharNum% + 1
        MSTR &&Start,&&End=<%&&CharNum%><%&&NextCharNum%>%&&This_CharKeyWords%
        GETF &SMBIOSTableData,( %&&Start% + 1 )#( %&&End% - %&&Start%),&&This_Info
        CODE ***ANSI,&&This_Info,**UNI,&&This_Info
        MSTR * -trim &This_Info=&This_Info
        //MESS %&&This_Info%
        ENVI-ret %3=%&This_Info%
    _END
    最后于 2023-9-12 被123编辑 ,原因:
    123
  • avatar image
    caocaofff 2023-9-12
    123 为什么粘贴代码直接就乱了 ENVI^ ENVIMODE=1 ENVI$ &NL=0d 0a //转换RSMB为DWORD----开始 CODE *,RSMB,*-ANSI,&F ...

    粘贴代码可以用“插入/编辑代码示例”功能

    image.webp

    官方QQ群:872611894(群密码:pecmd.net)
  • avatar image
    123 2023-9-12
    caocaofff 粘贴代码可以用&ldquo;插入/编辑代码示例&rdquo;功能

    原来是点这个,我用错了,点的第一个

    123
  • avatar image
    anson4 2023-9-12
    楼主   12
    123 从注册表读取(信息可能会有一些缺失): ENVI^ ENVIMODE=1ENVI$ &amp;NL=0d 0aREGI .HKEY_LOCAL_MACHINE\SYSTEM\CurrentC ...

    从注册表读取的这段,没获取到序列号,为啥呢?

    单机计算
  • avatar image
    123 2023-9-12
    anson4 从注册表读取的这段,没获取到序列号,为啥呢?

    具体我也没看,反正从注册表和api读取的原始结构都不一样,api读取的开头就是bios信息,注册表读取的直接就没有bios信息,其他的我也没细看

    123
  • avatar image
    anson4 2023-9-12
    楼主   14
    123 具体我也没看,反正从注册表和api读取的原始结构都不一样,api读取的开头就是bios信息,注册表读取的直接就没有bios信息,其他的我也没细看

    好的,谢谢!

    API有个缺点,就是在XP下用不了。

    单机计算
  • avatar image
    123 2023-9-12

    支持64位的

    Screenshot_20230912_214601_com.rainsee.create.webp

    123
  • avatar image
    anson4 2023-9-12
    楼主   16
    123 支持64位的

    32 位的 XP 偶尔还能遇到使用的,64 位的没遇到过。

    单机计算
  • avatar image
    爱心会员VIP会员
    527104427 2023-9-12
    123 从注册表读取(信息可能会有一些缺失): ENVI^ ENVIMODE=1 ENVI$ &amp;NL=0d 0a REGI .HKEY_LOCAL_MACHINE\SYSTEM\Curr ...

    我建议你到源码分享区开个帖子,方便别人搜索。

    https://www.123pan.com/s/NflRVv-Cm5Sh
  • avatar image
    123 2023-9-13
    527104427 我建议你到源码分享区开个帖子,方便别人搜索。

    好的

    123
返回