#!perl -w # (C) 2003-2007 Willem Jan Hengeveld # Web: http://www.xs4all.nl/~itsme/ # http://wiki.xda-developers.com/ # # $Id: opimg2dir.pl 1502 2007-04-15 07:54:20Z itsme $ # use strict; $|=1; use IO::File; if (@ARGV!=3) { die "Usage: opimg2dir \n"; } my $romimage= shift; my $cfgfile= shift; my $directory= shift; my $fh= IO::File->new($romimage, "r") or die "$romimage: $!"; binmode $fh; my $start= FindOperatorStuff($fh); printf("found at %08lx\n", $start); $fh->seek($start, SEEK_SET); my $hdr1= ReadDword($fh); my $hdr2= ReadDword($fh); my $hdr3= ReadDword($fh); printf("hdr: %08lx %08lx %08lx\n", $hdr1, $hdr2, $hdr3); my @entries; while(1) { my $filename= ReadString($fh); last if (!$filename); my $offset= ReadDword($fh); my $length= ReadDword($fh); my $configid= ReadString($fh); printf("%08lx %7d %8s %s\n", $offset, $length, $configid, $filename); my ($path, $name)= ($filename =~ /(.*)\\([^\\]+)$/); push @entries, { storedpath=>$path, storedname=>$name, offset=>$offset, filelength=>$length, configid=>$configid }; } exit if (!$cfgfile || !$directory); my $cfg= IO::File->new($cfgfile, "w+") or die "$cfgfile: $!\n"; for (@entries) { $fh->seek($start+0x4000+$_->{offset}, SEEK_SET); my $data; $fh->read($data, $_->{filelength}); my $localname= $_->{storedname}; # first prefix with configuration id if ($_->{configid} ne "0") { $localname = "$_->{configid}-$localname"; } my $fullname= $localname; if (-e "$directory/$fullname") { # optionally prefix with a unique making number. for (my $i=0 ; 1 ; $i++) { $fullname= sprintf("%03d_%s", $i, $localname); last if (! -e "$directory/$fullname"); } } my $out= IO::File->new("$directory/$fullname", "w+") or die "$directory/$fullname: $!"; binmode $out; $out->print($data); $out->close(); if ($_->{configid} eq "0" && $fullname eq $_->{storedname}) { $cfg->print("$fullname=$_->{storedpath}\n"); } else { $cfg->print("$fullname=$_->{storedpath}=$_->{storedname}=$_->{configid}\n"); } } $cfg->close(); $fh->close(); sub ReadString { my ($fh)= @_; my $str; my $data; while(1) { $fh->read($data, 1); last if (ord($data)==0); return if (ord($data)==0xff); $str .= $data; } return $str; } sub ReadDword { my ($fh)= @_; my $data; $fh->read($data, 4); return unpack("V", $data); } sub FindOperatorStuff { my ($fh)= @_; for (my $ofs= 0 ; $ofs< -s $fh ; $ofs+=0x40000) { $fh->seek($ofs, SEEK_SET) or die "$!"; if (ReadDword($fh)==0x34798243) { return $ofs; } $fh->seek($ofs+0x20, SEEK_SET) or die "$!"; if (ReadDword($fh)==0x34798243) { return $ofs+0x20; } } die "could not find operator rom\n"; }