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'm sorry if this is a bit lengthy, but sometimes I need to hear what's on my mind :)
TL;DR: Proper version of #3588 also handles #3615 (and hopefully some more cases)
Now a bit of prose:
It somehow bugged me that my initial solution (#3588) did not work and I thought about it for some while.
I finally decided to set up VS to see stuff in-depth (thanks for the easy setup!).
To find the root cause, let's use the latest version of x64dbg (snapshot_2025-07-04_16-03) so we can have a common .exe to talk about and also use the last version from the development branch (with the reverted Pull Request)
If I copy the first 2 instructions at the entry point and then do a pattern search in the Current Module (as d2k2-git did in #3615 ), the following instruction is created (argv in cbInstrFindAllMem):
Which returns 1 result at Address=7FF6EB897E40.
The first page that is added to searchPages is the one starting at 7FF6EB890000 (Module Base) which makes sense.
So far, so good, that's what we expected.
But now let's try to find that pattern manually at - let's say - 1 byte before the entry point by typing in the following command:
The first page that is added to searchPages is now the one starting at 7FF6EB8B1000 (Start of .rdata) which is way beyond the place where we wanted to start the search from.
And as expected, we get zero results.
So, my initial idea was that
page.address >= addr
is wrong. The page must start BEFORE the searchaddress, hencepage.address <= addr
would seem like the right logic.And if I change the code to that, my manual command works fine. But now "Search in Current Module" breaks. Why is that so? There must be a problem in the second part of the &&-conjunction.
Let's re-write it a bit so we can place a breakpoint on the interesting part:
It's easy to see that now it adds all pages where the address of the last byte is below the end of the searchrange which is ok, but it will now also add pages where
page.address + page.size < addr
would be true and we would get pages that we don't want.Also now that I can step through the code in the debugger, I see what's the problem: The second page of the module (Address=7FF6EB891000 Size=20000) is within the searchrange, but past the base address, so it's not added.
So what we really need is a "does one range overlap the other?" logic:
Of course you could merge that together, I just find it easier to read.
Testcases:
Result:
searchPages[0] = {address=0x7ff6eb890000}
...
searchPages[7] = {address=0x7ff6eb8cc000}
Result:
searchPages[0] = {address=0x7ff6eb891000}
Same result
Result:
searchPages[0] = {address=0x7ff6eb890000}
No results (as expected)
Result:
searchPages[0] = {address=0x7FFE0000}
...
searchPages[53] = {address=0x7FF8B6067000}
So I'm somewhat sure that this will solve it :)
But now a new problem arises: It is now possible to get searchresults below addr and beyond addr + find_size (which was also the case before), but this is easily fixable by filtering the results.
So for example take the following command:
Without filtering: 2347 results
With filtering: 4 results
Fingers crossed, nothing breaks this time.