【问题标题】:Does (get-item $file).GetHashCode() calculate the hash on the fly like get-filehash or used a pre-computed hash?(get-item $file).GetHashCode() 是像 get-filehash 一样即时计算哈希还是使用预先计算的哈希?
【发布时间】:2022-10-02 07:32:10
【问题描述】:

我们正在开发一个用于取证基线分析的 PowerShell 脚本,该脚本递归地遍历文件系统,记录目录和文件的层次结构,文件名映射到哈希并将该数据转储到 JSON。由于我们有兴趣对系统上的每个文件执行此操作,因此它需要尽可能快。

小型测试目录的理想输出如下:

{
    \"\\\\3D Objects\":  {

                     },
    \"\\\\Contacts\":  {

                   },
    \"\\\\Desktop\":  {
                      \"\\\\that\":  {
                                     \"\\\\somedoc\":  \"@{textdoc.txt=C700784FAD1A992A90D71CBC1ADB0F22BF286AD6FE4C9BF42A0407BAF8F3D068}\",
                                     \"bruh.txt\":  \"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855\",
                                     \"eula.lnk\":  \"FD068EACB3CC0C1ED2F246542426680F255614791BCD4E0EC615A4B1CEF1F0FA\"
                                 },
                      \"\\\\this\":  {
                                     \"\\\\another folder\":  \"@{\\\\kelp=; thebesometext.txt=BE47BDE1B74F38E47064C1185A1AC8261C9EEEBE9D32ACF25047F5BC4EB5BC8D}\",
                                     \"ok.txt\":  \"C5273884B90D490134E7737B29A65405CEA0F7BB786CA82C6337CEB24DE6F5ED\",
                                     \"sample.txt\":  \"766D6A6A2330070C98D2AD44C9A4345DB8C6E65BAECC82B6D2CF801126F98DF6\"
                                 },
                      \"192.168.176.131_Scraped_Files.zip\":  \"153891A4A3951D9D86C0DFC3F1D9B5FB7886EC754237B078C5657E271A8EC5FB\",
                      \"bruh.rar\":  \"BA9B9AD700B82029AEC0DAE52B06E4A09C60255D996DD5A40F7DED61D3DD2795\",
                      \"FileSystemtoJSON.ps1\":  \"2E8C2CDFD495DB137B7B46A7FDAC6040E51CD6464D5B9C84B67F179D2B7A9C2B\",
                      \"File_Scraper.ps1\":  \"7BFD3600894D39CEEB1BE921C24A3BCDB58C4CE1114D376DB908A95F2CF49FC1\",
                      \"FStoJson.ps1\":  \"FACF2C77FA004502C10066E8757D31B1A134878345965F60B80D5CC7CF2A2B44\"
                  },
    \"\\\\Documents\":  {
                        \"\\\\WindowsPowerShell\":  {

                                                }
                    },
    \"\\\\Downloads\":  {
                        \"winrar-x64-611.exe\":  \"24FC7955FADA6B9802F4E50E935EBD5654FD7382FAF641B27DD626F4B3563974\"
                    },
    \"\\\\Favorites\":  {
                        \"\\\\Links\":  {

                                    },
                        \"Bing.url\":  \"E0C0A5A360482B5C5DED8FAD5706C4C66F215F527851AD87B31380EF6060696E\"
                    },
    \"\\\\Links\":  {
                    \"Desktop.lnk\":  \"B559BF8483620D2C64B12901AAC7CAB21219F750E97FFC7FFC2808A7B5B9648D\",
                    \"Downloads.lnk\":  \"A0F8549CAB3926988971D8738CB9DE27964B6B47707674A3419DDCCA82935565\"
                },
    \"\\\\Music\":  {

                },
    \"\\\\OneDrive\":  {

                   },
    \"\\\\Pictures\":  {
                       \"\\\\Camera Roll\":  {

                                         },
                       \"\\\\Saved Pictures\":  {

                                            }
                   },
    \"\\\\Saved Games\":  {

                      },
    \"\\\\Searches\":  {
                       \"winrt--{S-1-5-21-321011808-3761883066-353627080-1000}-.searchconnector-ms\":  \"3B33937704E0EBEC50DD91E982DD4CADDC1ED0DB23864AB28A14A43910C393D0\"
                   },
    \"\\\\Videos\":  {

                 }
}

我们原来的脚本是这样的:

$root = [PSCustomObject]@{}

function FSSkimmer {
Param(
[Parameter(Mandatory=$True)][string]$path,
[Parameter(Mandatory=$True)][PsCustomObject]$currentobject)

$paths = gci $path | Select-Object -ExpandProperty Fullname
    foreach ($file in $paths) { 
        if (!$(get-item $file | Select-Object -ExpandProperty PSiscontainer)) {
            $name = get-item $file | Select-Object -ExpandProperty Name
            $hash = Get-FileHash $file -Algorithm SHA256 | Select-Object -ExpandProperty Hash
            $currentobject | Add-Member -MemberType NoteProperty -Name $name -Value $hash
        }
        else {
            $dir_name = get-item $file | Select-Object -ExpandProperty Name
            $dir = [PSCustomObject]@{}
            $currentobject | Add-Member -MemberType NoteProperty -Name \"\\$($dir_name)\" -Value $(FSSkimmer -path $file -currentobject $dir)
        }
    }
return $currentobject
}

$null = FSSkimmer -path \"C:\\\" -currentobject $root

ConvertTo-Json -InputObject $root

这很慢。将哈希算法从 Sha-256 减少到计算成本较低的算法确实有助于提高速度。但我注意到另一种选择:

(get-item $file).GetHashCode()

这种方法与get-filehash 有什么根本不同吗?它是否使用 Windows 存储的一些预先计算的哈希? (我知道文件资源管理器在您拉取属性时会显示一个哈希,但不知道这个哈希是在每次文件写入时缓存还是在每次打开属性时动态计算。我怀疑出于某种原因这可能是PS中暴露的相同功能。

  • \"哈希码是一个数值,用于在基于哈希的集合中插入和标识对象,例如 Dictionary<TKey,TValue> 类、Hashtable 类或从 DictionaryBase 类派生的类型。GetHashCode方法为需要快速检查对象相等性的算法提供此哈希码。\"(这与 Get-FileHashHashAlgorithm.ComputeHash 提供的文件哈希不同)
  • 在之前的 cmets 之后,有一些方法可以改善脚本运行时,例如,不使用很慢的 gci,不使用 add-member 而是创建一个类,使用 collections.queue 而不是递归等。 .
  • 结果是一个int32,它也用于哈希表索引和其他面向哈希的查找集合。它不像您使用的其他产品那么强大......但它enuf 用于“这可能和那个一样吗?”测试。 [咧嘴笑]
  • @Lee_Dailey 是的,我负担不起,因为我的用例是取证,攻击者可以使用哈希冲突来使恶意软件具有与良性事物相同的哈希。
  • @J.Todd - 酷!如果您需要更快的速度……有一些方法可以加快您的代码速度。 ///// [1] 在代码审查站点上发布/移动您的问题。 ///// [2] 将Get-ChildItem 替换为robocopy。第二个可以只给你完整的文件名而不改变任何东西。 ///// [3] 使用针对速度进行了优化的第 3 方哈希实用程序。 ///// [4] 使用[PSCustomObject] 而不是Add-Member 构建您的输出对象。

标签: powershell


【解决方案1】:

只是检查一下。创建一些文件夹,将相同的文件复制到其中并运行如下内容:

$tmp=Get-ChildItem -Path 'D:\test' -Recurse
foreach ($file in $tmp) {
  Get-FileHash -Path $file.FullName -Algorithm MD5 
  Write-Host $file.GetHashCode()
  Write-Host ($file.name).GetHashCode()
}

您会看到,FileHash 是相同的,但 HashCode 在第一种情况下不同,在第二种情况下相同。我认为 .GetHashCode() 适用于对象属性(名称、长度、路径等),但不适用于对象的“内容”

【讨论】:

    猜你喜欢
    • 2016-06-23
    • 2017-03-06
    • 1970-01-01
    • 2020-11-01
    • 2017-02-04
    • 2012-04-14
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多