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