in reply to Get EXE VersionInfo

If the intent is to extract the version information embedded in windows executables, whilst running under Linux, then it is a fairly trivial process to open the file, locate the appropriate offset and then read and interpret the relevant 32-bit integer.

The full MS specification for the PE & COFF file formats is downloadable, though enough information to locate and interpret the various version fields is freely obtainable many places on-line. For example: here.

To get you started here is a crude script I knocked up a couple of years ago to extract the timestamp field:

#! perl -slw use strict; open EXE, '<:raw', $ARGV[0] or die "$ARGV[0] : $!"; my $dos = do{ local $/ = \65536; <EXE> }; die "$ARGV[0] is not a .exe or .dll (sig='${ \substr $dos, 0, 2 }')" unless substr( $dos, 0, 2 ) eq 'MZ'; my $coffoff = 8+ unpack 'x60 V', $dos; read( EXE, $dos, $coffoff - 65536 + 4, 65536 ) or die $! if $coffoff > 65536; my $ts = unpack "x$coffoff V", $dos; print "$ARGV[0] : ", defined $ts ? ( scalar( localtime $ts) || "has unfathomable timestamp value $t +s" ) : 'has no timestamp'; __END__ C:\cl>p:exetime.pl atlprov.dll Sat Jan 5 11:46:16 2002 C:\cl>p:exetime.pl cl.exe Sat Jan 5 10:48:19 2002

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^2: Get EXE VersionInfo
by resistance (Beadle) on Jun 29, 2008 at 17:45 UTC
    Thanks BrowserUK for the example, it works (mostly)!

    Still not completely understand how to locate the appropriate offset. Looking at VersionInfo.xs code and winver.h and still unable to find the offsets.

    Just a question: is it possible to compile Win32::File::VersionInfo module on linux if I have WinVer.h somewhere in path or in the build directory?

    Sure if I write the code myself it were very helpful for understanding of EXE format but it seems to be not so trivial :-(

    regards
Re^2: Get EXE VersionInfo
by Anonymous Monk on Aug 22, 2008 at 12:33 UTC
    Hi, what this problem? This function (unpack) is native on perl? javaserver:~/teste-rnt # ./exetime.pl T080720081328.exe Global symbol "$t" requires explicit package name at ./exetime.pl line 16. Execution of ./exetime.pl aborted due to compilation errors. javaserver:~/teste-rnt # perl --version This is perl, v5.8.8 built for x86_64-linux-thread-multi thanks

      It would be a lot easier to diagnose if you posted the relevant code.

      The error message means that you've attempted to use a variable $t but haven't declared it: my $t anywhere in your code. My guess is that you've made a change to the code above, and have typed $t instead of $ts somewhere, but that's pure speculation.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        print "$ARGV[0] : ", defined $ts ? ( scalar( localtime $ts) || "has unfathomable timestamp value $t +s" ) copy and past change de code to $t"+"s not $ts I find the problem, thanks. deadrop
        Thank you to help me, i find the first problem, variable $ts not declared, copy and past change the code to $t"+"s not $ts.
        
        But now, the program return only values to diferent version files. see:
        
        avaserver:~/teste-rnt # ./exetime.pl V190820081243.exe -> ( Version 1.0.11 )
        T190820081243.exe : Fri Jun 19 19:22:17 1992
        
        javaserver:~/teste-rnt # ./exetime.pl V300720081251.exe -> ( Version 1.0.12 )
        T300720081251.exe : Fri Jun 19 19:22:17 1992
        
        The code:
        
        #!/usr/bin/perl -slw
        use strict;
        
        open EXE, '<:raw', $ARGV[0] or die "$ARGV[0] : $!";
        my $dos = do{ local $/ = \65536; <EXE> };
        die "$ARGV[0] is not a .exe or .dll (sig='${ \substr $dos, 0, 2 }')"
            unless substr( $dos, 0, 2 ) eq 'MZ';
        
        my $coffoff = 8+ unpack 'x60 V', $dos;
        read( EXE, $dos, $coffoff - 65536 + 4, 65536 ) or die $! 
            if $coffoff > 65536;
        
        my $ts = unpack "x$coffoff V", $dos;
        
        print "$ARGV[0] : ", defined $ts
            ? ( scalar( localtime $ts) || "has unfathomable timestamp value $ts" )
            : 'has no timestamp';