-
Notifications
You must be signed in to change notification settings - Fork 163
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pe: write support for PE binaries (#361)
* strtab: offer `len` method * pe(header): introduce full DOS header and DOS stub Required to rematerialize a whole PE, otherwise, it is a corrupted PE. * pe(section_table): add `data` function to retrieve the section data safely It now returns a Cow as we need to transfer ownership whenever we have virtual size > size of raw data, which forces us to pad with zeroes according to the PE specification. * pe(utils): add a zero-extension padding helper It can be used to zero-extend any buffer to make its length aligned on some boundary, e.g. quadwords, for attribute certificates. It is designed to be "zero cost" if you have no alignment to do, which will result in no-allocation! * pe: implement write support for AttributeCertificate * pe: implement write support for DataDirectories * pe: implement write support for Header It enables a lossless conversion from 64 bits to 32 bits headers except on platforms… that are strange. * pe: implement write support for SymbolTable * pe: implement write support for data directories This tucks `DataDirectory` with a Deref-style and expose `offset` for internal consumers (this crate) and offers write support for data directories. * pe: implement write support for SectionTable All that is needed is to import the allocation `Vec`. * pe: implement write support * examples(pe): add a identity rewrite PE binary This is a trivial rewriter that performs the identity transformation. * pe: debug assert that no overlapping sections are written To further improve the debuggability, a non-overlapping sanity check is added as a debug_assert!. * pe(coff): COFF symbols and COFF strings are deprecated Previously, I (we?) thought that COFF symbols/strings were always there. In fact, this is not the case and they are deprecated according to https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#coff-file-header-object-and-image > The file offset of the COFF symbol table, or zero > if no COFF symbol table is present. This value should be zero for an image > because COFF debugging information is deprecated. * pe(write): factor into `write_certificates` We had the write certificate logic in the `TryIntoCtx`, but it makes sense to have it separated to let consumers call it manually.
- Loading branch information
1 parent
03eb434
commit 6d664c0
Showing
13 changed files
with
694 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use goblin::pe::PE; | ||
use scroll::Pwrite; | ||
|
||
fn main() { | ||
stderrlog::new().verbosity(1).init().unwrap(); | ||
let args: Vec<String> = std::env::args().collect(); | ||
|
||
let file = std::fs::read(&args[1]).unwrap(); | ||
let file = &file[..]; | ||
let pe = PE::parse(file).unwrap(); | ||
println!("read {}", &args[1]); | ||
|
||
println!( | ||
"file alignment: {:?}", | ||
pe.header | ||
.optional_header | ||
.unwrap() | ||
.windows_fields | ||
.file_alignment | ||
); | ||
|
||
let mut new_pe = vec![0u8; file.len() + 8192]; | ||
let new_len = new_pe.pwrite(pe, 0).unwrap(); | ||
let pe = PE::parse(file).unwrap(); | ||
|
||
let out = &new_pe[..new_len]; | ||
std::fs::write(&args[2], &out).unwrap(); | ||
println!("written as {}", &args[2]); | ||
println!( | ||
"original PE size: {} bytes, new PE size: {} bytes, delta (new - original): {} bytes", | ||
file.len(), | ||
out.len(), | ||
out.len() as isize - file.len() as isize | ||
); | ||
|
||
let new_pe = PE::parse(&new_pe).unwrap(); | ||
println!( | ||
"original signatures: {}, new signatures: {}", | ||
pe.certificates.len(), | ||
new_pe.certificates.len() | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.