Commit b2bdd04f authored by Cyrille Bollu's avatar Cyrille Bollu

Import original source of Win32-Exe 0.17

parents
Release 0.17: 19 July 2011
* Noted that create_resource_section fails on WinXP and below
----------------------------------------------------------------------
Release 0.16: 26 May 2011
* Fixed Perl 5.14 Compilation
----------------------------------------------------------------------
Release 0.15: 30 November 2010
* Fixed parsing of Windows Object files (thanks to Nicolas Georges)
----------------------------------------------------------------------
Release 0.14: 03 May 2010
* Added support for multiple icons
* Added support for creating resource section for PE files that
have none (Win32 platforms only).
* Removed Module::Install usage - it does not work on Win32 for
sub directory build. Will restore usage once CPAN Module::Install
works. (next release according to CPAN reports).
----------------------------------------------------------------------
Release 0.13:
* Added support for PE+ (x64 64bit executables)
* Fixed manifest bug caused by 'pack' changes in perl 5.10
----------------------------------------------------------------------
Release 0.11:
* Applied patch by Mark Dootson to change the default exe manifest.
----------------------------------------------------------------------
Release 0.10:
* Updated Module::Install to 0.64.
* Applied patch by Mark Dootson to add support for exe manifests.
----------------------------------------------------------------------
Release 0.09:
* Updated Module::Install to 0.63.
* Updated Audrey's contact information.
----------------------------------------------------------------------
r3715: autrijus | 2004-03-18T05:06:01.118230Z
* This be 0.08.
* Load all require submodules with 'use', not 'require', so
it can work with 'pp' in PAR 0.80. Reported by Alan Stewart.
----------------------------------------------------------------------
r3626: autrijus | 2004-03-16T11:58:23.873748Z
* This be 0.07.
* Properly raises exception when loading an invalid file to Win32::Exe.
Reported by Macolm Noonings.
----------------------------------------------------------------------
r3896: autrijus | 2004-02-17T01:28:40.619691Z
* This be 0.06.
* conform to Parse::Binary 0.05 API
* suggestion by alan to retain the original groupname.
----------------------------------------------------------------------
r3857: autrijus | 2004-02-16T09:22:40.299320Z
* This be 0.05.
* add docs for exe_update.pl.
* Alan Stewart reported that our FindBin magic in tests was not quite good.
* Also, predeclare test numbers instead of no_plan.
----------------------------------------------------------------------
r3846: autrijus | 2004-02-15T22:38:40.264114Z
* This be 0.04.
* Work with Parse::Binary 0.04 to refresh only when needed.
This fixes the case of clobbering the exe twice, as reported
by Jouke Visser.
----------------------------------------------------------------------
r3819: autrijus | 2004-02-15T00:17:26.298029Z
* This be 0.03.
* a stupid typo caused all named resource strings to be stripped
from the table. oops.
* tidy up sort a little.
* depend on newer Parse::Binary.
----------------------------------------------------------------------
r3807: autrijus | 2004-02-14T19:43:30.059984Z
* This be 0.02.
* truncating executables to smaller size now works.
* properly extend the executable. it should now really work!
* forgot to refresh data directories after updating exe. bummer
* fix two gotchas that were probably preventing padding from working
----------------------------------------------------------------------
r3788: autrijus | 2004-02-13T23:49:21.521921Z
* This be Win32::Exe, version 0.01.
----------------------------------------------------------------------
Changes
insert/InsertResourceSection.xs
insert/Makefile.PL
insert/typemap
insert/t/0-load.t
insert/t/1-basic.t
lib/Win32/Exe.pm
lib/Win32/Exe/Base.pm
lib/Win32/Exe/DataDirectory.pm
lib/Win32/Exe/DebugDirectory.pm
lib/Win32/Exe/DebugTable.pm
lib/Win32/Exe/IconFile.pm
lib/Win32/Exe/InsertResourceSection.pm
lib/Win32/Exe/Manifest.pm
lib/Win32/Exe/Manifest/Parser.pm
lib/Win32/Exe/PE.pm
lib/Win32/Exe/PE/Header.pm
lib/Win32/Exe/PE/Header/PE32.pm
lib/Win32/Exe/PE/Header/PE32Plus.pm
lib/Win32/Exe/Resource.pm
lib/Win32/Exe/Resource/GroupIcon.pm
lib/Win32/Exe/Resource/Icon.pm
lib/Win32/Exe/Resource/Manifest.pm
lib/Win32/Exe/Resource/Version.pm
lib/Win32/Exe/ResourceData.pm
lib/Win32/Exe/ResourceEntry.pm
lib/Win32/Exe/ResourceEntry/Id.pm
lib/Win32/Exe/ResourceEntry/Name.pm
lib/Win32/Exe/ResourceTable.pm
lib/Win32/Exe/Section.pm
lib/Win32/Exe/Section/Code.pm
lib/Win32/Exe/Section/Data.pm
lib/Win32/Exe/Section/Debug.pm
lib/Win32/Exe/Section/Exports.pm
lib/Win32/Exe/Section/Imports.pm
lib/Win32/Exe/Section/Resources.pm
Makefile.PL
MANIFEST This list of files
META.yml
README
script/exe_update.pl
t/0-pod.t
t/1-basic.t
t/2-icon.t
t/3-manifest.t
t/4-execupdate.t
t/hd.ico
t/par.ico
t/winexe32.exe
t/winexe64.exe
t/application.xml
t/empty.xml
--- #YAML:1.0
name: Win32-Exe
version: 0.17
abstract: Manipulate Win32 executable files
author:
- Audrey Tang <cpan@audreyt.org>
license: perl
distribution_type: module
configure_requires:
ExtUtils::MakeMaker: 0
build_requires:
File::Copy: 0
Test::More: 0
requires:
Parse::Binary: 0.11
perl: 5.006000
XML::Parser: 2.36
XML::Simple: 2.18
no_index:
directory:
- t
- inc
generated_by: ExtUtils::MakeMaker version 6.56
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
#!/usr/bin/env perl
# Copyright 2004, 2007, 2010 by Audrey Tang <cpan@audreyt.org>
use ExtUtils::MakeMaker 6.46;
WriteMakefile(
NAME => 'Win32::Exe',
VERSION_FROM => 'lib/Win32/Exe.pm',
AUTHOR => 'Audrey Tang <cpan@audreyt.org>',
ABSTRACT => 'Manipulate Win32 executable files',
LICENSE => 'perl',
EXE_FILES => [ 'script/exe_update.pl' ],
MIN_PERL_VERSION => '5.6.0',
PREREQ_PM => { 'Parse::Binary' => 0.11,
'XML::Simple' => 2.18,
'XML::Parser' => 2.36,
},
BUILD_REQUIRES => { 'Test::More' => 0, 'File::Copy' => 0 },
NORECURS => ( $^O =~ /^mswin/i ) ? 0 : 1,
);
This is the README file for Win32::Exe, a module for manipulating
Win32 PE/COFF executable headers.
Please type "perldoc Win32::Exe" after installation to see
the module usage information.
* Installation
Win32::Exe uses the standard perl module install process:
cpansign -v # optional; see SIGNATURE for details
perl Makefile.PL
make # or 'nmake' on Win32
make test
make install
* Copyright
Copyright 2004-2010 by Audrey Tang <cpan@audreyt.org>.
All rights reserved. You can redistribute and/or modify
this bundle under the same terms as Perl itself.
See <http://www.perl.com/perl/misc/Artistic.html>.
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <shellapi.h>
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
MODULE = Win32::Exe::InsertResourceSection PACKAGE = Win32::Exe::InsertResourceSection
PROTOTYPES: DISABLE
void
_insert_resource_section( szFileName, lpData, cbData )
LPCSTR szFileName
LPVOID lpData
DWORD cbData
PPCODE:
BOOL bDeleteExistingResources = FALSE;
LPCTSTR lpType = RT_VERSION;
LPCTSTR lpName = RT_VERSION;
WORD wLanguage = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
BOOL ok;
BOOL fDiscard;
HANDLE hUpdate = BeginUpdateResource(szFileName, bDeleteExistingResources);
if (hUpdate == NULL) XSRETURN_UNDEF;
ok = UpdateResource(hUpdate, lpType, lpName, wLanguage, lpData, cbData);
fDiscard = ( ok ) ? FALSE : TRUE;
if (!EndUpdateResource(hUpdate, fDiscard)) XSRETURN_UNDEF;
if (!ok) XSRETURN_UNDEF;
XSRETURN_YES;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Win32::Exe::InsertResourceSection',
VERSION_FROM => '../lib/Win32/Exe/InsertResourceSection.pm',
);
#!/usr/bin/perl -w
use strict;
use Test::More tests => 1;
use_ok('Win32::Exe::InsertResourceSection');
1;
#!/usr/bin/perl -w
use strict;
use Test::More tests => 1;
use_ok('Win32::Exe::InsertResourceSection');
1;
TYPEMAP
BOOL T_IV
HWND T_IV
HBITMAP T_IV
LONG T_IV
LPVOID T_PV
UINT T_UV
LPCTSTR T_PV
LPCSTR T_PV
HMODULE T_IV
DWORD T_IV
WORD T_IV
This diff is collapsed.
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::Base;
use strict;
use base 'Parse::Binary';
use constant BASE_CLASS => 'Win32::Exe';
use constant FORMAT => (
Data => 'a',
);
sub align {
my ($self, $value, $boundary) = @_;
my $n = ($value % $boundary) or return $value;
return($value + $boundary - $n);
}
sub pad {
my ($self, $value, $bounary) = @_;
my $x = length($value) % $bounary or return '';
return "\0" x ($bounary - $x);
}
sub decode_ucs2 {
my ($self, $string) = @_;
return join('', map chr($_), unpack("v*", $string));
}
sub encode_ucs2 {
my ($self, $string) = @_;
return pack("v*", map ord($_), split(//, $string));
}
1;
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::DataDirectory;
use strict;
use base 'Win32::Exe::Base';
use constant FORMAT => (
VirtualAddress => 'V',
Size => 'V',
);
1;
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::DebugDirectory;
use strict;
use base 'Win32::Exe::Base';
use constant FORMAT => (
Flags => 'V',
TimeStamp => 'V',
VersionMajor => 'v',
VersionMinor => 'v',
Type => 'V',
Size => 'V',
VirtualAddress => 'V',
Offset => 'V',
);
1;
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::DebugTable;
use strict;
use base 'Win32::Exe::Base';
use constant FORMAT => (
'DebugDirectory' => [ 'a28', '*', 1 ],
);
1;
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::IconFile;
use strict;
use base 'Win32::Exe::Base';
use constant FORMAT => (
Magic => 'a2',
Type => 'v',
Count => 'v',
'Resource::Icon' => [ 'a16', '{$Count}', 1 ],
Data => 'a*',
);
use constant DEFAULT_ARGS => (
Magic => "\0\0",
Type => 1,
Count => 0,
Data => '',
);
use constant DISPATCH_FIELD => 'Magic';
use constant DISPATCH_TABLE => (
"\0\0" => '',
"MZ" => '__BASE__',
'*' => sub { die "Invalid icon file header: $_[1]" },
);
sub icons {
my $self = shift;
$self->members(@_);
}
sub set_icons {
my ($self, $icons) = @_;
$self->SetCount(scalar @$icons);
$self->set_members('Resource::Icon' => $icons);
$self->refresh;
foreach my $idx (0 .. $#{$icons}) {
$self->icons->[$idx]->SetImageOffset(length($self->dump));
$self->SetData( $self->Data . $icons->[$idx]->Data );
}
$self->refresh;
}
sub dump_iconfile {
my $self = shift;
my @icons = $self->icons;
my $obj = $self->require_class('IconFile')->new;
$obj->set_icons(\@icons);
return $obj->dump;
}
sub write_iconfile {
my ($self, $filename) = @_;
$self->write_file($filename, $self->dump_iconfile);
}
1;
#########################################################################################
# Package Win32::Exe::InsertResourceSection
# Description: Insert Resource Section
# Created Sun May 02 17:32:55 2010
# SVN Id $Id: InsertResourceSection.pm 2 2010-11-30 16:40:31Z mark.dootson $
# Copyright: Copyright (c) 2010 Mark Dootson
# Licence: This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself
#########################################################################################
package Win32::Exe::InsertResourceSection;
#########################################################################################
use strict;
use warnings;
use Exporter;
use base qw( Exporter );
use Carp;
use Win32::Exe;
our $VERSION = '0.17';
our @EXPORT = qw( insert_pe_resource_section );
sub _is_win { ($^O =~ /^mswin/i) }
if (_is_win()) {
require XSLoader;
XSLoader::load('Win32::Exe::InsertResourceSection', $VERSION);
}
sub create_resource_section {
my $filename = shift;
croak('Invalid filename') if $filename !~ /\.(dll|exe)$/i;
croak('Filename not found') if !-f $filename;
if(!_is_win()) {
warn 'Cannot add resource section to PE files on this platform. Requires MSWin';
return undef;
}
my $replacecode;
if($filename =~ /\.(dll|exe)$/i) {
#VFT_APP = 0x1
#VFT_DLL = 0x2
#VFT_DRV = 0x3
#VFT_FONT = 0x4
#VFT_VXD = 0x5
#VFT_STATIC_LIB = 0x7
if(lc($1) eq 'exe') {
$replacecode = '01';
} elsif(lc($1) eq 'dll') {
$replacecode = '02';
} else {
croak('Invalid filename');
}
} else {
croak('Invalid filename');
}
my @verdata = qw(
400234000000560053005F0056004500
5200530049004F004E005F0049004E00
46004F0000000000BD04EFFE00000100
00000000000000000000000000000000
3F0000000000000004000400XX000000
000000000000000000000000A0010000
010053007400720069006E0067004600
69006C00650049006E0066006F000000
7C010000010030003000300030003000
34004200300000002400020001004300
6F006D00700061006E0079004E006100
6D00650000000000200000002C000200
0100460069006C006500440065007300
6300720069007000740069006F006E00
00000000200000002400020001004600
69006C00650056006500720073006900
6F006E00000000002000000024000200
010049006E007400650072006E006100
6C004E0061006D006500000020000000
2800020001004C006500670061006C00
43006F00700079007200690067006800
74000000200000002C00020001004C00
6500670061006C005400720061006400
65006D00610072006B00730000000000
200000002C00020001004F0072006900
670069006E0061006C00460069006C00
65006E0061006D006500000020000000
240002000100500072006F0064007500
630074004E0061006D00650000000000
20000000280002000100500072006F00
64007500630074005600650072007300
69006F006E0000002000000044000000
0100560061007200460069006C006500
49006E0066006F000000000024000400
00005400720061006E0073006C006100
740069006F006E00000000000000B004
);
my $verdatahex = join('', @verdata);
$verdatahex =~ s/XX/$replacecode/;
my $verdataraw = pack('H*', $verdatahex);
my $verlen = length($verdataraw);
_insert_resource_section($filename, $verdataraw, $verlen);
}
sub insert_pe_resource_section {
my $filename = shift;
if(create_resource_section($filename)) {
# basic version info resource has been created
# we now have to replace the language and original
# filename / filename
my $exe = Win32::Exe->new($filename);
return ($exe->update( info => [ "FileVersion=0.0.0.0" ] )) ? $exe : undef;
} else {
return undef;
}
}
1;
This diff is collapsed.
This diff is collapsed.
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::PE;
use strict;
use base 'Win32::Exe';
use constant SUBFORMAT => (
Machine => 'v',
NumSections => 'v',
TimeStamp => 'V',
SymbolTable => 'V',
_ => 'a4',
OptHeaderSize => 'v',
Characteristics => 'v',
Data => 'a*',
);
use constant DISPATCH_FIELD => 'OptHeaderSize';
use constant DISPATCH_TABLE => (
'0' => '',
'*' => 'PE::Header',
);
1;
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::PE::Header;
use strict;
use base 'Win32::Exe::PE';
use constant SUBFORMAT => (
Magic2 => 'v',
LMajor => 'C',
LMinor => 'C',
CodeSize => 'V',
IDataSize => 'V',
UDataSize => 'V',
EntryPointRVA => 'V',
BaseOfCode => 'V',
Data => 'a*',
);
use constant MEMBER_CLASS => 'Data';
use constant DISPATCH_FIELD => 'Magic2';
use constant DISPATCH_TABLE => (
0x20b => 'PE::Header::PE32Plus',
'*' => 'PE::Header::PE32',
);
1;
# Copyright 2004 by Audrey Tang <cpan@audreyt.org>
package Win32::Exe::PE::Header::PE32;
use strict;
use base 'Win32::Exe::PE::Header';
use constant SUBFORMAT => (
BaseOfData => 'V',
ImageBase => 'V',
SectionAlign => 'V',
FileAlign => 'V',
OSMajor => 'v',
OSMinor => 'v',
UserMajor => 'v',
UserMinor => 'v',
SubsysMajor => 'v',
SubsysMinor => 'v',
_ => 'a4',
ImageSize => 'V',
HeaderSize => 'V',
FileChecksum => 'V',
SubsystemTypeId => 'v',
DLLFlags => 'v',
StackReserve => 'V',
StackCommit => 'V',
HeapReserve => 'V',
HeapCommit => 'V',
LoaderFlags => 'V',
NumDataDirs => 'V',
'DataDirectory' => [
'a8', '{$NumDataDirs}', 1
],
'Section' => [
'a40', '{$NumSections}', 1
],
Data => 'a*',
);
use constant SUBSYSTEM_TYPES => [qw(
_ native windows console _
_ _ posix _ windowsce
)];
use constant ST_TO_ID => {
map { (SUBSYSTEM_TYPES->[$_] => $_) } (0 .. $#{+SUBSYSTEM_TYPES})
};
use constant ID_TO_ST => { reverse %{+ST_TO_ID} };
sub st_to_id {
my ($self, $name) = @_;
return $name unless $name =~ /\D/;
return(+ST_TO_ID->{lc($name)} || die "No such type: $name");
}
sub id_to_st {
my ($self, $id) = @_;
return(+ID_TO_ST->{$id} || $id);
}
sub Subsystem {
my ($self) = @_;
return $self->id_to_st($self->SubsystemTypeId);
}
sub SetSubsystem {
my ($self, $type) = @_;
$self->SetSubsystemTypeId($self->st_to_id($type));
}
sub ExpectedOptHeaderSize { 224 };
1;
#--------------------------------------------------------------------
# 64 bit PE+ header as per 'Microsoft PE and COFF Specification' from
# http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
#--------------------------------------------------------------------
package Win32::Exe::PE::Header::PE32Plus;
use strict;
use base 'Win32::Exe::PE::Header';
use constant SUBFORMAT => (
ImageBase => 'a8',
SectionAlign => 'V',
FileAlign => 'V',
OSMajor => 'v',
OSMinor => 'v',
UserMajor => 'v',
UserMinor => 'v',
SubsysMajor => 'v',
SubsysMinor => 'v',
_ => 'a4',
ImageSize => 'V',
HeaderSize => 'V',
FileChecksum => 'V',
SubsystemTypeId => 'v',
DLLFlags => 'v',
StackReserve => 'a8',