解读 FindServicingStackDirectoryVersion
功能:
找到当前版本的 Servicing Stack的目录的版本号,
用输入的目录与保存在注册表中的值进行对照。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ComponentBased Servicing\Version
比如,可能是这样的值:
10.0.14393.693:%SystemRoot%\winsxs\amd64_microsoft-windows-servicingstack_31bf3856ad364e35_10.0.14393.693_none_42ff55c9655f38bf
在这个目录下,保存了这样一些文件:
amd64_installed
CbsCore.dll
CbsMsg.dll
cmiadapter.dll
cmiaisupport.dll
dpx.dll
drupdate.dll
drvstore.dll
GlobalInstallOrder.xml
msdelta.dll
mspatcha.dll
poqexec.exe
smiengine.dll
smipi.dll
TiFileFetcher.exe
TiWorker.exe
WcmTypes.xsd
wcp.dll
wdscore.dll
wrpint.dll
这不是导出函数,所以,还是要用直接地址法调用该函数。
a1:输入参数,Servicing Stack的目录,比如c:\\windows\\winsxs\\x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.3.9600.18384_none_9dfef83fe2e442e4\\
a2:输出参数,版本号的前两位,比如:0x00060003,即,6.3;
a3:输出参数,版本号的前两位,比如:0x258047d0,即:9600.18384。
这个函数本身并不很重要,但是,其中有几点是值得注意的:
1、计算Servicing Stack版本号的过程十分复杂,不是简单地把目录中的数值读出来就行了;
2、匹配Servicing Stack版本,需要同时满足这样几个条件:首先,能正确读出 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\ComponentBased Servicing\Version 注册表项,其次,
3、读注册表的函数RegOpenKeyExW
v4 =RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ComponentBased Servicing\\Version",
0,
0x20019u,
&phkResult);
不仅能读到 HKEY_LOCAL_MACHINE\SOFTWARE,还能读到 HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node,且完全是由 RegOpenKeyExW 自身所控制,不需要人为参与。
4、读出来的路径是内部表示形式,与实际的路径不同,用 FileExpandPath 函数进行扩展:
v15 =FileExpandPath(v3, (WCHAR**)&lpString2);
直接读出来的值:
%SystemRoot%\winsxs\amd64_microsoft-windows-servicingstack_31bf3856ad364e35_10.0.14393.693_none_42ff55c9655f38bf
经过函数 FileExpandPath的扩展以后,变成:
c:\\windows\\winsxs\\x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.3.9600.18384_none_9dfef83fe2e442e4
5、路径的比较使用CompareStringW函数
CompareStringW(0x7Fu,1u, lpString1, -1, v16, -1) == 2
在比较前,还要保证是字符串的后面加上 \。
更好的函数,即直接读 Servicing Stack 目录的函数在 ssshim.dll 中,GetServicingStackFilePath,在 dism 中调用,SsShimInterface::GetServicingStackFilePath。
很好的消息是,GetServicingStackFilePath是导出函数。
调用方法:
v16 =SsShimInterface::InternalBindServicingStack(
(SsShimInterface *)&hLibModule,*v6, v24, v72, v69, v64, v65);
v16 = SsShimInterface::GetServicingStackFilePath(
(SsShimInterface*)&hLibModule,
L"cbscore.dll",
(unsigned__int16 **)&lpMem);
//----- (10095990)--------------------------------------------------------
int __fastcall FindServicingStackDirectoryVersion(
const WCHAR*a1,
unsigned int *a2,
unsigned int *a3)
{
v41 =a2;
v4