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

📄 dumpxip.pl

📁 wince 内核dump程序
💻 PL
📖 第 1 页 / 共 3 页
字号:
    my %xip;    (        $xip{pvAddr},        $xip{dwLength},        $xip{dwMaxLength},        $xip{usOrder},        $xip{usFlags},        $xip{dwVersion},        $xip{szName},        $xip{dwAlgoFlags},        $xip{dwKeyLen},        $xip{byPublicKey},    )= unpack("VVVvvVA32VVa*", $xipentry);    return \%xip;}sub ParseXipChain {    my $self= shift;    my $xipchain= shift;    if (keys %g_xipchaininfo) {        printf("!!! found multiple xip-chains - appending\n");    }    my $nrxips= unpack("V", $xipchain);    for (my $i=0 ; $i<$nrxips ; $i++) {        my $xip= ParseXipChainEntry(substr($xipchain, 4+0x290*$i, 0x290));        $self->vadd($xip->{pvAddr}, 0, sprintf("xip block %08lx-%08lx '%s'", $xip->{pvAddr}, $xip->{pvAddr}+$xip->{dwLength}, $xip->{szName}));        if (exists $g_xipchaininfo{$xip->{pvAddr}}) {            printf("!!! xipchain contains duplicate address: %08lx\n", $xip->{pvAddr});        }        $g_xipchaininfo{$xip->{pvAddr}}= $xip;    }    if (substr($xipchain, 4+0x290*$nrxips) !~ /^\x00+$/) {        printf("!!! xip chain padded with non-null\n");    }}sub print {    my $self= shift;    my $prev;    for my $pofs (sort {$a<=>$b} keys %{$self->{items}}) {        if ($prev && $pofs>$prev) {            printf("%08lx-%08lx L%08lx  unknown\n", $prev, $pofs, $pofs-$prev);        }        elsif ($prev && $pofs<$prev) {            printf("%08lx-%08lx L%08lx  overlap!!\n", $pofs, $prev, $prev-$pofs);        }        my $maxlen;        for my $item (sort {$a->{len}<=>$b->{len}} @{$self->{items}{$pofs}}) {            $maxlen= $item->{len} if (!defined $maxlen || $maxlen < $item->{len});            # ... not printing information from blanks.            if ($item->{desc} eq "NUL" || $item->{desc} eq "ONE") {                next;            }            if (exists $item->{vstart}) {                printf("%08lx-%08lx | %08lx-%08lx L%08lx %s\n",                     $item->{pstart}, $item->{pstart}+$item->{len},                    $item->{vstart}, $item->{vstart}+$item->{len},                    $item->{len}, $item->{desc});            }            else {                printf("%08lx-%08lx  L%08lx %s\n",                     $item->{pstart}, $item->{pstart}+$item->{len},                    $item->{len}, $item->{desc});            }        }        $prev= $pofs+$maxlen;    }}##########################################################################################################################################################package ExeFile;use strict;use Carp;sub new {    my ($class, $cputype)= @_;    return bless {        cputype=>$cputype,    }, $class;}sub addo32 {    my ($self, $o32)= @_;    push @{$self->{o32rom}}, $o32;}sub adde32 {    my ($self, $e32)= @_;    $self->{e32rom}= $e32;}sub save_data {    my ($filename, $data)= @_;    my $fh= IO::File->new($filename, "w") or die "$filename: $!\n";    binmode $fh;    $fh->print($data);    $fh->close();}sub SaveToFile {    my ($self, $fn)= @_;    my $exedata= $self->reconstruct_binary();    save_data($fn, $exedata);}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},         $o32obj->{dataptr},         $o32obj->{realaddr},         $o32obj->{access},         $o32obj->{temp3},         $o32obj->{flags});}sub IMAGE_FILE_RELOCS_STRIPPED { 1 };sub IMAGE_SCN_COMPRESSED               { 0x00002000 }sub IMAGE_SCN_CNT_CODE                 { 0x00000020 }sub IMAGE_SCN_CNT_INITIALIZED_DATA     { 0x00000040 }sub IMAGE_SCN_CNT_UNINITIALIZED_DATA   { 0x00000080 }sub STD_EXTRA    {  16 }sub IMAGE_FILE_MACHINE_ARM  { 0x01c0 }sub FindFirstSegment {    my ($segtypeflag, @o32rom)= @_;    for my $o32ent (@o32rom) {        if ($o32ent->{flags} & $segtypeflag) {            return $o32ent->{rva};        }    }    return 0;}sub CalcSegmentSizeSum {    my ($segtypeflag, @o32rom)= @_;    my $size= 0;    for my $o32ent (@o32rom) {        # vsize is not entirely correct, I should use the uncompressed size,        # but, I don't know that here yet.        if ($o32ent->{flags}&$segtypeflag) {            $size += $o32ent->{vsize};        }    }    return $size;}sub round_to_page {    my ($val, $page)= @_;    if ($val%$page) {        return (int($val/$page)+1)*$page;    }    return $val;}sub round_padding {    my ($val, $page)= @_;    if ($val%$page) {        return $page - ($val%$page);    }    return 0;}sub convert_e32rom_to_e32exe {    my ($cputype, $e32rom, @o32rom)= @_;    my %e32exe;    $e32exe{magic}= "PE";    $e32exe{cpu}= $cputype;    $e32exe{objcnt}= $e32rom->{objcnt};    $e32exe{timestamp}= $e32rom->{timestamp}||0;    $e32exe{symtaboff}=0;    $e32exe{symcount}=0;    $e32exe{opthdrsize}= 0xe0;   # fixed.    $e32exe{imageflags}= $e32rom->{imageflags} | IMAGE_FILE_RELOCS_STRIPPED;    $e32exe{coffmagic}= 0x10b;    $e32exe{linkmajor}= 6;    $e32exe{linkminor}= 1;    $e32exe{codesize}= CalcSegmentSizeSum(IMAGE_SCN_CNT_CODE, @o32rom);    $e32exe{initdsize}= CalcSegmentSizeSum(IMAGE_SCN_CNT_INITIALIZED_DATA, @o32rom);    $e32exe{uninitdsize}= CalcSegmentSizeSum(IMAGE_SCN_CNT_UNINITIALIZED_DATA, @o32rom);    $e32exe{entryrva}= $e32rom->{entryrva};    $e32exe{codebase}= FindFirstSegment(IMAGE_SCN_CNT_CODE, @o32rom);    $e32exe{database}= FindFirstSegment(IMAGE_SCN_CNT_INITIALIZED_DATA, @o32rom);    $e32exe{vbase}= $e32rom->{vbase};    $e32exe{objalign}= 0x1000;    $e32exe{filealign}= 0x200;    $e32exe{osmajor}= 4;    $e32exe{osminor}= 0;    $e32exe{usermajor}= 0;    $e32exe{userminor}= 0;    $e32exe{subsysmajor}= $e32rom->{subsysmajor};    $e32exe{subsysminor}= $e32rom->{subsysminor};    $e32exe{res1}= 0;   # 'Win32 version' according to dumpbin    $e32exe{vsize}= $e32rom->{vsize};    $e32exe{hdrsize}= round_to_page(0x80+0xf8+@o32rom*0x28, $e32exe{filealign});    $e32exe{filechksum}= 0;    $e32exe{subsys}= $e32rom->{subsys};    $e32exe{dllflags}= 0;    $e32exe{stackmax}= $e32rom->{stackmax};    $e32exe{stackinit}=0x1000; # ?    $e32exe{heapmax}=0x100000; # ?    $e32exe{heapinit}=0x1000;  # ?    $e32exe{res2}= 0;      # 'loader flags' according to dumpbin    $e32exe{hdrextra}= STD_EXTRA;   # nr of directories    $e32exe{EXP_rva}= $e32rom->{EXP_rva}; $e32exe{EXP_size}= $e32rom->{EXP_size};    $e32exe{IMP_rva}= $e32rom->{IMP_rva}; $e32exe{IMP_size}= $e32rom->{IMP_size};    $e32exe{RES_rva}= $e32rom->{RES_rva}; $e32exe{RES_size}= $e32rom->{RES_size};    $e32exe{EXC_rva}= $e32rom->{EXC_rva}; $e32exe{EXC_size}= $e32rom->{EXC_size};    $e32exe{SEC_rva}= $e32rom->{SEC_rva}; $e32exe{SEC_size}= $e32rom->{SEC_size}; # always 0    # relocation info is always missing    # $e32exe{FIX_rva}= $e32rom->{FIX_rva}; $e32exe{FIX_size}= $e32rom->{FIX_size};    # $e32exe{DEB_rva}= $e32rom->{DEB_rva}; $e32exe{DEB_size}= $e32rom->{DEB_size};    $e32exe{IMD_rva}= $e32rom->{IMD_rva}; $e32exe{IMD_size}= $e32rom->{IMD_size}; # always 0    $e32exe{MSP_rva}= $e32rom->{MSP_rva}; $e32exe{MSP_size}= $e32rom->{MSP_size}; # always 0    $e32exe{RS4_rva}= $e32rom->{sect14rva}; $e32exe{RS4_size}= $e32rom->{sect14size};    return \%e32exe;}sub convert_o32rom_to_o32obj {    my ($o32rom, $e32rom)= @_;    my $segtype;    if ($e32rom->{RES_rva} == $o32rom->{rva} && $e32rom->{RES_size} == $o32rom->{vsize}) {        $segtype= ".rsrc";    }    elsif ($e32rom->{EXC_rva} == $o32rom->{rva} && $e32rom->{EXC_size} == $o32rom->{vsize}) {        $segtype= ".pdata";    }    elsif ($o32rom->{flags}&IMAGE_SCN_CNT_CODE) {        $segtype= ".text";    }    elsif ($o32rom->{flags}&IMAGE_SCN_CNT_INITIALIZED_DATA) {        $segtype= ".data";    }    elsif ($o32rom->{flags}&IMAGE_SCN_CNT_UNINITIALIZED_DATA) {        $segtype= ".pdata";    }    else {        $segtype= ".other";    }    my %o32obj;    # todo: add sequence nrs to identically named sections    $o32obj{name} = $segtype;    $o32obj{vsize}= $o32rom->{vsize};    $o32obj{rva}  = $g_use_wince3_compression         ? $o32rom->{rva}        : (($o32rom->{realaddr}||$o32rom->{dataptr}) - $e32rom->{vbase});    $o32obj{psize}= $o32rom->{psize};    $o32obj{psize}= length($o32rom->{data}) if (length($o32rom->{data}) > $o32rom->{psize});    $o32obj{dataptr}= 0;  # *** set at a later moment    $o32obj{realaddr}= 0; # file pointer to relocation table    $o32obj{access}= 0;   # file pointer to line numbers    $o32obj{temp3}= 0;    # number of relocations + number of line numbers    $o32obj{flags}= $o32rom->{flags} & ~IMAGE_SCN_COMPRESSED;    return \%o32obj;}sub convert_rom_to_exe {    my ($perom)= @_;    my %peexe;    $peexe{e32exe}= convert_e32rom_to_e32exe($perom->{cputype}, $perom->{e32rom}, @{$perom->{o32rom}});        my $fileofs= $peexe{e32exe}{hdrsize};    for my $o32ent (@{$perom->{o32rom}}) {        my $o32obj= convert_o32rom_to_o32obj($o32ent, $perom->{e32rom});        push @{$peexe{o32obj}}, $o32obj;        $o32obj->{dataptr}= $fileofs;        $peexe{rvamap}{$o32ent->{rva}}= { rva=>$o32obj->{rva}, size=>$o32obj->{vsize} };        $fileofs += round_to_page($o32obj->{psize}, $peexe{e32exe}{filealign})    }    return \%peexe;}sub RvaToFileOfs {    my ($rva, @o32obj)= @_;    for my $o32ent (@o32obj) {        if ($o32ent->{rva}<=$rva && $rva < $o32ent->{rva} + $o32ent->{vsize}) {            return $o32ent->{dataptr}+$rva-$o32ent->{rva};        }    }}sub strread_dword {    my ($pstr, $ofs)= @_;    return unpack("V", substr($$pstr, $ofs, 4));}sub strwrite_dword {    my ($pstr, $ofs, $dword)= @_;    substr($$pstr, $ofs, 4)= pack("V", $dword);}# rvamap maps romrva's to objrva'ssub find_rva_patch {    my ($objrva, $rvamap)= @_;        #$peexe{rvamap}{$_->{rva}}= { rva=>$o32obj->{rva}, size=>$o32obj->{vsize} };    for my $romrva (keys %$rvamap) {        my $info= $rvamap->{$romrva};        if ($romrva <= $objrva && $objrva < $romrva+$info->{size}) {            return $objrva-$romrva+$info->{rva};        }    }    return $objrva;}sub reconstruct_binary {    my ($file)= @_;    my $peexe= $file->convert_rom_to_exe();    my $mz_data = pack_mz_header();    # $file->{sections}[$i]{data}  contains the section data    my $e32exe_data = pack_e32exe($peexe->{e32exe});    my @o32exe_data = map { pack_o32obj($_) } @{$peexe->{o32obj}};    my $image= $mz_data;    $image .= $e32exe_data;    $image .= $_ for (@o32exe_data);    # page to filealign    $image .= "\x00" x ($peexe->{e32exe}{hdrsize} - length($image));    for my $o32ent (@{$file->{o32rom}}) {        $image .= $o32ent->{data};        $image .= "\x00" x round_padding(length($o32ent->{data}), $peexe->{e32exe}{filealign});    }    # repair import table.    my $impofs= RvaToFileOfs($peexe->{e32exe}{IMP_rva}, @{$peexe->{o32obj}});    while (1) {        my $impaddr= strread_dword(\$image, $impofs+0x10);        last if ($impaddr==0);        my $newimpaddr = find_rva_patch($impaddr, $peexe->{rvamap});        strwrite_dword(\$image, $impofs+0x10, $newimpaddr);        $impofs += 0x14;    }    return $image;}

⌨️ 快捷键说明

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