Skip to content
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

Implement PE & MDMP base relocations #4711

Merged
merged 2 commits into from
Nov 21, 2024
Merged

Implement PE & MDMP base relocations #4711

merged 2 commits into from
Nov 21, 2024

Conversation

Roeegg2
Copy link
Contributor

@Roeegg2 Roeegg2 commented Nov 11, 2024

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository
  • I made sure to follow the project's coding style
  • I've documented or updated the documentation of every function and struct this PR changes. If not so I've explained why.
  • I've added tests that prove my fix is effective or that my feature works (if possible)
  • I've updated the rizin book with the relevant information (if needed)

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:

  • PE base relocation parsing + assigning
  • PE base relocation tests

Still need to implement:

  • relocation patching - Rizin always loads the binary in it's expected base address, so no patching is needed (I added a detailed comment about this in relocs function in bin_pe.inc)
  • make MDMP use the new base relocation MDMP doesn't have relocations, only imports.
  • add COFF relocations for object files technically PE can have COFF relocations since it's based off of COFF, but COFF relocations are only used for for object files, and there is no reason to use PE for object files, so it's never actually used.

Notes:

  • There are no names printed with base relocations, since they don't have a symbol/name field associated with them. Simply a type and offset to apply the relocation in.
    ...

Test plan

All tests green.

...

Closing issues

...

@Roeegg2
Copy link
Contributor Author

Roeegg2 commented Nov 11, 2024

Some things I wasn't sure about:

  • The comment in has_canary seems to be from r2, and I don't see what leaks might be caused from this...
  • Should I add licensing to the new created files?
  • I deliberately didn't add COFF base relocations yet, since we could use the COFF format code for this. There is actually quite a handful of code we could use from COFF plugin instead of completely re implementing it for PE. It might be better to add that to a separate issue & PR since this seems like an issue on its own. This might take a lot of work though since it would require changing a lot of the internal structures used by PE plugin, as well as re implementing handling of many things in COFF to make it compatible with PE as well.

librz/bin/format/pe/pe_relocs.c Show resolved Hide resolved
librz/bin/format/pe/pe64_relocs.c Show resolved Hide resolved
librz/bin/format/pe/pe_relocs.c Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
@@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this comment too

@XVilka XVilka changed the title Implement PE & MDMP base relocations. DO NOT MERGE YET! [WIP] Implement PE & MDMP base relocations. DO NOT MERGE YET! Nov 11, 2024
@XVilka
Copy link
Member

XVilka commented Nov 11, 2024

I deliberately didn't add COFF base relocations yet, since we could use the COFF format code for this. There is actually quite a handful of code we could use from COFF plugin instead of completely re implementing it for PE. It might be better to add that to a separate issue & PR since this seems like an issue on its own. This might take a lot of work though since it would require changing a lot of the internal structures used by PE plugin, as well as re implementing handling of many things in COFF to make it compatible with PE as well.

For now, I think some code duplication is fine. Sharing the code between two plugins is non-trivial at this point.

@Roeegg2 Roeegg2 force-pushed the pe-reloc branch 2 times, most recently from 64455b5 to 7cac944 Compare November 11, 2024 16:52
@wargio wargio marked this pull request as draft November 12, 2024 02:29
librz/bin/format/pe/pe_relocs.c Show resolved Hide resolved
@@ -0,0 +1,4 @@
// SPDX-FileCopyrightText: 2024 Roee Toledano <[email protected]>
// SPDX-License-Identifier: LGPL-3.0-only
#define RZ_BIN_PE64 1
Copy link
Member

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 Show resolved Hide resolved
Copy link
Member

@wargio wargio left a 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

Copy link
Member

@wargio wargio left a 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.

librz/bin/format/pe/pe.h Outdated Show resolved Hide resolved
@Roeegg2
Copy link
Contributor Author

Roeegg2 commented Nov 16, 2024

Sorry for the ugly commit history. I could rebase interactive + squash with the old ones so it's easier to review.

@Roeegg2
Copy link
Contributor Author

Roeegg2 commented Nov 16, 2024

All tests are green except flagspace tests. Because there is no symbol associated with base relocations, they have no name associated with them, so I'm not sure how we can use flags here

librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
Copy link
Member

@XVilka XVilka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good changes, but why did you remove MDMP relocs completely?

librz/bin/format/pe/pe_relocs.c Outdated Show resolved Hide resolved
librz/bin/format/pe/pe_relocs.c Outdated Show resolved Hide resolved
librz/bin/format/pe/pe_relocs.c Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Show resolved Hide resolved
@XVilka XVilka added this to the 0.8.0 milestone Nov 20, 2024
@XVilka
Copy link
Member

XVilka commented Nov 20, 2024

I think it should be in 0.8.0 release, assuming it will be finished in time.

@wargio
Copy link
Member

wargio commented Nov 20, 2024

Ok, i checked the documentation and saw how other tools shows this, so the changes are ok, just give it a name like pe_<va offset> so rizin can create the flags reloc.pe_<va offset>, when you define the name use rz_str_newf("pe_%08" PFMT64x", offset) (change "offset" to the correct variable holding the vaddr).

please also fix the mdmp relocs that you have removed.

@Roeegg2 Roeegg2 changed the title [WIP] Implement PE & MDMP base relocations. DO NOT MERGE YET! Implement PE & MDMP base relocations Nov 20, 2024
@Roeegg2 Roeegg2 marked this pull request as ready for review November 20, 2024 14:30
Comment on lines 73 to 74
ut32 page_rva;
ut32 block_size;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please give a short description of what these fields are.
Example of formatting

Suggested change
ut32 page_rva;
ut32 block_size;
ut32 page_rva; ///< PE RVA see doc https://bla
ut32 block_size; ///< PE reloc block size for xxxxx

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a link to the base relocations documentation section of the specification, I will add detailed comments to each struct field too though

librz/bin/format/pe/pe.h Outdated Show resolved Hide resolved
librz/bin/p/bin_pe.inc Outdated Show resolved Hide resolved
MDMP doesn't have any relocations (base or COFF), only contains imports of the dumped executable.
Up until now, imports were used which is wrong.

* Remove MDMP relocations
* Remove MDMP relocations tests
1. Everything is based off of Microsoft's PE format documentation [found here](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format)
2. Up until now, imports were used for relocations in the PE & MDMP format,
   which is wrong. PE uses base relocations.
3. PE relocations do not have symbols associated with them, and thus
   have no name. In order to still have flags in relocs flagspace, dummy
   symbols were allocated with generic names composed of the relocation's
   virtual address space.

* 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
* Add missing `PE_IMAGE_FILE_MACHINE` types
* Add PE base relocation types
* Fix PE format 'has_canary' function
* Remove 'RzBinPEObj.endian' and use 'RzBinPEObj.big_endian' instead
* Removed a.exe and b.exe tests, as they don't contain base relocations
  and swapped them with correct tests
* Corrected old PE relocation tests
* Add new PE base relocation tests
@XVilka XVilka merged commit 82b119d into rizinorg:dev Nov 21, 2024
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants