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

📄 rdmsflsh.pl

📁 wince 内核dump程序
💻 PL
📖 第 1 页 / 共 2 页
字号:
        $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 IMAGE_SCN_TYPE_NOLOAD              { 0x00000002 }sub IMAGE_SCN_MEM_DISCARDABLE          { 0x02000000 }sub IMAGE_SCN_MEM_EXECUTE              { 0x20000000 }sub IMAGE_SCN_MEM_READ                 { 0x40000000 }sub IMAGE_SCN_MEM_WRITE                { 0x80000000 }sub STD_EXTRA    {  16 }sub IMAGE_FILE_MACHINE_ARM  { 0x01c0 }sub FindFirstSegment {    my ($segtypeflag, @o32rom)= @_;    for (@o32rom) {        if ($_->{flags} & $segtypeflag) {            return $_->{rva};        }    }    return 0;}sub CalcSegmentSizeSum {    my ($segtypeflag, @o32rom)= @_;    my $size= 0;    for (@o32rom) {        # vsize is not entirely correct, I should use the uncompressed size,        # but, I don't know that here yet.        if ($_->{flags}&$segtypeflag) {            $size += $_->{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 ($e32rom, @o32rom)= @_;    my %e32exe;    $e32exe{magic}= "PE";    $e32exe{cpu}= IMAGE_FILE_MACHINE_ARM;   # todo: get this from romhdr.    $e32exe{objcnt}= $e32rom->{objcnt};    $e32exe{timestamp}= $e32rom->{timestamp};    $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    # ...fixup segment does not look like a real fixup seg.    # so we do include the data, but don't do anything with it.    #$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 ($e32rom->{FIX_rva} == $o32rom->{rva} && $e32rom->{FIX_size} == $o32rom->{vsize}) {        $segtype= ".reloc";    }    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};    if (($o32rom->{flags}&IMAGE_SCN_TYPE_NOLOAD)!=0 && $o32rom->{realaddr}==0) {        # most likely fixup        $o32obj{rva}  = $o32rom->{rva};    }    else {        $o32obj{rva}  = $o32rom->{realaddr} - $e32rom->{vbase};    }    $o32obj{psize}= $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->{e32rom}, @{$perom->{o32rom}});        my $fileofs= $peexe{e32exe}{hdrsize};    for (@{$perom->{o32rom}}) {        my $o32obj= convert_o32rom_to_o32obj($_, $perom->{e32rom});        push @{$peexe{o32obj}}, $o32obj;        $o32obj->{dataptr}= $fileofs;        $peexe{rvamap}{$_->{rva}}= { rva=>$o32obj->{rva}, size=>$o32obj->{vsize} };        $fileofs += round_to_page($o32obj->{psize}, $peexe{e32exe}{filealign})    }    return \%peexe;}sub RvaToFileOfs {    my ($rva, @o32obj)= @_;    for (@o32obj) {        if ($_->{rva}<=$rva && $rva < $_->{rva} + $_->{vsize}) {            return $_->{dataptr}+$rva-$_->{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 ($rva, $rvamap)= @_;        #$peexe{rvamap}{$_->{rva}}= { rva=>$o32obj->{rva}, size=>$o32obj->{vsize} };    for (keys %$rvamap) {        my $info= $rvamap->{$_};        if ($_ <= $rva && $rva < $_+$info->{size}) {            return $rva-$_+$info->{rva};        }    }    return $rva;}sub reconstruct_binary {    my ($file)= @_;    my $perom= parse_pe_data($file->{data});    my $peexe= convert_rom_to_exe($perom);    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 $i (0 .. $#{$file->{sections}}) {        my $section = $file->{sections}[$i];        my $o32= $peexe->{o32obj}[$i] if ($i<@{$peexe->{o32obj}});        $image .= $section->{data};#       if ($o32 && $o32->{name} eq ".reloc") {#           printf("reloc %-20s %s %08lx-%08lx-%08lx (%04x): %s\n", #               $file->{name},#               $section->{name},#               $o32->{rva}, $o32->{rva}+$o32->{psize}, $o32->{rva}+$o32->{vsize},#               length($section->{data}), unpack("H*", $section->{data}));#       }        $image .= "\x00" x round_padding(length($section->{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;}# 0000: magic  0xFFFFF6FD# 0004: DWORD dwNextDataTableOffset;# 0008: DWORD dwNextStreamHeaderOffset;# 000c: FS_NAME fsName; : cchName + wFlags# 0010:                 : wszShortName[4]# 0014:# 0018: DWORD dwStreamSize;# 001c: FS_DATA_RUN dataTable[1];# 0020:# 0024:# 0028:# 002c:# 0030:sub process_sectionentry {    my ($dirent, $file)= @_;    my %section;    my $magic;    (        $magic,        $section{unk}[0],        # 0  always 0   : nextdatatable offset        $section{next},          # 1  dirptr to next section entry        $section{unk}[1],        # 2  always 4   == name flags        $section{name},          # 3,4  WCHAR[4] == sectionname        $section{size},          # 5  total section size        $section{indexblock},    # 6,7  dataptr,size  ptr  to index block of section data        $section{indexsize},        @{$section{unk}}[2..5],     # 8-b  always 0    ) = unpack("VVVVa8VVVVVVV", $dirent);    if ($magic != 0xfffff6fd && $magic != 0xfffffcfd) {        croak sprintf("invalid magic %08lx in section entry for %s\n", $magic, $file->{name});    }    $section{name} = unicode2string($section{name});    $section{name} =~ s/\x00+$//g;    my $sdesc= sprintf("indexblock section %s for %s", $section{name}, $file->{name});    $section{data}= process_indexed_data($rd->ReadData($section{indexblock}, $section{indexsize}, $sdesc), $sdesc);    #printf("file %s section %s: %s\n", $file->{name}, $section{name}, $section{data});    return \%section;}# magic: 0xfffffefe or 0xfffff6fe# 0000: magic# 0004: DWORD dwNextDataTableOffset;# 0008: DWORD dwNextStreamHeaderOffset;# 000c: FS_NAME fsName.cchName;# 000e: FS_NAME fsName.wFlags;# 0010: FS_NAME fsName.szShortName;# 0014: FS_NAME fsName.longName;# 0018: DWORD dwStreamSize;# 001c: DWORD dwFileAttributes;# 0020: _FILETIME fileTime;# 0028: DWORD dwReserved;# 002c: FS_DATA_RUN dataTable[1];# 0030:sub process_fileentry {    my ($dirent, $desc)= @_;    my $magic;    my %file;    (        $magic,        $file{unk}[0],          # 0  always 0        $file{firstsection},    # 1  dirptr to first section file        $file{namelength},      # 2  WORD  filename length  : <=4 -> char[4]+ptr = literal filename.        $file{nameflags},       #    WORD  flag: 2= filename ptr is direntry, 0= filenameptr is datablock        $file{namehash},        # 3  char[4]        $file{filenameptr},     # 4  ptr to filename file ( see flag for type )        $file{size},            # 5  total file length        $file{attributes},      # 6  file attributes        $file{timestamp},       # 7,8  timestamp        $file{unk}[1],          # 9  always 0        $file{indexblock},    # a,b  dataptr,length  to index block of file data        $file{indexsize},    ) = unpack("VVVvva4VVVa8VVV", $dirent);    $file{timestamp}= cvtime::convert2unixtime($file{timestamp});    if ($magic!=0xfffffefe && $magic!=0xfffff6fe) {        croak sprintf("invalid magic: %08lx in fileent\n", $magic);    }    if ($file{nameflags}&2) {        $file{name}= process_nameentry($rd->ReadData($file{filenameptr}, 4*13, "name entry $desc"));    }    elsif ($file{namelength}<=4) {        $file{name}= unicode2string(substr($dirent, 16, 8));        $file{filenameptr}= 0;        $file{namehash}= "";    }    else {        $file{name}= unicode2string($rd->ReadData($file{filenameptr}, $file{namelength}*2, "filenameblock $desc"));    }    $file{name} =~ s/\x00+$//g;    if ($file{firstsection}) {        $stats{modules}++;    }    else {        $stats{files}++;    }    printf("%s: %s\n", $desc, $file{name}) if ($main::verbose);    for (my $ofs= $file{firstsection} ; $ofs ; $ofs= $file{sections}[-1]{next})    {        $stats{sections}++;        push @{$file{sections}}, process_sectionentry($rd->ReadData($ofs, 4*13, sprintf("sectionentry %d for %s", scalar @{$file{sections}}, $file{name})), \%file);    }    if ($file{indexblock}) {        my $fdesc= sprintf("indexblock filedata for %s", $file{name});        $stats{datablocks}++;        $file{data}= process_indexed_data($rd->ReadData($file{indexblock}, $file{indexsize}, $fdesc), $fdesc);    }    else {        printf("no index block %08lx %08lx for %s\n", $file{indexblock}, $file{indexsize}, $file{name});    }    #printf("file %s: %s\n", $file{name}, $file{data});    return \%file;}sub process_indexed_data {    my ($index, $desc)= @_;    my $data= "";    for (my $iofs=0 ; $iofs<length($index) ; $iofs+=8) {        $stats{datablocks}++;        my ($compsize, $fullsize, $dataofs)= unpack("vvV", substr($index, $iofs, 8));        last if ($dataofs==0);        my $block= $rd->ReadData($dataofs, $compsize, sprintf("datablock %d for %s", $iofs/8, $desc));        if (!defined $block) {            printf("error reading data from %08lx l=%08lx : datablock %d for %s\n", $dataofs, $compsize, $iofs/8, $desc);        }        elsif ($fullsize==$compsize) {            $data .= $block;            $stats{uncompressed}++;        }        elsif ($imgfs_hdr->{compression} eq "XPR") {            $stats{compressed}++;            my $decomp= XdaDevelopers::CompressUtils::XPR_DecompressDecode($block.("\x00" x 16), $fullsize);            if (!defined $decomp) {                printf("no decomp !!!: %08lx->%08lx %s\n", $compsize, $fullsize, $desc);                $data .= $block;            }            else {                $data .= $decomp;            }        }        elsif ($imgfs_hdr->{compression} eq "LZX") {            $stats{compressed}++;            my $decomp= XdaDevelopers::CompressUtils::LZX_DecompressDecode($block.("\x00" x 16), $fullsize);            if (!defined $decomp) {                printf("no decomp !!!: %08lx->%08lx %s\n", $compsize, $fullsize, $desc);                $data .= $decomp;            }            else {                $data .= $decomp;            }        }    }    return $data;}sub unicode2string {    my ($data)= @_;    return pack("U*", unpack("v*", $data));}# magic 0xfffffefbsub process_nameentry {    my ($nameent)= @_;    my ($magic, $name)= unpack("Va*", $nameent);    if ($magic!=0xfffffefb) {        croak "unexpected: no nameentry magic\n";    }    return unicode2string($name);}

⌨️ 快捷键说明

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