解讀 FindServicingStackDirectoryVersion

解讀 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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章