Searching process for hex bytes appears to be limited to first 64k

I’ve opened a 64-bit process, and I’m attempting to find a code pattern. Using the UI’s ‘find’ (ctrl-F) I’m able to do so with no problem - there is one instance of this code sequence and it’s found properly. When I search for the same hex sequence via FindAll, I get zero matches. I’ve verified that my script is searching the right process.

In testing to figure out why this is, I stripped what I’m searching for down to the first byte. This results in 43 matches, but the offsets of them are all 0xffff or lower. If I’m reading the parameters correctly, the defaults should result in searching the entire process / file.

To test further, I added additional parameters and changed the ‘start’ parameter to start further into the process. This results in the FindAll showing results for the 64k block starting at this start address. I’ve tried passing larger values than 64k to the ‘size’ parameter but this doesn’t result in searching more of the process.

Here is the code I’m testing with - the commented out FindAll is the full pattern I’m looking for, and the active one is the test search. Again, if I search for that hex sequence with the UI it is properly found.

Thanks in advance!

Printf("Searching for code pattern...\n");

//TFindResults r = FindAll("480FBAE0177211488B15,h");
TFindResults r = FindAll("48,h", true, false, 0, 0.0, 1, 0);

Printf("Total matches: %d\n\n", r.count);

int i;
for(i = 0; i < r.count; i++)
  Printf("%LX %LX\n", r.start[i], r.size[i]);

Additional findings, I updated my script to iterate through 64k blocks and varying the ‘start’ parameter for FindAll, and setting ‘size’ to 64k. This successfully walks all the blocks and gives the right result within a few seconds. Note that if I do the same thing but don’t specify a size field, the script takes a LONG time to run. This makes me believe it’s actually searching more than 64k, but the search result is only including results from the first block. While this does currently give me a workaround, it would fail if the code happened to straddle a 64k boundary. I can of course search overlapping blocks instead, but I’d love if FindAll was working as desired and searching the whole process. I’ve also tried FindFirst and it behaves the same.

Here’s my updated script:

Printf("Searching for code pattern...\n");
int64 fileSize = FileSize();
int64 searchFrom = 0;
local TFindResults r;

Printf("File size: %LX\n", fileSize);

for (searchFrom = 0; searchFrom < fileSize; searchFrom = searchFrom + 0x10000)
{
    //Printf("Searching from %LX\n", searchFrom);
    r = FindAll("480FBAE0177211488B15,h", true, false, 0, 0.0, 1, searchFrom, 0x10000);
    //TFindResults r = FindAll("48,h", true, false, 0, 0.0, 1, 0);
    
    if (r.count > 0)
    {
        Printf("Total matches: %d\n\n", r.count);
    
        int i;
        for(i = 0; i < r.count; i++)
            Printf("%LX %LX\n", r.start[i], r.size[i]);
    }
}

Okay, did some more testing. I tried starting my search from higher starting addresses (before where I know the pattern is), and searching with a size of zero (so it would search the remaining process space hopefully). I found an address from which I could reliably search and find the bytes. Then I started lowering that base address - it would then start failing, and I’d increase it a bit (sort of a binary search process). But then I’d decrease it again and it’d start working. This makes me wonder if it’s sometimes failing when some of the process memory is paged out? After backing the start address down progressively like this, I can now search with 0 start and 0 size and successfully find the bytes. Definitely confusing, and I’m not sure how to go about getting you better repro steps for the problem.

I think what is going on is that the FindAll function is receiving read errors when the process layout has changed (e.g. heaps are created or deleted or resized). When a read error occurs the FIndAll function is stopping and not reporting any other occurrences. We are going to look at this and see if we can either keep going and try to keep searching when a read error occurs, or try to automatically update the process structure when layout changes happen. We’ll have to look into this more and get back to you. Cheers!

Graeme
SweetScape Software

Much appreciated, let me know if I can provide any additional information - I’ll use the iterative workaround for the short term.