Skip to content

fix(pe): only map file-backed sections to offsets#527

Open
supervacuus wants to merge 1 commit intom4b:masterfrom
supervacuus:fix/pe-file-backed-rva
Open

fix(pe): only map file-backed sections to offsets#527
supervacuus wants to merge 1 commit intom4b:masterfrom
supervacuus:fix/pe-file-backed-rva

Conversation

@supervacuus
Copy link
Copy Markdown

This is complementary to the parse_imports option change (#522). That change adds an escape hatch for callers who do not need import parsing. This PR otoh, solves the underlying issue that prompted this option (which could still make sense). The result is that, even with import parsing enabled in permissive mode, we get the same baseline runtime as if import parsing were disabled.

For on-disk PE parsing, sections with SizeOfRawData == 0 are virtual-only. goblin currently still maps RVAs in such sections by falling back to VirtualSize. On affected files (in our case, mingw/msys debug companions), this causes unrelated bytes to be parsed as imports, and similarly affects other PE data directories.

This PR makes PE RVA resolution treat sections with SizeOfRawData == 0 as not file-backed. Resource parsing is also made permissive-mode-friendly for the same class of virtual-only .rsrc directories, and the malformed_resource_tree() test is adjusted to assert parse failure rather than a specific panic path since the corrected mapping changes the failure point.

@supervacuus supervacuus changed the title pe: only map file-backed sections to offsets fix(pe): only map file-backed sections to offsets Apr 16, 2026
@m4b
Copy link
Copy Markdown
Owner

m4b commented Apr 20, 2026

@supervacuus just so I fully understand, the other PR that adds permissive parsing to the source directories that I've just merged (and caused a merge conflict with the similar changes in this PR), does this fix the underlying perf issue you were seeing, or does it require the RVA fixes as well?

@supervacuus
Copy link
Copy Markdown
Author

does this fix the underlying perf issue you were seeing, or does it require the RVA fixes as well?

No, they are independent.

Both PRs can make sense independently. But I proposed the other PR due to performance issues this PR would resolve. It might still make sense to turn off imports parsing entirely if this PR lands, but having the option to turn it off would be less relevant for the downstream use cases in symbolic or sentry-cli.

@supervacuus
Copy link
Copy Markdown
Author

Oh, I am sorry... I thought you meant #522, but you were talking about #526, right?

No, while #526 also adds the is_permissive() check as I did in this PR, the essential change for the performance fix is in src/pe/utils.rs.

Copy link
Copy Markdown
Owner

@m4b m4b left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for your patience! I'd like @kkent030315 to review if possible the pe::utils stuff but seems ready to go to me otherwise

Comment thread src/pe/mod.rs Outdated
Comment thread src/pe/utils.rs
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@kkent030315 could you review changes in this file? I generally defer to you on PE stuff :)

Comment thread src/pe/utils.rs

if virtual_size == 0 {
read_size
} else if read_size == 0 {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The only question I have is regressions in other cases that might happen because this check was removed; to be fair, I can't remember why it was added, and there's no comment explaining the logic here, so if this fixes a big bug for you, and all our tests pass, I'm biased towards just merging.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The actual fix is the early exit on size_of_raw_data == 0, which prevents this fallback to virtual_size. I see no other way in which read_size could be 0 now. That is why I removed the check, because it tests a case that should not exist once we exclude size_of_raw_data == 0. But maybe I misunderstood.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This check was added in #396. It was added to fix parsing of the file in https://github.com/ideeockus/goblin/blob/f504af9de4c86bdf697ceb6876f2683c0226886f/tests/bins/pe/exception_rva_mapping/amdcleanuputility.exe.upx_packed, which was giving the same error as #307. That error reappears with this PR regardless of whether this check is removed or not (the earlier early return is enough to cause it). I think the change in this PR is fine, and #396 should be fixed differently (use the permissive parsing option).

Comment thread src/pe/mod.rs Outdated
Comment thread src/pe/mod.rs Outdated
@supervacuus supervacuus force-pushed the fix/pe-file-backed-rva branch from 59932f9 to f4b2c70 Compare April 20, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants