SPUG: Parsing (Windows) PE files in Perl

jerry gay jerry.gay at gmail.com
Thu Jan 12 06:56:45 PST 2006


On 1/12/06, Uri London <uril at exchange.microsoft.com> wrote:
> Please forgive me if this is a trivial question – I'm just doing my very
> first steps in Perl.
>
welcome!

> I need to extract some information from the headers of PE files (If you have
> left the Unix realm, PE files are Windows executables – DLL's, EXE's, SYS's
> etc. These files start with 'MZ').
>
> The files have a binary structure. They starts with IMAGE_DOS_HEADER, which
> is concatenated with IMAGE_OS_HEADER, IMAGE_FILE_HEADER, and then bunch of
> different directories, with various offsets, depends on values on the
> previous headers. The headers contains information such as size (of various
> sections), bunch of attributes, version, check-sums, timestamps, offsets to
> other structures resources, offsets to tables, list of imports, list of
> exports, etc. etc.
>
> These structures and various definitions to magic values are all public and
> defined in C/C++ in winnt.h in the platform SDK.
>
> I'm not sure that Perl is the best choice for this task, but I'd like to try
> to do it in Perl, so I'd like to consult this alias about the best strategy.
>
> Is Perl the right language to parse binary files?
>
YES!

> Is anyone aware of an already existing package to does this job?
>
no, i'm not. but the best place to look is CPAN (http://search.cpan.org/)

> Assuming a package doesn't exist, please help with some novice questions:
>
> -          How to open a file in a binary mode?
see 'perldoc -f binmode'
it'll go something like:

    my $file = 'foo.dll';
    open(local *PE, '>', my $file)
        or die qq{can't open $file: $!};
    binmode 1;

    # read from the file...

    close *PE;  # remember to close it when you're done

> -          How do I read blobs from a file?
>
see 'perldoc -f read'

> -          How to unpack a binary structure?
>
see 'perldoc -f unpack', and related, 'perldoc -f pack'. there's too
much to go into here, but google is your friend. something like 'perl
pack tutorial' should provide helpful.

> -          If I need to, can I seek (forward, backward), or another mean to
> have random access. Does Perl support memory mapping?
>
you can use 'seek' and 'tell' to move around in the file, and find out
where you are.

    my $curpos;
    my $newpos = 2;
    seek *PE, $newpos, 0
        or die qq{can't move to position $newpos in file $file: $!};
    $curpos = tell *PE;
    print qq{i'm at position $curpos in file $file};

for memory mapping, there is a module you can use to help: see
Win32::MMF (http://search.cpan.org/~roger/Win32-MMF-0.09e/)

good luck!
~jerry

BTW i use the qq{} quoting construct instead of single- or
double-quotes so i don't have to worry about escaping them. you can
find more by reading the 'Quote and Quote-Like Operators' section
'perldoc perlop'.


More information about the spug-list mailing list