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

📄 rdmsflsh.pl

📁 dumprom source code,use for learning the dumprom.exe tool for wince
💻 PL
📖 第 1 页 / 共 3 页
字号:
    $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}, 
        $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

⌨️ 快捷键说明

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