CasualX / pelite

Lightweight, memory-safe, zero-allocation library for reading and navigating PE binaries.
MIT License
280 stars 42 forks source link

Use correct base address for 32-bit ASLR images #267

Closed tremwil closed 1 year ago

tremwil commented 1 year ago

Fixes #266.

Adds a method image_base(&self) -> Va to the Pe trait:

The return value of this method is used for VA/RVA conversions in the Pe trait, replacing self.optional_header().ImageBase.

CasualX commented 1 year ago

Unfortunately PeView was meant to be also usable if you just copied the memory of a running image (eg. from another process) where the image ptr is not actually the real virtual address of the image. I've always had a nagging feeling that ignoring it and relying on ImageBase being 'corrected' was not reliable and now it's coming back to bite me :)

This will probably require an extra field in PeView containing the actual image base and trying not to break APIs.

tremwil commented 1 year ago

I see. In this case, adding the extra field as you said and only setting it to self.image.as_ptr() as Va when the PeView is constructed using PeView::module should not break any existing APIs, correct?

Also, I guess a new (unsafe?) PeView constructor taking a AsRef<[u8]> and the base address would be useful in case one encounters issue #266 after copying the memory of a running image from another process.

tremwil commented 1 year ago

PeView should work when copying the memory of a running image now. However, I'm not familiar with the Serde library, so I'm not sure how to serialize the PeView's image_base field without potentially breaking backwards compatibility for some formats (e.g. sequential ones). Is it fine to assume that some formats may not be compatible no matter what and just add a new serialize_field call at the end of serialize_pe that writes the image base?

CasualX commented 1 year ago

Thanks for the update! I'm a bit distracted with other projects right now, I'll try to take a look at it tomorrow or during next week.

CasualX commented 1 year ago

I've changed the API to set the base address after construction (I'm not a fan of a bunch of _with constructors, Rust could really use default parameter values...)