⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rdmsflsh.pl

📁 wince 内核dump程序
💻 PL
📖 第 1 页 / 共 2 页
字号:
#!perl -w# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl># Web: http://www.xs4all.nl/~itsme/#      http://wiki.xda-developers.com/## $Id: rdmsflsh.pl 1638 2007-11-01 12:31:13Z itsme $## this perl script decodes the IMGFS rom filesystem format# as used by wm2005 devices## todo: repair import table.# todo: get this from romhdr.# todo: add sequence nrs to identically named sections# # problem: files with RELOC section, the reloc section needs more padding.# package Reader;use strict;use IO::File;sub new {    my ($type, $fh, $base)= @_;    my $self= bless {        fh=>$fh,        baseofs=>$base,    }, $type;    return $self;}package TyphReader;use strict;use IO::File;our @ISA=qw(Reader);sub ReadData {    my ($self, $ofs, $len, $desc)= @_;    printf("%08lx-%08lx l=%08lx %s\n", $ofs, $ofs+$len, $len, $desc) if ($main::verbose && $desc);    $self->{fh}->seek($self->cv2file($ofs), SEEK_SET) or return;    my $data="";    $self->{fh}->read($data, $len) or return;    return $data;}sub ReadDword {    my ($self, $ofs, $desc)= @_;    printf("%08lx-%08lx l=%08lx %s\n", $ofs, $ofs+4, 4, $desc) if ($main::verbose && $desc);    $self->{fh}->seek($self->cv2file($ofs), SEEK_SET) or return;    my $data;    $self->{fh}->read($data, 4) or return;    return unpack("V", $data);}sub cv2file {    my ($self, $ofs)= @_;    return $self->{baseofs} + $ofs;}package HimaReader;use strict;use IO::File;our @ISA=qw(Reader);sub ReadData {    my ($self, $ofs, $len, $desc)= @_;    printf("%08lx-%08lx l=%08lx %s\n", $ofs, $ofs+$len, $len, $desc) if ($main::verbose && $desc);    my $data="";    while ($len) {        my $want= $len;        my $realofs= $self->cv2file($ofs);        $self->{fh}->seek($realofs, SEEK_SET) or return;        if ($want>0x40000-($realofs&0x3ffff)) {            $want= 0x40000-($realofs&0x3ffff);        }        $self->{fh}->read($data, $want, length($data)) or return;        $len -= $want;        $ofs += $want;    }    return $data;}sub ReadDword {    my ($self, $ofs, $desc)= @_;    printf("%08lx-%08lx l=%08lx %s\n", $ofs, $ofs+4, 4, $desc) if ($main::verbose && $desc);    $self->{fh}->seek($self->cv2file($ofs), SEEK_SET) or return;    my $data;    $self->{fh}->read($data, 4) or return;    return unpack("V", $data);}sub cv2file {    my ($self, $ofs)= @_;    return $self->{baseofs} + int($ofs/0x3f000)*0x40000+($ofs%0x3f000);}package cvtime;use strict;use POSIX;sub convert2unixtime {    my $wtime= shift;    my @w= unpack("VV", $wtime);    return int(($w[1]*(2**32)+$w[0])/10000000.0-11644473600)}package main;use strict;use Getopt::Long;use Carp;use IO::File;use integer;use XdaDevelopers::CompressUtils;$|=1;## i split the wm2005 sp rom apart as follows:## 00000000-00000400  : hdr.nb# 00000400-00200400  : first xip# 00200400-00210000  : empty, filled with 0xff# 00210000-003f0000  : second xip# 003f0000-01819f00  : imgfs filesystem# 01819f00-01819f80   signature?# 01819f80-01b00000   empty 0xff## this script operates on the extracted imgfs part#my $reader;my $outdir;our $verbose;my %stats;sub usage {    return <<__EOF__Usage: rdmsflsh [-d savedir] file__EOF__}GetOptions(    "d=s"=> \$outdir,    "v"=>\$verbose,) or die usage();my $fn= shift or die "usage: need filename\n";my $fh= IO::File->new($fn, "r") or croak "$fn: $!\n";binmode $fh;mkdir $outdir if ($outdir);# himalaya 80500000# 00000000: f8 ac 2c 9d e3 d4 2b 4d bd 30 91 6e d8 4f 31 dc# 00000010: 00000001 00000001 00000001 00000034# 00000020: 00000040 00001000 00001000 "LZX"# 00000030: 0000057b 00000020# # typhoon: 003f0000# 00000000: f8 ac 2c 9d e3 d4 2b 4d bd 30 91 6e d8 4f 31 dc# 00000010: 00000001 00000001 00000001 00000034# 00000020: 00000008 00000200 00001000 "XPR"# 00000030: 00001730 00000100# universal: 706e0000# 00000000: f8 ac 2c 9d e3 d4 2b 4d bd 30 91 6e d8 4f 31 dc# 00000010: 00000001 00000001 00000001 00000034# 00000020: 00000008 00000200 00001000 "LZX"# 00000030: 0000ce0c 00000100my $imgfs_hdr= findimgfs_header($fh) || die "could not find imgfs header\n";#       universal   tornado0   tornado1   wizard   himalaya   typhoon# 0000:      ** "MSFLSH50" **# 0008:      ** 00000000 **# 000c:      ** 00000038 **                                               size of this header# 0010:      ** 00000000 **# 0014:      ** 00000000 **# 0018: 00000000   00000000   00000000   00000000   00000010   00000000# 001c: 0000005e   00000048   0000004c   00000060   00000000   0000003f   start block of imgfs# 0020: 00000080   00000080   00000080   00000080   00000040   00000080   nr of sectors per block# 0024: 00010000   00010000   00010000   00010000   00040000   00010000   imgfs blocksize# 0028:      ** 00000000 **# 002c:      ** 00000001 **# 0030: 00000000   00000000   00000000   00000000   00000010   00000000# 0034: 00000000   00000000   00000000   00000000   0000006c   00000000# 0038: 00000392   000001e8   00000204   00000330   00000000   00000171   nr of blocks in imgfs# 003c: 00000080   00000080   00000080   00000080   0000003f   00000080   nr of used sectors per block# 0040: 00010000   00010000   00010000   00010000   00040000   00010000   imgfs blocksize# 0044: 00000000   00000000   00000000   00000000   00000002   00000000#      :005e0000: :00480000: :004c0000: :00600000: :00500000: :003f0000:# 0000:      ** f8ac2c9de3d42b4dbd30916ed84f31dc **                       guidBootSignature# 0010:      ** 00000001 **                                               dwFSVersion;# 0014:      ** 00000001 **                                               dwSectorsPerHeaderBlock;# 0018:      ** 00000001 **                                               dwRunsPerFileHeader;# 001c:      ** 00000034 **                                               dwBytesPerHeader;# 0020: 00000008   00000008   00000008   00000008   00000040   00000008   dwChunksPerSector;# 0024: 00000200   00000200   00000200   00000200   00001000   00000200   dwFirstHeaderBlockOffset;# 0028:      ** 00001000 **                                               dwDataBlockSize;# 002c: "LZX"      "LZX"      "LZX"      "LZX"      "LZX"      "XPR"      zCompressionType[4];# 0030: 0000ce0c   000072a5   00001e72   0000cf31   0000057b   00001730   dwFreeSectorCount;# 0034: 00000100   00000100   00000100   00000100   00000020   00000100   dwHiddenSectorCount;# 0038:      ** 00000000 **                                               dwUpdateModeFlag;# 0000:  magic == f8ac2c9de3d42b4dbd30916ed84f31dc# 0010:0                                            dwFSVersion;# 0014:1                                            dwSectorsPerHeaderBlock;# 0018:2                                            dwRunsPerFileHeader;# 001c:3  header length == 0x34                     dwBytesPerHeader;# 0020:4  .. reader type                            dwChunksPerSector;# 0024:5  .. dir block size                         dwFirstHeaderBlockOffset;# 0028:6                                            dwDataBlockSize;# 002c:7  compression magic == "LZX" or == "XPR"    szCompressionType[4];# 0030:8  .. nr of files                            dwFreeSectorCount;# 0034:9                                            dwHiddenSectorCount;# 0038:a                                            dwUpdateModeFlag;sub findimgfs_header {    my ($fh)= @_;    my $signature= pack("H*", "f8ac2c9de3d42b4dbd30916ed84f31dc");    my $ofs= 0;    while (1) {        my $data;        $fh->seek($ofs, SEEK_SET);        $fh->read($data, 512) or last;        my $i= index($data, $signature);        if ($i>512-40) {            warn sprintf("ignoring sig at %08lx\n", $ofs+$i);        }        elsif ($i>=0) {            my @hdr= unpack("V7A4V2", substr($data, $i+16));            if ($hdr[3]==0x34 && ($hdr[7] eq "LZX" || $hdr[7] eq "XPR")) {                printf("found hdr at %08lx\n", $ofs+$i);                return {                    baseofs=>$ofs+$i,                    compression=>$hdr[7],                    readertype=>$hdr[4],                    dirblocksize=>$hdr[5],                    firstdirofs=>$hdr[5],                    nroffiles=>$hdr[8],                };            }            else {                printf("sig at %08lx, but inv hdr: %08lx %s\n", $i+$ofs, $hdr[3], $hdr[7]);            }        }        $ofs += 0x400;    }    return undef;}my $rd= $imgfs_hdr->{readertype}==8 || $imgfs_hdr->{readertype}==0x20        ? TyphReader->new($fh, $imgfs_hdr->{baseofs})        : $imgfs_hdr->{readertype}==0x40        ? HimaReader->new($fh, $imgfs_hdr->{baseofs})        : undef;if (!$rd) {    die sprintf("could not determine filetype: rd=0x%x base=0x%x\n", $imgfs_hdr->{readertype}, $imgfs_hdr->{baseofs});}my $dirdata="";my $ofs= $imgfs_hdr->{firstdirofs};while (length($dirdata)==0 || $ofs) {    my $magic= $rd->ReadDword($ofs, "dirblock magic");    if ($magic != 0x2f5314ce) {        carp sprintf("%08lx: magic =%08lx  != 2f5314ce\n", $ofs, $magic);        last;    }    my $dirchunk = $rd->ReadData($ofs+8, $imgfs_hdr->{dirblocksize}-8, sprintf("dirchunk %08lx", $ofs));    $dirchunk =~ s/(?:\xff\xff\xff\xff)+$//;    $dirdata .= $dirchunk;    $ofs= $rd->ReadDword($ofs+4, "dirblock nextptr");}my %ref;for (my $i= 0 ; $i<length($dirdata) ; $i+=4*13){    my $type= unpack("V", substr($dirdata, $i, 4));    $stats{sprintf("ent_%x", $type)}++;    if ($type == 0xfffff6fe || $type == 0xfffffefe) {        my $file= process_fileentry(substr($dirdata, $i, 4*13), sprintf("fileent %d", $i));        save_file($outdir, $file) if ($outdir);        printf(" %7d %04x %s %s\n",             $file->{size},             $file->{attributes},             POSIX::strftime("%Y-%m-%d %H:%M:%S", localtime $file->{timestamp}),            $file->{name});    }}print "statistics:\n";print map { sprintf("%6d [ 0x%08x ] %s\n", $stats{$_}, $stats{$_}, $_) } sort keys %stats;exit(0);sub save_data {    my ($filename, $data)= @_;    my $fh= IO::File->new($filename, "w") or die "$filename: $!\n";    binmode $fh;    $fh->print($data) if (defined $data && length($data));    $fh->close();}sub save_file {    my ($dirpath, $file)= @_;    my $filepath= sprintf("%s/%s", $dirpath, $file->{name});    if ($file->{sections} && @{$file->{sections}}) {        my $exedata= reconstruct_binary($file);        save_data($filepath, $exedata);    }    else {        save_data($filepath, $file->{data});    }}sub unpack_e32rom {    my ($data)= @_;    my %e32rom;    (        $e32rom{objcnt},                # 0x00        $e32rom{imageflags},            # 0x02        $e32rom{entryrva},              # 0x04        $e32rom{vbase},                 # 0x08        $e32rom{subsysmajor},           # 0x0C        $e32rom{subsysminor},           # 0x0E        $e32rom{stackmax},              # 0x10        $e32rom{vsize},                 # 0x14        $e32rom{sect14rva},             # 0x18        $e32rom{sect14size},            # 0x1C        $e32rom{timestamp},             # 0x20        $e32rom{EXP_rva}, $e32rom{EXP_size},    # 0x24        $e32rom{IMP_rva}, $e32rom{IMP_size},    # 0x2c        $e32rom{RES_rva}, $e32rom{RES_size},    # 0x34        $e32rom{EXC_rva}, $e32rom{EXC_size},    # 0x3c        $e32rom{SEC_rva}, $e32rom{SEC_size},    # 0x44        $e32rom{FIX_rva}, $e32rom{FIX_size},    # 0x4c        $e32rom{DEB_rva}, $e32rom{DEB_size},    # 0x54        $e32rom{IMD_rva}, $e32rom{IMD_size},    # 0x5c        $e32rom{MSP_rva}, $e32rom{MSP_size},    # 0x64        $e32rom{subsys},                # 0x6c    )= unpack("v2V2v2V23v", $data);    return \%e32rom;}sub unpack_o32rom {    my ($data)= @_;    my %o32rom;    (        $o32rom{vsize},        $o32rom{rva},        $o32rom{psize},        $o32rom{dataptr},        $o32rom{realaddr},        $o32rom{flags},    ) = unpack("V6", $data);    return \%o32rom;}sub parse_pe_data {    my ($data)= @_;    my %pe;    if (length($data) < 0x70) {        printf("WARNING: PE data block too small\n");    }    $pe{e32rom}= unpack_e32rom(substr($data, 0, 0x70));    if (length($data) < 0x70 + $pe{e32rom}{objcnt}*0x18) {        printf("WARNING: PE data block too small\n");    }    elsif (length($data) > 0x70 + $pe{e32rom}{objcnt}*0x18) {        printf("WARNING: PE data block too large: %s\n", unpack("H*", substr($data, 0x70+0x18*$pe{e32rom}{objcnt})));    }    for (my $i=0 ; $i<$pe{e32rom}{objcnt} ; $i++) {        push @{$pe{o32rom}}, unpack_o32rom(substr($data, 0x70+0x18*$i, 0x18));    }    return \%pe;}sub pack_mz_header {    return pack("H*", "4d5a90000300000004000000ffff0000").           pack("H*", "b8000000000000004000000000000000").           pack("H*", "00000000000000000000000000000000").           pack("H*", "00000000000000000000000080000000").           pack("H*", "0e1fba0e00b409cd21b8014ccd215468").           pack("H*", "69732070726f6772616d2063616e6e6f").           pack("H*", "742062652072756e20696e20444f5320").           pack("H*", "6d6f64652e0d0d0a2400000000000000");}sub pack_e32exe {    my ($e32exe)= @_;    my @info= qw(EXP IMP RES EXC SEC FIX DEB IMD MSP TLS CBK RS1 RS2 RS3 RS4 RS5);    return pack("a4vvVVVvvvCCVV8v6V4v2V6",            $e32exe->{magic},             $e32exe->{cpu},             $e32exe->{objcnt},             $e32exe->{timestamp},             $e32exe->{symtaboff},             $e32exe->{symcount},             $e32exe->{opthdrsize},             $e32exe->{imageflags},             $e32exe->{coffmagic},             $e32exe->{linkmajor},             $e32exe->{linkminor},             $e32exe->{codesize},             $e32exe->{initdsize},             $e32exe->{uninitdsize},             $e32exe->{entryrva},             $e32exe->{codebase},             $e32exe->{database},             $e32exe->{vbase},             $e32exe->{objalign},             $e32exe->{filealign},             $e32exe->{osmajor},             $e32exe->{osminor},             $e32exe->{usermajor},             $e32exe->{userminor},             $e32exe->{subsysmajor},             $e32exe->{subsysminor},             $e32exe->{res1},             $e32exe->{vsize},             $e32exe->{hdrsize},             $e32exe->{filechksum},             $e32exe->{subsys},             $e32exe->{dllflags},             $e32exe->{stackmax},             $e32exe->{stackinit},             $e32exe->{heapmax},             $e32exe->{heapinit},             $e32exe->{res2},             $e32exe->{hdrextra},     ).  join("", map { pack("VV", $e32exe->{"${_}_rva"}||0, $e32exe->{"${_}_size"}||0) } @info);}sub pack_o32obj {    my ($o32obj)= @_;    return pack("a8V8",        $o32obj->{name},        $o32obj->{vsize},         $o32obj->{rva},         $o32obj->{psize}, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -