大家都知道很多Anti Cheat会封硬件序列号,所以本文探索一下如何get and modify序列号。
这个服务是比较贵的:
于是有了研究一下的想法。
思路:
1. 通过厂商自带的程序刷新固件。
2. 自己写驱动修改。
思路1不讨论,要拿到厂商去修改,很不方便。这里重点讨论思路2。
思路2是通过修改SMBIOS表,有两种方法,一种需要开机自启动,一种不需要,后面会介绍。
SMBIOS:
SMBIOS(System Management BIOS)是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范。
而DMI(Desktop Management Interface, DMI) 就是帮助收集电脑系统信息的管理系统。
DMI信息的收集必须在严格遵照SMBIOS规范的前提下进行。
两种方法都需要解析SMBIOS。
一、先介绍不需要重启的方法:
1.从物理内存 0x000F0000-0x000FFFFF 之间寻找关键字 “ _SM_” 。
2.找到后再向后16个字节,看后面5个BYTE是否是关键字“_DMI_”,如果是,EPS表即找到。
EPS表结构中16H以及18H处,得出数据表长度和数据表地址,即可通过地址访问 SMBIOS 数据结构表。
SMBIOS表结构由头和体组成,其中头的结构定义如下:
其中TYPE 0结构是BIOS information,TYPE 1结构是SYSTEM Information,其它类型大家查阅我附件里的文档。
总之是依据文档标准去解析。这里给出关键代码:
从而找到EPS和SMBIOS表。然后修改SMBIOS表中的字段。
这样可以修改CPU、主板、内存、硬盘序列号。
由于篇幅关系,先介绍到这里,具体代码见附件:GetSMBiosRing0.zip。
效果如下:
图右侧显示BIOS模式为"传统",代表BIOS,非UEFI。
二、再介绍需要重启的方法:
1.
先是想注册回调来修改,通过NtSetSystemInformation函数的
SystemRegisterFirmwareTableInformationHandler,见下面的WRK代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
|
编写代码:
1 2 3 4 5 6 |
|
发现ntStatus没有成功,返回STATUS_OBJECT_NAME_EXISTS,对象已经存在。
于是尝试先删除已经存在的,TableHandler.Register设置为FALSE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
发现还是删除不了Raw SMBIOS,第一次funZwSetSystemInfomation返回STATUS_INVALID_PARAMETER,
第二次返回STATUS_OBJECT_NAME_EXISTS。
然后查看上面ZwSetSystemInfomation对SystemRegisterFirmwareTableInformationHandler的处理
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
|
从上面返回的STATUS_OBJECT_NAME_EXISTS错误码和EX_FOR_EACH_IN_LIST代码:
1 2 3 4 5 6 7 8 |
|
推断出WmipRegisterFirmwareProviders函数中的g_PnpDriverObject不对。WRK中IoPnpDriverObject未导出。
2.Hook ExpFirmwareTableProviderListHead指针来修改硬件Id:
核心代码来自UC论坛,我对代码进行了简单的修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
|
函数指针替换成功,WmipRawSMBiosTableHandlerHook函数可以正确调用。
但是,不能修改SMBios数据,只能读取。
下面说下我想到的能够修改主板序列号的方法:
通过 WmipFindSMBiosStructure -> WmipSMBiosTablePhysicalAddress获得SMBios表的地址,然后找到
WmipFindSMBiosStructure -> WmipSMBiosTableLength获得SMBios表的长度。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
然后遍历、修改表。这里给出SMBios用到的几个结构体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
|
具体请见 https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.7.1.pdf
System Management BIOS (SMBIOS) Reference Specification。
然后遍历、修改表代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
|
具体代码见附件HardwareSNModify(fix版).7z,是对附件HardwareSNModify.rar的升级。
效果如下:
上面只截了UEFI的图,BIOS也同样有效果。
这里分别对不同类型的SMBIOS进行了修改,CPU、主板、内存、硬盘序列号。经过详细测试,稳定运行。
其实CPU虚拟化也可以修改CPU序列号,但考虑有些PC不开启VT,所以还是选择了上面的方法。
其余的序列号修改可以参考附件里的手册。
之前想着直接清空硬件序列号,但这种方法可能会被Anti-Cheat forbid。所以实现为Random序列号。
注意:
另外,若是需要重启的方法,驱动加载后需要修改注册表, 把Start键值改为1。如下图:
总结:
上文两种方法,不需要重启的方法,要求是BIOS引导。需要重启的方法,UEFI和BIOS的都兼容。第一种方法关于UEFI的下回再分解,第二种方法设置为开机启动,其实也很方便。
附件里还有SetupRwX64.exe,是上文所用到的RW工具。
拜拜,谢谢各位大佬阅读本文!