Como obtenho todas as strings VersionInfo de um arquivo .exe no prompt de comando do Windows?

1

Antes do Windows 10, era possível obter todas as strings VersionInfo clicando com o botão direito do mouse em um arquivo e fazendo propriedades. Isso não funciona mais. É como se alguém apenas decidisse mostrar os que adquiriram um significado padrão ao longo das décadas. Mas o GUI não importa, exceto por notar que ele não funciona, portanto, as chamadas COM para a página de propriedades não ajudarão. Queremos saber como na linha de comando de qualquer maneira.

Tentei:

PS> get-childitem .\execautablename | FormatList VersionInfo
PS> (get-item .\execautablename | format-list -force)
PS> get-childitem .\execautablename | ? {$_.VersionInfo.Xyz}
cmd> wmic datafile where Name="C:\Full\Path\to\executablename.exe" list full

O terceiro comando pode obter apenas algumas strings de versão, mas outras que eu conheço não estão lá.

É como se todas as formas agora conhecessem uma lista "padrão" (há duas ou três idéias sobre o que é a lista padrão) e nenhuma delas sabe como enumerar todas as cadeias VersionInfo mais. Eu tenho um binário com a string "ProductHash", que é o git commit hash do código-fonte correspondente usado para compilá-lo.

Eu continuo recebendo respostas sugeridas envolvendo {$_.VersionInfo} . Esse caminho nunca funcionará porque VersionInfo acredita em uma lista fixa de propriedades do versioninfo a serem recuperadas. O compilador rc e a estrutura VERSIONINFO PE acreditam de forma diferente. E o wmic tem uma lista fixa diferente que é recuperada.

Estaéapropriedade.Elesóapareceudepoisdeaplicar extensão do shell VersInfoEx do Fish linkado por postanote .

Snippit de origem ( recurso do Windows ):

#include <windows.h>

1 VERSIONINFO
FILEVERSION 10, 0, 0, 0
PRODUCTVERSION 10, 0, 0, 0
FILEFLAGSMASK 0
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "FileDescription", "Hello RC"
VALUE "FileVersion", "10.0.0.0"
VALUE "LegalCopyright", "Copyright (C) Cedaron Medical, Inc. 2018"
VALUE "InternalName", "hellorc"
VALUE "ProductHash", "Hello_World_abcdefgh" /* this is the value I'm after */
VALUE "ProductName", "Hello RC"
VALUE "ProductVersion", "10.0.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END

Eu consegui uma resposta realmente horrível e insatisfatória que não sabe nada sobre VERSIONINFO e lê em megabytes de arquivo e depende da maneira como está sendo instalado.

cmd> c:\cygwin64\bin\tr -d 
PS> Get-Content ".\executablename.exe" | % { if($_ -match "ProductHash") { write-host $_}}
PS>
< filename.exe | c:\cygwin64\bin\strings | c:\cygwin64\bin\grep ^^ProductHash. | c:\cygwin64\bin\sed s/ProductHash//

Isso funciona desde que o nome da string VERSIONINFO sendo pesquisado não esteja em outro lugar do binário. Espero que uma resposta ruim seja suficiente para explicar melhor a questão.

Tentando fazer a mesma coisa com o powershell sugerido pelo Pimp Juice IT não funcionou:

PS> Get-Content ".\executablename.exe" | c:\cygwin64\bin\tr.exe -d 
PS> get-childitem .\execautablename | FormatList VersionInfo
PS> (get-item .\execautablename | format-list -force)
PS> get-childitem .\execautablename | ? {$_.VersionInfo.Xyz}
cmd> wmic datafile where Name="C:\Full\Path\to\executablename.exe" list full
| % { if($_ -match "ProductHash") { write-host $_}} InternalNameexecutablenameh$ProductNameMyProductPProductVersion10.0.591.927r)ProductHash50acd7cedb99dddab69c5de9b2f021ef72d64ca0DVarFileInfo$Translation ????<?xml version="1.0" encoding="UTF-8" standalone="yes"?> PS>

Estava perto o suficiente de uma ideia de trabalho que eu era capaz de determinar por que não produzia nenhuma saída. Eu coloquei o tr do cygwin de volta no pipeline e o comando demorou tanto para ser executado. Eu pensei que ele tinha acabado, mas eventualmente consegui alguma saída.

#include <windows.h>

1 VERSIONINFO
FILEVERSION 10, 0, 0, 0
PRODUCTVERSION 10, 0, 0, 0
FILEFLAGSMASK 0
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "FileDescription", "Hello RC"
VALUE "FileVersion", "10.0.0.0"
VALUE "LegalCopyright", "Copyright (C) Cedaron Medical, Inc. 2018"
VALUE "InternalName", "hellorc"
VALUE "ProductHash", "Hello_World_abcdefgh" /* this is the value I'm after */
VALUE "ProductName", "Hello RC"
VALUE "ProductVersion", "10.0.0.0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END

Eu fiz um binário mínimo hello.zip (1313 bytes, descomprime para 4096 bytes). A chave versioninfo "ProductHash" tem o valor "Hello_World_abcdefgh".

Não seja enganado. ProductHash não é um hash do binário. É uma chave hash no repositório do código-fonte para encontrar o código-fonte do qual o binário foi compilado. A ideia é que, se alguém acaba com alguma versão estranha, podemos rastreá-la e determinar exatamente o código que ela possui. Em vez de fazer com que o cliente nos envie um arquivo grande, preferimos enviar um pequeno comando para obter o valor dele.

    
por Joshua 16.08.2018 / 01:50

2 respostas

3

Lógica final da solução de trabalho

Este script leva em consideração o layout atual da estrutura do versioninfo e trabalha com um parâmetro extra (o 1 ou 2 próximo ao final) para a paridade da string de entrada.

$versioninfostate = 0
(Get-Content "hello.exe" -Encoding Unicode) -split {$_ -lt " "} | % { if ($versioninfostate -eq 1) { write-host $_ } if ($versioninfostate -gt 0) { $versioninfostate = $versioninfostate - 1} if ($_ -match "ProductHash$") { $versioninfostate = 2 }}

Desenvolvimento do caminho final da solução

  1. "The last command can get only some version strings but not others I know are there"
    • Use Select * to get additional properties not shown with just Format-List

    •   
  2.   
  3. "Obter todas as cadeias do VersionInfo de um arquivo .exe"      
    • Pipe the exe over to % {$_.VersionInfo} to use Foreach-Object rather than Where-Object with $_.VersionInfo zeroing in on just its properties in one list/record set

    •   
  4.   
  5. "Não é possível resolver nomes de propriedades arbitrárias"      
    • Actually using the #1 & #2 as listed above you can (see below) enter image description here

    •   
  6.   
  7. "De acordo com sua última atualização, mostrando que você instalou um utilitário de terceiros recomendado por alguém em um comentário, esse software   parece ser de 2010 e projetado especificamente para o Windows 7. Em qualquer   caso, parece adicionar uma propriedade adicional chamada ProductHash como   por sua última captura de tela de atualização. "      
    • Use Get-FileHash and then explicitly get the hash value of the exe that way

    •   
  8.   

Abaixo está alguma lógica do PowerShell que. . .

  • Usa % em vez de ? para colocar o executável por Foreach-Object em vez de Where-Object
  • Usa Select * em vez de Format-List para garantir que o objeto da variável seja de System.Object BaseType em vez de usar System.Array como Format-List
  • Define uma variável com o valor da propriedade explícita conforme você especifica na VersionInfo list
  • Usa Get-FileHash para obter o valor de hash exe

PowerShell

$t = get-childitem ".\executablename" | % {$_.VersionInfo} | Select *
$Hash = (Get-FileHash $Exe).Hash
$t.<Property>, $Hash

Exemplo de saída

Coolest - www.CoolTool.com
30E14E358DD76EC712CCC6B5FD1E79DDEAA653E682E968DA0229BE13BED2B991

Objeto da lista VersionInfo

PS C:\WINDOWS\system32> get-childitem ".\executablename" | % {$_.VersionInfo} | Select *


FileVersionRaw     : 1.80.0.0
ProductVersionRaw  : 1.80.0.0
Comments           : 
CompanyName        : Coolest - www.CoolTool.com
FileBuildPart      : 0
FileDescription    : Program - Cool memory analyzer
FileMajorPart      : 1
FileMinorPart      : 80
FileName           : C:\Users\User\Desktop\Coolio.exe
FilePrivatePart    : 0
FileVersion        : 1.80
InternalName       : TooCool
IsDebug            : False
IsPatched          : False
IsPrivateBuild     : False
IsPreRelease       : False
IsSpecialBuild     : False
Language           : English (United States)
LegalCopyright     : Copyright © 1985-2099 Michael Jordan
LegalTrademarks    : 
OriginalFilename   : Coolio
PrivateBuild       : 
ProductBuildPart   : 0
ProductMajorPart   : 1
ProductMinorPart   : 80
ProductName        : TooCool
ProductPrivatePart : 0
ProductVersion     : 1.80
SpecialBuild       : 

Pesquisar conteúdo da sequência binária

Observação: Assim como os comandos cygwin cli string , grep e outros procuram o binário do arquivo para corresponder à string "ProductHash" , você pode ler isto de comandos semelhantes do PowerShell também.

$Match = (Get-Content ".\executablename") -replace "'0", "" | % {if($_ -match "(ProductHash)") {$Matches[0]}}
$Line  = (Get-Content ".\executablename") -replace "'0", "" | % {if($_ -match "(ProductHash)") {$_}} | % {if($_ -match "(ProductHash).*$") {$Matches[0]}} 
$Line  = $Line -replace "[\W]", "'r'n" | % {if($_ -match "(ProductHash).*\s") {$Matches[0]}}
$MisMatch = $Line.Replace($Match, "")
Write-Output "$Match': $MisMatch"

Example Output

ProductHash: Hello_World_abcdefgh2

Mais recursos

por 16.08.2018 / 20:37
1

Eu fiz isso em um executável e vejo as informações da versão na guia detalhes. Então, eu sou uma espécie de perda sobre o que você quer dizer com isso.

Esta abordagem PS também está documentada aqui:

link

No meu cliente Win10

 (Get-CimInstance -CimInstance Win32_OperatingSystem).Caption
Microsoft Windows 10 Pro

 $PSVersionTable

Name                           Value                                                                                                                                       
----                           -----                                                                                                                                       
PSVersion                      5.1.17134.228                                                                                                                               
PSEdition                      Desktop                                                                                                                                     
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.228}                                                                                                    
BuildVersion                   10.0.17134.228                                                                                                                              
CLRVersion                     4.0.30319.42000                                                                                                                             
WSManStackVersion              3.0                                                                                                                                         
PSRemotingProtocolVersion      2.3                                                                                                                                         
SerializationVersion           1.1.0.1                                                                                                                                     



 (Get-Item -Path 'F:\Downloads\WindowsAzureADRightsManagementAdministration_x64.exe').VersionInfo | Format-List -Force 


OriginalFilename  : setup.exe
FileDescription   : Software Installer
ProductName       : Windows Azure AD Rights Management Administration
Comments          : 
CompanyName       : Microsoft Corporation
FileName          : F:\Downloads\WindowsAzureADRightsManagementAdministration_x64.exe
FileVersion       : 1.0.594.1
ProductVersion    : 1.0.594.1
IsDebug           : False
IsPatched         : False
IsPreRelease      : False
IsPrivateBuild    : False
IsSpecialBuild    : False
Language          : English (United States)
LegalCopyright    : Copyright (c) Microsoft Corporation. All rights reserved.
LegalTrademarks   : Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the U.S. and/or other countries.
PrivateBuild      : **************************************
SpecialBuild      : 
FileVersionRaw    : 1.0.594.1
ProductVersionRaw : 1.0.594.1
    
por 16.08.2018 / 07:08