-
-
Notifications
You must be signed in to change notification settings - Fork 363
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
[WIP] Implement PE & MDMP base relocations. DO NOT MERGE YET! #4711
base: dev
Are you sure you want to change the base?
Conversation
* Add missing `PE_IMAGE_FILE_MACHINE` types * Add PE base relocation types Everything is based off of Microsoft's PE format documentation [found here](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format)
Some things I wasn't sure about:
|
@@ -554,30 +638,16 @@ err: | |||
} | |||
|
|||
static int has_canary(RzBinFile *bf) { | |||
// XXX: We only need imports here but this causes leaks, we need to wait for the below. This is a horrible solution! | |||
// TODO: use O(1) when imports sdbized |
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.
Remove this comment too
For now, I think some code duplication is fine. Sharing the code between two plugins is non-trivial at this point. |
64455b5
to
7cac944
Compare
@@ -0,0 +1,74 @@ | |||
// SPDX-FileCopyrightText: 2024 Roee Toledano <roeetoledano10@gmail.com> | |||
// SPDX-License-Identifier: LGPL-3.0-only | |||
#include "pe.h" |
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.
Please leave 1 empty line between SPDX headers and first #include
@@ -0,0 +1,4 @@ | |||
// SPDX-FileCopyrightText: 2024 Roee Toledano <roeetoledano10@gmail.com> | |||
// SPDX-License-Identifier: LGPL-3.0-only | |||
#define RZ_BIN_PE64 1 |
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.
Same
librz/bin/format/pe/pe.h
Outdated
ut32 block_size; | ||
} RzBinPeRelocBlock; | ||
|
||
typedef struct rz_bin_pe_reloc_ent_t { |
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.
Bitfields aren't portable. Please use masks instead. It's ok for keeping them in definition, but they should not be used for reading. It's especially important for reading files of different endianess from the host Rizin compiled 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.
use the le/be methods from rz_util/rz_buf.h
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.
use the le/be methods from
rz_util/rz_buf.h
I've used ble
. Is there something I did wrong?
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.
This needs to be tested via distro-
branch before merge. @XVilka
librz/bin/format/pe/pe_relocs.c
Outdated
rz_buf_read(b, ent_buf, sizeof(ent_buf)); | ||
reloc = rz_read_ble16(ent_buf, big_endian); |
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.
maybe use the rz_buf_read_ble16_offset
which is a special api which updates automatically the offset/address parameter and returns true on successful read.
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.
also be sure to check the boolean return value to fail gracefully.
librz/bin/format/pe/pe_relocs.c
Outdated
rz_buf_read(b, block_buf, sizeof(block_buf)); | ||
RzBinPeRelocBlock block; | ||
PE_READ_STRUCT_FIELD_L(block_buf, block, RzBinPeRelocBlock, page_rva, 32); | ||
PE_READ_STRUCT_FIELD_L(block_buf, block, RzBinPeRelocBlock, block_size, 32); |
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.
you can do the same here using rz_buf_read_bleXX_offset
and checking the return value.
you can do this in a static function like this and fail when returns false.
librz/bin/format/pe/pe_relocs.c
Outdated
|
||
do { | ||
bytes_read += 2; | ||
RzBinPeRelocEnt reloc; |
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.
always init this to 0.
RzBinPeRelocEnt reloc; | |
RzBinPeRelocEnt reloc = 0; |
librz/bin/format/pe/pe_relocs.c
Outdated
do { | ||
ut8 block_buf[sizeof(RzBinPeRelocBlock)]; | ||
rz_buf_read(b, block_buf, sizeof(block_buf)); | ||
RzBinPeRelocBlock block; |
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.
RzBinPeRelocBlock block; | |
RzBinPeRelocBlock block = { 0 }; |
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.
Please always initialize the variables to 0
or NULL
so we can avoid random crashes and weird unintentional behavior.
* Remove old code of setting import entries to PE relocations * Parse PE base relocations * Implement converting from the specific RzBinPeRelocEnt type to the general RzBinReloc type * Implement corrent type naming of PE relocations
* Removed a.exe and b.exe tests, as they don't contain base relocations and swapped them with good tests * Corrected the olds tests 1. Need to add MDMP 2. Need to implement PE relocs patching to get the other tests to work
// encoding is 12 bits for type and 4 bits for offset. | ||
// See: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-reloc-section-image-only | ||
#define PE_RELOC_ENT_TYPE(val) ((val) >> 12) | ||
#define PE_RELOC_ENT_OFFSET(val) ((val)&0b111111111111) |
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'm not sure how 0b111111111111
is portable. use hex (0xfff
).
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.
You're right, totally forgot about that. I'll fix it
Your checklist for this pull request
Detailed description
Up until now PE relocations were implemented as imports, which is incorrect. The PE format uses base relocations for image files (ie executable files) and classic COFF relocations for object files.
Implemented so far:
Still need to implement:
Notes:
type
andoffset
to apply the relocation in....
Test plan
All tests green, except the MDMP & and the ones dependent of relocation patching.
...
Closing issues
...