nlitsme / eimgfs

Tool for editting Windows CE/Mobile firmware images.
MIT License
66 stars 11 forks source link

PE section truncated if data compressed #2

Closed Andrik45719 closed 4 years ago

Andrik45719 commented 6 years ago

If section is compressed only psize bytes written to PE section.

XipFile::tostream() compsize 44581, fullsize 146597 XipFile::tostream(() decompress 146597 23CA5, fullsize 146597 o32exe::o32exe() o32exe psize 44581, rom->psize 44581

nlitsme commented 6 years ago

can you provide a sample file?

Andrik45719 commented 6 years ago

./eimgfs W111JFCL.013 -fs xip -extract Antitheft.exe

found xip imgfs: partition table not found tostream() _exe->o32compsize(i) 616 _exe->o32fullsize(i) 1128 tostream() _exe->o32compsize(i) 964 _exe->o32fullsize(i) 2416 o32exe() psize 1024 vsize 1128 o32exe() psize 1024 vsize 2416

trunc.zip

nlitsme commented 6 years ago

i think you are right. strange that i have never noticed this before.

Andrik45719 commented 6 years ago

may be this help you: in the method add_sectioninfo(uint64_t size) size is always passed as zero I think this is type cast problem.

void add_sectioninfo(const std::string& name, uint64_t size, ReadWriter_ptr r)
{
    printf("size %ld\n", size); //always == 0
    _sections.push_back(sectioninfo_ptr(new sectioninfo(name, size, r)));
}

                _exe->add_sectioninfo(stringformat("S%03d", i),
                        fulldata.size(),
                        ReadWriter_ptr(new ByteVectorReader(fulldata)));
nlitsme commented 6 years ago

i am not sure why you are seeing that. That is not the problem .. also: the 'size' argument of sectioninfo is not used anyway. In the exe_reconstructor::save function, on line 2285, is where the data is copied.

The problem is in the calculation of dataptr.

nlitsme commented 6 years ago

This will solve it. but now vsize is always equal to psize. i am not sure if that is desirable.

@@ -1967,7 +1967,7 @@ private:
             else {
                 rva= rom->realaddr - e32->vbase;
             }
-            psize= roundsize(rom->psize, e32->filealign);
+            psize= roundsize(rom->vsize, e32->filealign);       // note: ignoring rom psize, this is the compressed size.
             dataptr= 0;         // set later
             realaddr= 0;
             access= 0;
Andrik45719 commented 6 years ago

thank you. my workaround is: psize= roundsize(std::max(rom->psize, rom->vsize), e32->filealign);