Get Version of exe via PHP

前端 未结 8 1396
自闭症患者
自闭症患者 2020-12-08 11:14

Is getting the version of a exe possible with php? I\'d like to print the version of a file that can be downloaded...

Windows exe and php is running on linux server<

相关标签:
8条回答
  • 2020-12-08 11:44

    For me to get the code from Toni to work I had to do a small change:

    function GetFileVersion($FileName) {
    
    $handle=fopen($FileName,'rb');
    if (!$handle) return FALSE;
    $Header=fread ($handle,64);
    if (substr($Header,0,2)!='MZ') return FALSE;
    $PEOffset=unpack("V",substr($Header,60,4));
    if ($PEOffset[1]<64) return FALSE;
    fseek($handle,$PEOffset[1],SEEK_SET);
    $Header=fread ($handle,24);
    if (substr($Header,0,2)!='PE') return FALSE;
    $Machine=unpack("v",substr($Header,4,2));
    if ($Machine[1]!=332) return FALSE;
    $NoSections=unpack("v",substr($Header,6,2));
    $OptHdrSize=unpack("v",substr($Header,20,2));
    fseek($handle,$OptHdrSize[1],SEEK_CUR);
    $ResFound=FALSE;
    for ($x=0;$x<$NoSections[1];$x++) {      //$x fixed here
        $SecHdr=fread($handle,40);
        if (substr($SecHdr,0,5)=='.rsrc') {         //resource section
            $ResFound=TRUE;
            break;
        }
    }
    if (!$ResFound) return FALSE;
    $InfoVirt=unpack("V",substr($SecHdr,12,4));
    $InfoSize=unpack("V",substr($SecHdr,16,4));
    $InfoOff=unpack("V",substr($SecHdr,20,4));
    fseek($handle,$InfoOff[1],SEEK_SET);
    $Info=fread($handle,$InfoSize[1]);
    $NumDirs=unpack("v",substr($Info,16,2));
    $InfoFound=FALSE;
    for ($x=0;$x<$NumDirs[1];$x++) {
        $Type=unpack("V",substr($Info,($x*8)+16,4));
        if($Type[1]==16) {             //FILEINFO resource
            $InfoFound=TRUE;
            $SubOff=unpack("V",substr($Info,($x*8)+20,4));
            break;
        }
    }
    if (!$InfoFound) return FALSE;
    $SubOff[1]&=0x7fffffff;
    $InfoOff=unpack("V",substr($Info,$SubOff[1]+20,4)); //offset of first FILEINFO
    $InfoOff[1]&=0x7fffffff;
    $InfoOff=unpack("V",substr($Info,$InfoOff[1]+20,4));    //offset to data
    $DataOff=unpack("V",substr($Info,$InfoOff[1],4));
    $DataSize=unpack("V",substr($Info,$InfoOff[1]+4,4));
    $CodePage=unpack("V",substr($Info,$InfoOff[1]+8,4));
    $DataOff[1]-=$InfoVirt[1];
    $Version=unpack("v4",substr($Info,$DataOff[1]+48,8));
    $x=$Version[2];
    $Version[2]=$Version[1];
    $Version[1]=$x;
    $x=$Version[4];
    $Version[4]=$Version[3];
    $Version[3]=$x;
    return $Version;
    }
    

    Where I only changed 14 to 16 in the line

    $NumDirs=unpack("v",substr($Info,16,2));
    

    Maybe this has something to do with what j_schultz already added in the comments.

    0 讨论(0)
  • 2020-12-08 11:49

    I combined the answers together and added the NamedDirs fix. Also want to highlight not to use the code by NeuD, the offset should remain 16; 14 is definitely wrong. Hope it helps someone.

    function GetFileVersion($FileName)
    {
        return GetValueOfSeeking($FileName, "FileVersion");
    }
    
    function GetValueOfSeeking($FileName, $seeking)
    {
        $handle = fopen($FileName, 'rb');
        if (!$handle) return FALSE;
        $Header = fread($handle, 64);
    
        if (substr($Header, 0, 2) != 'MZ') return FALSE;
    
        $PEOffset = unpack("V", substr($Header, 60, 4));
        if ($PEOffset[1]<64) return FALSE;
    
        fseek($handle, $PEOffset[1], SEEK_SET);
        $Header = fread ($handle, 24);
    
        if (substr($Header, 0, 2) != 'PE') return FALSE;
    
        $Machine = unpack("v", substr($Header, 4, 2));
        if ($Machine[1] != 332) return FALSE;
    
        $NoSections = unpack("v", substr($Header, 6, 2));
        $OptHdrSize = unpack("v", substr($Header, 20, 2));
        fseek($handle, $OptHdrSize[1], SEEK_CUR);
    
        $ResFound = FALSE;
        for ($x = 0; $x < $NoSections[1]; $x++)
        {
            //$x fixed here
            $SecHdr = fread($handle, 40);
            if (substr($SecHdr, 0, 5) == '.rsrc')
            {
                //resource section
                $ResFound = TRUE;
                break;
            }
        }
    
        if (!$ResFound) return FALSE;
        $InfoVirt = unpack("V", substr($SecHdr, 12, 4));
        $InfoSize = unpack("V", substr($SecHdr, 16, 4));
        $InfoOff = unpack("V", substr($SecHdr, 20, 4));
    
        fseek($handle, $InfoOff[1], SEEK_SET);
        $Info = fread($handle, $InfoSize[1]);
    
        $NumNamedDirs = unpack("v",substr($Info, 12, 2));
        $NumDirs = unpack("v", substr($Info, 14, 2));
    
        $InfoFound = FALSE;
        for ($x = 0; $x < ($NumDirs[1] + $NumNamedDirs[1]); $x++)
        {
            $Type = unpack("V", substr($Info, ($x * 8) + 16, 4));
            if($Type[1] == 16)
            {
                //FILEINFO resource
                $InfoFound = TRUE;
                $SubOff = unpack("V", substr($Info, ($x * 8) + 20, 4));
                break;
            }
        }
    
        if (!$InfoFound) return FALSE;
    
        if (0)
        {
            $SubOff[1]  &= 0x7fffffff;
            $InfoOff    = unpack("V", substr($Info, $SubOff[1] + 20, 4)); //offset of first FILEINFO
            $InfoOff[1] &= 0x7fffffff;
            $InfoOff    = unpack("V", substr($Info, $InfoOff[1] + 20, 4));    //offset to data
            $DataOff    = unpack("V", substr($Info, $InfoOff[1], 4));
            $DataSize   = unpack("V", substr($Info, $InfoOff[1] + 4, 4));
            $CodePage   = unpack("V", substr($Info, $InfoOff[1] + 8, 4));
            $DataOff[1] -= $InfoVirt[1];
            $Version    = unpack("v4", substr($Info, $DataOff[1] + 48, 8));
            $x          = $Version[2];
            $Version[2] = $Version[1];
            $Version[1] = $x;
            $x          = $Version[4];
            $Version[4] = $Version[3];
            $Version[3] = $x;
    
            return $Version;
        }
    
        //view data...
        //echo print_r(explode("\x00\x00\x00", $Info));
        // could prolly substr on VS_VERSION_INFO
        $encodedKey = implode("\x00",str_split($seeking));
        $StartOfSeekingKey = strpos($Info, $encodedKey);
        if ($StartOfSeekingKey !== false) {
            $ulgyRemainderOfData = substr($Info, $StartOfSeekingKey);
            $ArrayOfValues = explode("\x00\x00\x00", $ulgyRemainderOfData);
            // the key your are seeking is 0, where the value is one
            return trim($ArrayOfValues[1]);
        }
    
        return false;
    }
    
    0 讨论(0)
提交回复
热议问题