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

📄 dumpxip.pl

📁 wince 内核dump程序
💻 PL
📖 第 1 页 / 共 3 页
字号:
#!perl -w# (C) 2003-2007 Willem Jan Hengeveld <itsme@xs4all.nl># Web: http://www.xs4all.nl/~itsme/#      http://wiki.xda-developers.com/## $Id: dumpxip.pl 1766 2008-04-10 11:57:58Z itsme $##  G:\archive\software\WINCE420/PUBLIC/COMMON/OAK/INC/pehdr.h#  G:\archive\software\WINCE420/PUBLIC/COMMON/OAK/INC/romldr.h### .... i think the problem is that there are 2 xip section both at the same virtual address#  ... see for instance decompress data of ceconfig.h#    ... it returns the wrong data.use strict;$|=1;use Getopt::Long;use IO::File;use Carp;my $g_fileseek;my $g_doprint= 0;my $g_savedir;my $g_use_wince3_compression;my %seen_extensions;my %g_xipchaininfo;#use XdaDevelopers::CompressUtils;# this requires a patch to Win32::API, which can be found at#   http://www.xs4all.nl/~itsme/projects/perl/Win32-API-0.41-wj2.tar.gz#use Win32::API;# CEDecompress is to be used for wince3.x roms# CEDecompressROM is to be used for wince4.x roms## problem is that this call sometimes crashes the app.# ##my $g_decompress= Win32::API->new("CECompress.dll", "CEDecompress", "PNPNNNN", "N", "_cdecl")#my $g_decompress= Win32::API->new("CECompress.dll", "CEDecompressROM", "PNPNNNN", "N", "_cdecl")#     or warn "error importing CEDecompress: $!\n";GetOptions(    "s=s"=> sub { $g_fileseek= eval($_[1]); },    "d:s"=> \$g_savedir,    "3"  => \$g_use_wince3_compression,) or die usage();sub usage {    return <<__EOF__Usage: dumpxip.pl -o baseoffet [-l length] [-d savedir] [-s fileseek] romfile__EOF__}my $g_filename= shift or die usage();die "$g_filename not found\n" if (!-e $g_filename);my $g_data= ReadFile($g_filename, $g_fileseek);my $rom= ROM->new($g_data);my $mem= MemSpace->new();my $xipblocks= XipBlock::FindXipBlocks($rom);# [0x00000000, 0x10078000], [0x00100000, 0x80000000], [0x00900000, 0x82040000], [0x015c0000, 0x82d00000], [0x01640000, 0x82d80000], [0x01940000, 0x83080000] for my $xipblock ( @$xipblocks ) {    $rom->setbase($xipblock->{ofs}, $xipblock->{base});    $mem->setvbase($xipblock->{ofs}, $xipblock->{base});    my $xip= XipBlock->new($rom, $mem, $xipblock->{base});    $xip->ParseXipBlock();    $xip->DumpInfo();    $xip->PrintFileList();    $xipblock->{parsedxip}= $xip;}$mem->pfillblanks($rom, 0, $rom->{size});$mem->print();if ($g_savedir) {    my $xipindex= 1;    for my $xipblock ( @$xipblocks ) {        $rom->setbase($xipblock->{ofs}, $xipblock->{base});        $mem->setvbase($xipblock->{ofs}, $xipblock->{base});        my $xipname= exists $g_xipchaininfo{$xipblock->{base}} ? "xip_".$g_xipchaininfo{$xipblock->{base}}{szName} : sprintf("xip_%02d", $xipindex);        $xipblock->{parsedxip}->SaveFiles($g_savedir, $xipname);        $xipindex++;    }}print "finished\n";exit(0);sub ReadFile {    my $fn= shift;    my $ofs= shift || 0;    my $len= shift || (-s $fn)-$ofs;    my $data;    my $fh= IO::File->new($fn, "r") or die "$fn: $!";    binmode $fh;    $fh->seek($ofs, SEEK_SET);    $fh->read($data, $len);    $fh->close();    return $data;}##########################################################################################################################################################package XipBlock;use POSIX;use strict;use Carp;use Dumpvalue;sub new {    my $class= shift;    my $rom= shift;    my $mem= shift;    my $start= shift;    return bless { rom_type=>undef, xipstart=>$start, rom=>$rom, mem=>$mem }, $class;}sub ParseXipBlock {    my $self= shift;    my $rom= $self->{rom};    my $mem= $self->{mem};    if ($rom->GetDword($self->{xipstart}+0x40) != 0x43454345) {        die "ECEC signature not found\n";    }    my $romhdrofs= $rom->GetDword($self->{xipstart}+0x44);    $mem->vadd($self->{xipstart}+0x40, 8, "ECEC signature + romhdr ptr");    my $romhdr= $self->{romhdr}= $self->ParseRomHdr($rom->GetVData($romhdrofs, 0x54));    $mem->vadd($romhdrofs, 0x54, $romhdr->{desc});    my $modlistofs= $romhdrofs+ 0x54;    my $modules= $self->{modules}= $self->ParseModulesList($rom->GetVData($modlistofs, 0x20*$romhdr->{nummods}));    $mem->vadd($modlistofs, 0x20*$romhdr->{nummods}, "modules list, %d modules", $romhdr->{nummods});    $_->{filename}= $rom->GetString($_->{lpszFileName}) for (@$modules);    my $filesofs= $modlistofs + 0x20*$romhdr->{nummods};    my $files= $self->{files}= $self->ParseFilesList($rom->GetVData($filesofs, 0x1c*$romhdr->{numfiles}));    $mem->vadd($filesofs, 0x1c*$romhdr->{numfiles}, "files list, %d files", $romhdr->{numfiles});    $_->{filename}= $rom->GetString($_->{lpszFileName}) for (@$files);    if ($romhdr->{ulCopyEntries}) {        $self->{copylist}= $self->ParseCopyList($rom->GetVData($romhdr->{ulCopyOffset}, 0x10*$romhdr->{ulCopyEntries}));        $mem->vadd($romhdr->{ulCopyOffset}, 0x10*$romhdr->{ulCopyEntries}, "copy list, %d entries", $romhdr->{ulCopyEntries});    }    else {        $self->{copylist}= [];    }    $self->AddModuleHeaders($_) for (@{$modules});    $self->ParseExtensions($romhdr->{pExtensions});}sub ParseExtension {    my $self= shift;    my $data= shift;    my @fields= unpack("A24V5", $data);    my @names= qw(name type pdata length reserved pNextExt);    my @fmt= qw(%s %08lx %08lx %08lx %08lx %08lx);    return  {        desc=>sprintf("extension: %s", join ", ", map { sprintf("%s:$fmt[$_]", $names[$_], $fields[$_]) } (0..$#names)),        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub isValidRomOfs {    my ($ofs)= @_;    return ($ofs>=0x80000000 && $ofs<0xa0000000);}sub ParseExtensions {    my ($self, $extptr)= @_;    my $first=1;    while ($extptr) {        last if (!$self->{rom}->IsInRange($extptr));        last if ($seen_extensions{$extptr});        $seen_extensions{$extptr}= 1;        my $ext= $self->ParseExtension($self->{rom}->GetVData($extptr, 44));        last if (            ($ext->{pdata}!=0 && !isValidRomOfs($ext->{pdata}))            ||($ext->{pNextExt}!=0 && !isValidRomOfs($ext->{pNextExt}))            ||$ext->{length}>0x1000000);        if (!$first) {            $self->{mem}->vadd($extptr, 44, $ext->{desc});            $self->{mem}->vadd($ext->{pdata}, $ext->{length}, "data for extension %s: %s", $ext->{name},                join(",", map { sprintf("%08lx", $_); } unpack("V*", $self->{rom}->GetVData($ext->{pdata}, $ext->{length})))            ) if ($ext->{pdata});        }        $first= 0;        $extptr= $ext->{pNextExt};    }}sub SaveFiles {    my $self= shift;    my $savedir= shift;    my $xipname= shift;    if ($savedir) {        mkdir $savedir;    }    $savedir .= "/$xipname";    if ($savedir) {        mkdir $savedir;    }    die "$savedir does not exist\n" if (!-d $savedir);    print "saving files to $savedir\n";    $self->SaveFile($_, $savedir) for (@{$self->{files}});    print "saving modules to $savedir\n";    $self->SaveModule($_, $savedir) for (@{$self->{modules}});}sub DumpInfo {    my $self= shift;    $self->DumpFilesAreas();    $self->DumpModulesAreas();    $self->{mem}->vfillblanks($self->{rom}, $self->{romhdr}{physfirst}, $self->{romhdr}{physlast});    #$self->{mem}->print();}sub filetimestring {    my ($file)= @_;    # 100 ns intervals since 1-1-1601    my $win32ftime= $file->{ftTime_high}*(2**32)+$file->{ftTime_low};    my $unixtime= int($win32ftime/10000000.0-11644473600);    #return sprintf("%08lX%08lX", $file->{ftTime_high}, $file->{ftTime_low});    return POSIX::strftime("%Y-%m-%d %H:%M:%S", localtime $unixtime);}sub PrintFile {    my ($self, $file)= @_;    printf("@%08lx %6d %s %s\n",         $file->{ulLoadOffset},         exists $file->{nRealFileSize}?$file->{nRealFileSize}:$file->{nFileSize},         filetimestring($file),         $file->{filename});}sub PrintFileList {    my ($self)= @_;    $self->PrintFile($_) for (@{$self->{files}});    $self->PrintFile($_) for (@{$self->{modules}});}sub ParseRomHdr {    my $self= shift;    my $data= shift;    my @fields= unpack("V17v2V3", $data);    my @names= qw(dllfirst dlllast physfirst physlast nummods ulRAMStart ulRAMFree ulRAMEnd ulCopyEntries ulCopyOffset ulProfileLen ulProfileOffset numfiles ulKernelFlags ulFSRamPercent ulDrivglobStart ulDrivglobLen usCPUType usMiscFlags pExtensions ulTrackingStart ulTrackingLen);    return  {        desc=>sprintf("romhdr : %s", join ", ", map { sprintf("%s:%08lx", $names[$_], $fields[$_]) } (0..$#names)),        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub ParseModulesList {    my $self= shift;    my $data= shift;    my @modules;    my $i;    for ($i= 0 ; $i<length($data) ; $i+=0x20) {        push @modules, ParseModuleEntry(substr($data, $i, 0x20), sprintf("module entry %d", $i/0x20));    }    if ($i!=length($data)) {        warn "uneven modules list\n";    }    return \@modules;}sub ParseModuleEntry {    my $data= shift;    my $desc= shift;    my @fields= unpack("V8", $data);    my @names= qw(dwFileAttributes ftTime_low ftTime_high nFileSize lpszFileName ulE32Offset ulO32Offset ulLoadOffset);    return  {        desc=>sprintf("%s : %s", $desc, join ", ", map { sprintf("%s:%08lx", $names[$_], $fields[$_]) } (0..$#names)),        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub ParseFilesList {    my $self= shift;    my $data= shift;    my @files;    my $i;    for ($i= 0 ; $i<length($data) ; $i+=0x1c) {        push @files, $self->ParseFilesEntry(substr($data, $i, 0x1c), sprintf("files entry %d", $i/0x1c));    }    if ($i!=length($data)) {        warn "uneven files list\n";    }    return \@files;}sub ParseFilesEntry {    my $self= shift;    my $data= shift;    my $desc= shift;    my @fields= unpack("V7", $data);    my @names= qw(dwFileAttributes ftTime_low ftTime_high nRealFileSize nCompFileSize lpszFileName ulLoadOffset);    return  {        desc=>sprintf("%s : %s", $desc, join ", ", map { sprintf("%s:%08lx", $names[$_], $fields[$_]) } (0..$#names)),        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub ParseCopyList {    my $self= shift;    my $data= shift;    my @list;    my $i;    for ($i= 0 ; $i<length($data) ; $i+=0x10) {        push @list, $self->ParseCopyEntry(substr($data, $i, 0x10), sprintf("copy entry %d", $i/0x10));    }    if ($i!=length($data)) {        warn "uneven copy list\n";    }    return \@list;}sub ParseCopyEntry {    my $self= shift;    my $data= shift;    my $desc= shift;    my @fields= unpack("V4", $data);    my @names= qw(ulSource ulDest ulCopyLen ulDestLen);    return  {        desc=>sprintf("%s : %s", $desc, join ", ", map { sprintf("%s:%08lx", $names[$_], $fields[$_]) } (0..$#names)),        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub AddModuleHeaders {    my $self= shift;    my $module= shift;    my $rom= $self->{rom};    my $mem= $self->{mem};    if (!defined $self->{rom_type}) {        $self->{rom_type}= determine_rom_type($rom->GetVData($module->{ulE32Offset}, 0x70));    }    if ($self->{rom_type}==5) {        $module->{e32}= ParseE32Header_v5($rom->GetVData($module->{ulE32Offset}, 0x6e));        $mem->vadd($module->{ulE32Offset}, 0x6e, "e32 header %s", $module->{filename});    }    elsif ($self->{rom_type}==4) {        $module->{e32}= ParseE32Header_v4($rom->GetVData($module->{ulE32Offset}, 0x6a));        $mem->vadd($module->{ulE32Offset}, 0x6a, "e32 header %s", $module->{filename});    }    else {        die "unknown romtype $self->{rom_type}\n";    }    for my $objidx (1..$module->{e32}{objcnt}) {        push @{$module->{o32}}, ParseO32Header($rom->GetVData($module->{ulO32Offset}+($objidx-1)*0x18, 0x18));    }    $mem->vadd($module->{ulO32Offset}, 0x18*$module->{e32}{objcnt}, "o32 headers %s", $module->{filename});}sub determine_rom_type {    my @f= unpack("V*", shift);    if ($f[8] < $f[5] && $f[26]>0) {        return 4;    }    else {        return 5;    }}# with extra timestamp field!sub ParseE32Header_v5 {    my $data= shift;    my @fields= unpack("v2V2v2V5V18v", $data);    my @names= qw(objcnt imageflags entryrva vbase subsysmajor subsysminor stackmax vsize sect14rva sect14size timestamp EXP_rva EXP_size IMP_rva IMP_size RES_rva RES_size EXC_rva EXC_size SEC_rva SEC_size FIX_rva FIX_size DEB_rva DEB_size IMD_rva IMD_size MSP_rva MSP_size subsys);    return  {        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub ParseE32Header_v4 {    my $data= shift;    my @fields= unpack("v2V2v2V4V18v", $data);    my @names= qw(objcnt imageflags entryrva vbase subsysmajor subsysminor stackmax vsize sect14rva sect14size EXP_rva EXP_size IMP_rva IMP_size RES_rva RES_size EXC_rva EXC_size SEC_rva SEC_size FIX_rva FIX_size DEB_rva DEB_size IMD_rva IMD_size MSP_rva MSP_size subsys);    return  {        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub ParseO32Header {    my $data= shift;    my @fields= unpack("V6", $data);    my @names= qw(vsize rva psize dataptr realaddr flags);    return  {        map { ( $names[$_] => $fields[$_] ) } (0..$#names)    };}sub DumpFilesAreas {    my $self= shift;    for my $file (@{$self->{files}}) {        my $desc= $file->{filename};        $self->{mem}->vadd($file->{ulLoadOffset}, $file->{nCompFileSize}, (($file->{dwFileAttributes}&0x800)?"compressed ":"")."file data %s", $desc);        $self->{mem}->vadd($file->{lpszFileName}, length($file->{filename})+1, "file filename %s", $desc);    }}sub DumpModulesAreas {    my $self= shift;    my $mem= $self->{mem};    for my $mod (@{$self->{modules}}) {        my $desc= $mod->{filename};        $mem->vadd($mod->{lpszFileName}, length($mod->{filename})+1, "module filename %s", $desc);        for my $o32ent (@{$mod->{o32}}) {            my $l= $o32ent->{psize}; $l= $o32ent->{vsize} if ($o32ent->{vsize}<$l);            $mem->vadd($o32ent->{dataptr}, $l, 

⌨️ 快捷键说明

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