-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PE: preparations for a writer outside of Goblin #389
base: master
Are you sure you want to change the base?
Conversation
e744736
to
97d7bda
Compare
This is a generic function to perform various alignments, this avoids reinventing locally the magic alignment dance and reusable for consumers who may themselves align things.
97d7bda
to
977179f
Compare
https://github.com/RaitoBezarius/ifrit will be my model for the meta writer PE, if it graduates, I will send it your way in faerie if it makes sense. :) |
977179f
to
6e70141
Compare
fd3cf62
to
e2b0631
Compare
lol i love the name :) so just catching up here again, iiuc, this has no breaking changes, but you'd like this patch merged right? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly questions about pub
Addressed your comments @m4b, please take a look again. Right now, it's mostly working, except I'm chasing an alignment issue somewhere... which appeared since the split. |
Cool let me know when you found it ! otherwise this is looking pretty good :) |
This is a simple function to assemble a template section table with zeros in the unpredictable fields, it's up to the caller to carry on the fill procedure, e.g. a writer structure which can do the layout. It can automatically set the virtual address and size based on another binary to append it, only the on-disk offsets are left to the caller.
Previously, we were handling the offset ourselves, but we can just use `gwrite_with` to let the offset be moved. We don't need to use the "read" offset, this is only a distraction and can get wrong results sometimes. We only need to write in the order and assume linearity.
025a5f6
to
2465eaa
Compare
It is now easy to peek into the data of a data directory and list all directories with their originally parsed offsets.
> 216/232 8 Reserved, must be zero According to the table mentioned in https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#optional-header-data-directories-image-only In the past, we returned errors in case they were present.
Relative virtual address to disk offset is a classical operation to perform for various things, it is likely this operation won't change and if it changes, we can keep it around and deprecate it quite easily in the next release. An example for external consumers: compute debug directory data offsets from RVAs to write a debug directory.
- derives additionally `Debug` on it for logging - derives additionally `Pwrite`, `SizeWith` for good developer experience with scroll on it - provides a natural type alias in accordance with `WIN_CERTIFICATE` name
We forgot those but they come handy in the UEFI ecosystem when you are reading UEFI signature lists.
There's no reason to render it as private, this enable a user to peek inside the raw structure and perform more complicated reading without holding the original bytes around. Nonetheless, we expose it via a function to make it easier to deprecate it or modify as we need.
It can be hard to debug why your writer is not working as intended, here are some `debug!` traces to help in that endeavor.
…e certificates It's possible that a user may pass an improperly created attribute certificate and the write will cause all sorts of failure. We sprinkle some `debug_assert!` to avoid this.
2465eaa
to
d814cbc
Compare
@m4b I believe we are ready to go, I tracked the last bug which was not a bug in Goblin but my tests being overzealous and wanting equality between unaligned certificates and aligned certificates, so I forked out to this sort of things: https://github.com/nix-community/goblin-signing/pull/6/files#diff-85ad85dc9b5387ec57ec5c58ab8880b11f7897b4e4cf3bb78f02907e630891d3R26-R53 |
Since you mention breaking changes, there are many that should be made for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is ok, other than the optional thing and the unwrap being infallible (which can be fixed backwards compatibly); I will wait till tomorrow, if no response, will merge; thanks for your patience @RaitoBezarius :)
I will note this does make a lot more functions pub, which is more maintenance burden, but seems good overall so i'm ok with it.
/// Given a view of the PE binary, represented by `bytes` and the on-disk offset `disk_offset` | ||
/// this will return a view of the data directory's contents. | ||
/// If the range are out of bands, this will fail with a [`error::Error::Malformed`] error. | ||
pub fn data<'a>(&self, bytes: &'a [u8], disk_offset: usize) -> error::Result<&'a [u8]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this should have just returned an Option
? sort of like get()
for arrays; e.g., is the error message actually useful? there's only one parameter passed in, so similar to an index, it means it's the wrong value basically (bad offset). anyway it's already here so it's probably fine, other than it having to allocate for the format.
.last() | ||
.map(|last_section| last_section.virtual_address + last_section.virtual_size) | ||
.ok_or(0u32) | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this unwrap infallible?
@JohnScience if you have some suggestions here feel free to open up a tracker issue/wishlist/things you think are wrong and we can investigate :) especially if you think there are crucial things that need fixing and will break backwards compat, now is the time; if they are large overarching changes to the architecture of goblin's PE though, there is realistically not a good chance it will be merged, but hard to say :) |
Hi there @m4b, as we discussed it in #381. Here's are commits, more in the mind of:
For now, I will focus on making it possible to write final executables, not object files. I believe this may require more efforts from someone who is really interested into writing a PE compiler or PE object files with this ecosystem.
This is a bunch of QoL improvements for the writer that I'm preparing in another repo, if it's good, and I get myself to 0.x something, I will try to see if it makes sense to send it to faerie or something that would be the good place for such a thing.
In the time being, to unblock on the reviews and merging, here's a bunch of easy things.
I make some stuff
pub
on purpose because I don't believe it's a big deal to let the user observe it, please correct me if you disagree, and I can try to find a way to make it better.As far as I can tell, this PR has no breaking changes. I have more in stock which I am fleshing out to make this easy for you.