解读 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;
  v43 =0;
  v44 =0;
  v45 =0;
  lpString1 =a1;
  phkResult =0;
  v48 =0;
  lpString2 =0;
  v3 =0;
  v4 =RegOpenKeyExW(
         HKEY_LOCAL_MACHINE,
         L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ComponentBased Servicing\\Version",
         0,
         0x20019u,
         &phkResult);
  v5 =v4 < 0;
  if (v4 > 0)
    v5 =(((unsigned __int16)v4 | 0x80070000) & 0x80000000) != 0;
  if (v5 )
  {
LABEL_98:
    v15 =-2147023728;
    CBSWdsLog(0x4000000, -2147023728, 1, "Failed to find a matching version for servicing stack:%S", lpString1);
    goto LABEL_64;
  }
  for
(i = 0;; i = dwIndex + 1 )
  {
    dwIndex =i;
    memset(&Dst, 0,0x206u);
    v7 =phkResult;
    v51 =260;
    ValueName =0;
    Type =0;
    cbData =0;
    cchValueName = 260;
    v8 =RegEnumValueW(phkResult, i, &ValueName, &cchValueName,0, &Type,0, &cbData);
    if (v8 > 0)
      v9 =(unsigned __int16)v8 | 0x80070000;
    else
      v9 =v8;
    if (v8 != 259)
    {
      if
(v9 < 0)
      {
        CBSWdsLog(0x4000000, v9, 1, "Failed to RegEnumValue.");
        goto LABEL_14;
      }
      if
(Type != 2&& Type != 1 )
      {
        v9 =-2147024883;
        CBSWdsLog(0x4000000, -2147024883, 1, "Registry value for %S is not a dword type.",&ValueName);
        v15 =-2147024883;
LABEL_74:
        CBSWdsLog(0x4000000, v9, 1, "Failed to enumerate all servicing stackversions.");
        goto LABEL_64;
      }
      v10 =(cbData >>1) + 1;
      if (v10 > 0x3FFFFFFF)
      {
        v37 =-2147317563;
        CBSWdsLog(0x4000000, -2147317563, 1, "string sizetoo big");
LABEL_77:
        v9 =v37;
        CBSWdsLog(0x4000000, v37, 1, "Failed to allocate string to enum registry value:%S", &ValueName);
        v3 =v48;
        goto LABEL_14;
      }
      v11 =(wchar_t *)operator new(2 * v10 + 4);
      EndPtr =v11;
      if (!v11 )
      {
        v37 =-2147024882;
        CBSWdsLog(0x4000000, -2147024882, 1, "Failed to allocate string");
        goto LABEL_77;
      }
      *
(_DWORD *)v11 =v10;
      v12 =(BYTE *)(v11 + 2);
      *(_WORD *)v12 = 0;
      v9 =0;
      v13 =RegEnumValueW(v7, dwIndex, &ValueName, &v51,0, &Type,v12, &cbData);
      if (v13 )
      {
        if
( v13 > 0 )
          v9 =(unsigned __int16)v13 | 0x80070000;
        else
          v9 =v13;
        CBSWdsLog(0x4000000, v9, 1, "Failed to enum value after it already existedonce.");
        operator delete(EndPtr);
        v3 =v48;
      }
      else
      {

        v14 =EndPtr;
        EndPtr[v10+ 1] = 0;
        v3 =v14 + 2;
        v48 =v14 + 2;
      }
    }

LABEL_14:
    v15 =v9;
    if (v9 == -2147024637 )
      break;
    if (v9 < 0)
      goto LABEL_74;
    v15 =FileExpandPath(v3, (WCHAR**)&lpString2);
    if (v15 < 0)
    {
      CBSWdsLog(0x4000000, v15, 1, "Failed to expand path from onine store: %S",lpString2);
      goto LABEL_64;
    }
    v15 =0;
    v16 =lpString2;
    if (lpString2[wcslen(lpString2) - 1] != 92 )
    {
      v17 =0;
      EndPtr =0;
      v18 =0;
      if (lpString2 )
      {
        v17 =*((_DWORD*)lpString2- 1);
        v18 =wcslen(lpString2);
      }
      if
(v17 < v18 + 2 )
      {
        v38 =operator new(2 * (v18 + 2) + 4);
        if ( v38 )
        {
          v39 =(WCHAR *)lpString2;
          *v38= v18 +2;
          v40 =v38 + 1;
          if ( v39 )
            memcpy(v40, v39, 2 * v18 +2);
          else
            *
(_WORD *)v40 = 0;
          v16 =(const WCHAR *)v40;
          EndPtr = v39;
          v17 =v18 + 2;
          lpString2 = v16;
          goto LABEL_21;
        }
        v27 =-2147024882;
        CBSWdsLog(0x4000000, -2147024882, 1, "Failed to allocate string");
        v15 =-2147024882;
      }
      else
      {

LABEL_21:
        v15 =0;
        if ( !v17 || v17 >0x7FFFFFFF )
          v15 =-2147024809;
        if ( v15 >= 0 )
        {
          v15 =0;
          v19 =v17;
          v20 =v16;
          if ( v17 )
          {
            while
( *v20 )
            {
              ++
v20;
              if ( !--v19 )
                goto LABEL_90;
            }
            if
( v19 )
            {
              v21 = v17 -v19;
              goto LABEL_30;
            }
          }

LABEL_90:
          v15 =-2147024809;
        }
        v21 =0;
LABEL_30:
        if ( v15 >= 0 )
        {
          v15 =0;
          v22 =&lpString2[v21];
          v23 =v17 - v21;
          if ( v17 ==v21 )
            goto LABEL_92;
          v24 =v23 - v17 +v21 + 2147483646;
          v25 =(char *)((char *)L"\\" - (char*)v22);
          while ( v24 )
          {
            v26 = *(_WORD *)&v25[(_DWORD)v22];
            if ( !v26 )
              break;
            *v22= v26;
            --v24;
            ++v22;
            if ( !--v23 )
              goto LABEL_92;
          }
          if
( !v23 )
          {
LABEL_92:
            --v22;
            v15 = -2147024774;
          }
          *
v22= 0;
        }
        v27 =v15;
        if ( v15 < 0 )
          CBSWdsLog(0x4000000, v15, 1, "Failed to concatstring.");
        if ( EndPtr )
          operator delete(EndPtr -2);
        if ( v15 >= 0 )
        {
LABEL_45:
          v3 =v48;
          v16 =lpString2;
          goto LABEL_46;
        }
      }

      CBSWdsLog(0x4000000, v27, 1, "Failed to concat backslash onto string.");
      goto LABEL_45;
    }
LABEL_46:
    if (v15 < 0)
    {
      CBSWdsLog(0x4000000, v15, 1, "Failed to ensure path to online store is backslashterminated: %S", v16);
      goto LABEL_64;
    }
    if
(CompareStringW(0x7Fu, 1u, lpString1, -1, v16, -1) == 2 )
    {
      EndPtr =&ValueName;
      v28 =_wcstoul(&ValueName,&EndPtr, 10);
      if (EndPtr )
      {
        if
( 46 ==*EndPtr )
        {
          v29 =v28 << 16;
          ++EndPtr;
          v30 =_wcstoul(EndPtr, &EndPtr,10);
          if ( EndPtr )
          {
            if
( 46 == *EndPtr)
            {
              v31 = v30 |v29;
              ++EndPtr;
              v32 = _wcstoul(EndPtr,&EndPtr, 10);
              if ( EndPtr )
              {
                if
( 46 == *EndPtr)
                {
                  v33 = v32 <<16;
                  ++EndPtr;
                  v34 = _wcstoul(EndPtr,&EndPtr, 10);
                  if ( EndPtr )
                  {
                    if
( !*EndPtr)
                    {
                      v35 = v34 |v33;
                      if ( v31 >v44 || v31 == v44 &&v35 > v45 )
                      {
                        v43 = 1;
                        v44 = v31;
                        v45 = v35;
                      }
                    }
                  }
                }
              }

              v3 = v48;
            }
          }
        }
      }
    }
    if
(v3 )
    {
      operator delete
((void *)(v3 - 2));
      v3 =0;
      v48 =0;
    }
  }

  v15 =0;
  if (!v43 )
    goto LABEL_98;
  *v41= v44;  // a2,输出
  *a3= v45;   //    输出
LABEL_64:  // 清理
  if (lpString2 )
    operator delete((void *)(lpString2 -2));
  if (v3 )
    operator delete((void *)(v3 - 2));
  if (phkResult )
    RegCloseKey(phkResult);
  return v15;
}

解读 FindServicingStackDirectoryVersion相关推荐

  1. Python Re 模块超全解读!详细

    内行必看!Python Re 模块超全解读! 2019.08.08 18:59:45字数 953阅读 121 re模块下的函数 compile(pattern):创建模式对象 > import ...

  2. Bert系列(二)——源码解读之模型主体

    本篇文章主要是解读模型主体代码modeling.py.在阅读这篇文章之前希望读者们对bert的相关理论有一定的了解,尤其是transformer的结构原理,网上的资料很多,本文内容对原理部分就不做过多 ...

  3. Bert系列(三)——源码解读之Pre-train

    https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...

  4. NLP突破性成果 BERT 模型详细解读 bert参数微调

    https://zhuanlan.zhihu.com/p/46997268 NLP突破性成果 BERT 模型详细解读 章鱼小丸子 不懂算法的产品经理不是好的程序员 ​关注她 82 人赞了该文章 Goo ...

  5. 解读模拟摇杆原理及实验

    解读模拟摇杆原理及实验 Interpreting Analog Sticks 当游戏支持控制器时,玩家可能会一直使用模拟摇杆.在整个体验过程中,钉住输入处理可能会对质量产生重大影响.让来看一些核心概念 ...

  6. 自监督学习(Self-Supervised Learning)多篇论文解读(下)

    自监督学习(Self-Supervised Learning)多篇论文解读(下) 之前的研究思路主要是设计各种各样的pretext任务,比如patch相对位置预测.旋转预测.灰度图片上色.视频帧排序等 ...

  7. 自监督学习(Self-Supervised Learning)多篇论文解读(上)

    自监督学习(Self-Supervised Learning)多篇论文解读(上) 前言 Supervised deep learning由于需要大量标注信息,同时之前大量的研究已经解决了许多问题.所以 ...

  8. 可视化反投射:坍塌尺寸的概率恢复:ICCV9论文解读

    可视化反投射:坍塌尺寸的概率恢复:ICCV9论文解读 Visual Deprojection: Probabilistic Recovery of Collapsed Dimensions 论文链接: ...

  9. 从单一图像中提取文档图像:ICCV2019论文解读

    从单一图像中提取文档图像:ICCV2019论文解读 DewarpNet: Single-Image Document Unwarping With Stacked 3D and 2D Regressi ...

最新文章

  1. Nginx源码研究之nginx限流模块详解
  2. SourceInsight下面一直出现unable to write to temp file for saving operation 这样的提示
  3. Oracle DB_LINK如何使用
  4. 关于概率性事件的产品性能和客户体验讨论
  5. 智能替换DataTable.Select中会导致错误的单引号 的另一种算法实现.
  6. springmvc上传图片后显示损毁或不能显示_猿蜕变系列7——也说说springMVC上传姿势...
  7. 一个白学家眼里的 WebAssembly
  8. mybatis plus使用
  9. 手把手带你免费申请《软件著作权》 超详细计算机软件著作权申请教程 文末送模板
  10. CGLIB动态代理使用介绍
  11. 华为云服务器安全组设置
  12. android网络编程-socket基础
  13. Am3358增加Uboot的logo显示 增加Uboot自定义命令控制LCD
  14. 曲面显示器和平面显示器玩游戏买哪个好
  15. 轻松几步获得上万点击率(三)
  16. sql - repalce函数
  17. cat /etc/sysconfig/network-scripts/ifcfg-ens33
  18. Chicken Soup 【阻碍你成长的最大敌人竟然是它-无意识】
  19. 【GP】Greenplum入门解析(一)
  20. Informix IDS 11琐屑管理(918测验)认证指南,第 7 部分: IDS复制(20)

热门文章

  1. 共享单车行业首起并购:永安行子公司收购哈罗单车
  2. 为什么人工智能机器人多女性
  3. 12月19日绝地求生服务器维护公告,绝地求生12月19日更新到几点能玩 绝地求生正式服更新维护公告...
  4. 2022,Cerebro(码小二)V3.0来啦!
  5. android 修改 dpi_设计规范 | Android系统
  6. Android 亮度调节的方法
  7. python怎么做笔记本(文本编辑器)
  8. 自动化运维工具——SaltStack(上)
  9. 查看python所支持的whl文件类型
  10. Python试卷自动生成器