Fix offset issue when reading StringFileInfo#79
Merged
Conversation
This changes the string parsing logic to add the length of the alignment padding to the size of the string when reporting the size of the StringFileInfo structure. Previously, the caller did not keep track of this, and would end reading the next string a few bytes short. This was generally fixed by the alignment code except for the case where the offset was short by four bytes, leading to the code trying to read the string from the wrong offset leading to corrupted data.
ayoubfaouzi
reviewed
May 30, 2023
Member
There was a problem hiding this comment.
LGTM ! Thanks for the catch @dmjb 👍
I just checked, the pwsh.exe binary file size is not very big that git will complain about it, so you can check in the binary the test folder.
And kudos for the detailed description.
Contributor
Author
|
Thank you for your review @LordNoteworthy. I have included the test file and uncommented out my test case. The tests pass locally in my environment: |
Member
|
Amazing ! Thanks a lot for the contribution. Merging it. FYI @rabbitstack |
Member
|
Tag |
Contributor
|
Thanks for the fix @dmjb and @LordNoteworthy for the heads-up! |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I ran into an issue while using this library to read version info from certain PE files. My main test case has been the exe of Powershell 7.3.4, but have found the same issue in other binaries. Using the latest revision of this library, reading the version info from pwsh.exe would lead to the following truncated and corrupted output:
Debugging the code, I discovered the issue appears to stem from the version parsing code's handling of alignment. The
ParseVersionResourcesfunction keeps track of astringOffsetwhere it expects to find the next string, and passes it to theparseStringfunction. TheparseStringfunction calcuates its own offset into the file based on thestringOffsetpassed to it, aligns the new offset, and then reads the string from the file using the aligned offset.parseStringthen returns the length of the string toParseVersionResources, where it is added to thestringOffsetto get the expected location of the next string.However, the length of the padding is not included in this calculation. As such, when
ParseVersionResourcesadds the string length to its offset, it ends up being a few bytes short of where it should be, since it is adding the length of the string to a non aligned offset. As long as the difference between the expected location and the actual location is not a a multiple of four, the alignment process insideparseStringends up fixing the problem. However in the case of the pwsh.exe binary I was examining, there were two cases where the difference between the expected offset and the actual offset was exactly four bytes. As a result, the alignment did not adjust the offset, and the code attempted to read the string four bytes short of where it should have, resulting in junk data being loaded.To fix this, I added a new private offset calculation function which returns the aligned offset, as well as the number of bytes added to achieve alignment. This latter value is added to the string length before being returned to
ParseVersionResources, and gives the following correct result:I have written a test case around the Powershell binary, but it seems the gitignore rules prevent the inclusion of .exe files. It's not clear to me if I should try and force-add the executable. The binary is relatively small (about 200-odd kb), freely available and is open source software. However, I will defer to the maintainers of this project if they want the binary and the test case included.