Question

I am using c++ cli. I am trying to scan files to see if they have been packed by a pe packer.

here is the problem

if I put my code not in a try block it will scan any file size 20mb or more, but the problem is that if a file is a system file (like ntuser.dat) it will give me an error can not access the file. this is fine because I do not need to scan files like that, so I put my code in a try block to eliminate that error. now the problem is that when it gets to that 20mb file it will skip over it instead of scanning it. I don't know why the try block is making it skip big files. the only way it will not skip the file is if the big file is the first file to be scanned, but that is useless since it will be scanning multiple big files.

here is the code

try
{
    FileStream^ fs2 = gcnew FileStream(line, FileMode::Open, FileAccess::Read, FileShare::ReadWrite);

    BinaryReader^ br = gcnew BinaryReader(fs2);

    array<Byte>^writeArray = br->ReadBytes(br->BaseStream->Length);

    fs2->Close();

    String^ datafile = BitConverter::ToString(writeArray);
    datafile = datafile->Replace("-","");

    if (datafile->Contains("55505830")) {
        listBox1->Items->Add(line);
    }   
}
catch (...)
{

}

I did not put the loop part where it reads the next file from the text file because that part is fine.

so how do I get it to scan big files and ignore the system files.

do I need to change the catch exceptions maybe.

thank you

Was it helpful?

Solution

If your current code is failing, then knowing what exceptions are getting thrown is essential. Before you do anything else, put a Debug::WriteLine in your catch block and see what exceptions you're getting!

However, the method you have listed is near-guaranteed to give you problems on large files. You're reading the entire file contents into memory, then converting the byte array into a Unicode string, resulting in a 6x expansion, then removing dashes from the string, resulting in total memory usage of 10x the original file size.

Instead, read the bytes in and check them as they're read. Perhaps something like this:

array<Byte>^ target = { 0x55, 0x50, 0x58, 0x30 };

try
{
    int matched = 0;
    FileStream^ fs2 = gcnew FileStream(line, FileMode::Open, FileAccess::Read, FileShare::ReadWrite)

    int value;
    do
    {
        value = fs2->ReadByte();
        if(value == target[matched])
            matched++;
        else
            matched = 0;

        if(matched == target->Length)
        {
            listBox1->Items->Add(line);
            break;
        }
    } while (value != -1);

    fs2->Close();
}
catch(Exception^ e)
{
    Debug::WriteLine("Skipping file: " + line + " due to " + e->Message);
}

You'll still get exceptions trying to open operating system files, but at least you'll have some idea what the exceptions are, and you'll be able to handle large files without problems.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top